From 2a3421790918a265a314f072ced84e0b78b58d99 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:14:47 -0500 Subject: [PATCH] Linux 2.1.89pre2 [sct] a patch against ipc/shm.c was missing from my swap patches, and another fix for spurious warnings about shared dirty pages. [changelog pieced together by davej] --- CREDITS | 11 +- Documentation/Changes | 120 +++++-- Documentation/Configure.help | 7 + Documentation/filesystems/affs.txt | 5 + Documentation/filesystems/vfs.txt | 2 +- Documentation/isdn/README | 2 +- Documentation/m68k/kernel-options.txt | 2 +- arch/alpha/kernel/osf_sys.c | 2 +- arch/i386/kernel/setup.c | 16 +- arch/m68k/defconfig | 2 +- arch/mips/Makefile | 4 +- arch/mips/dec/setup.c | 2 +- arch/mips/deskstation/setup.c | 2 +- arch/ppc/kernel/residual.c | 4 +- drivers/char/Config.in | 1 + drivers/char/apm_bios.c | 65 +++- drivers/char/epca.c | 6 +- drivers/char/lp.c | 18 +- drivers/char/tty_io.c | 6 +- drivers/macintosh/aty.c | 4 +- drivers/misc/parport_arc.c | 6 +- drivers/misc/parport_ax.c | 82 ++--- drivers/misc/parport_pc.c | 108 +++--- drivers/misc/parport_share.c | 1 + drivers/net/dgrs.c | 2 +- drivers/sbus/audio/Makefile | 16 +- drivers/sbus/char/flash.c | 2 +- drivers/scsi/README.ncr53c8xx | 2 +- fs/affs/Changes | 38 ++ fs/affs/bitmap.c | 1 + fs/affs/file.c | 236 +++++++------ fs/affs/inode.c | 36 +- fs/affs/namei.c | 289 +++++++-------- fs/affs/super.c | 486 ++++++++++++++------------ fs/ntfs/fs.c | 9 +- fs/ntfs/inode.c | 7 + include/asm-mips/ng1.h | 26 -- include/asm-mips/prctl.h | 42 --- include/asm-sparc/svr4.h | 2 +- include/asm-sparc64/svr4.h | 2 +- include/linux/affs_fs_sb.h | 1 + include/linux/elf.h | 2 +- include/linux/if_shaper.h | 2 +- include/linux/parport.h | 164 +++++---- include/linux/parport_pc.h | 54 +-- include/linux/sdla_x25.h | 2 +- include/linux/wireless.h | 2 +- include/net/tcp.h | 2 +- ipc/shm.c | 4 +- kernel/ksyms.c | 4 + kernel/module.c | 8 +- mm/page_io.c | 2 + mm/vmscan.c | 13 +- net/core/skbuff.c | 2 +- net/ipv4/syncookies.c | 2 +- net/ipv4/tcp_ipv4.c | 2 +- 56 files changed, 1030 insertions(+), 910 deletions(-) diff --git a/CREDITS b/CREDITS index c0ef35e9bb6d..2b5586c8e8cf 100644 --- a/CREDITS +++ b/CREDITS @@ -37,7 +37,8 @@ N: C. Scott Ananian E: cananian@alumni.princeton.edu W: http://www.pdos.lcs.mit.edu/~cananian P: 1024/85AD9EED AD C0 49 08 91 67 DF D7 FA 04 1A EE 09 E8 44 B0 -D: pty improvements. +D: Unix98 pty support. +D: APM update to 1.2 spec. N: Erik Andersen E: andersee@debian.org @@ -930,8 +931,8 @@ S: Unix Centre of Pedagogical Faculty, University of South Bohemia N: Bas Laarhoven E: bas@vimec.nl D: Loadable modules and ftape driver -S: Mr. v. Boemellaan 39 -S: NL-5237 KA 's-Hertogenbosch +S: J. Obrechtstr 23 +S: NL-5216 GP 's-Hertogenbosch S: The Netherlands N: Savio Lam @@ -1133,8 +1134,8 @@ S: USA N: Dirk Melchers E: dirk@merlin.nbg.sub.org D: 8 bit XT hard disk driver for OMTI5520 -S: Heidackerstrass 19 -S: D-91056 Erlangen +S: Schloessleinsgasse 31 +S: D-90453 Nuernberg S: Germany N: Michael Meskes diff --git a/Documentation/Changes b/Documentation/Changes index db147780c7a3..6f778a20f0e9 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -14,10 +14,10 @@ functional and running at least 2.0.x. therefore owes credit to the same people as that file (Jared Mauch, Axel Boldt, Alessandro Sigala, and countless other users all over the 'net). Please feel free to submit changes, corrections, gripes, -flames, money, etc. to me (gt1355b@prism.gatech.edu). If you do so, -you don't need to bother doing so in the form of a diff, as this is -generated by texinfo so a diff is useless anyway (though I can -incorporate one by hand if you insist upon sending it that way ;-). +flames, money, etc. to me (kaboom@gatech.edu). If you do so, you don't +need to bother doing so in the form of a diff, as this is generated by +texinfo so a diff is useless anyway (though I can incorporate one by +hand if you insist upon sending it that way ;-). Check out http://www.cviog.uga.edu/Misc/info/LinuxBleed.html for an HTML-ized shopping list. @@ -26,8 +26,14 @@ HTML-ized shopping list. http://www.datanet.hu/generations/linux/Changes2.html is an English-language HTML version. -Last updated: September 13. 1997 -Current Author: Chris Ricker (gt1355b@prism.gatech.edu). + The most current version should always be available from +http://cyberbuzz.gatech.edu/kaboom/linux/ as well. + + Also, don't forget http://www.linuxhq.com/ for all your Linux kernel +needs. + +Last updated: February 16. 1998 +Current Author: Chris Ricker (kaboom@gatech.edu). Current Minimal Requirements **************************** @@ -36,21 +42,24 @@ Current Minimal Requirements encountered a bug! If you're unsure what version you're currently running, the suggested command should tell you. -- Kernel modules modutils-2.1.55 ; insmod -V +- Kernel modules modutils-2.1.85 ; insmod -V - Gnu C 2.7.2.3 ; gcc --version - Binutils 2.8.1.0.1 ; ld -v - Linux C Library 5.4.38 ; ls -l /lib/libc.so.* - Dynamic Linker (ld.so) 1.9.5 ; ldd -v - Linux C++ Library 2.7.2.8 ; ls -l /usr/lib/libg++.so.* -- Procps 1.2 ; ps --version +- Procps 1.2.5 ; ps --version - Procinfo 0.11 ; procinfo -v -- Mount 2.6h ; mount --version +- Mount 2.7l ; mount --version - Net-tools 1.41 ; hostname -V - Loadlin 1.6a - Sh-utils 1.16 ; expr --v -- Autofs 0.3.11 ; automount --version +- Autofs 0.3.11 ; automount --version - NFS 0.4.21 ; showmount --version - Bash 1.14.7 ; bash -version +- Ncpfs 2.1.1 ; ncpmount -v +- Pcmcia-cs 2.9.12 +- PPP 2.3.3 ; pppd -v Upgrade notes ************* @@ -76,7 +85,7 @@ accordingly. For modules to work, you need to be running libc-5.4.x or greater. Since updates to libc fix other problems as well (security flaws, for example) and since 5.4.7 is missing a few needed symbols, try to get -the latest 5.4.x you can. Currently, libc-5.4.38 is the latest public +the latest 5.4.x you can. Currently, libc-5.4.44 is the latest public release. If you upgrade to libc-5.4.x, you also have to upgrade your dynamic @@ -90,10 +99,14 @@ unless you're running glibc2 / libc6. If you upgrade to libc-5.4.x, you may also need to upgrade ypbind if you're using NIS. + If you upgrade to libc-5.4.44, please read and pay attention to its +accompanying release notes. The section about it breaking make is not +a joke. + Modules ======= - You need to upgrade to modutils-2.1.55 for kernels 2.1.55 and later. + You need to upgrade to modutils-2.1.85 for kernels 2.1.85 and later. This version will also work with 2.0.x kernels. Binutils @@ -108,9 +121,13 @@ Gnu C You need at least GCC 2.7.2 to compile the kernel. If you're upgrading from an earlier release, you might as well get GCC 2.7.2.3, -the latest public release. If you already have GCC 2.7.2 on your -system, you don't have to upgrade just so the kernel will work (though -feel free to upgrade if you want the gcc bug fixes). +the latest stable public release. If you already have GCC 2.7.2 on +your system, you don't have to upgrade just so the kernel will work +(though feel free to upgrade if you want the gcc bug fixes). + + Note that the latest compilers (egcs, pgcc, gcc 2.8) may do Bad +Things while compiling your kernel, particularly if absurd +optimizations (like -O9) are used. Caveat emptor. Networking Changes ================== @@ -190,18 +207,13 @@ parallel port may no longer be where you expect it; for example, LPT1 /dev/lp0 with the new Plug-and-Play driver. If printing breaks with the new driver, try checking your lpd configuration. -pppd -==== -This kernel version needs a minor bugfix to pppd. See -Documentation/networking/ppp.txt for more information. - Syncookies ========== -When you build your kernel with Syncookie support (CONFIG_SYN_COOKIES) -the syncookie code still defaults to off (unlike the 2.0.30+ behaviour). -You have to explicitely enable it by add a line like -echo 1 >/proc/sys/net/ipv4/tcp_syncookies -to one of your startup scripts (e.g. /etc/rc.d/rc.local on a redhat system) + + When you build your kernel with Syncookie support +(CONFIG_SYN_COOKIES) the syncookie code still defaults to off (unlike +the 2.0.30+ behavior). You have to explicitly enable it by issuing the +following command: echo 1 > /proc/sys/net/ipv4/tcp_syncookies Bash ==== @@ -210,6 +222,24 @@ Bash cause problems when compiling modules. Upgrade to at least 1.14 to fix this problem. +Ncpfs +===== + + To mount NetWare shares, you'll need to upgrade to a more recent +version of the ncpfs utils. + +Pcmcia-cs +========= + + If you use pcmcia cards, you'll need to upgrade the daemon and +support utils to the latest release of pcmcia-cs. + +PPP +=== + + Due to changes in the routing code, those of you using PPP +networking will need to upgrade your pppd. + Where to get the files ********************** @@ -263,16 +293,16 @@ ftp://sunsite.unc.edu/pub/Linux/GCC/ld.so-1.9.5.tar.gz Modules utilities ================= -The 2.1.55 release: -ftp://ftp.redhat.com/pub/alphabits/modutils/modutils-2.1.55.tar.gz -ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.55.tar.gz +The 2.1.85 release: +ftp://ftp.redhat.com/pub/alphabits/modutils/modutils-2.1.85.tar.gz +ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.85.tar.gz Procps utilities ================ The 1.2 release: -ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.tar.gz -ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.tgz +ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.5.tar.gz +ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.5.tgz Procinfo utilities ================== @@ -317,8 +347,8 @@ ftp://prep.ai.mit.edu/pub/gnu/sh-utils-1.16.tar.gz Mount ===== -The 2.6h release: -ftp://ftp.win.tue.nl/pub/linux/util/mount-2.6h.tar.gz +The 2.7l release: +ftp://ftp.win.tue.nl/pub/linux/util/mount/mount-2.7l.tar.gz Autofs ====== @@ -336,9 +366,8 @@ ftp://linux.nrao.edu/pub/people/okir/linux-nfs-0.4.21.tar.gz Net-tools ========= -The 1.41 release: -ftp://ftp.london.uk.eu.org/pub/ipv6/net-tools-1.41.tar.gz -ftp://ftp.cs-ipv6.lancs.ac.uk/pub/Code/Linux/Net_Tools/net-tools-1.41.tar.gz +The 1.432 release: +ftp://ftp.cs-ipv6.lancs.ac.uk/pub/Code/Linux/Net_Tools/net-tools-1.432.tar.gz Ypbind ====== @@ -352,6 +381,25 @@ Bash The 1.14.7 release: ftp://prep.ai.mit.edu/pub/gnu/bash-1.14.7.tar.gz +Ncpfs +===== + +The 2.1.1 release: +ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/ncpfs-2.1.1.tgz +ftp://sunsite.unc.edu/pub/Linux/system/Filesystems/ncpfs/ncpfs-2.1.1.tgz + +Pcmcia-cs +========= + +The 1.9.12 release: +ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs-2.9.12.tar.gz + +PPP +=== + +The 2.3.3 release: +ftp://cs.anu.edu.au/pub/software/ppp/ppp-2.3.3.tar.gz + Other Info ========== @@ -380,5 +428,5 @@ more information and the files. Please send info about any other packages that 2.1.x "broke" or about any new features of 2.1.x that require extra or new packages for use to -Chris Ricker (gt1355b@prism.gatech.edu). +Chris Ricker (kaboom@gatech.edu). diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 49a10500c976..edcb7eb340b6 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -6477,6 +6477,13 @@ CONFIG_APM_POWER_OFF powers off the computer). As with the other APM options, this option may not work reliably with some APM BIOS implementations. +Ignore multiple suspend/standby events +CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + This option is necessary on the Thinkpad 560, but should work on all + other laptops. When the APM BIOS returns multiple suspend or standby + events while one is already being processed they will be ignored. + Without this the Thinkpad 560 has troubles with apmd, and pcmcia-cs. + Watchdog Timer Support CONFIG_WATCHDOG If you say Y here (and to one of the following options) and create a diff --git a/Documentation/filesystems/affs.txt b/Documentation/filesystems/affs.txt index bc892a75bd8b..4c5d7fa7a4ba 100644 --- a/Documentation/filesystems/affs.txt +++ b/Documentation/filesystems/affs.txt @@ -65,6 +65,11 @@ quiet The file system will not return an error for disallowed verbose The volume name, file system type and block size will be written to the syslog when the filesystem is mounted. +mufs The filesystem is really a muFS, also it doesn't + identify itself as one. This option is neccessary if + the filesystem wasn't formatted as muFS, but is used + as one. + prefix=path Path will be prefixed to every absolute path name of symbolic links on an AFFS partition. Default = / diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index e4922c3b966b..0644c2e2fe5d 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -8,7 +8,7 @@ I've learned while writing lofs... The VFS relatively simple, but it is nice not to have to browse through pages of code to determine what is expected when writing a filesystem. Hopefully this helps anyone attempting such a feat, as well as clearing up -a few important points/dependancies. +a few important points/dependencies. register_filesystem (struct file_system_type *fstype) diff --git a/Documentation/isdn/README b/Documentation/isdn/README index 770694f2b819..48dec2d836c8 100644 --- a/Documentation/isdn/README +++ b/Documentation/isdn/README @@ -285,7 +285,7 @@ README for the ISDN-subsystem 5. Application a) For some card-types, firmware has to be loaded into the cards, before - proceeding with device-independant setup. See README. + proceeding with device-independent setup. See README. for how to do that. b) If you only intend to use ttys, you are nearly ready now. diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt index 589d1f7e83d7..7b611ef55cc6 100644 --- a/Documentation/m68k/kernel-options.txt +++ b/Documentation/m68k/kernel-options.txt @@ -567,7 +567,7 @@ Syntax: ataflop=[,[,[,]]] type. The second parameter tells the kernel whether to use - track buffering (1) or not (0). The default is machine dependant: + track buffering (1) or not (0). The default is machine-dependent: no for the Medusa and yes for all others. With the two following parameters, you can change the default diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index d462bfe5e84c..a63fb2be6102 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -872,7 +872,7 @@ asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, software but have not been seen, enable the exception in hardware so that we can update our software status mask. */ fpcr = rdfpcr() & (~FPCR_MASK | FPCR_DYN_MASK); - fpcr = ieee_swcr_to_fpcr(swcr | (~swcr & IEEE_STATUS_MASK)>>16); + fpcr |= ieee_swcr_to_fpcr(swcr | (~swcr & IEEE_STATUS_MASK)>>16); wrfpcr(fpcr); return 0; diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index d2861d3f875d..44eb058131da 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -341,7 +341,7 @@ static struct cpu_model_info cpu_models[] __initdata = { NULL, NULL, NULL, NULL }}, { X86_VENDOR_INTEL, 6, { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II", NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }}, + "Pentium II (0.25 um)", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }}, { X86_VENDOR_CYRIX, 4, { NULL, NULL, NULL, NULL, "MediaGX", NULL, NULL, NULL, NULL, "5x86", NULL, NULL, NULL, NULL, NULL, NULL }}, @@ -383,8 +383,7 @@ __initfunc(void identify_cpu(struct cpuinfo_x86 *c)) c->cpuid_level < 0) return; - if ((c->x86_vendor == X86_VENDOR_AMD && amd_model(c)) || - (c->x86_vendor == X86_VENDOR_CYRIX && cyrix_model(c))) + if (c->x86_vendor == X86_VENDOR_CYRIX && cyrix_model(c)) return; if (c->x86_model < 16) @@ -394,10 +393,15 @@ __initfunc(void identify_cpu(struct cpuinfo_x86 *c)) p = cpu_models[i].model_names[c->x86_model]; break; } - if (p) + if (p) { strcpy(c->x86_model_id, p); - else - sprintf(c->x86_model_id, "%02x/%02x", c->x86_vendor, c->x86_model); + return; + } + + if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c)) + return; + + sprintf(c->x86_model_id, "%02x/%02x", c->x86_vendor, c->x86_model); } static char *cpu_vendor_names[] __initdata = { diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig index 8f09a651303e..e9fe2175b57f 100644 --- a/arch/m68k/defconfig +++ b/arch/m68k/defconfig @@ -15,7 +15,7 @@ CONFIG_EXPERIMENTAL=y # CONFIG_KERNELD is not set # -# Platform dependant setup +# Platform-dependent setup # CONFIG_AMIGA=y # CONFIG_ATARI is not set diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 2624d2d0c7b3..4f596aee902c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -65,7 +65,7 @@ CFLAGS := $(CFLAGS) -g endif # -# CPU dependand compiler/assembler options for optimization. +# CPU-dependent compiler/assembler options for optimization. # ifdef CONFIG_CPU_R3000 CFLAGS := $(CFLAGS) -mcpu=r3000 -mips1 @@ -93,7 +93,7 @@ CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2 endif # -# Board dependand options and extra files +# Board-dependent options and extra files # ifdef CONFIG_ALGOR_P4032 CORE_FILES += arch/mips/algor/algor.o diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index b748371dce34..3a900dd9cc68 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c @@ -1,5 +1,5 @@ /* - * Setup pointers to hardware dependand routines. + * Setup pointers to hardware-dependent routines. * * 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 diff --git a/arch/mips/deskstation/setup.c b/arch/mips/deskstation/setup.c index 939730b91d4e..314ed44d61e4 100644 --- a/arch/mips/deskstation/setup.c +++ b/arch/mips/deskstation/setup.c @@ -1,5 +1,5 @@ /* - * Setup pointers to hardware dependand routines. + * Setup pointers to hardware-dependent routines. * * 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 diff --git a/arch/ppc/kernel/residual.c b/arch/ppc/kernel/residual.c index 3c5f60af8800..fdf62e921764 100644 --- a/arch/ppc/kernel/residual.c +++ b/arch/ppc/kernel/residual.c @@ -300,10 +300,10 @@ static void printsmallpacket(PnP_TAG_PACKET * pkt, int size) { #undef p break; case StartDepFunc: - printk("Start dependant function:\n"); + printk("Start dependent function:\n"); break; case EndDepFunc: - printk("End dependant function\n"); + printk("End dependent function\n"); break; case IOPort: #define p pkt->S8_Pack diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 3ee30b7f91b6..89faab38cdab 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -89,6 +89,7 @@ if [ "$CONFIG_APM" = "y" ]; then bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK bool ' Power off on shutdown' CONFIG_APM_POWER_OFF + bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND fi bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then diff --git a/drivers/char/apm_bios.c b/drivers/char/apm_bios.c index 6419ea55d413..ff07c4b77e7c 100644 --- a/drivers/char/apm_bios.c +++ b/drivers/char/apm_bios.c @@ -27,6 +27,7 @@ * Version 1.0 and 1.1 * May 1996, Version 1.2 * Feb 1998, Version 1.3 + * Feb 1998, Version 1.4 * * History: * 0.6b: first version in official kernel, Linux 1.3.46 @@ -46,8 +47,11 @@ * The new replacment for it is, but Linux doesn't yet support this. * Alan Cox Linux 2.1.55 * 1.3: Set up a valid data descriptor 0x40 for buggy BIOS's + * 1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by + * Dean Gaudet . + * C. Scott Ananian Linux 2.1.87 * - * Reference: + * APM 1.1 Reference: * * Intel Corporation, Microsoft Corporation. Advanced Power Management * (APM) BIOS Interface Specification, Revision 1.1, September 1993. @@ -58,6 +62,15 @@ * ftp://ftp.intel.com/pub/IAL/software_specs/apmv11.doc. It is also * available from Microsoft by calling 206.882.8080.] * + * APM 1.2 Reference: + * Intel Corporation, Microsoft Corporation. Advanced Power Management + * (APM) BIOS Interface Specification, Revision 1.2, February 1996. + * + * [This document is available from Intel at: + * http://www.intel.com/IAL/powermgm + * or Microsoft at + * http://www.microsoft.com/windows/thirdparty/hardware/pcfuture.htm + * ] */ #include @@ -128,6 +141,11 @@ extern unsigned long get_cmos_time(void); * problems have been reported when using this option with gpm (if you'd * like to debug this, please do so). * + * CONFIG_APM_IGNORE_MULTIPLE_SUSPEND: The IBM TP560 bios seems to insist + * on returning multiple suspend/standby events whenever one occurs. We + * really only need one at a time, so just ignore any beyond the first. + * This is probably safe on most laptops. + * * If you are debugging the APM support for your laptop, note that code for * all of these options is contained in this file, so you can #define or * #undef these on the next line to avoid recompiling the whole kernel. @@ -341,6 +359,9 @@ static int clock_slowed = 0; #endif static int suspends_pending = 0; static int standbys_pending = 0; +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND +static int waiting_for_resume = 0; +#endif static long clock_cmos_diff; static int got_clock_diff = 0; @@ -350,7 +371,7 @@ static struct apm_bios_struct * user_list = NULL; static struct timer_list apm_timer; -static char driver_version[] = "1.3"; /* no spaces */ +static char driver_version[] = "1.4"; /* no spaces */ #ifdef APM_DEBUG static char * apm_event_name[] = { @@ -614,8 +635,15 @@ static int queue_event(apm_event_t event, struct apm_bios_struct *sender) if (as == sender) continue; as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; - if (as->event_head == as->event_tail) + if (as->event_head == as->event_tail) { + static int notified; + + if (notified == 0) { + printk( "apm_bios: an event queue overflowed\n" ); + notified = 1; + } as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; + } as->events[as->event_head] = event; if (!as->suser) continue; @@ -722,9 +750,23 @@ static void check_events(void) apm_event_t event; while ((event = get_event()) != 0) { +#ifdef APM_DEBUG + if (event <= NR_APM_EVENT_NAME) + printk(KERN_DEBUG "APM BIOS received %s notify\n", + apm_event_name[event - 1]); + else + printk(KERN_DEBUG "APM BIOS received unknown " + "event 0x%02x\n", event); +#endif switch (event) { case APM_SYS_STANDBY: case APM_USER_STANDBY: +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + if (waiting_for_resume) { + return; + } + waiting_for_resume = 1; +#endif send_event(event, APM_STANDBY_RESUME, NULL); if (standbys_pending <= 0) standby(); @@ -737,6 +779,12 @@ static void check_events(void) break; #endif case APM_SYS_SUSPEND: +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + if (waiting_for_resume) { + return; + } + waiting_for_resume = 1; +#endif send_event(event, APM_NORMAL_RESUME, NULL); if (suspends_pending <= 0) suspend(); @@ -745,6 +793,9 @@ static void check_events(void) case APM_NORMAL_RESUME: case APM_CRITICAL_RESUME: case APM_STANDBY_RESUME: +#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + waiting_for_resume = 0; +#endif set_time(); send_event(event, 0, NULL); break; @@ -763,14 +814,6 @@ static void check_events(void) suspend(); break; } -#ifdef APM_DEBUG - if (event <= NR_APM_EVENT_NAME) - printk(KERN_DEBUG "APM BIOS received %s notify\n", - apm_event_name[event - 1]); - else - printk(KERN_DEBUG "APM BIOS received unknown event 0x%02x\n", - event); -#endif } } diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 7ef302e28f4d..0a6f0dd829e5 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -185,7 +185,7 @@ static struct channel *card_ptr[MAXCARDS]; /* ---------------------------------------------------------------------- Begin generic memory functions. These functions will be alias - (point at) more specific functions dependant on the board being + (point at) more specific functions dependent on the board being configured. ----------------------------------------------------------------------- */ @@ -461,7 +461,7 @@ static inline void pcxi_assertmemoff(struct channel *ch) cards (Such as PCI) needs no windowing routines at all. We provide these do nothing routines so that the same code base can be used. The driver will ALWAYS call a windowing routine if it thinks it needs - to; regardless of the card. However, dependant on the card the routine + to; regardless of the card. However, dependent on the card the routine may or may not do anything. ---------------------------------------------------------------------------*/ @@ -4066,7 +4066,7 @@ int get_PCI_configuration(char bus, char device_fn, base_addr5); /* ------------------------------------------------------------------------ - NOTE - The code below mask out either the 2 or 4 bits dependant on the + NOTE - The code below mask out either the 2 or 4 bits dependent on the space being addressed. (base_addr value reflecting io space, have their first 2 bits mask out, while base_addr value reflecting mem space, have their first 4 bits mask out.) These bits are flag bits and should always diff --git a/drivers/char/lp.c b/drivers/char/lp.c index acb183b4fa35..a27e74098058 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -128,7 +128,7 @@ static int lp_preempt(void *handle) static __inline__ void lp_yield (int minor) { - if (parport_yield (lp_table[minor].dev, 1) == 1 && need_resched) + if (!parport_yield_blocking (lp_table[minor].dev) && need_resched) schedule (); } @@ -654,7 +654,14 @@ static int parport_ptr = 0; __initfunc(void lp_setup(char *str, int *ints)) { - if (!strncmp(str, "parport", 7)) { + if (!str) { + if (ints[0] == 0 || ints[1] == 0) { + /* disable driver on "lp=" or "lp=0" */ + parport[0] = LP_PARPORT_OFF; + } else { + printk(KERN_WARNING "warning: 'lp=0x%x' is deprecated, ignored\n", ints[1]); + } + } else if (!strncmp(str, "parport", 7)) { int n = simple_strtoul(str+7, NULL, 10); if (parport_ptr < LP_NO) parport[parport_ptr++] = n; @@ -667,13 +674,6 @@ __initfunc(void lp_setup(char *str, int *ints)) parport[parport_ptr++] = LP_PARPORT_NONE; } else if (!strcmp(str, "reset")) { reset = 1; - } else { - if (ints[0] == 0 || ints[1] == 0) { - /* disable driver on "lp=" or "lp=0" */ - parport[0] = LP_PARPORT_OFF; - } else { - printk(KERN_WARNING "warning: 'lp=0x%x' is deprecated, ignored\n", ints[1]); - } } } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 65918ce338a4..dcc38830fdd7 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1961,8 +1961,10 @@ long console_init(long kmem_start, long kmem_end) return kmem_start; } -static struct tty_driver dev_tty_driver, dev_console_driver, - dev_syscons_driver, dev_ptmx_driver; +static struct tty_driver dev_tty_driver, dev_syscons_driver, dev_ptmx_driver; +#ifdef CONFIG_VT +static struct tty_driver dev_console_driver; +#endif /* * Ok, now we can initialize the rest of the tty devices and can count diff --git a/drivers/macintosh/aty.c b/drivers/macintosh/aty.c index d4bc50cdbf9e..ec70b4a505bf 100644 --- a/drivers/macintosh/aty.c +++ b/drivers/macintosh/aty.c @@ -39,11 +39,11 @@ struct aty_cmap_regs { typedef struct aty_regvals { int offset[3]; /* first pixel address */ - int crtc_h_sync_strt_wid[3]; /* depth dependant */ + int crtc_h_sync_strt_wid[3]; /* depth dependent */ int crtc_gen_cntl[3]; int mem_cntl[3]; - int crtc_h_tot_disp; /* mode dependant */ + int crtc_h_tot_disp; /* mode dependent */ int crtc_v_tot_disp; int crtc_v_sync_strt_wid; int crtc_off_pitch; diff --git a/drivers/misc/parport_arc.c b/drivers/misc/parport_arc.c index f86ec75305f7..b6a0e08c0a47 100644 --- a/drivers/misc/parport_arc.c +++ b/drivers/misc/parport_arc.c @@ -31,15 +31,15 @@ #define DATA_LATCH 0x3350010 /* ARC can't read from the data latch, so we must use a soft copy. */ -static unsigned int data_copy; +static unsigned char data_copy; -static void arc_write_data(struct parport *p, unsigned int data) +static void arc_write_data(struct parport *p, unsigned char data) { data_copy = data; outb(data, DATA_LATCH); } -static unsigned int arc_read_data(struct parport *p) +static unsigned char arc_read_data(struct parport *p) { return data_copy; } diff --git a/drivers/misc/parport_ax.c b/drivers/misc/parport_ax.c index c2050942cf4e..645b1303e2f9 100644 --- a/drivers/misc/parport_ax.c +++ b/drivers/misc/parport_ax.c @@ -55,83 +55,83 @@ parport_ax_null_intr_func(int irq, void *dev_id, struct pt_regs *regs) } void -parport_ax_write_epp(struct parport *p, unsigned int d) +parport_ax_write_epp(struct parport *p, unsigned char d) { outb(d, p->base + EPPREG); } -unsigned int +unsigned char parport_ax_read_epp(struct parport *p) { - return (unsigned int)inb(p->base + EPPREG); + return inb(p->base + EPPREG); } -unsigned int +unsigned char parport_ax_read_configb(struct parport *p) { - return (unsigned int)inb(p->base + CONFIGB); + return inb(p->base + CONFIGB); } void -parport_ax_write_data(struct parport *p, unsigned int d) +parport_ax_write_data(struct parport *p, unsigned char d) { outb(d, p->base + DATA); } -unsigned int +unsigned char parport_ax_read_data(struct parport *p) { - return (unsigned int)inb(p->base + DATA); + return inb(p->base + DATA); } void -parport_ax_write_control(struct parport *p, unsigned int d) +parport_ax_write_control(struct parport *p, unsigned char d) { outb(d, p->base + CONTROL); } -unsigned int +unsigned char parport_ax_read_control(struct parport *p) { - return (unsigned int)inb(p->base + CONTROL); + return inb(p->base + CONTROL); } -unsigned int -parport_ax_frob_control(struct parport *p, unsigned int mask, unsigned int val) +unsigned char +parport_ax_frob_control(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base + CONTROL); + unsigned char old = inb(p->base + CONTROL); outb(((old & ~mask) ^ val), p->base + CONTROL); return old; } void -parport_ax_write_status(struct parport *p, unsigned int d) +parport_ax_write_status(struct parport *p, unsigned char d) { outb(d, p->base + STATUS); } -unsigned int +unsigned char parport_ax_read_status(struct parport *p) { - return (unsigned int)inb(p->base + STATUS); + return inb(p->base + STATUS); } void -parport_ax_write_econtrol(struct parport *p, unsigned int d) +parport_ax_write_econtrol(struct parport *p, unsigned char d) { outb(d, p->base + ECONTROL); } -unsigned int +unsigned char parport_ax_read_econtrol(struct parport *p) { - return (unsigned int)inb(p->base + ECONTROL); + return inb(p->base + ECONTROL); } -unsigned int -parport_ax_frob_econtrol(struct parport *p, unsigned int mask, unsigned int val) +unsigned char +parport_ax_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base + ECONTROL); + unsigned char old = inb(p->base + ECONTROL); outb(((old & ~mask) ^ val), p->base + ECONTROL); return old; } @@ -143,12 +143,12 @@ parport_ax_change_mode(struct parport *p, int m) } void -parport_ax_write_fifo(struct parport *p, unsigned int v) +parport_ax_write_fifo(struct parport *p, unsigned char v) { outb(v, p->base + DFIFO); } -unsigned int +unsigned char parport_ax_read_fifo(struct parport *p) { return inb(p->base + DFIFO); @@ -221,29 +221,29 @@ parport_ax_restore_state(struct parport *p, struct parport_state *s) parport_ax_write_econtrol(p, s->u.pc.ecr); } -unsigned int -parport_ax_epp_read_block(struct parport *p, void *buf, unsigned int length) +size_t +parport_ax_epp_read_block(struct parport *p, void *buf, size_t length) { return 0; /* FIXME */ } -unsigned int -parport_ax_epp_write_block(struct parport *p, void *buf, unsigned int length) +size_t +parport_ax_epp_write_block(struct parport *p, void *buf, size_t length) { return 0; /* FIXME */ } -unsigned int -parport_ax_ecp_read_block(struct parport *p, void *buf, unsigned int length, - void (*fn)(struct parport *, void *, unsigned int), +int +parport_ax_ecp_read_block(struct parport *p, void *buf, size_t length, + void (*fn)(struct parport *, void *, size_t), void *handle) { return 0; /* FIXME */ } -unsigned int -parport_ax_ecp_write_block(struct parport *p, void *buf, unsigned int length, - void (*fn)(struct parport *, void *, unsigned int), +int +parport_ax_ecp_write_block(struct parport *p, void *buf, size_t length, + void (*fn)(struct parport *, void *, size_t), void *handle) { return 0; /* FIXME */ @@ -331,7 +331,8 @@ static struct parport_operations parport_ax_ops = */ static int parport_ECR_present(struct parport *pb) { - unsigned int r, octr = pb->ops->read_control(pb), + unsigned int r; + unsigned char octr = pb->ops->read_control(pb), oecr = pb->ops->read_econtrol(pb); r = pb->ops->read_control(pb); @@ -360,7 +361,8 @@ static int parport_ECR_present(struct parport *pb) static int parport_ECP_supported(struct parport *pb) { - int i, oecr = pb->ops->read_econtrol(pb); + int i; + unsigned char oecr = pb->ops->read_econtrol(pb); /* If there is no ECONTROL, we have no hope of supporting ECP. */ if (!(pb->modes & PARPORT_MODE_PCECR)) @@ -398,7 +400,8 @@ static int parport_ECP_supported(struct parport *pb) static int parport_PS2_supported(struct parport *pb) { - int ok = 0, octr = pb->ops->read_control(pb); + int ok = 0; + unsigned char octr = pb->ops->read_control(pb); pb->ops->write_control(pb, octr | 0x20); /* try to tri-state buffer */ @@ -415,7 +418,8 @@ static int parport_PS2_supported(struct parport *pb) static int parport_ECPPS2_supported(struct parport *pb) { - int mode, oecr = pb->ops->read_econtrol(pb); + int mode; + unsigned char oecr = pb->ops->read_econtrol(pb); if (!(pb->modes & PARPORT_MODE_PCECR)) return 0; diff --git a/drivers/misc/parport_pc.c b/drivers/misc/parport_pc.c index 2195e7276566..e5ba92c9e89d 100644 --- a/drivers/misc/parport_pc.c +++ b/drivers/misc/parport_pc.c @@ -58,71 +58,71 @@ static void parport_pc_null_intr_func(int irq, void *dev_id, struct pt_regs *reg /* Null function - does nothing */ } -void parport_pc_write_epp(struct parport *p, unsigned int d) +void parport_pc_write_epp(struct parport *p, unsigned char d) { outb(d, p->base+EPPREG); } -unsigned int parport_pc_read_epp(struct parport *p) +unsigned char parport_pc_read_epp(struct parport *p) { - return (unsigned int)inb(p->base+EPPREG); + return inb(p->base+EPPREG); } -unsigned int parport_pc_read_configb(struct parport *p) +unsigned char parport_pc_read_configb(struct parport *p) { - return (unsigned int)inb(p->base+CONFIGB); + return inb(p->base+CONFIGB); } -void parport_pc_write_data(struct parport *p, unsigned int d) +void parport_pc_write_data(struct parport *p, unsigned char d) { outb(d, p->base+DATA); } -unsigned int parport_pc_read_data(struct parport *p) +unsigned char parport_pc_read_data(struct parport *p) { - return (unsigned int)inb(p->base+DATA); + return inb(p->base+DATA); } -void parport_pc_write_control(struct parport *p, unsigned int d) +void parport_pc_write_control(struct parport *p, unsigned char d) { outb(d, p->base+CONTROL); } -unsigned int parport_pc_read_control(struct parport *p) +unsigned char parport_pc_read_control(struct parport *p) { - return (unsigned int)inb(p->base+CONTROL); + return inb(p->base+CONTROL); } -unsigned int parport_pc_frob_control(struct parport *p, unsigned int mask, unsigned int val) +unsigned char parport_pc_frob_control(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base+CONTROL); + unsigned char old = inb(p->base+CONTROL); outb(((old & ~mask) ^ val), p->base+CONTROL); return old; } -void parport_pc_write_status(struct parport *p, unsigned int d) +void parport_pc_write_status(struct parport *p, unsigned char d) { outb(d, p->base+STATUS); } -unsigned int parport_pc_read_status(struct parport *p) +unsigned char parport_pc_read_status(struct parport *p) { - return (unsigned int)inb(p->base+STATUS); + return inb(p->base+STATUS); } -void parport_pc_write_econtrol(struct parport *p, unsigned int d) +void parport_pc_write_econtrol(struct parport *p, unsigned char d) { outb(d, p->base+ECONTROL); } -unsigned int parport_pc_read_econtrol(struct parport *p) +unsigned char parport_pc_read_econtrol(struct parport *p) { - return (unsigned int)inb(p->base+ECONTROL); + return inb(p->base+ECONTROL); } -unsigned int parport_pc_frob_econtrol(struct parport *p, unsigned int mask, unsigned int val) +unsigned char parport_pc_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base+ECONTROL); + unsigned char old = inb(p->base+ECONTROL); outb(((old & ~mask) ^ val), p->base+ECONTROL); return old; } @@ -132,12 +132,12 @@ void parport_pc_change_mode(struct parport *p, int m) /* FIXME */ } -void parport_pc_write_fifo(struct parport *p, unsigned int v) +void parport_pc_write_fifo(struct parport *p, unsigned char v) { /* FIXME */ } -unsigned int parport_pc_read_fifo(struct parport *p) +unsigned char parport_pc_read_fifo(struct parport *p) { return 0; /* FIXME */ } @@ -184,22 +184,22 @@ void parport_pc_restore_state(struct parport *p, struct parport_state *s) parport_pc_write_econtrol(p, s->u.pc.ecr); } -unsigned int parport_pc_epp_read_block(struct parport *p, void *buf, unsigned int length) +size_t parport_pc_epp_read_block(struct parport *p, void *buf, size_t length) { return 0; /* FIXME */ } -unsigned int parport_pc_epp_write_block(struct parport *p, void *buf, unsigned int length) +size_t parport_pc_epp_write_block(struct parport *p, void *buf, size_t length) { return 0; /* FIXME */ } -unsigned int parport_pc_ecp_read_block(struct parport *p, void *buf, unsigned int length, void (*fn)(struct parport *, void *, unsigned int), void *handle) +int parport_pc_ecp_read_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle) { return 0; /* FIXME */ } -unsigned int parport_pc_ecp_write_block(struct parport *p, void *buf, unsigned int length, void (*fn)(struct parport *, void *, unsigned int), void *handle) +int parport_pc_ecp_write_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle) { return 0; /* FIXME */ } @@ -337,7 +337,7 @@ static int parport_detect_dma_transfer(int dma, int size) /* Only if supports ECP mode */ static int programmable_dma_support(struct parport *pb) { - int dma, oldstate = parport_pc_read_econtrol(pb); + unsigned char dma, oldstate = parport_pc_read_econtrol(pb); parport_pc_write_econtrol(pb, 0xe0); /* Configuration MODE */ @@ -375,7 +375,7 @@ static int programmable_dma_support(struct parport *pb) static int parport_dma_probe(struct parport *pb) { int dma,retv; - int dsr,dsr_read; + unsigned char dsr,dsr_read; char *buff; retv = programmable_dma_support(pb); @@ -424,7 +424,7 @@ static int parport_dma_probe(struct parport *pb) */ static int epp_clear_timeout(struct parport *pb) { - int r; + unsigned char r; if (!(parport_pc_read_status(pb) & 0x01)) return 1; @@ -470,7 +470,7 @@ static int parport_SPP_supported(struct parport *pb) */ static int parport_ECR_present(struct parport *pb) { - unsigned int r, octr = parport_pc_read_control(pb), + unsigned char r, octr = parport_pc_read_control(pb), oecr = parport_pc_read_econtrol(pb); r = parport_pc_read_control(pb); @@ -499,7 +499,8 @@ static int parport_ECR_present(struct parport *pb) static int parport_ECP_supported(struct parport *pb) { - int i, oecr = parport_pc_read_econtrol(pb); + int i; + unsigned char oecr = parport_pc_read_econtrol(pb); /* If there is no ECR, we have no hope of supporting ECP. */ if (!(pb->modes & PARPORT_MODE_PCECR)) @@ -553,7 +554,8 @@ static int parport_EPP_supported(struct parport *pb) static int parport_ECPEPP_supported(struct parport *pb) { - int mode, oecr = parport_pc_read_econtrol(pb); + int mode; + unsigned char oecr = parport_pc_read_econtrol(pb); if (!(pb->modes & PARPORT_MODE_PCECR)) return 0; @@ -587,7 +589,8 @@ static int parport_ECPEPP_supported(struct parport *pb) static int parport_PS2_supported(struct parport *pb) { - int ok = 0, octr = parport_pc_read_control(pb); + int ok = 0; + unsigned char octr = parport_pc_read_control(pb); epp_clear_timeout(pb); @@ -606,7 +609,8 @@ static int parport_PS2_supported(struct parport *pb) static int parport_ECPPS2_supported(struct parport *pb) { - int mode, oecr = parport_pc_read_econtrol(pb); + int mode; + unsigned char oecr = parport_pc_read_econtrol(pb); if (!(pb->modes & PARPORT_MODE_PCECR)) return 0; @@ -676,33 +680,25 @@ static int close_intr_election(long tmp) /* Only if supports ECP mode */ static int programmable_irq_support(struct parport *pb) { - int irq, oecr = parport_pc_read_econtrol(pb); + int irq, intrLine; + unsigned char oecr = parport_pc_read_econtrol(pb); + static const int lookup[8] = { + PARPORT_IRQ_NONE, 7, 9, 10, 11, 14, 15, 5 + }; parport_pc_write_econtrol(pb,0xE0); /* Configuration MODE */ - irq = (parport_pc_read_configb(pb) >> 3) & 0x07; - - switch(irq){ - case 2: - irq = 9; - break; - case 7: - irq = 5; - break; - case 0: - irq = PARPORT_IRQ_NONE; - break; - default: - irq += 7; - } - + intrLine = (parport_pc_read_configb(pb) >> 3) & 0x07; + irq = lookup[intrLine]; + parport_pc_write_econtrol(pb, oecr); return irq; } static int irq_probe_ECP(struct parport *pb) { - int irqs, i, oecr = parport_pc_read_econtrol(pb); + int irqs, i; + unsigned char oecr = parport_pc_read_econtrol(pb); probe_irq_off(probe_irq_on()); /* Clear any interrupts */ irqs = open_intr_election(); @@ -725,7 +721,8 @@ static int irq_probe_ECP(struct parport *pb) */ static int irq_probe_EPP(struct parport *pb) { - int irqs, octr = parport_pc_read_control(pb); + int irqs; + unsigned char octr = parport_pc_read_control(pb); #ifndef ADVANCED_DETECT return PARPORT_IRQ_NONE; @@ -755,7 +752,8 @@ static int irq_probe_EPP(struct parport *pb) static int irq_probe_SPP(struct parport *pb) { - int irqs, octr = parport_pc_read_control(pb); + int irqs; + unsigned char octr = parport_pc_read_control(pb); #ifndef ADVANCED_DETECT return PARPORT_IRQ_NONE; diff --git a/drivers/misc/parport_share.c b/drivers/misc/parport_share.c index 62af8735741c..ac0f15ed8a09 100644 --- a/drivers/misc/parport_share.c +++ b/drivers/misc/parport_share.c @@ -90,6 +90,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, tmp->devices = tmp->cad = NULL; tmp->flags = 0; tmp->ops = ops; + tmp->number = portcount; spin_lock_init (&tmp->lock); tmp->name = kmalloc(15, GFP_KERNEL); diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index fc3868f7aa27..e562446e829a 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -21,7 +21,7 @@ * When compiled as a loadable module, this driver can operate * the board as either a 4/6 port switch with a 5th or 7th port * that is a conventional NIC interface as far as the host is - * concerned, OR as 4/6 independant NICs. To select multi-NIC + * concerned, OR as 4/6 independent NICs. To select multi-NIC * mode, add "nicmode=1" on the insmod load line for the driver. * * This driver uses the "dev" common ethernet device structure diff --git a/drivers/sbus/audio/Makefile b/drivers/sbus/audio/Makefile index a4f7c9f48fda..3dcb06f826fc 100644 --- a/drivers/sbus/audio/Makefile +++ b/drivers/sbus/audio/Makefile @@ -16,37 +16,37 @@ O_OBJS := M_OBJS := ifeq ($(CONFIG_SPARCAUDIO),y) -M=y +SBUS_AUDIO=y else ifeq ($(CONFIG_SPARCAUDIO),m) - MM=y + SBUS_AUDIO_MODULE=y endif endif ifeq ($(CONFIG_SPARCAUDIO_AMD7930),y) -M=y +SBUS_AUDIO=y OX_OBJS += amd7930.o else ifeq ($(CONFIG_SPARCAUDIO_AMD7930),m) - MM=y + SBUS_AUDIO_MODULE=y MX_OBJS += amd7930.o endif endif ifeq ($(CONFIG_SPARCAUDIO_CS4231),y) -M=y +SBUS_AUDIO=y O_OBJS += cs4231.o else ifeq ($(CONFIG_SPARCAUDIO_CS4231),m) - MM=y + SBUS_AUDIO_MODULE=y M_OBJS += cs4231.o endif endif -ifdef M +ifdef SBUS_AUDIO OX_OBJS += audio.o else - ifdef MM + ifdef SBUS_AUDIO_MODULE MX_OBJS += audio.o endif endif diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 0f504d6d3657..ba67381a08c1 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -134,7 +134,7 @@ static struct file_operations flash_fops = { flash_llseek, flash_read, NULL, /* no write to the Flash, use mmap - * and play flash dependant tricks. + * and play flash dependent tricks. */ NULL, /* readdir */ NULL, /* poll */ diff --git a/drivers/scsi/README.ncr53c8xx b/drivers/scsi/README.ncr53c8xx index 4dab71b4a63e..4b179a31806b 100644 --- a/drivers/scsi/README.ncr53c8xx +++ b/drivers/scsi/README.ncr53c8xx @@ -941,7 +941,7 @@ applies a patch to some files of the kernel tree. Change to linux source directory Configure with NCR53C7,8XX support = N Configure with NCR53C8XX support = Y (or m) - Make dependancies + Make dependencies Make the kernel (use make zdisk first) Make and install modules if you have configured with 'm' diff --git a/fs/affs/Changes b/fs/affs/Changes index bab6385c4982..851b0514aec0 100644 --- a/fs/affs/Changes +++ b/fs/affs/Changes @@ -28,6 +28,44 @@ Known bugs: Please direct bug reports to: hjw@zvw.de +Version 3.8 +----------- +Bill Hawes kindly reviewed the affs and sent me the +patches he did. They're marked (BH). Thanks, Bill! + +- Cleanup of error handling in read_super(). + Didn't release all ressources in case of an + error. (BH) + +- put_inode() releases the ext cache only if it's + no longer needed. (BH) + +- One set of dentry callbacks is enough. (BH) + +- Cleanup of error handling in namei.c. (BH) + +- Cleanup of error handling in file.c. (BH) + +- The original blocksize of the device is + restored when the fs is unmounted. (BH) + +- getblock() did not invalidate the key cache + when it allocated a new block. + +- Removed some unneccessary locks as Bill + suggested. + +- Simplified match_name(), changed all hashing + and case insensitive name comparisons to use + uppercase. This makes the tolower() routines + obsolete. + +- Added mount option 'mufs' to force muFS + uid/gid interpretation. + +- File mode changes were not updated on disk. + This was fixed before, but somehow got lost. + Version 3.7 ----------- diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index 832214e798ad..26098dd191b4 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c @@ -7,6 +7,7 @@ * block allocation, deallocation, calculation of free space. */ +#define DEBUG 0 #include #include #include diff --git a/fs/affs/file.c b/fs/affs/file.c index 79b66d0e73b4..d0d4bd7bcf48 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -309,7 +309,7 @@ affs_bmap(struct inode *inode, int block) for (;;) { bh = affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode)); - if (!bh) + if (!bh) return 0; index = seqnum_to_index(ext); if (index > inode->u.affs_i.i_ec->max_ext && @@ -360,57 +360,57 @@ affs_bmap(struct inode *inode, int block) static struct buffer_head * affs_getblock(struct inode *inode, s32 block) { - struct buffer_head *bh; - struct buffer_head *ebh; - struct buffer_head *pbh; + struct super_block *sb = inode->i_sb; + int ofs = sb->u.affs_sb.s_flags & SF_OFS; + int ext = block / AFFS_I2HSIZE(inode); + struct buffer_head *bh, *ebh, *pbh = NULL; struct key_cache *kc; s32 key, nkey; - int ext; int cf, j, pt; int index; - int ofs; + int err; pr_debug("AFFS: getblock(%lu,%d)\n",inode->i_ino,block); if (block < 0) - return NULL; + goto out_fail; - /* Writers always use cache line 3. In almost all cases, files - * will be written by only one process at the same time, and - * they also will be written in strict sequential order. Thus - * there is not much sense in looking whether the key of the - * requested block is available - it won't be there. - */ - kc = &inode->u.affs_i.i_ec->kc[3]; - ofs = inode->i_sb->u.affs_sb.s_flags & SF_OFS; - ext = block / AFFS_I2HSIZE(inode); key = calc_key(inode,&ext); block -= ext * AFFS_I2HSIZE(inode); pt = ext ? T_LIST : T_SHORT; - pbh = NULL; + /* Key refers now to the last known extension block, + * ext is its sequence number (if 0, key refers to the + * header block), and block is the block number relative + * to the first block stored in that extension block. + */ for (;;) { /* Loop over header block and extension blocks */ + struct file_front *fdp; + bh = affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode)); if (!bh) - return NULL; - if (affs_checksum_block(AFFS_I2BSIZE(inode),bh->b_data,&cf,&j) || - cf != pt || j != ST_FILE) { - affs_error(inode->i_sb,"getblock","Inode %d is not a valid %s",key, - pt == T_SHORT ? "file header" : "extension block"); - affs_brelse(bh); - return NULL; + goto out_fail; + fdp = (struct file_front *) bh->b_data; + err = affs_checksum_block(AFFS_I2BSIZE(inode),bh->b_data,&cf,&j); + if (err || cf != pt || j != ST_FILE) { + affs_error(sb, "getblock", + "Block %d is not a valid %s", key, + pt == T_SHORT ? "file header" : "ext block"); + goto out_free_bh; } j = be32_to_cpu(((struct file_front *)bh->b_data)->block_count); - cf = 0; - while (j < AFFS_I2HSIZE(inode) && j <= block) { + for (cf = 0; j < AFFS_I2HSIZE(inode) && j <= block; j++) { if (ofs && !pbh && inode->u.affs_i.i_lastblock >= 0) { - if (j > 0) - pbh = affs_bread(inode->i_dev,cpu_to_be32(AFFS_BLOCK(bh->b_data,inode,j - 1)), - AFFS_I2BSIZE(inode)); - else + if (j > 0) { + s32 k = AFFS_BLOCK(bh->b_data, inode, + j - 1); + pbh = affs_bread(inode->i_dev, + be32_to_cpu(k), + AFFS_I2BSIZE(inode)); + } else pbh = affs_getblock(inode,inode->u.affs_i.i_lastblock); if (!pbh) { - affs_error(inode->i_sb,"getblock", + affs_error(sb,"getblock", "Cannot get last block in file"); break; } @@ -419,46 +419,44 @@ affs_getblock(struct inode *inode, s32 block) if (!nkey) break; inode->u.affs_i.i_lastblock++; - lock_super(inode->i_sb); if (AFFS_BLOCK(bh->b_data,inode,j)) { - unlock_super(inode->i_sb); - affs_warning(inode->i_sb,"getblock","Block already allocated"); - affs_free_block(inode->i_sb,nkey); - j++; + affs_warning(sb,"getblock","Block already allocated"); + affs_free_block(sb,nkey); continue; } - unlock_super(inode->i_sb); AFFS_BLOCK(bh->b_data,inode,j) = cpu_to_be32(nkey); if (ofs) { ebh = affs_bread(inode->i_dev,nkey,AFFS_I2BSIZE(inode)); if (!ebh) { - affs_error(inode->i_sb,"getblock", + affs_error(sb,"getblock", "Cannot get block %d",nkey); - affs_free_block(inode->i_sb,nkey); + affs_free_block(sb,nkey); AFFS_BLOCK(bh->b_data,inode,j) = 0; break; } DATA_FRONT(ebh)->primary_type = cpu_to_be32(T_DATA); DATA_FRONT(ebh)->header_key = cpu_to_be32(inode->i_ino); DATA_FRONT(ebh)->sequence_number = cpu_to_be32(inode->u.affs_i.i_lastblock + 1); + affs_fix_checksum(AFFS_I2BSIZE(inode), + ebh->b_data, 5); + mark_buffer_dirty(ebh, 0); if (pbh) { DATA_FRONT(pbh)->data_size = cpu_to_be32(AFFS_I2BSIZE(inode) - 24); DATA_FRONT(pbh)->next_data = cpu_to_be32(nkey); affs_fix_checksum(AFFS_I2BSIZE(inode),pbh->b_data,5); mark_buffer_dirty(pbh,0); - mark_buffer_dirty(ebh,0); affs_brelse(pbh); } pbh = ebh; } - j++; cf = 1; } + /* N.B. May need to release pbh after here */ + if (cf) { if (pt == T_SHORT) - ((struct file_front *)bh->b_data)->first_data = - AFFS_BLOCK(bh->b_data,inode,0); - ((struct file_front *)bh->b_data)->block_count = cpu_to_be32(j); + fdp->first_data = AFFS_BLOCK(bh->b_data,inode,0); + fdp->block_count = cpu_to_be32(j); affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5); mark_buffer_dirty(bh,1); } @@ -469,52 +467,63 @@ affs_getblock(struct inode *inode, s32 block) break; } if (j < AFFS_I2HSIZE(inode)) { - affs_brelse(bh); - return NULL; + /* N.B. What about pbh here? */ + goto out_free_bh; } block -= AFFS_I2HSIZE(inode); key = be32_to_cpu(FILE_END(bh->b_data,inode)->extension); if (!key) { key = affs_new_header(inode); - if (!key) { - affs_brelse(bh); - return NULL; - } + if (!key) + goto out_free_bh; ebh = affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode)); if (!ebh) { - affs_free_block(inode->i_sb,key); - return NULL; + /* N.B. must free bh here */ + goto out_free_block; } ((struct file_front *)ebh->b_data)->primary_type = cpu_to_be32(T_LIST); ((struct file_front *)ebh->b_data)->own_key = cpu_to_be32(key); FILE_END(ebh->b_data,inode)->secondary_type = cpu_to_be32(ST_FILE); FILE_END(ebh->b_data,inode)->parent = cpu_to_be32(inode->i_ino); affs_fix_checksum(AFFS_I2BSIZE(inode),ebh->b_data,5); + mark_buffer_dirty(ebh, 1); FILE_END(bh->b_data,inode)->extension = cpu_to_be32(key); affs_fix_checksum(AFFS_I2BSIZE(inode),bh->b_data,5); mark_buffer_dirty(bh,1); affs_brelse(bh); bh = ebh; } - affs_brelse(bh); pt = T_LIST; ext++; - if ((index = seqnum_to_index(ext)) > inode->u.affs_i.i_ec->max_ext && - AFFS_ISINDEX(ext) && inode->u.affs_i.i_ec) { + index = seqnum_to_index(ext); + if (index > inode->u.affs_i.i_ec->max_ext && + AFFS_ISINDEX(ext)) { inode->u.affs_i.i_ec->ec[index] = key; inode->u.affs_i.i_ec->max_ext = index; } + affs_brelse(bh); + } + + /* Invalidate key cache */ + for (j = 0; j < 4; j++) { + kc = &inode->u.affs_i.i_ec->kc[j]; + kc->kc_last = -1; } - kc->kc_this_key = key; - kc->kc_this_seq = ext; - kc->kc_next_key = be32_to_cpu(FILE_END(bh->b_data,inode)->extension); key = be32_to_cpu(AFFS_BLOCK(bh->b_data,inode,block)); affs_brelse(bh); if (!key) - return NULL; - - return affs_bread(inode->i_dev,key,AFFS_I2BSIZE(inode)); + goto out_fail; + + bh = affs_bread(inode->i_dev, key, AFFS_I2BSIZE(inode)); + return bh; + +out_free_block: + affs_free_block(sb, key); +out_free_bh: + affs_brelse(bh); +out_fail: + return NULL; } static ssize_t @@ -592,14 +601,11 @@ affs_file_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) inode->i_mode); return -EINVAL; } - if (!inode->u.affs_i.i_ec) { - if (alloc_ext_cache(inode)) { - return -ENOMEM; - } - } - if (filp->f_flags & O_APPEND) { + if (!inode->u.affs_i.i_ec && alloc_ext_cache(inode)) + return -ENOMEM; + if (filp->f_flags & O_APPEND) pos = inode->i_size; - } else + else pos = *ppos; written = 0; blocksize = AFFS_I2BSIZE(inode); @@ -734,6 +740,23 @@ affs_file_write_ofs(struct file *filp, const char *buf, size_t count, loff_t *pp return written; } +/* Free any preallocated blocks */ +void +affs_free_prealloc(struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + int block; + + pr_debug("AFFS: free_prealloc(ino=%lu)\n", inode->i_ino); + + while (inode->u.affs_i.i_pa_cnt) { + block = inode->u.affs_i.i_data[inode->u.affs_i.i_pa_next++]; + inode->u.affs_i.i_pa_next &= AFFS_MAX_PREALLOC - 1; + inode->u.affs_i.i_pa_cnt--; + affs_free_block(sb, block); + } +} + void affs_truncate(struct inode *inode) { @@ -764,12 +787,7 @@ affs_truncate(struct inode *inode) } bh = affs_getblock(inode,first - 1); - while (inode->u.affs_i.i_pa_cnt) { /* Free any preallocated blocks */ - affs_free_block(inode->i_sb, - inode->u.affs_i.i_data[inode->u.affs_i.i_pa_next++]); - inode->u.affs_i.i_pa_next &= AFFS_MAX_PREALLOC - 1; - inode->u.affs_i.i_pa_cnt--; - } + affs_free_prealloc(inode); if (inode->u.affs_i.i_zone) { lock_super(inode->i_sb); zone = &inode->i_sb->u.affs_sb.s_zones[inode->u.affs_i.i_zone]; @@ -868,56 +886,66 @@ affs_truncate(struct inode *inode) static int affs_release_file(struct inode *inode, struct file *filp) { + struct super_block *sb = inode->i_sb; struct affs_zone *zone; pr_debug("AFFS: release_file(ino=%lu)\n",inode->i_ino); if (filp->f_mode & 2) { /* Free preallocated blocks */ - while (inode->u.affs_i.i_pa_cnt) { - affs_free_block(inode->i_sb, - inode->u.affs_i.i_data[inode->u.affs_i.i_pa_next++]); - inode->u.affs_i.i_pa_next &= AFFS_MAX_PREALLOC - 1; - inode->u.affs_i.i_pa_cnt--; - } + affs_free_prealloc(inode); if (inode->u.affs_i.i_zone) { - lock_super(inode->i_sb); - zone = &inode->i_sb->u.affs_sb.s_zones[inode->u.affs_i.i_zone]; + zone = &sb->u.affs_sb.s_zones[inode->u.affs_i.i_zone]; if (zone->z_ino == inode->i_ino) zone->z_ino = 0; - unlock_super(inode->i_sb); } } return 0; } +/* + * Called only when we need to allocate the extension cache. + */ static int alloc_ext_cache(struct inode *inode) { s32 key; int i; + unsigned long cache_page; + int error = 0; pr_debug("AFFS: alloc_ext_cache(ino=%lu)\n",inode->i_ino); - lock_super(inode->i_sb); - if (!inode->u.affs_i.i_ec) { - inode->u.affs_i.i_ec = (struct ext_cache *)get_free_page(GFP_KERNEL); - if (inode->u.affs_i.i_ec) { - /* We only have to initialize non-zero values. - * get_free_page() zeroed the page already. - */ - key = inode->u.affs_i.i_original ? inode->u.affs_i.i_original : inode->i_ino; - inode->u.affs_i.i_ec->ec[0] = key; - for (i = 0; i < 4; i++) { - inode->u.affs_i.i_ec->kc[i].kc_this_key = key; - inode->u.affs_i.i_ec->kc[i].kc_last = -1; - } - } - } - unlock_super(inode->i_sb); - - if (!inode->u.affs_i.i_ec) { - affs_error(inode->i_sb,"alloc_ext_cache","Cache allocation failed"); - return -ENOMEM; + cache_page = get_free_page(GFP_KERNEL); + /* + * Check whether somebody else allocated it for us ... + */ + if (inode->u.affs_i.i_ec) + goto out_free; + if (!cache_page) + goto out_error; + + inode->u.affs_i.i_ec = (struct ext_cache *) cache_page; + /* We only have to initialize non-zero values. + * get_free_page() zeroed the page already. + */ + key = inode->u.affs_i.i_original; + if (!inode->u.affs_i.i_original) + key = inode->i_ino; + inode->u.affs_i.i_ec->ec[0] = key; + for (i = 0; i < 4; i++) { + inode->u.affs_i.i_ec->kc[i].kc_this_key = key; + inode->u.affs_i.i_ec->kc[i].kc_last = -1; } - return 0; +out: + return error; + +out_free: + if (cache_page) + free_page(cache_page); + goto out; + +out_error: + affs_error(inode->i_sb,"alloc_ext_cache","Cache allocation failed"); + error = -ENOMEM; + goto out; } diff --git a/fs/affs/inode.c b/fs/affs/inode.c index d94d14643191..9dc72d6e04f1 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c @@ -229,36 +229,40 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr) error = inode_change_ok(inode,attr); if (error) - return error; + goto out; if (((attr->ia_valid & ATTR_UID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETUID)) || ((attr->ia_valid & ATTR_GID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETGID)) || ((attr->ia_valid & ATTR_MODE) && - (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) - error = -EPERM; - - if (error) - return (inode->i_sb->u.affs_sb.s_flags & SF_QUIET) ? 0 : error; + (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) { + if (!(inode->i_sb->u.affs_sb.s_flags & SF_QUIET)) + error = -EPERM; + goto out; + } if (attr->ia_valid & ATTR_MODE) inode->u.affs_i.i_protect = mode_to_prot(attr->ia_mode); - inode_setattr(inode,attr); - - return 0; + inode_setattr(inode, attr); + mark_inode_dirty(inode); + error = 0; +out: + return error; } void affs_put_inode(struct inode *inode) { - pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink); - lock_super(inode->i_sb); - if (inode->u.affs_i.i_ec) { - pr_debug("AFFS: freeing ext cache\n"); - free_page((unsigned long)inode->u.affs_i.i_ec); - inode->u.affs_i.i_ec = NULL; + pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", + inode->i_ino,inode->i_nlink); + if (inode->i_count == 1) { + unsigned long cache_page = (unsigned long) inode->u.affs_i.i_ec; + if (cache_page) { + pr_debug("AFFS: freeing ext cache\n"); + inode->u.affs_i.i_ec = NULL; + free_page(cache_page); + } } - unlock_super(inode->i_sb); } void diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 5ae476cee9eb..96d8c6f5a946 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -21,23 +21,17 @@ #include -/* Simple toupper()/tolower() for DOS\1 */ +/* Simple toupper() for DOS\1 */ -static inline unsigned int +static unsigned int affs_toupper(unsigned int ch) { return ch >= 'a' && ch <= 'z' ? ch -= ('a' - 'A') : ch; } -static inline unsigned int -affs_tolower(unsigned int ch) -{ - return ch >= 'A' && ch <= 'Z' ? ch + ('a' - 'A') : ch; -} +/* International toupper() for DOS\3 ("international") */ -/* International toupper()/tolower() for DOS\3 ("international") */ - -static inline unsigned int +static unsigned int affs_intl_toupper(unsigned int ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 0xE0 @@ -45,23 +39,8 @@ affs_intl_toupper(unsigned int ch) ch - ('a' - 'A') : ch; } -static inline unsigned int -affs_intl_tolower(unsigned int ch) -{ - return (ch >= 'A' && ch <= 'Z') || (ch >= 0xC0 - && ch <= 0xDE && ch != 0xD7) ? - ch + ('a' - 'A') : ch; -} - -/* We need 2 sets of dentry operations, since we cannot - * determine the fs flavour in the callback routines. - */ - static int affs_hash_dentry(struct dentry *, struct qstr *); static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); -static int affs_hash_dentry_intl(struct dentry *, struct qstr *); -static int affs_compare_dentry_intl(struct dentry *, struct qstr *, struct qstr *); - struct dentry_operations affs_dentry_operations = { NULL, /* d_validate */ affs_hash_dentry, /* d_hash */ @@ -69,24 +48,25 @@ struct dentry_operations affs_dentry_operations = { NULL /* d_delete */ }; -struct dentry_operations affs_dentry_operations_intl = { - NULL, /* d_validate */ - affs_hash_dentry_intl, /* d_hash */ - affs_compare_dentry_intl, /* d_compare */ - NULL /* d_delete */ -}; - +/* + * Note: the dentry argument is the parent dentry. + */ static int affs_hash_dentry(struct dentry *dentry, struct qstr *qstr) { + unsigned int (*toupper)(unsigned int) = affs_toupper; unsigned long hash; int i; if ((i = affs_check_name(qstr->name,qstr->len))) return i; + + /* Check whether to use the international 'toupper' routine */ + if (AFFS_I2FSTYPE(dentry->d_inode)) + toupper = affs_intl_toupper; hash = init_name_hash(); for (i = 0; i < qstr->len && i < 30; i++) - hash = partial_name_hash(affs_tolower(qstr->name[i]),hash); + hash = partial_name_hash(toupper(qstr->name[i]), hash); qstr->hash = end_name_hash(hash); return 0; @@ -95,6 +75,9 @@ affs_hash_dentry(struct dentry *dentry, struct qstr *qstr) static int affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) { + unsigned int (*toupper)(unsigned int) = affs_toupper; + int alen = a->len; + int blen = b->len; int i; /* 'a' is the qstr of an already existing dentry, so the name @@ -107,45 +90,19 @@ affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) /* If the names are longer than the allowed 30 chars, * the excess is ignored, so their length may differ. */ - - if ((a->len < 30 || b->len < 30) && a->len != b->len) + if (alen > 30) + alen = 30; + if (blen > 30) + blen = 30; + if (alen != blen) return 1; - for (i = 0; i < a->len && i < 30; i++) - if (affs_tolower(a->name[i]) != affs_tolower(b->name[i])) - return 1; - - return 0; -} - -static int -affs_hash_dentry_intl(struct dentry *dentry, struct qstr *qstr) -{ - unsigned long hash; - int i; + /* Check whether to use the international 'toupper' routine */ + if (AFFS_I2FSTYPE(dentry->d_inode)) + toupper = affs_intl_toupper; - if ((i = affs_check_name(qstr->name,qstr->len))) - return i; - hash = init_name_hash(); - for (i = 0; i < qstr->len && i < 30; i++) - hash = partial_name_hash(affs_intl_tolower(qstr->name[i]),hash); - qstr->hash = end_name_hash(hash); - - return 0; -} - -static int -affs_compare_dentry_intl(struct dentry *dentry, struct qstr *a, struct qstr *b) -{ - int i; - - if (affs_check_name(b->name,b->len)) - return 1; - if ((a->len < 30 || b->len < 30) && a->len != b->len) - return 1; - - for (i = 0; i < a->len && i < 30; i++) - if (affs_intl_tolower(a->name[i]) != affs_intl_tolower(b->name[i])) + for (i = 0; i < alen; i++) + if (toupper(a->name[i]) != toupper(b->name[i])) return 1; return 0; @@ -158,6 +115,9 @@ affs_compare_dentry_intl(struct dentry *dentry, struct qstr *a, struct qstr *b) static int affs_match(const unsigned char *name, int len, const unsigned char *compare, int dlen, int intl) { + unsigned int (*toupper)(unsigned int) = intl ? affs_intl_toupper : affs_toupper; + int i; + if (!compare) return 0; @@ -171,21 +131,9 @@ affs_match(const unsigned char *name, int len, const unsigned char *compare, int return 1; if (dlen != len) return 0; - if (intl) { - while (dlen--) { - if (affs_intl_toupper(*name) != affs_intl_toupper(*compare)) - return 0; - name++; - compare++; - } - } else { - while (dlen--) { - if (affs_toupper(*name) != affs_toupper(*compare)) - return 0; - name++; - compare++; - } - } + for (i = 0; i < len; i++) + if (toupper(name[i]) != toupper(compare[i])) + return 0; return 1; } @@ -211,23 +159,22 @@ static struct buffer_head * affs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino) { struct buffer_head *bh; - int intl; + int intl = AFFS_I2FSTYPE(dir); s32 key; const char *name = dentry->d_name.name; int namelen = dentry->d_name.len; pr_debug("AFFS: find_entry(\"%.*s\")\n",namelen,name); - intl = AFFS_I2FSTYPE(dir); - bh = affs_bread(dir->i_dev,dir->i_ino,AFFS_I2BSIZE(dir)); + bh = affs_bread(dir->i_dev,dir->i_ino,AFFS_I2BSIZE(dir)); if (!bh) return NULL; - if (affs_match(name,namelen,".",1,intl)) { + if (namelen == 1 && name[0] == '.') { *ino = dir->i_ino; return bh; } - if (affs_match(name,namelen,"..",2,intl)) { + if (namelen == 2 && name[0] == '.' && name[1] == '.') { *ino = affs_parent_ino(dir); return bh; } @@ -239,10 +186,9 @@ affs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino) int cnamelen; affs_brelse(bh); - if (key == 0) { - bh = NULL; + bh = NULL; + if (key == 0) break; - } bh = affs_bread(dir->i_dev,key,AFFS_I2BSIZE(dir)); if (!bh) break; @@ -274,8 +220,7 @@ affs_lookup(struct inode *dir, struct dentry *dentry) if (!inode) return -EACCES; } - dentry->d_op = AFFS_I2FSTYPE(dir) ? &affs_dentry_operations_intl - : &affs_dentry_operations; + dentry->d_op = &affs_dentry_operations; d_add(dentry,inode); return 0; } @@ -291,10 +236,7 @@ affs_unlink(struct inode *dir, struct dentry *dentry) pr_debug("AFFS: unlink(dir=%ld,\"%.*s\")\n",dir->i_ino, (int)dentry->d_name.len,dentry->d_name.name); - bh = NULL; retval = -ENOENT; - if (!dir) - goto unlink_done; if (!(bh = affs_find_entry(dir,dentry,&ino))) goto unlink_done; @@ -312,8 +254,10 @@ affs_unlink(struct inode *dir, struct dentry *dentry) inode->i_nlink = retval; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); - retval = 0; d_delete(dentry); + mark_inode_dirty(dir); + retval = 0; + unlink_done: affs_brelse(bh); return retval; @@ -328,11 +272,10 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode) pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,(int)dentry->d_name.len, dentry->d_name.name,mode); - if (!dir) - return -ENOENT; + error = -ENOSPC; inode = affs_new_inode(dir); if (!inode) - return -ENOSPC; + goto out; pr_debug(" -- ino=%lu\n",inode->i_ino); if (dir->i_sb->u.affs_sb.s_flags & SF_OFS) @@ -341,19 +284,22 @@ affs_create(struct inode *dir, struct dentry *dentry, int mode) inode->i_op = &affs_file_inode_operations; error = affs_add_entry(dir,NULL,inode,dentry,ST_FILE); - if (error) { - inode->i_nlink = 0; - mark_inode_dirty(inode); - iput(inode); - return error; - } + if (error) + goto out_iput; inode->i_mode = mode; inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode); + d_instantiate(dentry,inode); + mark_inode_dirty(inode); dir->i_version = ++event; mark_inode_dirty(dir); - d_instantiate(dentry,inode); +out: + return error; - return 0; +out_iput: + inode->i_nlink = 0; + mark_inode_dirty(inode); + iput(inode); + goto out; } int @@ -365,25 +311,29 @@ affs_mkdir(struct inode *dir, struct dentry *dentry, int mode) pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%o)\n",dir->i_ino, (int)dentry->d_name.len,dentry->d_name.name,mode); + error = -ENOSPC; inode = affs_new_inode(dir); if (!inode) - return -ENOSPC; + goto out; inode->i_op = &affs_dir_inode_operations; error = affs_add_entry(dir,NULL,inode,dentry,ST_USERDIR); - if (error) { - inode->i_nlink = 0; - mark_inode_dirty(inode); - iput(inode); - return error; - } + if (error) + goto out_iput; inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask); inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode); + d_instantiate(dentry,inode); + mark_inode_dirty(inode); dir->i_version = ++event; mark_inode_dirty(dir); - d_instantiate(dentry,inode); +out: + return error; - return 0; +out_iput: + inode->i_nlink = 0; + mark_inode_dirty(inode); + iput(inode); + goto out; } static int @@ -399,24 +349,18 @@ empty_dir(struct buffer_head *bh, int hashsize) int affs_rmdir(struct inode *dir, struct dentry *dentry) { + struct inode *inode = dentry->d_inode; int retval; unsigned long ino; - struct inode *inode; struct buffer_head *bh; pr_debug("AFFS: rmdir(dir=%lu,\"%.*s\")\n",dir->i_ino, (int)dentry->d_name.len,dentry->d_name.name); - inode = NULL; - bh = NULL; retval = -ENOENT; - if (!dir) - goto rmdir_done; if (!(bh = affs_find_entry(dir,dentry,&ino))) goto rmdir_done; - inode = dentry->d_inode; - retval = -EPERM; if (current->fsuid != inode->i_uid && current->fsuid != dir->i_uid && !fsuser()) @@ -425,31 +369,31 @@ affs_rmdir(struct inode *dir, struct dentry *dentry) goto rmdir_done; if (inode == dir) /* we may not delete ".", but "../dir" is ok */ goto rmdir_done; - if (!S_ISDIR(inode->i_mode)) { - retval = -ENOTDIR; + retval = -ENOTDIR; + if (!S_ISDIR(inode->i_mode)) goto rmdir_done; - } - down(&inode->i_sem); - if (dentry->d_count > 1) { + /* + * Make sure the directory is empty and the dentry isn't busy. + */ + if (dentry->d_count > 1) shrink_dcache_parent(dentry); - } - up(&inode->i_sem); - if (!empty_dir(bh,AFFS_I2HSIZE(inode))) { - retval = -ENOTEMPTY; + retval = -ENOTEMPTY; + if (!empty_dir(bh,AFFS_I2HSIZE(inode))) goto rmdir_done; - } - if (inode->i_count > 1) { - retval = -EBUSY; + retval = -EBUSY; + if (dentry->d_count > 1) goto rmdir_done; - } + if ((retval = affs_remove_header(bh,inode)) < 0) goto rmdir_done; inode->i_nlink = retval; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; retval = 0; + mark_inode_dirty(dir); mark_inode_dirty(inode); d_delete(dentry); + rmdir_done: affs_brelse(bh); return retval; @@ -462,27 +406,25 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) struct inode *inode; char *p; unsigned long tmp; - int i, maxlen; + int i, maxlen, error; char c, lc; pr_debug("AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->i_ino, (int)dentry->d_name.len,dentry->d_name.name,symname); maxlen = 4 * AFFS_I2HSIZE(dir) - 1; + error = -ENOSPC; inode = affs_new_inode(dir); if (!inode) - return -ENOSPC; + goto out; inode->i_op = &affs_symlink_inode_operations; inode->i_mode = S_IFLNK | 0777; inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode); + error = -EIO; bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode)); - if (!bh) { - inode->i_nlink = 0; - mark_inode_dirty(inode); - iput(inode); - return -EIO; - } + if (!bh) + goto out_iput; i = 0; p = ((struct slink_front *)bh->b_data)->symname; lc = '/'; @@ -514,25 +456,30 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) mark_buffer_dirty(bh,1); affs_brelse(bh); mark_inode_dirty(inode); + + /* N.B. This test shouldn't be necessary ... dentry must be negative */ + error = -EEXIST; bh = affs_find_entry(dir,dentry,&tmp); - if (bh) { - inode->i_nlink = 0; - iput(inode); - affs_brelse(bh); - return -EEXIST; - } - i = affs_add_entry(dir,NULL,inode,dentry,ST_SOFTLINK); - if (i) { - inode->i_nlink = 0; - mark_inode_dirty(inode); - iput(inode); - affs_brelse(bh); - return i; - } - dir->i_version = ++event; + if (bh) + goto out_release; + /* N.B. Shouldn't we add the entry before dirtying the buffer? */ + error = affs_add_entry(dir,NULL,inode,dentry,ST_SOFTLINK); + if (error) + goto out_release; d_instantiate(dentry,inode); - - return 0; + dir->i_version = ++event; + mark_inode_dirty(dir); + +out: + return error; + +out_release: + affs_brelse(bh); +out_iput: + inode->i_nlink = 0; + mark_inode_dirty(inode); + iput(inode); + goto out; } int @@ -547,6 +494,7 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) pr_debug("AFFS: link(%lu,%lu,\"%.*s\")\n",oldinode->i_ino,dir->i_ino, (int)dentry->d_name.len,dentry->d_name.name); + /* N.B. Do we need this test? The dentry must be negative ... */ bh = affs_find_entry(dir,dentry,&i); if (bh) { affs_brelse(bh); @@ -556,8 +504,9 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) affs_warning(dir->i_sb,"link","Impossible link to link"); return -EINVAL; } + error = -ENOSPC; if (!(inode = affs_new_inode(dir))) - return -ENOSPC; + goto out; inode->i_op = oldinode->i_op; inode->u.affs_i.i_protect = mode_to_prot(oldinode->i_mode); @@ -573,6 +522,7 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) inode->i_nlink = 0; else { dir->i_version = ++event; + mark_inode_dirty(dir); mark_inode_dirty(oldinode); oldinode->i_count++; d_instantiate(dentry,oldinode); @@ -580,6 +530,7 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) mark_inode_dirty(inode); iput(inode); +out: return error; } @@ -600,7 +551,7 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, new_dir->i_ino,new_dentry->d_name.len,new_dentry->d_name.name,new_inode); if ((retval = affs_check_name(new_dentry->d_name.name,new_dentry->d_name.len))) - return retval; + goto out; new_bh = NULL; retval = -ENOENT; @@ -630,8 +581,10 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!S_ISDIR(old_inode->i_mode)) goto end_rename; retval = -EINVAL; - if (is_subdir(new_dentry,old_dentry)) + if (is_subdir(new_dentry, old_dentry)) goto end_rename; + if (new_dentry->d_count > 1) + shrink_dcache_parent(new_dentry); retval = -ENOTEMPTY; if (!empty_dir(new_bh,AFFS_I2HSIZE(new_inode))) goto end_rename; @@ -644,7 +597,7 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_inode && !S_ISDIR(new_inode->i_mode)) goto end_rename; retval = -EINVAL; - if (is_subdir(new_dentry,old_dentry)) + if (is_subdir(new_dentry, old_dentry)) goto end_rename; if (affs_parent_ino(old_inode) != old_dir->i_ino) goto end_rename; @@ -681,6 +634,6 @@ new_checksum: end_rename: affs_brelse(old_bh); affs_brelse(new_bh); - +out: return retval; } diff --git a/fs/affs/super.c b/fs/affs/super.c index 6579a6bb4739..b4ce6756f693 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -62,12 +62,10 @@ affs_put_super(struct super_block *sb) kfree(sb->u.affs_sb.s_bitmap); affs_brelse(sb->u.affs_sb.s_root_bh); - /* I'm not happy with this. It would be better to save the previous - * value of this devices blksize_size[][] in the super block and - * restore it here, but with the affs superblock being quite large - * already ... + /* + * Restore the previous value of this device's blksize_size[][] */ - set_blocksize(sb->s_dev,BLOCK_SIZE); + set_blocksize(sb->s_dev, sb->u.affs_sb.s_blksize); sb->s_dev = 0; unlock_super(sb); @@ -100,7 +98,7 @@ affs_write_super(struct super_block *sb) } else sb->s_dirt = 0; - pr_debug("AFFS: write_super() at %d, clean=%d\n",CURRENT_TIME,clean); + pr_debug("AFFS: write_super() at %lu, clean=%d\n", CURRENT_TIME, clean); } static struct super_operations affs_sops = { @@ -119,7 +117,7 @@ static int parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s32 *root, int *blocksize, char **prefix, char *volume, unsigned long *mount_opts) { - char *this_char, *value; + char *this_char, *value, *optn; int f; /* Fill in defaults */ @@ -138,18 +136,18 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s f = 0; if ((value = strchr(this_char,'=')) != NULL) *value++ = 0; - if (!strcmp(this_char,"protect")) { - if (value) { - printk("AFFS: Option protect does not take an argument\n"); - return 0; - } + if ((optn = "protect") && !strcmp(this_char, optn)) { + if (value) + goto out_inv_arg; *mount_opts |= SF_IMMUTABLE; - } else if (!strcmp(this_char,"verbose")) { - if (value) { - printk("AFFS: Option verbose does not take an argument\n"); - return 0; - } + } else if ((optn = "verbose") && !strcmp(this_char, optn)) { + if (value) + goto out_inv_arg; *mount_opts |= SF_VERBOSE; + } else if ((optn = "mufs") && !strcmp(this_char, optn)) { + if (value) + goto out_inv_arg; + *mount_opts |= SF_MUFS; } else if ((f = !strcmp(this_char,"setuid")) || !strcmp(this_char,"setgid")) { if (value) { if (!*value) { @@ -165,55 +163,51 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s } } } else if (!strcmp(this_char,"prefix")) { - if (!value || !*value) { - printk("AFFS: The prefix option requires an argument\n"); - return 0; - } - if (*prefix) /* Free any previous prefix */ + optn = "prefix"; + if (!value || !*value) + goto out_no_arg; + if (*prefix) { /* Free any previous prefix */ kfree(*prefix); + *prefix = NULL; + } *prefix = kmalloc(strlen(value) + 1,GFP_KERNEL); if (!*prefix) return 0; strcpy(*prefix,value); *mount_opts |= SF_PREFIX; } else if (!strcmp(this_char,"volume")) { - if (!value || !*value) { - printk("AFFS: The volume option requires an argument\n"); - return 0; - } + optn = "volume"; + if (!value || !*value) + goto out_no_arg; if (strlen(value) > 30) value[30] = 0; strncpy(volume,value,30); } else if (!strcmp(this_char,"mode")) { - if (!value || !*value) { - printk("AFFS: The mode option requires an argument\n"); - return 0; - } + optn = "mode"; + if (!value || !*value) + goto out_no_arg; *mode = simple_strtoul(value,&value,8) & 0777; if (*value) return 0; *mount_opts |= SF_SETMODE; } else if (!strcmp(this_char,"reserved")) { - if (!value || !*value) { - printk("AFFS: The reserved option requires an argument\n"); - return 0; - } + optn = "reserved"; + if (!value || !*value) + goto out_no_arg; *reserved = simple_strtoul(value,&value,0); if (*value) return 0; } else if (!strcmp(this_char,"root")) { - if (!value || !*value) { - printk("AFFS: The root option requires an argument\n"); - return 0; - } + optn = "root"; + if (!value || !*value) + goto out_no_arg; *root = simple_strtoul(value,&value,0); if (*value) return 0; } else if (!strcmp(this_char,"bs")) { - if (!value || !*value) { - printk("AFFS: The bs option requires an argument\n"); - return 0; - } + optn = "bs"; + if (!value || !*value) + goto out_no_arg; *blocksize = simple_strtoul(value,&value,0); if (*value) return 0; @@ -234,6 +228,13 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s } } return 1; + +out_no_arg: + printk("AFFS: The %s option requires an argument\n", optn); + return 0; +out_inv_arg: + printk("AFFS: Option %s does not take an argument\n", optn); + return 0; } /* This function definitely needs to be split up. Some fine day I'll @@ -241,14 +242,14 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s */ static struct super_block * -affs_read_super(struct super_block *s,void *data, int silent) +affs_read_super(struct super_block *s, void *data, int silent) { struct buffer_head *bh = NULL; struct buffer_head *bb; struct inode *root_inode; kdev_t dev = s->s_dev; s32 root_block; - int size; + int blocks, size, blocksize; u32 chksum; u32 *bm; s32 ptype, stype; @@ -256,7 +257,6 @@ affs_read_super(struct super_block *s,void *data, int silent) int num_bm; int i, j; s32 key; - int blocksize; uid_t uid; gid_t gid; int reserved; @@ -268,57 +268,55 @@ affs_read_super(struct super_block *s,void *data, int silent) pr_debug("affs_read_super(%s)\n",data ? (const char *)data : "no options"); MOD_INC_USE_COUNT; - - s->u.affs_sb.s_prefix = NULL; - if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, - &blocksize,&s->u.affs_sb.s_prefix,s->u.affs_sb.s_volume,&mount_flags)) { - s->s_dev = 0; - printk(KERN_ERR "AFFS: Error parsing options\n"); - MOD_DEC_USE_COUNT; - return NULL; - } lock_super(s); - - /* Get the size of the device in 512-byte blocks. - * If we later see that the partition uses bigger - * blocks, we will have to change it. - */ - - size = blksize_size[MAJOR(dev)][MINOR(dev)]; - size = (size ? size : BLOCK_SIZE) / 512 * blk_size[MAJOR(dev)][MINOR(dev)]; - + s->s_magic = AFFS_SUPER_MAGIC; + s->s_op = &affs_sops; s->u.affs_sb.s_bitmap = NULL; s->u.affs_sb.s_root_bh = NULL; + s->u.affs_sb.s_prefix = NULL; + s->u.affs_sb.s_hashsize= 0; + + if (!parse_options(data,&uid,&gid,&i,&reserved,&root_block, + &blocksize,&s->u.affs_sb.s_prefix, + s->u.affs_sb.s_volume, &mount_flags)) + goto out_bad_opts; + /* N.B. after this point s_prefix must be released */ + s->u.affs_sb.s_flags = mount_flags; s->u.affs_sb.s_mode = i; s->u.affs_sb.s_uid = uid; s->u.affs_sb.s_gid = gid; + s->u.affs_sb.s_reserved= reserved; - if (size == 0) { - s->s_dev = 0; - unlock_super(s); - printk(KERN_ERR "AFFS: Could not determine device size\n"); - goto out; - } - s->u.affs_sb.s_partition_size = size; - s->u.affs_sb.s_reserved = reserved; + /* Get the size of the device in 512-byte blocks. + * If we later see that the partition uses bigger + * blocks, we will have to change it. + */ + + blocks = blk_size[MAJOR(dev)][MINOR(dev)]; + if (blocks == 0) + goto out_bad_size; + s->u.affs_sb.s_blksize = blksize_size[MAJOR(dev)][MINOR(dev)]; + if (!s->u.affs_sb.s_blksize) + s->u.affs_sb.s_blksize = BLOCK_SIZE; + size = (s->u.affs_sb.s_blksize / 512) * blocks; + pr_debug("AFFS: initial blksize=%d, blocks=%d\n", + s->u.affs_sb.s_blksize, blocks); /* Try to find root block. Its location depends on the block size. */ - s->u.affs_sb.s_hashsize = 0; + i = 512; + j = 4096; if (blocksize > 0) { - i = blocksize; - j = blocksize; - } else { - i = 512; - j = 4096; + i = j = blocksize; + size = size / (blocksize / 512); } for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) { + s->u.affs_sb.s_root_block = root_block; if (root_block < 0) s->u.affs_sb.s_root_block = (reserved + size - 1) / 2; - else - s->u.affs_sb.s_root_block = root_block; - set_blocksize(dev,blocksize); + pr_debug("AFFS: setting blocksize to %d\n", blocksize); + set_blocksize(dev, blocksize); /* The root block location that was calculated above is not * correct if the partition size is an odd number of 512- @@ -331,35 +329,31 @@ affs_read_super(struct super_block *s,void *data, int silent) * block behind the calculated one. So we check this one, too. */ for (num_bm = 0; num_bm < 2; num_bm++) { - pr_debug("AFFS: Dev %s - trying bs=%d bytes, root at %u, " - "size=%d blocks, %d reserved\n",kdevname(dev),blocksize, - s->u.affs_sb.s_root_block + num_bm,size,reserved); - bh = affs_bread(dev,s->u.affs_sb.s_root_block + num_bm,blocksize); - if (!bh) { - printk(KERN_ERR "AFFS: Cannot read root block\n"); - goto out; - } + pr_debug("AFFS: Dev %s, trying root=%u, bs=%d, " + "size=%d, reserved=%d\n", + kdevname(dev), + s->u.affs_sb.s_root_block + num_bm, + blocksize, size, reserved); + bh = affs_bread(dev, s->u.affs_sb.s_root_block + num_bm, + blocksize); + if (!bh) + continue; if (!affs_checksum_block(blocksize,bh->b_data,&ptype,&stype) && ptype == T_SHORT && stype == ST_ROOT) { s->s_blocksize = blocksize; s->u.affs_sb.s_hashsize = blocksize / 4 - 56; s->u.affs_sb.s_root_block += num_bm; key = 1; - break; + goto got_root; } + affs_brelse(bh); + bh = NULL; } - if (key) - break; - affs_brelse(bh); - bh = NULL; - } - if (!key) { - affs_brelse(bh); - if (!silent) - printk(KERN_ERR "AFFS: Cannot find a valid root block on device %s\n", - kdevname(dev)); - goto out; } + goto out_no_valid_block; + + /* N.B. after this point bh must be released */ +got_root: root_block = s->u.affs_sb.s_root_block; s->u.affs_sb.s_partition_size = size; @@ -369,59 +363,54 @@ affs_read_super(struct super_block *s,void *data, int silent) /* Find out which kind of FS we have */ bb = affs_bread(dev,0,s->s_blocksize); - if (bb) { - chksum = be32_to_cpu(*(u32 *)bb->b_data); - - /* Dircache filesystems are compatible with non-dircache ones - * when reading. As long as they aren't supported, writing is - * not recommended. - */ - if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS - || chksum == MUFS_DCOFS) && !(s->s_flags & MS_RDONLY)) { - printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n", - kdevname(dev)); - s->s_flags |= MS_RDONLY; - s->u.affs_sb.s_flags |= SF_READONLY; - } - switch (chksum) { - case MUFS_FS: - case MUFS_INTLFFS: - s->u.affs_sb.s_flags |= SF_MUFS; - /* fall thru */ - case FS_INTLFFS: - s->u.affs_sb.s_flags |= SF_INTL; - break; - case MUFS_DCFFS: - case MUFS_FFS: - s->u.affs_sb.s_flags |= SF_MUFS; - break; - case FS_DCFFS: - case FS_FFS: - break; - case MUFS_OFS: - s->u.affs_sb.s_flags |= SF_MUFS; - /* fall thru */ - case FS_OFS: - s->u.affs_sb.s_flags |= SF_OFS; - break; - case MUFS_DCOFS: - case MUFS_INTLOFS: - s->u.affs_sb.s_flags |= SF_MUFS; - case FS_DCOFS: - case FS_INTLOFS: - s->u.affs_sb.s_flags |= SF_INTL | SF_OFS; - break; - default: - printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n", - kdevname(dev),chksum); - affs_brelse(bb); - goto out; - } - affs_brelse(bb); - } else { - printk(KERN_ERR "AFFS: Cannot read boot block\n"); - goto out; + if (!bb) + goto out_no_root_block; + chksum = be32_to_cpu(*(u32 *)bb->b_data); + affs_brelse(bb); + + /* Dircache filesystems are compatible with non-dircache ones + * when reading. As long as they aren't supported, writing is + * not recommended. + */ + if ((chksum == FS_DCFFS || chksum == MUFS_DCFFS || chksum == FS_DCOFS + || chksum == MUFS_DCOFS) && !(s->s_flags & MS_RDONLY)) { + printk(KERN_NOTICE "AFFS: Dircache FS - mounting %s read only\n", + kdevname(dev)); + s->s_flags |= MS_RDONLY; + s->u.affs_sb.s_flags |= SF_READONLY; + } + switch (chksum) { + case MUFS_FS: + case MUFS_INTLFFS: + s->u.affs_sb.s_flags |= SF_MUFS; + /* fall thru */ + case FS_INTLFFS: + s->u.affs_sb.s_flags |= SF_INTL; + break; + case MUFS_DCFFS: + case MUFS_FFS: + s->u.affs_sb.s_flags |= SF_MUFS; + break; + case FS_DCFFS: + case FS_FFS: + break; + case MUFS_OFS: + s->u.affs_sb.s_flags |= SF_MUFS; + /* fall thru */ + case FS_OFS: + s->u.affs_sb.s_flags |= SF_OFS; + break; + case MUFS_DCOFS: + case MUFS_INTLOFS: + s->u.affs_sb.s_flags |= SF_MUFS; + case FS_DCOFS: + case FS_INTLOFS: + s->u.affs_sb.s_flags |= SF_INTL | SF_OFS; + break; + default: + goto out_unknown_fs; } + if (mount_flags & SF_VERBOSE) { chksum = cpu_to_be32(chksum); printk(KERN_NOTICE "AFFS: Mounting volume \"%*s\": Type=%.3s\\%c, Blocksize=%d\n", @@ -430,14 +419,14 @@ affs_read_super(struct super_block *s,void *data, int silent) (char *)&chksum,((char *)&chksum)[3] + '0',blocksize); } - s->s_magic = AFFS_SUPER_MAGIC; s->s_flags |= MS_NODEV | MS_NOSUID; /* Keep super block in cache */ - if (!(s->u.affs_sb.s_root_bh = affs_bread(dev,root_block,s->s_blocksize))) { - printk(KERN_ERR "AFFS: Cannot read root block\n"); - goto out; - } + bb = affs_bread(dev,root_block,s->s_blocksize); + if (!bb) + goto out_no_root_block; + s->u.affs_sb.s_root_bh = bb; + /* N.B. after this point s_root_bh must be released */ /* Allocate space for bitmaps, zones and others */ @@ -448,11 +437,10 @@ affs_read_super(struct super_block *s,void *data, int silent) az_no * sizeof(struct affs_alloc_zone) + MAX_ZONES * sizeof(struct affs_zone); pr_debug("num_bm=%d, az_no=%d, sum=%d\n",num_bm,az_no,ptype); - if (!(s->u.affs_sb.s_bitmap = kmalloc(ptype,GFP_KERNEL))) { - printk(KERN_ERR "AFFS: Not enough memory\n"); - goto out; - } + if (!(s->u.affs_sb.s_bitmap = kmalloc(ptype, GFP_KERNEL))) + goto out_no_bitmap; memset(s->u.affs_sb.s_bitmap,0,ptype); + /* N.B. after the point s_bitmap must be released */ s->u.affs_sb.s_zones = (struct affs_zone *)&s->u.affs_sb.s_bitmap[num_bm]; s->u.affs_sb.s_alloc = (struct affs_alloc_zone *)&s->u.affs_sb.s_zones[MAX_ZONES]; @@ -490,91 +478,79 @@ affs_read_super(struct super_block *s,void *data, int silent) s->u.affs_sb.s_flags |= SF_READONLY; continue; } - bb = affs_bread(s->s_dev,be32_to_cpu(bm[i]),s->s_blocksize); - if (bb) { - if (affs_checksum_block(s->s_blocksize,bb->b_data,NULL,NULL) && - !(s->s_flags & MS_RDONLY)) { - printk(KERN_WARNING "AFFS: Bitmap (%d,key=%u) invalid - " - "mounting %s read only.\n",mapidx,be32_to_cpu(bm[i]), - kdevname(dev)); - s->s_flags |= MS_RDONLY; - s->u.affs_sb.s_flags |= SF_READONLY; - } - /* Mark unused bits in the last word as allocated */ - if (size <= s->s_blocksize * 8 - 32) { /* last bitmap */ - ptype = size / 32 + 1; /* word number */ - key = size & 0x1F; /* used bits */ - if (key && !(s->s_flags & MS_RDONLY)) { - chksum = cpu_to_be32(0x7FFFFFFF >> (31 - key)); - ((u32 *)bb->b_data)[ptype] &= chksum; - affs_fix_checksum(s->s_blocksize,bb->b_data,0); - mark_buffer_dirty(bb,1); - bmalt = 1; - } - ptype = (size + 31) & ~0x1F; - size = 0; - s->u.affs_sb.s_flags |= SF_BM_VALID; - } else { - ptype = s->s_blocksize * 8 - 32; - size -= ptype; - } - s->u.affs_sb.s_bitmap[mapidx].bm_firstblk = offset; - s->u.affs_sb.s_bitmap[mapidx].bm_bh = NULL; - s->u.affs_sb.s_bitmap[mapidx].bm_key = be32_to_cpu(bm[i]); - s->u.affs_sb.s_bitmap[mapidx].bm_count = 0; - offset += ptype; - - for (j = 0; ptype > 0; j++, az_no++, ptype -= key) { - key = MIN(ptype,AFFS_ZONE_SIZE); /* size in bits */ - s->u.affs_sb.s_alloc[az_no].az_size = key / 32; - s->u.affs_sb.s_alloc[az_no].az_free = - affs_count_free_bits(key / 8,bb->b_data + - j * (AFFS_ZONE_SIZE / 8) + 4); + bb = affs_bread(dev,be32_to_cpu(bm[i]),s->s_blocksize); + if (!bb) + goto out_no_read_bm; + if (affs_checksum_block(s->s_blocksize,bb->b_data,NULL,NULL) && + !(s->s_flags & MS_RDONLY)) { + printk(KERN_WARNING "AFFS: Bitmap (%d,key=%u) invalid - " + "mounting %s read only.\n",mapidx,be32_to_cpu(bm[i]), + kdevname(dev)); + s->s_flags |= MS_RDONLY; + s->u.affs_sb.s_flags |= SF_READONLY; + } + /* Mark unused bits in the last word as allocated */ + if (size <= s->s_blocksize * 8 - 32) { /* last bitmap */ + ptype = size / 32 + 1; /* word number */ + key = size & 0x1F; /* used bits */ + if (key && !(s->s_flags & MS_RDONLY)) { + chksum = cpu_to_be32(0x7FFFFFFF >> (31 - key)); + ((u32 *)bb->b_data)[ptype] &= chksum; + affs_fix_checksum(s->s_blocksize,bb->b_data,0); + mark_buffer_dirty(bb,1); + bmalt = 1; } - affs_brelse(bb); + ptype = (size + 31) & ~0x1F; + size = 0; + s->u.affs_sb.s_flags |= SF_BM_VALID; } else { - printk(KERN_ERR "AFFS: Cannot read bitmap\n"); - goto out; + ptype = s->s_blocksize * 8 - 32; + size -= ptype; + } + s->u.affs_sb.s_bitmap[mapidx].bm_firstblk = offset; + s->u.affs_sb.s_bitmap[mapidx].bm_bh = NULL; + s->u.affs_sb.s_bitmap[mapidx].bm_key = be32_to_cpu(bm[i]); + s->u.affs_sb.s_bitmap[mapidx].bm_count = 0; + offset += ptype; + + for (j = 0; ptype > 0; j++, az_no++, ptype -= key) { + key = MIN(ptype,AFFS_ZONE_SIZE); /* size in bits */ + s->u.affs_sb.s_alloc[az_no].az_size = key / 32; + s->u.affs_sb.s_alloc[az_no].az_free = + affs_count_free_bits(key / 8,bb->b_data + + j * (AFFS_ZONE_SIZE / 8) + 4); } + affs_brelse(bb); } key = be32_to_cpu(bm[stype]); /* Next block of bitmap pointers */ ptype = 0; stype = s->s_blocksize / 4 - 1; affs_brelse(bh); + bh = NULL; if (key) { - if (!(bh = affs_bread(s->s_dev,key,s->s_blocksize))) { - printk(KERN_ERR "AFFS: Cannot read bitmap extension\n"); - goto out; - } - } else - bh = NULL; - } - if (mapidx < num_bm) { - printk(KERN_ERR "AFFS: Got only %d bitmap blocks, expected %d\n",mapidx,num_bm); - goto out; + bh = affs_bread(dev,key,s->s_blocksize); + if (!bh) + goto out_no_bm_ext; + } } + if (mapidx < num_bm) + goto out_bad_num; + nobitmap: s->u.affs_sb.s_bm_count = num_bm; /* set up enough so that it can read an inode */ - s->s_dev = dev; - s->s_op = &affs_sops; s->s_dirt = 1; root_inode = iget(s,root_block); - s->s_root = d_alloc_root(root_inode,NULL); - unlock_super(s); - - if (!(s->s_root)) { - s->s_dev = 0; - affs_brelse(s->u.affs_sb.s_root_bh); - printk(KERN_ERR "AFFS: get root inode failed\n"); - MOD_DEC_USE_COUNT; - return NULL; - } - s->s_root->d_op = (s->u.affs_sb.s_flags & SF_INTL) ? &affs_dentry_operations_intl - : &affs_dentry_operations; + if (!root_inode) + goto out_no_root; + s->s_root = d_alloc_root(root_inode, NULL); + if (!s->s_root) + goto out_no_root; + s->s_root->d_op = &affs_dentry_operations; + unlock_super(s); /* Record date of last change if the bitmap was truncated and * create data zones if the volume is writable. */ @@ -592,12 +568,56 @@ nobitmap: pr_debug("AFFS: s_flags=%lX\n",s->s_flags); return s; - out: /* Kick out for various error conditions */ - affs_brelse (bh); +out_bad_opts: + printk(KERN_ERR "AFFS: Error parsing options\n"); + goto out_fail; +out_bad_size: + printk(KERN_ERR "AFFS: Could not determine device size\n"); + goto out_free_prefix; +out_no_valid_block: + if (!silent) + printk(KERN_ERR "AFFS: No valid root block on device %s\n", + kdevname(dev)); + goto out_restore; +out_unknown_fs: + printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n", + kdevname(dev), chksum); + goto out_free_bh; +out_no_root_block: + printk(KERN_ERR "AFFS: Cannot read root block\n"); + goto out_free_bh; +out_no_bitmap: + printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); + goto out_free_root_block; +out_no_read_bm: + printk(KERN_ERR "AFFS: Cannot read bitmap\n"); + goto out_free_bitmap; +out_no_bm_ext: + printk(KERN_ERR "AFFS: Cannot read bitmap extension\n"); + goto out_free_bitmap; +out_bad_num: + printk(KERN_ERR "AFFS: Got only %d bitmap blocks, expected %d\n", + mapidx, num_bm); + goto out_free_bitmap; +out_no_root: + printk(KERN_ERR "AFFS: get root inode failed\n"); + + /* + * Begin the cascaded cleanup ... + */ + iput(root_inode); +out_free_bitmap: + kfree(s->u.affs_sb.s_bitmap); +out_free_root_block: affs_brelse(s->u.affs_sb.s_root_bh); - if (s->u.affs_sb.s_bitmap) - kfree(s->u.affs_sb.s_bitmap); - set_blocksize(dev,BLOCK_SIZE); +out_free_bh: + affs_brelse(bh); +out_restore: + set_blocksize(dev, s->u.affs_sb.s_blksize); +out_free_prefix: + if (s->u.affs_sb.s_prefix) + kfree(s->u.affs_sb.s_prefix); +out_fail: s->s_dev = 0; unlock_super(s); MOD_DEC_USE_COUNT; diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index ac4f5892b167..aa6a7c40cb3f 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -668,7 +668,11 @@ static void ntfs_read_inode(struct inode* inode) static void ntfs_put_inode(struct inode *ino) { - ntfs_debug(DEBUG_OTHER, "ntfs_put_inode %lx\n",ino->i_ino); +} + +static void _ntfs_clear_inode(struct inode *ino) +{ + ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n",ino->i_ino); #ifdef NTFS_IN_LINUX_KERNEL if(ino->i_ino!=FILE_MFT) ntfs_clear_inode(&ino->u.ntfs_i); @@ -680,7 +684,7 @@ static void ntfs_put_inode(struct inode *ino) ino->u.generic_ip=0; } #endif - clear_inode(ino); + return; } /* Called when umounting a filesystem by do_umount() in fs/super.c */ @@ -753,6 +757,7 @@ struct super_operations ntfs_super_operations = { NULL, /* write_super */ ntfs_statfs, ntfs_remount_fs, /* remount */ + _ntfs_clear_inode, /* clear_inode */ }; /* Called to mount a filesystem by read_super() in fs/super.c diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 65647c15442f..a2a067f4c0ec 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -289,8 +289,14 @@ int ntfs_init_inode(ntfs_inode *ino,ntfs_volume *vol,int inum) void ntfs_clear_inode(ntfs_inode *ino) { int i; + if(!ino->attr){ + ntfs_error("ntfs_clear_inode: double free\n"); + return; + } ntfs_free(ino->attr); + ino->attr=0; ntfs_free(ino->records); + ino->records=0; for(i=0;iattr_count;i++) { if(ino->attrs[i].name) @@ -305,6 +311,7 @@ void ntfs_clear_inode(ntfs_inode *ino) } } ntfs_free(ino->attrs); + ino->attrs=0; } /* Check and fixup a MFT record */ diff --git a/include/asm-mips/ng1.h b/include/asm-mips/ng1.h index eafa666a3449..5559b59e5fb8 100644 --- a/include/asm-mips/ng1.h +++ b/include/asm-mips/ng1.h @@ -46,29 +46,3 @@ struct ng1_setgammaramp_args { unsigned char green [256]; unsigned char blue [256]; }; - - - -#define GFX_NAME_NEWPORT "NG1" - -/* ioctls */ -#define NG1_SET_CURSOR_HOTSPOT 21001 -struct ng1_set_cursor_hotspot { - unsigned short xhot; - unsigned short yhot; -}; - -#define NG1_SETDISPLAYMODE 21006 -struct ng1_setdisplaymode_args { - int wid; - unsigned int mode; -}; - -#define NG1_SETGAMMARAMP0 21007 -struct ng1_setgammaramp_args { - unsigned char red [256]; - unsigned char green [256]; - unsigned char blue [256]; -}; - - diff --git a/include/asm-mips/prctl.h b/include/asm-mips/prctl.h index 094a60b265a9..0e009bfb9c7d 100644 --- a/include/asm-mips/prctl.h +++ b/include/asm-mips/prctl.h @@ -1,45 +1,3 @@ -/* - * IRIX prctl interface - * - * The IRIX kernel maps a page at PRDA_ADDRESS with the - * contents of prda and fills it the bits on prda_sys. - * $Id: prctl.h,v 1.1 1997/09/21 22:27:19 miguel Exp $ - */ - -#ifndef __PRCTL_H__ -#define __PRCTL_H__ - -#define PRDA_ADDRESS 0x200000L -#define PRDA ((struct prda *) PRDA_ADDRESS) - -struct prda_sys { - pid_t t_pid; - u32 t_hint; - u32 t_dlactseq; - u32 t_fpflags; - u32 t_prid; /* processor type, $prid CP0 register */ - u32 t_dlendseq; - u64 t_unused1[5]; - pid_t t_rpid; - s32 t_resched; - u32 t_unused[8]; - u32 t_cpu; /* current/last cpu */ - - /* FIXME: The signal information, not supported by Linux now */ - u32 t_flags; /* if true, then the sigprocmask is in userspace */ - u32 t_sigprocmask [1]; /* the sigprocmask */ -}; - -struct prda { - char fill [0xe00]; - struct prda_sys prda_sys; -}; - -#define t_sys prda_sys - -ptrdiff_t prctl (int op, int v1, int v2); - -#endif /* * IRIX prctl interface * diff --git a/include/asm-sparc/svr4.h b/include/asm-sparc/svr4.h index 7eb1c3aad615..7d163a6fc2e1 100644 --- a/include/asm-sparc/svr4.h +++ b/include/asm-sparc/svr4.h @@ -69,7 +69,7 @@ typedef struct { caddr_t ptr; } svr4_xrs_t; -/* Machine dependant context */ +/* Machine dependent context */ typedef struct { svr4_gregset_t greg; /* registers 0..19 (see top) */ svr4_gwindows_t *gwin; /* may point to register windows */ diff --git a/include/asm-sparc64/svr4.h b/include/asm-sparc64/svr4.h index 5dcee9d3f197..2e624a94b9d1 100644 --- a/include/asm-sparc64/svr4.h +++ b/include/asm-sparc64/svr4.h @@ -70,7 +70,7 @@ typedef struct { u32 ptr; } svr4_xrs_t; -/* Machine dependant context */ +/* Machine dependent context */ typedef struct { svr4_gregset_t greg; /* registers 0..19 (see top) */ u32 gwin; /* may point to register windows */ diff --git a/include/linux/affs_fs_sb.h b/include/linux/affs_fs_sb.h index 7ab2612092fd..a066aee71f12 100644 --- a/include/linux/affs_fs_sb.h +++ b/include/linux/affs_fs_sb.h @@ -37,6 +37,7 @@ struct affs_zone { struct affs_sb_info { int s_partition_size; /* Partition size in blocks. */ + int s_blksize; /* Initial device blksize */ s32 s_root_block; /* FFS root block number. */ int s_hashsize; /* Size of hash table. */ unsigned long s_flags; /* See below. */ diff --git a/include/linux/elf.h b/include/linux/elf.h index e17a72c1b026..f2e7373f0503 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -128,7 +128,7 @@ typedef __u64 Elf64_Word; #define AT_GID 13 /* real gid */ #define AT_EGID 14 /* effective gid */ #define AT_PLATFORM 15 /* string identifying cpu for optimizations */ -#define AT_HWCAP 16 /* arch dependant hints at cpu capabilities */ +#define AT_HWCAP 16 /* arch dependent hints at cpu capabilities */ typedef struct dynamic{ Elf32_Sword d_tag; diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index a7f0b53e4850..7377867e70ee 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -5,7 +5,7 @@ #define SHAPER_QLEN 10 /* - * This is a bit speed dependant (read it shouldnt be a constant!) + * This is a bit speed dependent (read it shouldn't be a constant!) * * 5 is about right for 28.8 upwards. Below that double for every * halving of speed or so. - ie about 20 for 9600 baud. diff --git a/include/linux/parport.h b/include/linux/parport.h index 102594683683..35b7fbb5a215 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -3,6 +3,64 @@ #ifndef _PARPORT_H_ #define _PARPORT_H_ +/* Start off with user-visible constants */ + +/* Maximum of 8 ports per machine */ +#define PARPORT_MAX 8 + +/* Magic numbers */ +#define PARPORT_IRQ_NONE -1 +#define PARPORT_DMA_NONE -1 +#define PARPORT_IRQ_AUTO -2 +#define PARPORT_DMA_AUTO -2 +#define PARPORT_DISABLE -2 + +#define PARPORT_CONTROL_STROBE 0x1 +#define PARPORT_CONTROL_AUTOFD 0x2 +#define PARPORT_CONTROL_INIT 0x4 +#define PARPORT_CONTROL_SELECT 0x8 +#define PARPORT_CONTROL_INTEN 0x10 +#define PARPORT_CONTROL_DIRECTION 0x20 + +#define PARPORT_STATUS_ERROR 0x8 +#define PARPORT_STATUS_SELECT 0x10 +#define PARPORT_STATUS_PAPEROUT 0x20 +#define PARPORT_STATUS_ACK 0x40 +#define PARPORT_STATUS_BUSY 0x80 + +/* Type classes for Plug-and-Play probe. */ +typedef enum { + PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */ + PARPORT_CLASS_PRINTER, + PARPORT_CLASS_MODEM, + PARPORT_CLASS_NET, + PARPORT_CLASS_HDC, /* Hard disk controller */ + PARPORT_CLASS_PCMCIA, + PARPORT_CLASS_MEDIA, /* Multimedia device */ + PARPORT_CLASS_FDC, /* Floppy disk controller */ + PARPORT_CLASS_PORTS, + PARPORT_CLASS_SCANNER, + PARPORT_CLASS_DIGCAM, + PARPORT_CLASS_OTHER, /* Anything else */ + PARPORT_CLASS_UNSPEC /* No CLS field in ID */ +} parport_device_class; + +/* The "modes" entry in parport is a bit field representing the following + * modes. + * Note that PARPORT_MODE_PCECPEPP is for the SMC EPP+ECP mode which is NOT + * 100% compatible with EPP. + */ +#define PARPORT_MODE_PCSPP 0x0001 +#define PARPORT_MODE_PCPS2 0x0002 +#define PARPORT_MODE_PCEPP 0x0004 +#define PARPORT_MODE_PCECP 0x0008 +#define PARPORT_MODE_PCECPEPP 0x0010 +#define PARPORT_MODE_PCECR 0x0020 /* ECR Register Exists */ +#define PARPORT_MODE_PCECPPS2 0x0040 + +/* The rest is for the kernel only */ +#ifdef __KERNEL__ + #include #include #include @@ -11,16 +69,6 @@ #define PARPORT_NEED_GENERIC_OPS -/* Maximum of 8 ports per machine */ -#define PARPORT_MAX 8 - -/* Magic numbers */ -#define PARPORT_IRQ_NONE -2 -#define PARPORT_DMA_NONE -2 -#define PARPORT_IRQ_AUTO -1 -#define PARPORT_DMA_AUTO -1 -#define PARPORT_DISABLE -2 - /* Define this later. */ struct parport; @@ -39,29 +87,29 @@ struct parport_state { }; struct parport_operations { - void (*write_data)(struct parport *, unsigned int); - unsigned int (*read_data)(struct parport *); - void (*write_control)(struct parport *, unsigned int); - unsigned int (*read_control)(struct parport *); - unsigned int (*frob_control)(struct parport *, unsigned int mask, unsigned int val); - void (*write_econtrol)(struct parport *, unsigned int); - unsigned int (*read_econtrol)(struct parport *); - unsigned int (*frob_econtrol)(struct parport *, unsigned int mask, unsigned int val); - void (*write_status)(struct parport *, unsigned int); - unsigned int (*read_status)(struct parport *); - void (*write_fifo)(struct parport *, unsigned int); - unsigned int (*read_fifo)(struct parport *); + void (*write_data)(struct parport *, unsigned char); + unsigned char (*read_data)(struct parport *); + void (*write_control)(struct parport *, unsigned char); + unsigned char (*read_control)(struct parport *); + unsigned char (*frob_control)(struct parport *, unsigned char mask, unsigned char val); + void (*write_econtrol)(struct parport *, unsigned char); + unsigned char (*read_econtrol)(struct parport *); + unsigned char (*frob_econtrol)(struct parport *, unsigned char mask, unsigned char val); + void (*write_status)(struct parport *, unsigned char); + unsigned char (*read_status)(struct parport *); + void (*write_fifo)(struct parport *, unsigned char); + unsigned char (*read_fifo)(struct parport *); void (*change_mode)(struct parport *, int); void (*release_resources)(struct parport *); int (*claim_resources)(struct parport *); - unsigned int (*epp_write_block)(struct parport *, void *, unsigned int); - unsigned int (*epp_read_block)(struct parport *, void *, unsigned int); + size_t (*epp_write_block)(struct parport *, void *, size_t); + size_t (*epp_read_block)(struct parport *, void *, size_t); - unsigned int (*ecp_write_block)(struct parport *, void *, unsigned int, void (*fn)(struct parport *, void *, unsigned int), void *); - unsigned int (*ecp_read_block)(struct parport *, void *, unsigned int, void (*fn)(struct parport *, void *, unsigned int), void *); + int (*ecp_write_block)(struct parport *, void *, size_t, void (*fn)(struct parport *, void *, size_t), void *); + int (*ecp_read_block)(struct parport *, void *, size_t, void (*fn)(struct parport *, void *, size_t), void *); void (*save_state)(struct parport *, struct parport_state *); void (*restore_state)(struct parport *, struct parport_state *); @@ -74,36 +122,6 @@ struct parport_operations { void (*dec_use_count)(void); }; -#define PARPORT_CONTROL_STROBE 0x1 -#define PARPORT_CONTROL_AUTOFD 0x2 -#define PARPORT_CONTROL_INIT 0x4 -#define PARPORT_CONTROL_SELECT 0x8 -#define PARPORT_CONTROL_INTEN 0x10 -#define PARPORT_CONTROL_DIRECTION 0x20 - -#define PARPORT_STATUS_ERROR 0x8 -#define PARPORT_STATUS_SELECT 0x10 -#define PARPORT_STATUS_PAPEROUT 0x20 -#define PARPORT_STATUS_ACK 0x40 -#define PARPORT_STATUS_BUSY 0x80 - -/* Type classes for Plug-and-Play probe. */ -typedef enum { - PARPORT_CLASS_LEGACY = 0, /* Non-IEEE1284 device */ - PARPORT_CLASS_PRINTER, - PARPORT_CLASS_MODEM, - PARPORT_CLASS_NET, - PARPORT_CLASS_HDC, /* Hard disk controller */ - PARPORT_CLASS_PCMCIA, - PARPORT_CLASS_MEDIA, /* Multimedia device */ - PARPORT_CLASS_FDC, /* Floppy disk controller */ - PARPORT_CLASS_PORTS, - PARPORT_CLASS_SCANNER, - PARPORT_CLASS_DIGCAM, - PARPORT_CLASS_OTHER, /* Anything else */ - PARPORT_CLASS_UNSPEC /* No CLS field in ID */ -} parport_device_class; - struct parport_device_info { parport_device_class class; char *mfr; @@ -178,7 +196,7 @@ struct parport { struct parport_operations *ops; void *private_data; /* for lowlevel driver */ - + int number; /* port index - the `n' in `parportn' */ spinlock_t lock; }; @@ -243,28 +261,29 @@ extern int parport_claim_or_block(struct pardevice *dev); extern void parport_release(struct pardevice *dev); -extern __inline__ unsigned int parport_yield(struct pardevice *dev, - unsigned int block) +/* parport_yield relinquishes the port if it would be helpful to other + * drivers. The return value is the same as for parport_claim. + */ +extern __inline__ unsigned int parport_yield(struct pardevice *dev) { unsigned long int timeslip = (jiffies - dev->time); if ((dev->port->waithead == NULL) || (timeslip < dev->timeslice)) - return 1; + return 0; parport_release(dev); - return (block)?parport_claim_or_block(dev):parport_claim(dev); + return parport_claim(dev); } -/* The "modes" entry in parport is a bit field representing the following - * modes. - * Note that LP_ECPEPP is for the SMC EPP+ECP mode which is NOT - * 100% compatible with EPP. +/* parport_yield_blocking is the same but uses parport_claim_or_block + * instead of parport_claim. */ -#define PARPORT_MODE_PCSPP 0x0001 -#define PARPORT_MODE_PCPS2 0x0002 -#define PARPORT_MODE_PCEPP 0x0004 -#define PARPORT_MODE_PCECP 0x0008 -#define PARPORT_MODE_PCECPEPP 0x0010 -#define PARPORT_MODE_PCECR 0x0020 /* ECR Register Exists */ -#define PARPORT_MODE_PCECPPS2 0x0040 +extern __inline__ unsigned int parport_yield_blocking(struct pardevice *dev) +{ + unsigned long int timeslip = (jiffies - dev->time); + if ((dev->port->waithead == NULL) || (timeslip < dev->timeslice)) + return 0; + parport_release(dev); + return parport_claim_or_block(dev); +} /* Flags used to identify what a device does. */ #define PARPORT_DEV_TRAN 0x0000 /* We're transient. */ @@ -329,4 +348,5 @@ extern void (*parport_probe_hook)(struct parport *port); #define parport_claim_resources(p) (p)->ops->claim_resources(p) #endif +#endif /* __KERNEL__ */ #endif /* _PARPORT_H_ */ diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h index 3d6e5cb27dfa..45f4c0fb8333 100644 --- a/include/linux/parport_pc.h +++ b/include/linux/parport_pc.h @@ -13,80 +13,80 @@ #define STATUS 0x1 #define DATA 0 -extern __inline__ void parport_pc_write_epp(struct parport *p, unsigned int d) +extern __inline__ void parport_pc_write_epp(struct parport *p, unsigned char d) { outb(d, p->base+EPPREG); } -extern __inline__ unsigned int parport_pc_read_epp(struct parport *p) +extern __inline__ unsigned char parport_pc_read_epp(struct parport *p) { - return (unsigned int)inb(p->base+EPPREG); + return inb(p->base+EPPREG); } -extern __inline__ unsigned int parport_pc_read_configb(struct parport *p) +extern __inline__ unsigned char parport_pc_read_configb(struct parport *p) { - return (unsigned int)inb(p->base+CONFIGB); + return inb(p->base+CONFIGB); } -extern __inline__ void parport_pc_write_data(struct parport *p, unsigned int d) +extern __inline__ void parport_pc_write_data(struct parport *p, unsigned char d) { outb(d, p->base+DATA); } -extern __inline__ unsigned int parport_pc_read_data(struct parport *p) +extern __inline__ unsigned char parport_pc_read_data(struct parport *p) { - return (unsigned int)inb(p->base+DATA); + return inb(p->base+DATA); } -extern __inline__ void parport_pc_write_control(struct parport *p, unsigned int d) +extern __inline__ void parport_pc_write_control(struct parport *p, unsigned char d) { outb(d, p->base+CONTROL); } -extern __inline__ unsigned int parport_pc_read_control(struct parport *p) +extern __inline__ unsigned char parport_pc_read_control(struct parport *p) { - return (unsigned int)inb(p->base+CONTROL); + return inb(p->base+CONTROL); } -extern __inline__ unsigned int parport_pc_frob_control(struct parport *p, unsigned int mask, unsigned int val) +extern __inline__ unsigned char parport_pc_frob_control(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base+CONTROL); + unsigned char old = inb(p->base+CONTROL); outb(((old & ~mask) ^ val), p->base+CONTROL); return old; } -extern __inline__ void parport_pc_write_status(struct parport *p, unsigned int d) +extern __inline__ void parport_pc_write_status(struct parport *p, unsigned char d) { outb(d, p->base+STATUS); } -extern __inline__ unsigned int parport_pc_read_status(struct parport *p) +extern __inline__ unsigned char parport_pc_read_status(struct parport *p) { - return (unsigned int)inb(p->base+STATUS); + return inb(p->base+STATUS); } -extern __inline__ void parport_pc_write_econtrol(struct parport *p, unsigned int d) +extern __inline__ void parport_pc_write_econtrol(struct parport *p, unsigned char d) { outb(d, p->base+ECONTROL); } -extern __inline__ unsigned int parport_pc_read_econtrol(struct parport *p) +extern __inline__ unsigned char parport_pc_read_econtrol(struct parport *p) { - return (unsigned int)inb(p->base+ECONTROL); + return inb(p->base+ECONTROL); } -extern __inline__ unsigned int parport_pc_frob_econtrol(struct parport *p, unsigned int mask, unsigned int val) +extern __inline__ unsigned char parport_pc_frob_econtrol(struct parport *p, unsigned char mask, unsigned char val) { - unsigned int old = (unsigned int)inb(p->base+ECONTROL); + unsigned char old = inb(p->base+ECONTROL); outb(((old & ~mask) ^ val), p->base+ECONTROL); return old; } extern void parport_pc_change_mode(struct parport *p, int m); -extern void parport_pc_write_fifo(struct parport *p, unsigned int v); +extern void parport_pc_write_fifo(struct parport *p, unsigned char v); -extern unsigned int parport_pc_read_fifo(struct parport *p); +extern unsigned char parport_pc_read_fifo(struct parport *p); extern void parport_pc_disable_irq(struct parport *p); @@ -100,13 +100,13 @@ extern void parport_pc_save_state(struct parport *p, struct parport_state *s); extern void parport_pc_restore_state(struct parport *p, struct parport_state *s); -extern unsigned int parport_pc_epp_read_block(struct parport *p, void *buf, unsigned int length); +extern size_t parport_pc_epp_read_block(struct parport *p, void *buf, size_t length); -extern unsigned int parport_pc_epp_write_block(struct parport *p, void *buf, unsigned int length); +extern size_t parport_pc_epp_write_block(struct parport *p, void *buf, size_t length); -extern unsigned int parport_pc_ecp_read_block(struct parport *p, void *buf, unsigned int length, void (*fn)(struct parport *, void *, unsigned int), void *handle); +extern int parport_pc_ecp_read_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle); -extern unsigned int parport_pc_ecp_write_block(struct parport *p, void *buf, unsigned int length, void (*fn)(struct parport *, void *, unsigned int), void *handle); +extern int parport_pc_ecp_write_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle); extern int parport_pc_examine_irq(struct parport *p); diff --git a/include/linux/sdla_x25.h b/include/linux/sdla_x25.h index 9bb502741971..4c0f4372587f 100644 --- a/include/linux/sdla_x25.h +++ b/include/linux/sdla_x25.h @@ -159,7 +159,7 @@ typedef struct X25Cmd #define X25RES_PROTO_VIOLATION 0x41 /* protocol violation occured */ #define X25RES_PKT_TIMEOUT 0x42 /* X.25 packet time out */ #define X25RES_PKT_RETRY_LIMIT 0x43 /* X.25 packet retry limit exceeded */ -/*----- Command-dependant results -----*/ +/*----- Command-dependent results -----*/ #define X25RES_LINK_DISC 0x00 /* HDLC_LINK_STATUS */ #define X25RES_LINK_IN_ABM 0x01 /* HDLC_LINK_STATUS */ #define X25RES_NO_DATA 0x01 /* HDLC_READ/READ_TRACE_DATA*/ diff --git a/include/linux/wireless.h b/include/linux/wireless.h index b15f2a0db02f..0c2e9fb2a06a 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h @@ -213,7 +213,7 @@ struct iw_encoding struct iw_statistics { __u8 status; /* Status - * - device dependant for now */ + * - device dependent for now */ struct iw_quality qual; /* Quality of the link * (instant/mean/max) */ diff --git a/include/net/tcp.h b/include/net/tcp.h index b25a37a6bdc4..e680fbfa0621 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -54,7 +54,7 @@ extern int sysctl_tcp_sack; extern int sysctl_tcp_timestamps; extern int sysctl_tcp_window_scaling; -/* These are AF independant. */ +/* These are AF independent. */ static __inline__ int tcp_bhashfn(__u16 lport) { return (lport ^ (lport >> 7)) & (TCP_BHTABLE_SIZE - 1); diff --git a/ipc/shm.c b/ipc/shm.c index 5234208e7c5f..a476a0dbc4c8 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -689,7 +689,7 @@ static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, uns goto done; } if (!pte_none(pte)) { - rw_swap_page(READ, pte_val(pte), (char *) page, 1); /* FIXME */ + rw_swap_page_nocache(READ, pte_val(pte), (char *)page); pte = __pte(shp->shm_pages[idx]); if (pte_present(pte)) { free_page (page); /* doesn't sleep */ @@ -820,7 +820,7 @@ int shm_swap (int prio, int dma) if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) != 1) goto check_table; shp->shm_pages[idx] = swap_nr; - rw_swap_page(WRITE, swap_nr, (char *) pte_page(page), 1); /* FIXME */ + rw_swap_page_nocache (WRITE, swap_nr, (char *) pte_page(page)); free_page(pte_page(page)); swap_successes++; shm_swp++; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index f64943673bf0..9b85d2f934fc 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -206,6 +206,10 @@ EXPORT_SYMBOL(shrink_dcache_parent); EXPORT_SYMBOL(find_inode_number); EXPORT_SYMBOL(is_subdir); +#ifdef CONFIG_AUTOFS_FS_MODULE +EXPORT_SYMBOL(locks_remove_flock); +#endif + #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE) EXPORT_SYMBOL(do_nfsservctl); #endif diff --git a/kernel/module.c b/kernel/module.c index b4edc07d96db..afbbb4c72299 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -305,17 +305,17 @@ sys_init_module(const char *name_user, struct module *mod_user) for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) { struct module *o, *d = dep->dep; - /* Make sure the indicated dependancies are really modules. */ + /* Make sure the indicated dependencies are really modules. */ if (d == mod) { printk(KERN_ERR "init_module: self-referential " - "dependancy in mod->deps.\n"); + "dependency in mod->deps.\n"); goto err3; } for (o = module_list; o != &kernel_module; o = o->next) if (o == d) goto found_dep; - printk(KERN_ERR "init_module: found dependancy that is " + printk(KERN_ERR "init_module: found dependency that is " "(no longer?) a module.\n"); goto err3; @@ -790,7 +790,7 @@ free_module(struct module *mod, int tag_freed) mod->flags &= ~MOD_RUNNING; } - /* Remove the module from the dependancy lists. */ + /* Remove the module from the dependency lists. */ for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) { struct module_ref **pp; diff --git a/mm/page_io.c b/mm/page_io.c index cbbdc6ecc9d4..e02565def7e6 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -201,7 +201,9 @@ void rw_swap_page_nocache(int rw, unsigned long entry, char *buffer) } page->inode = &swapper_inode; page->offset = entry; + atomic_inc(&page->count); /* Protect from shrink_mmap() */ rw_swap_page(rw, entry, buffer, 1); + atomic_dec(&page->count); page->inode = 0; clear_bit(PG_swap_cache, &page->flags); } diff --git a/mm/vmscan.c b/mm/vmscan.c index c8c177d961af..36f5b01c0275 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -108,17 +108,8 @@ static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struc * * -- Stephen Tweedie 1998 */ - if (pte_write(pte)) { - /* - * We _will_ allow dirty cached mappings later on, once - * MAP_SHARED|MAP_ANONYMOUS is working, but for now - * catch this as a bug. - */ - if (is_page_shared(page_map)) { - printk ("VM: Found a shared writable dirty page!\n"); - return 0; - } - if (PageSwapCache(page_map)) { + if (PageSwapCache(page_map)) { + if (pte_write(pte)) { printk ("VM: Found a writable swap-cached page!\n"); return 0; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0206d8c7f86b..9180b8b54fbb 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -128,7 +128,7 @@ struct sk_buff *alloc_skb(unsigned int size,int gfp_mask) } /* - * FIXME: We could do with an architecture dependant + * FIXME: We could do with an architecture dependent * 'alignment mask'. */ diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index d3e018be8154..179c4ef9df0d 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -92,7 +92,7 @@ found: return isn; } -/* This value should be dependant on TCP_TIMEOUT_INIT and +/* This value should be dependent on TCP_TIMEOUT_INIT and * sysctl_tcp_retries1. It's a rather complicated formula * (exponential backoff) to compute at runtime so it's currently hardcoded * here. diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ae4a96647d0c..30bf6f0ee320 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -174,7 +174,7 @@ static __inline__ int tcp_lport_inuse(int num) return 0; } -/* Find a "good" local port, this is family independant. +/* Find a "good" local port, this is family independent. * There are several strategies working in unison here to * get the best possible performance. The current socket * load is kept track of, if it is zero there is a strong -- 2.39.5