summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2003-09-05 00:52:09 -0700
committerPatrick Mochel <mochel@osdl.org>2003-09-05 00:52:09 -0700
commita01cb2dfa8e91cb773483b2d83c778407515c876 (patch)
tree638647b50108536fef8d62a271b4d8096e33c1d7
parentf5b61a1fb00721206413b25f64e78edfb6b87777 (diff)
parent7c2dd86b82e5d4e44a41c871b9d8cdad5317645f (diff)
Merge
-rw-r--r--Documentation/Changes2
-rw-r--r--Documentation/cpu-freq/cpu-drivers.txt8
-rw-r--r--arch/arm/Kconfig34
-rw-r--r--arch/arm/Makefile5
-rw-r--r--arch/arm/kernel/entry-armv.S4
-rw-r--r--arch/arm/kernel/head.S6
-rw-r--r--arch/arm/kernel/pm.c10
-rw-r--r--arch/arm/kernel/setup.c1
-rw-r--r--arch/arm/mach-integrator/cpu.c2
-rw-r--r--arch/arm/mach-integrator/impd1.c2
-rw-r--r--arch/arm/mach-pxa/pm.c15
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c10
-rw-r--r--arch/arm/mach-sa1100/pm.c9
-rw-r--r--arch/arm/mm/proc-arm1020.S2
-rw-r--r--arch/i386/defconfig2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/elanfreq.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/gx-suspmod.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c337
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.h201
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longrun.c3
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k6.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c5
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-ich.c5
-rw-r--r--arch/i386/pci/pcbios.c3
-rw-r--r--arch/ia64/sn/io/hwgfs/ramfs.c3
-rw-r--r--arch/m68k/atari/stram.c6
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c3
-rw-r--r--arch/ppc/platforms/pmac_setup.c2
-rw-r--r--arch/sh/kernel/cpufreq.c2
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c2
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c2
-rw-r--r--arch/um/drivers/ubd_kern.c3
-rw-r--r--arch/x86_64/defconfig2
-rw-r--r--arch/x86_64/kernel/pci-gart.c4
-rw-r--r--crypto/Makefile3
-rw-r--r--crypto/autoload.c37
-rw-r--r--crypto/internal.h10
-rw-r--r--drivers/base/map.c5
-rw-r--r--drivers/block/DAC960.h32
-rw-r--r--drivers/block/as-iosched.c55
-rw-r--r--drivers/block/cciss.c222
-rw-r--r--drivers/block/deadline-iosched.c73
-rw-r--r--drivers/block/elevator.c26
-rw-r--r--drivers/block/floppy98.c1
-rw-r--r--drivers/block/ll_rw_blk.c32
-rw-r--r--drivers/block/noop-iosched.c19
-rw-r--r--drivers/block/paride/pt.c505
-rw-r--r--drivers/block/scsi_ioctl.c2
-rw-r--r--drivers/char/agp/Kconfig3
-rw-r--r--drivers/char/agp/Makefile2
-rw-r--r--drivers/char/agp/agp.h2
-rw-r--r--drivers/char/agp/amd64-agp.c (renamed from drivers/char/agp/amd-k8-agp.c)84
-rw-r--r--drivers/char/agp/i460-agp.c2
-rw-r--r--drivers/char/drm/drmP.h4
-rw-r--r--drivers/char/n_tty.c13
-rw-r--r--drivers/char/pcmcia/synclink_cs.c7
-rw-r--r--drivers/char/rocket.c30
-rw-r--r--drivers/char/synclink.c43
-rw-r--r--drivers/char/synclinkmp.c7
-rw-r--r--drivers/char/tipar.c1
-rw-r--r--drivers/char/tty_io.c153
-rw-r--r--drivers/cpufreq/Kconfig47
-rw-r--r--drivers/cpufreq/Makefile7
-rw-r--r--drivers/cpufreq/cpufreq.c (renamed from kernel/cpufreq.c)115
-rw-r--r--drivers/cpufreq/cpufreq_performance.c57
-rw-r--r--drivers/cpufreq/cpufreq_powersave.c56
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c (renamed from drivers/cpufreq/userspace.c)8
-rw-r--r--drivers/cpufreq/proc_intf.c26
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-io.c6
-rw-r--r--drivers/ieee1394/ieee1394_types.h4
-rw-r--r--drivers/md/dm-ioctl-v1.c2
-rw-r--r--drivers/md/dm-ioctl-v4.c2
-rw-r--r--drivers/md/dm-table.c2
-rw-r--r--drivers/md/linear.c1
-rw-r--r--drivers/md/md.c1
-rw-r--r--drivers/md/multipath.c1
-rw-r--r--drivers/md/raid0.c1
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/media/video/videodev.c2
-rw-r--r--drivers/media/video/zoran_driver.c2
-rw-r--r--drivers/net/Space.c6
-rw-r--r--drivers/net/wan/Kconfig2
-rw-r--r--drivers/net/wan/cosa.c30
-rw-r--r--drivers/net/wan/sdla.c36
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/tape_proc.c2
-rw-r--r--drivers/s390/char/tubio.h18
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--fs/afs/inode.c1
-rw-r--r--fs/autofs4/inode.c1
-rw-r--r--fs/block_dev.c4
-rw-r--r--fs/char_dev.c23
-rw-r--r--fs/cifs/dir.c3
-rw-r--r--fs/cifs/file.c4
-rw-r--r--fs/cifs/inode.c4
-rw-r--r--fs/coda/dir.c3
-rw-r--r--fs/cramfs/inode.c3
-rw-r--r--fs/devfs/base.c9
-rw-r--r--fs/efs/inode.c2
-rw-r--r--fs/ext2/inode.c4
-rw-r--r--fs/ext2/namei.c10
-rw-r--r--fs/ext3/inode.c4
-rw-r--r--fs/ext3/namei.c3
-rw-r--r--fs/ext3/super.c2
-rw-r--r--fs/freevxfs/vxfs_inode.c2
-rw-r--r--fs/hfs/inode.c1
-rw-r--r--fs/hpfs/inode.c36
-rw-r--r--fs/hpfs/namei.c2
-rw-r--r--fs/hugetlbfs/inode.c1
-rw-r--r--fs/inode.c6
-rw-r--r--fs/intermezzo/dir.c3
-rw-r--r--fs/intermezzo/journal.c10
-rw-r--r--fs/intermezzo/kml_reint.c5
-rw-r--r--fs/intermezzo/vfs.c2
-rw-r--r--fs/isofs/inode.c3
-rw-r--r--fs/isofs/rock.c4
-rw-r--r--fs/jffs/inode-v23.c9
-rw-r--r--fs/jffs2/dir.c5
-rw-r--r--fs/jffs2/fs.c3
-rw-r--r--fs/jffs2/super.c6
-rw-r--r--fs/jfs/inode.c3
-rw-r--r--fs/jfs/jfs_imap.c7
-rw-r--r--fs/jfs/jfs_incore.h3
-rw-r--r--fs/jfs/jfs_mount.c2
-rw-r--r--fs/jfs/namei.c6
-rw-r--r--fs/libfs.c20
-rw-r--r--fs/minix/inode.c8
-rw-r--r--fs/minix/namei.c7
-rw-r--r--fs/ncpfs/dir.c6
-rw-r--r--fs/ncpfs/inode.c4
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/nfs2xdr.c6
-rw-r--r--fs/nfsd/nfsproc.c7
-rw-r--r--fs/partitions/nec98.c3
-rw-r--r--fs/ramfs/inode.c1
-rw-r--r--fs/reiserfs/inode.c6
-rw-r--r--fs/reiserfs/journal.c3
-rw-r--r--fs/reiserfs/namei.c3
-rw-r--r--fs/romfs/inode.c6
-rw-r--r--fs/smbfs/dir.c3
-rw-r--r--fs/stat.c2
-rw-r--r--fs/sysfs/inode.c1
-rw-r--r--fs/sysv/inode.c14
-rw-r--r--fs/sysv/namei.c10
-rw-r--r--fs/udf/inode.c11
-rw-r--r--fs/udf/namei.c3
-rw-r--r--fs/ufs/inode.c16
-rw-r--r--fs/ufs/namei.c9
-rw-r--r--fs/xfs/linux/xfs_iops.c5
-rw-r--r--fs/xfs/linux/xfs_super.c4
-rw-r--r--fs/xfs/xfs_types.h2
-rw-r--r--fs/xfs/xfsidbg.c2
-rw-r--r--include/asm-i386/termios.h2
-rw-r--r--include/asm-sparc/termios.h3
-rw-r--r--include/asm-sparc64/termios.h3
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/cpufreq.h22
-rw-r--r--include/linux/elevator.h16
-rw-r--r--include/linux/fs.h10
-rw-r--r--include/linux/kdev_t.h109
-rw-r--r--include/linux/kmod.h2
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/mman.h29
-rw-r--r--include/linux/nfs_xdr.h2
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/sctp.h9
-rw-r--r--include/linux/tty_ldisc.h3
-rw-r--r--include/linux/vcache.h26
-rw-r--r--include/net/sctp/sctp.h23
-rw-r--r--include/net/sctp/sm.h12
-rw-r--r--include/net/sctp/structs.h171
-rw-r--r--include/net/sctp/user.h8
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/futex.c427
-rw-r--r--kernel/ksyms.c1
-rw-r--r--mm/Makefile2
-rw-r--r--mm/fremap.c31
-rw-r--r--mm/memory.c2
-rw-r--r--mm/mmap.c27
-rw-r--r--mm/mprotect.c7
-rw-r--r--mm/shmem.c1
-rw-r--r--mm/vcache.c90
-rw-r--r--net/README26
-rw-r--r--net/appletalk/ddp.c5
-rw-r--r--net/atm/br2684.c137
-rw-r--r--net/atm/common.c33
-rw-r--r--net/atm/common.h13
-rw-r--r--net/atm/pppoatm.c7
-rw-r--r--net/atm/proc.c7
-rw-r--r--net/atm/pvc.c2
-rw-r--r--net/atm/resources.c28
-rw-r--r--net/atm/resources.h14
-rw-r--r--net/atm/svc.c2
-rw-r--r--net/ax25/af_ax25.c3
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/core/dv.c1
-rw-r--r--net/core/rtnetlink.c3
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/ipmr.c1
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipx/af_ipx.c5
-rw-r--r--net/lapb/lapb_iface.c3
-rw-r--r--net/llc/af_llc.c5
-rw-r--r--net/llc/llc_main.c2
-rw-r--r--net/sctp/associola.c23
-rw-r--r--net/sctp/bind_addr.c40
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/ipv6.c29
-rw-r--r--net/sctp/primitive.c14
-rw-r--r--net/sctp/protocol.c27
-rw-r--r--net/sctp/sm_make_chunk.c179
-rw-r--r--net/sctp/sm_statefuns.c3
-rw-r--r--net/sctp/socket.c481
-rw-r--r--net/sctp/sysctl.c4
-rw-r--r--net/socket.c4
-rw-r--r--net/unix/af_unix.c141
223 files changed, 2600 insertions, 2594 deletions
diff --git a/Documentation/Changes b/Documentation/Changes
index 5ce920c736c7..f26c7c282164 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -54,7 +54,7 @@ o binutils 2.12 # ld -v
o util-linux 2.10o # fdformat --version
o module-init-tools 0.9.9 # depmod -V
o e2fsprogs 1.29 # tune2fs
-o jfsutils 1.0.14 # fsck.jfs -V
+o jfsutils 1.1.3 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o xfsprogs 2.1.0 # xfs_db -V
o pcmcia-cs 3.1.21 # cardmgr -V
diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
index be5c94d0f753..43c743903dd7 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -64,6 +64,12 @@ And optionally
cpufreq_driver.exit - A pointer to a per-CPU cleanup function.
+cpufreq_driver.resume - A pointer to a per-CPU resume function
+ which is called with interrupts disabled
+ and _before_ the pre-suspend frequency
+ and/or policy is restored by a call to
+ ->target or ->setpolicy.
+
cpufreq_driver.attr - A pointer to a NULL-terminated list of
"struct freq_attr" which allow to
export values to sysfs.
@@ -119,7 +125,7 @@ section 2 for details on frequency table helpers.
You need to make sure that at least one valid frequency (or operating
range) is within policy->min and policy->max. If necessary, increase
-policy->max fist, and only if this is no solution, decreas policy->min.
+policy->max first, and only if this is no solution, decrease policy->min.
1.4 target or setpolicy?
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f4846273df06..31cca56d8e2f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -542,39 +542,15 @@ config CPU_FREQ_SA1100
bool
depends on CPU_FREQ && SA1100_LART
default y
+ select CPU_FREQ_DEFAULT_GOV_USERSPACE
+ select CPU_FREQ_24_API if SYSCTL
config CPU_FREQ_SA1110
bool
depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3)
default y
-
-if (CPU_FREQ_SA1100 || CPU_FREQ_SA1110)
-
-config CPU_FREQ_GOV_USERSPACE
- tristate
- depends on CPU_FREQ
- default y
-
-config CPU_FREQ_24_API
- bool
- depends on CPU_FREQ_GOV_USERSPACE && SYSCTL
- default y
-
-config CPU_FREQ_PROC_INTF
- tristate "/proc/cpufreq interface (deprecated)"
- depends on CPU_FREQ && PROC_FS
- help
- This enables the /proc/cpufreq interface for controlling
- CPUFreq. Please note that it is recommended to use the sysfs
- interface instead (which is built automatically).
-
- For details, take a look at linux/Documentation/cpufreq.
-
- If in doubt, say N.
-
-endif
-
-# CPUfreq on Integrator can use the generic cpufreq core
+ select CPU_FREQ_DEFAULT_GOV_USERSPACE
+ select CPU_FREQ_24_API if SYSCTL
config CPU_FREQ_INTEGRATOR
tristate "CPUfreq driver for ARM Integrator CPUs"
@@ -587,7 +563,7 @@ config CPU_FREQ_INTEGRATOR
If in doubt, say Y.
-if (CPU_FREQ_INTEGRATOR)
+if (CPU_FREQ_INTEGRATOR) || (CPU_FREQ_SA1110) || (CPU_FREQ_SA1100)
source "drivers/cpufreq/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c2181d7de0a7..c6c817b0f9ef 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -34,7 +34,7 @@ comma = ,
# Note that GCC does not numerically define an architecture version
# macro, but instead defines a whole series of macros which makes
# testing for a specific architecture or later rather impossible.
-arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call check_gcc,-march=armv5te,-march=armv4 -Wa$(comma)-mxscale)
+arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call check_gcc,-march=armv5te,-march=armv4)
arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
@@ -47,8 +47,9 @@ tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
-tune-$(CONFIG_CPU_XSCALE) :=$(call check_gcc,-mtune=xscale,-mtune=strongarm110)
+tune-$(CONFIG_CPU_XSCALE) :=$(call check_gcc,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+# Need -Uarm for gcc < 3.x
CFLAGS_BOOT :=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
AFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0a5c2ea51b99..f6f64875dfd4 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -772,8 +772,8 @@ __irq_svc: sub sp, sp, #S_FRAME_SIZE
preempt_return:
ldr r0, [r8, #TI_PREEMPT] @ read preempt value
teq r0, r7
- strne r0, [r0, -r0] @ bug()
str r9, [r8, #TI_PREEMPT] @ restore preempt count
+ strne r0, [r0, -r0] @ bug()
#endif
ldr r0, [sp, #S_PSR] @ irqs are already disabled
msr spsr, r0
@@ -908,8 +908,8 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE
#ifdef CONFIG_PREEMPT
ldr r0, [r8, #TI_PREEMPT]
teq r0, r7
- strne r0, [r0, -r0]
str r9, [r8, #TI_PREEMPT]
+ strne r0, [r0, -r0]
mov tsk, r8
#else
get_thread_info tsk
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 4b233763aa0c..4de9941c54e2 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -120,9 +120,9 @@ __turn_mmu_on:
orr r0, r0, #2 @ ...........A.
#endif
mcr p15, 0, r0, c1, c0, 0 @ write control reg
- mrc p15, 0, r0, c1, c0, 0 @ read it back.
- mov r0, r0
- mov r0, r0
+ mrc p15, 0, r3, c0, c0, 0 @ read id reg
+ mov r3, r3
+ mov r3, r3
mov pc, lr
/*
diff --git a/arch/arm/kernel/pm.c b/arch/arm/kernel/pm.c
index e4a71e4e438f..fbe2d7a89580 100644
--- a/arch/arm/kernel/pm.c
+++ b/arch/arm/kernel/pm.c
@@ -11,6 +11,7 @@
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/device.h>
+#include <linux/sysdev.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -36,18 +37,25 @@ int suspend(void)
if (ret != 0)
goto out;
- device_suspend(3);
+ ret = device_suspend(3);
+ if (ret)
+ goto resume_legacy;
local_irq_disable();
leds_event(led_stop);
+ sysdev_suspend(3);
+
ret = pm_do_suspend();
+ sysdev_resume();
+
leds_event(led_start);
local_irq_enable();
device_resume();
+ resume_legacy:
pm_send_all(PM_RESUME, (void *)0);
out:
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index cb3a112f2905..1e16dd88c251 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -28,6 +28,7 @@
#include <asm/procinfo.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index c14943864287..50eab0a09c11 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -170,7 +170,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
vco.r = 22;
/* set default policy and cpuinfo */
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.max_freq = 160000;
policy->cpuinfo.min_freq = 12000;
policy->cpuinfo.transition_latency = 1000; /* 1 ms, assumed */
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 29608b2f91fa..15e2e27da2de 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -186,7 +186,7 @@ static int impd1_probe(struct device *dev)
memset(d, 0, sizeof(struct amba_device));
snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
- "lm%x:%5.5x", pdev->id, idev->offset >> 12);
+ "lm%x:%5.5lx", pdev->id, idev->offset >> 12);
d->dev.parent = &pdev->dev;
d->res.start = res->start + idev->offset;
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 98b4d76cf7c3..c8183c873e1a 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -12,6 +12,7 @@
*/
#include <linux/errno.h>
+#include <linux/time.h>
#include <asm/hardware.h>
#include <asm/memory.h>
@@ -63,15 +64,11 @@ int pm_do_suspend(void)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
unsigned long checksum = 0;
+ unsigned long delta;
int i;
- cli();
- clf();
-
- leds_event(led_stop);
-
/* preserve current time */
- RCNR = xtime.tv_sec;
+ delta = xtime.tv_sec - RCNR;
/*
* Temporary solution. This won't be necessary once
@@ -184,16 +181,12 @@ int pm_do_suspend(void)
RESTORE(FFIER);
/* restore current time */
- xtime.tv_sec = RCNR;
+ xtime.tv_sec = RCNR + delta;
#ifdef DEBUG
printk(KERN_DEBUG "*** made it back from resume\n");
#endif
- leds_event(led_start);
-
- sti();
-
return 0;
}
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index f71a28cdcf26..2ec95ad1db47 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -222,7 +222,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = sa11x0_getspeed();
- policy->policy = CPUFREQ_POLICY_POWERSAVE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = 59000;
policy->cpuinfo.max_freq = 287000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 87a0d789e34a..8643bb5b0aa3 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -270,8 +270,12 @@ static int sa1110_target(struct cpufreq_policy *policy,
* We wait 20ms to be safe.
*/
sdram_set_refresh(2);
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(20 * HZ / 1000);
+ if (!irqs_disabled()) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(20 * HZ / 1000);
+ } else {
+ mdelay(20);
+ }
/*
* Reprogram the DRAM timings with interrupts disabled, and
@@ -317,7 +321,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = sa11x0_getspeed();
- policy->policy = CPUFREQ_POLICY_POWERSAVE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = 59000;
policy->cpuinfo.max_freq = 287000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index ca55d99f678e..5c37635429bd 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -57,9 +57,11 @@ enum { SLEEP_SAVE_SP = 0,
int pm_do_suspend(void)
{
unsigned long sleep_save[SLEEP_SAVE_SIZE];
+ unsigned long delta, gpio;
/* preserve current time */
- RCNR = xtime.tv_sec;
+ delta = xtime.tv_sec - RCNR;
+ gpio = GPLR;
/* save vital registers */
SAVE(OSCR);
@@ -112,6 +114,9 @@ int pm_do_suspend(void)
RESTORE(Ser1SDCR0);
+ GPSR = gpio;
+ GPCR = ~gpio;
+
/*
* Clear the peripheral sleep-hold bit.
*/
@@ -125,7 +130,7 @@ int pm_do_suspend(void)
RESTORE(OIER);
/* restore current time */
- xtime.tv_sec = RCNR;
+ xtime.tv_sec = RCNR + delta;
return 0;
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 1712b9682de9..4808a860d216 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -79,7 +79,7 @@ ENTRY(cpu_arm1020_proc_fin)
stmfd sp!, {lr}
mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
msr cpsr_c, ip
- bl cpu_arm1020_cache_clean_invalidate_all
+ bl arm1020_flush_kern_cache_all
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
bic r0, r0, #0x1000 @ ...i............
bic r0, r0, #0x000e @ ............wca.
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 150ff18161a8..c51259a5dbf4 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -718,7 +718,7 @@ CONFIG_AGP=y
# CONFIG_AGP_ALI is not set
# CONFIG_AGP_ATI is not set
# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_AMD_8151 is not set
+# CONFIG_AGP_AMD64 is not set
CONFIG_AGP_INTEL=y
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
index 36cbb5015deb..2b1e68cb66a6 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c
@@ -580,7 +580,7 @@ acpi_cpufreq_cpu_init (
if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency)
policy->cpuinfo.transition_latency = perf->states[i].transition_latency;
}
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000;
/* table init */
diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
index 9214b2e0c360..a15f1ee967ad 100644
--- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
@@ -216,7 +216,7 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
}
/* cpuinfo and default policy values */
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = elanfreq_get_cpu_frequency();
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
index 0cec751f8ae8..bb5471e2bc81 100644
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
@@ -434,7 +434,7 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
policy->min = maxfreq / POLICY_MIN_DIV;
policy->max = maxfreq;
policy->cur = curfreq;
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = maxfreq / max_duration;
policy->cpuinfo.max_freq = maxfreq;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 808f7f5079b1..42a5ddf38d4e 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -10,10 +10,11 @@
* +---------------------+----------+---------------------------------+
* | Marketing name | Codename | longhaul version / features. |
* +---------------------+----------+---------------------------------+
- * | Samuel/CyrixIII | C5A | v1 : multipliers only |
+ * | Samuel/CyrixIII | C5A | v1 : multipliers only |
* | Samuel2/C3 | C3E/C5B | v1 : multiplier only |
- * | Ezra | C5C | v2 : multipliers & voltage |
- * | Ezra-T | C5M/C5N | v3 : multipliers, voltage & FSB |
+ * | Ezra | C5C | v2 : multipliers & voltage |
+ * | Ezra-T | C5M | v3 : multipliers, voltage & FSB |
+ * | Nehemiah | C5N | v3 : multipliers, voltage & FSB |
* +---------------------+----------+---------------------------------+
*
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
@@ -54,197 +55,6 @@ static unsigned int fsb;
#define __hlt() __asm__ __volatile__("hlt": : :"memory")
-/*
- * Clock ratio tables.
- * The eblcr ones specify the ratio read from the CPU.
- * The clock_ratio ones specify what to write to the CPU.
- */
-
-/* VIA C3 Samuel 1 & Samuel 2 (stepping 0)*/
-static int __initdata longhaul1_clock_ratio[16] = {
- -1, /* 0000 -> RESERVED */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- -1, /* 0011 -> RESERVED */
- -1, /* 0100 -> RESERVED */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 55, /* 0111 -> 5.5x */
- 60, /* 1000 -> 6.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 50, /* 1011 -> 5.0x */
- 65, /* 1100 -> 6.5x */
- 75, /* 1101 -> 7.5x */
- -1, /* 1110 -> RESERVED */
- -1, /* 1111 -> RESERVED */
-};
-
-static int __initdata samuel1_eblcr[16] = {
- 50, /* 0000 -> RESERVED */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- -1, /* 0011 -> RESERVED */
- 55, /* 0100 -> 5.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- -1, /* 0111 -> RESERVED */
- -1, /* 1000 -> RESERVED */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 60, /* 1011 -> 6.0x */
- -1, /* 1100 -> RESERVED */
- 75, /* 1101 -> 7.5x */
- -1, /* 1110 -> RESERVED */
- 65, /* 1111 -> 6.5x */
-};
-
-/* VIA C3 Samuel2 Stepping 1->15 & VIA C3 Ezra */
-static int __initdata longhaul2_clock_ratio[16] = {
- 100, /* 0000 -> 10.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 90, /* 0011 -> 9.0x */
- 95, /* 0100 -> 9.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 55, /* 0111 -> 5.5x */
- 60, /* 1000 -> 6.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 50, /* 1011 -> 5.0x */
- 65, /* 1100 -> 6.5x */
- 75, /* 1101 -> 7.5x */
- 85, /* 1110 -> 8.5x */
- 120, /* 1111 -> 12.0x */
-};
-
-static int __initdata samuel2_eblcr[16] = {
- 50, /* 0000 -> 5.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 100, /* 0011 -> 10.0x */
- 55, /* 0100 -> 5.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 110, /* 0111 -> 11.0x */
- 90, /* 1000 -> 9.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 60, /* 1011 -> 6.0x */
- 120, /* 1100 -> 12.0x */
- 75, /* 1101 -> 7.5x */
- 130, /* 1110 -> 13.0x */
- 65, /* 1111 -> 6.5x */
-};
-
-static int __initdata ezra_eblcr[16] = {
- 50, /* 0000 -> 5.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 100, /* 0011 -> 10.0x */
- 55, /* 0100 -> 5.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 95, /* 0111 -> 9.5x */
- 90, /* 1000 -> 9.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 60, /* 1011 -> 6.0x */
- 120, /* 1100 -> 12.0x */
- 75, /* 1101 -> 7.5x */
- 85, /* 1110 -> 8.5x */
- 65, /* 1111 -> 6.5x */
-};
-
-/* VIA C5M. */
-static int __initdata longhaul3_clock_ratio[32] = {
- 100, /* 0000 -> 10.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 90, /* 0011 -> 9.0x */
- 95, /* 0100 -> 9.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 55, /* 0111 -> 5.5x */
- 60, /* 1000 -> 6.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 50, /* 1011 -> 5.0x */
- 65, /* 1100 -> 6.5x */
- 75, /* 1101 -> 7.5x */
- 85, /* 1110 -> 8.5x */
- 120, /* 1111 -> 12.0x */
-
- -1, /* 0000 -> RESERVED (10.0x) */
- 110, /* 0001 -> 11.0x */
- 120, /* 0010 -> 12.0x */
- -1, /* 0011 -> RESERVED (9.0x)*/
- 105, /* 0100 -> 10.5x */
- 115, /* 0101 -> 11.5x */
- 125, /* 0110 -> 12.5x */
- 135, /* 0111 -> 13.5x */
- 140, /* 1000 -> 14.0x */
- 150, /* 1001 -> 15.0x */
- 160, /* 1010 -> 16.0x */
- 130, /* 1011 -> 13.0x */
- 145, /* 1100 -> 14.5x */
- 155, /* 1101 -> 15.5x */
- -1, /* 1110 -> RESERVED (13.0x) */
- -1, /* 1111 -> RESERVED (12.0x) */
-};
-
-static int __initdata c5m_eblcr[32] = {
- 50, /* 0000 -> 5.0x */
- 30, /* 0001 -> 3.0x */
- 40, /* 0010 -> 4.0x */
- 100, /* 0011 -> 10.0x */
- 55, /* 0100 -> 5.5x */
- 35, /* 0101 -> 3.5x */
- 45, /* 0110 -> 4.5x */
- 95, /* 0111 -> 9.5x */
- 90, /* 1000 -> 9.0x */
- 70, /* 1001 -> 7.0x */
- 80, /* 1010 -> 8.0x */
- 60, /* 1011 -> 6.0x */
- 120, /* 1100 -> 12.0x */
- 75, /* 1101 -> 7.5x */
- 85, /* 1110 -> 8.5x */
- 65, /* 1111 -> 6.5x */
-
- -1, /* 0000 -> RESERVED (9.0x) */
- 110, /* 0001 -> 11.0x */
- 120, /* 0010 -> 12.0x */
- -1, /* 0011 -> RESERVED (10.0x)*/
- 135, /* 0100 -> 13.5x */
- 115, /* 0101 -> 11.5x */
- 125, /* 0110 -> 12.5x */
- 105, /* 0111 -> 10.5x */
- 130, /* 1000 -> 13.0x */
- 150, /* 1001 -> 15.0x */
- 160, /* 1010 -> 16.0x */
- 140, /* 1011 -> 14.0x */
- -1, /* 1100 -> RESERVED (12.0x) */
- 155, /* 1101 -> 15.5x */
- -1, /* 1110 -> RESERVED (13.0x) */
- 145, /* 1111 -> 14.5x */
-};
-
-/* Voltage scales. Div by 1000 to get actual voltage. */
-static int __initdata vrm85scales[32] = {
- 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,
- 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300,
- 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725,
- 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325,
-};
-
-static int __initdata mobilevrmscales[32] = {
- 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
- 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1,
- 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
- 1075, 1050, 1025, 1000, 975, 950, 925, -1,
-};
-
/* Clock ratios multiplied by 10 */
static int clock_ratio[32];
static int eblcr_table[32];
@@ -254,18 +64,24 @@ static int longhaul_version;
static struct cpufreq_frequency_table *longhaul_table;
-static int longhaul_get_cpu_fsb (void)
+static unsigned int calc_speed (int mult, int fsb)
{
+ return ((mult/10)*fsb) + ((mult%10)*(fsb/2));
+}
+
+
+static unsigned int longhaul_get_cpu_fsb (void)
+{
+ unsigned long lo, hi;
unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };
- unsigned long invalue=0,lo, hi;
+ unsigned int invalue=0;
if (fsb == 0) {
rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
invalue = (lo & (1<<18|1<<19)) >>18;
- return eblcr_fsb_table[invalue];
- } else {
- return fsb;
+ fsb = eblcr_fsb_table[invalue];
}
+ return fsb;
}
@@ -292,26 +108,27 @@ static int longhaul_get_cpu_mult (void)
static void longhaul_setstate (unsigned int clock_ratio_index)
{
- int vidindex, i;
+ int speed, mult;
struct cpufreq_freqs freqs;
union msr_longhaul longhaul;
union msr_bcr2 bcr2;
- if (clock_ratio[clock_ratio_index] == -1)
+ mult = clock_ratio[clock_ratio_index];
+ if (mult == -1)
return;
- if (((clock_ratio[clock_ratio_index] * fsb * 100) > highest_speed) ||
- ((clock_ratio[clock_ratio_index] * fsb * 100) < lowest_speed))
+ speed = calc_speed (mult, fsb);
+ if ((speed > highest_speed) || (speed < lowest_speed))
return;
- freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100;
- freqs.new = clock_ratio[clock_ratio_index] * fsb * 100;
+ freqs.old = calc_speed (longhaul_get_cpu_mult(), fsb);
+ freqs.new = speed;
freqs.cpu = 0; /* longhaul.c is UP only driver */
-
+
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- dprintk (KERN_INFO PFX "FSB:%d Mult(x10):%d\n",
- fsb * 100, clock_ratio[clock_ratio_index]);
+ dprintk (KERN_INFO PFX "FSB:%d Mult:%d.%dx\n", fsb,
+ mult/10, mult%10);
switch (longhaul_version) {
case 1:
@@ -329,6 +146,14 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
wrmsrl (MSR_VIA_BCR2, bcr2.val);
break;
+ /*
+ * Longhaul v2. (Ezra [C5C])
+ * We can scale voltage with this too, but that's currently
+ * disabled until we come up with a decent 'match freq to voltage'
+ * algorithm.
+ * We also need to do the voltage/freq setting in order depending
+ * on the direction of scaling (like we do in powernow-k7.c)
+ */
case 2:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
@@ -337,39 +162,16 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
/* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
longhaul.bits.RevisionKey = 1;
-
- if (can_scale_voltage) {
- /* PB: TODO fix this up */
- vidindex = (((highest_speed-lowest_speed) / (fsb/2)) -
- ((highest_speed-((clock_ratio[clock_ratio_index] * fsb * 100)/1000)) / (fsb/2)));
- for (i=0;i<32;i++) {
- dprintk (KERN_INFO "VID hunting. Looking for %d, found %d\n",
- minvid+(vidindex*25), voltage_table[i]);
- if (voltage_table[i]==(minvid + (vidindex * 25)))
- break;
- }
- if (i==32)
- goto bad_voltage;
-
- dprintk (KERN_INFO PFX "Desired vid index=%d\n", i);
-#if 0
- longhaul.bits.SoftVID = i;
- longhaul.bits.EnableSoftVID = 1;
-#endif
- }
-/* FIXME: Do voltage and freq seperatly like we do in powernow-k7 */
-bad_voltage:
wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
__hlt();
- rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
- longhaul.bits.EnableSoftBusRatio = 0;
- if (can_scale_voltage)
- longhaul.bits.EnableSoftVID = 0;
- longhaul.bits.RevisionKey = 1;
- wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
break;
+ /*
+ * Longhaul v3. (Ezra-T [C5M], Nehemiag [C5N])
+ * This can also do voltage scaling, but see above.
+ * Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
+ */
case 3:
rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
@@ -378,7 +180,6 @@ bad_voltage:
/* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
longhaul.bits.RevisionKey = 3; /* SoftVID & SoftBSEL */
-
wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
__hlt();
@@ -403,6 +204,8 @@ static int __init longhaul_get_ranges (void)
unsigned int j, k = 0;
union msr_longhaul longhaul;
+ fsb = longhaul_get_cpu_fsb();
+
switch (longhaul_version) {
case 1:
/* Ugh, Longhaul v1 didn't have the min/max MSRs.
@@ -430,23 +233,25 @@ static int __init longhaul_get_ranges (void)
break;
}
- highest_speed = maxmult * fsb * 100;
- lowest_speed = minmult * fsb * 100;
- dprintk (KERN_INFO PFX "MinMult(x10)=%d MaxMult(x10)=%d\n",
- minmult, maxmult);
- dprintk (KERN_INFO PFX "Lowestspeed=%d Highestspeed=%d\n",
- lowest_speed, highest_speed);
+ dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n",
+ minmult/10, minmult%10, maxmult/10, maxmult%10);
+ highest_speed = calc_speed (maxmult, fsb);
+ lowest_speed = calc_speed (minmult,fsb);
+ dprintk (KERN_INFO PFX "FSB: %dMHz Lowestspeed=%dMHz Highestspeed=%dMHz\n",
+ fsb, lowest_speed, highest_speed);
longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
if(!longhaul_table)
return -ENOMEM;
- for (j=0; (j<numscales); j++) {
- if (clock_ratio[j] == -1)
+ for (j=0; j < numscales; j++) {
+ unsigned int ratio;
+ ratio = clock_ratio[j];
+ if (ratio == -1)
continue;
- if (((unsigned int)clock_ratio[j] > maxmult) || ((unsigned int)clock_ratio[j] < minmult))
+ if (ratio > maxmult || ratio < minmult)
continue;
- longhaul_table[k].frequency= clock_ratio[j] * fsb * 100;
+ longhaul_table[k].frequency = calc_speed (ratio, fsb);
longhaul_table[k].index = (j << 8);
k++;
}
@@ -541,10 +346,12 @@ static int longhaul_target (struct cpufreq_policy *policy,
static int longhaul_cpu_init (struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = cpu_data;
+ char *cpuname=NULL;
int ret;
switch (c->x86_model) {
- case 6: /* VIA C3 Samuel C5A */
+ case 6:
+ cpuname = "C3 'Samuel' [C5A]";
longhaul_version=1;
memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio));
memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr));
@@ -553,11 +360,13 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
case 7: /* C5B / C5C */
switch (c->x86_mask) {
case 0:
+ cpuname = "C3 'Samuel 2' [C5B]";
longhaul_version=1;
memcpy (clock_ratio, longhaul1_clock_ratio, sizeof(longhaul1_clock_ratio));
memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr));
break;
case 1 ... 15:
+ cpuname = "C3 'Ezra' [C5C]";
longhaul_version=2;
memcpy (clock_ratio, longhaul2_clock_ratio, sizeof(longhaul2_clock_ratio));
memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr));
@@ -565,17 +374,26 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
}
break;
- case 8: /* C5M/C5N */
- return -ENODEV; // Waiting on updated docs from VIA before this is usable
+ case 8:
+ cpuname = "C3 'Ezra-T [C5M]";
longhaul_version=3;
numscales=32;
memcpy (clock_ratio, longhaul3_clock_ratio, sizeof(longhaul3_clock_ratio));
memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr));
break;
+ /*
+ case 9:
+ cpuname = "C3 'Nehemiah' [C5N]";
+ longhaul_version=3;
+ numscales=32;
+ */
+ default:
+ cpuname = "Unknown";
+ break;
}
- printk (KERN_INFO PFX "VIA CPU detected. Longhaul version %d supported\n",
- longhaul_version);
+ printk (KERN_INFO PFX "VIA %s CPU detected. Longhaul v%d supported.\n",
+ cpuname, longhaul_version);
if ((longhaul_version==2 || longhaul_version==3) && (dont_scale_voltage==0))
longhaul_setup_voltagescaling();
@@ -584,10 +402,9 @@ static int longhaul_cpu_init (struct cpufreq_policy *policy)
if (ret != 0)
return ret;
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
- policy->cur = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100);
+ policy->cur = calc_speed (longhaul_get_cpu_mult(), fsb);
return cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
}
@@ -604,14 +421,20 @@ static int __init longhaul_init (void)
{
struct cpuinfo_x86 *c = cpu_data;
- if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
+ if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
return -ENODEV;
switch (c->x86_model) {
case 6 ... 7:
return cpufreq_register_driver(&longhaul_driver);
case 8:
- return -ENODEV;
+ printk (KERN_INFO PFX "Ezra-T unsupported: Waiting on updated docs "
+ "from VIA before this is usable.\n");
+ break;
+ case 9:
+ printk (KERN_INFO PFX "Nehemiah unsupported: Waiting on working silicon "
+ "from VIA before this is usable.\n");
+ break;
default:
printk (KERN_INFO PFX "Unknown VIA CPU. Contact davej@codemonkey.org.uk\n");
}
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h
index 3070d708cb56..f4d4a472b449 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.h
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h
@@ -47,3 +47,204 @@ union msr_longhaul {
unsigned long long val;
};
+/*
+ * Clock ratio tables. Div/Mod by 10 to get ratio.
+ * The eblcr ones specify the ratio read from the CPU.
+ * The clock_ratio ones specify what to write to the CPU.
+ */
+
+/*
+ * VIA C3 Samuel 1 & Samuel 2 (stepping 0)
+ */
+static int __initdata longhaul1_clock_ratio[16] = {
+ -1, /* 0000 -> RESERVED */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ -1, /* 0011 -> RESERVED */
+ -1, /* 0100 -> RESERVED */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 55, /* 0111 -> 5.5x */
+ 60, /* 1000 -> 6.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 50, /* 1011 -> 5.0x */
+ 65, /* 1100 -> 6.5x */
+ 75, /* 1101 -> 7.5x */
+ -1, /* 1110 -> RESERVED */
+ -1, /* 1111 -> RESERVED */
+};
+
+static int __initdata samuel1_eblcr[16] = {
+ 50, /* 0000 -> RESERVED */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ -1, /* 0011 -> RESERVED */
+ 55, /* 0100 -> 5.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ -1, /* 0111 -> RESERVED */
+ -1, /* 1000 -> RESERVED */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 60, /* 1011 -> 6.0x */
+ -1, /* 1100 -> RESERVED */
+ 75, /* 1101 -> 7.5x */
+ -1, /* 1110 -> RESERVED */
+ 65, /* 1111 -> 6.5x */
+};
+
+/*
+ * VIA C3 Samuel2 Stepping 1->15 & VIA C3 Ezra
+ */
+static int __initdata longhaul2_clock_ratio[16] = {
+ 100, /* 0000 -> 10.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 90, /* 0011 -> 9.0x */
+ 95, /* 0100 -> 9.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 55, /* 0111 -> 5.5x */
+ 60, /* 1000 -> 6.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 50, /* 1011 -> 5.0x */
+ 65, /* 1100 -> 6.5x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 120, /* 1111 -> 12.0x */
+};
+
+static int __initdata samuel2_eblcr[16] = {
+ 50, /* 0000 -> 5.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 100, /* 0011 -> 10.0x */
+ 55, /* 0100 -> 5.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 110, /* 0111 -> 11.0x */
+ 90, /* 1000 -> 9.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 60, /* 1011 -> 6.0x */
+ 120, /* 1100 -> 12.0x */
+ 75, /* 1101 -> 7.5x */
+ 130, /* 1110 -> 13.0x */
+ 65, /* 1111 -> 6.5x */
+};
+
+static int __initdata ezra_eblcr[16] = {
+ 50, /* 0000 -> 5.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 100, /* 0011 -> 10.0x */
+ 55, /* 0100 -> 5.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 95, /* 0111 -> 9.5x */
+ 90, /* 1000 -> 9.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 60, /* 1011 -> 6.0x */
+ 120, /* 1100 -> 12.0x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 65, /* 1111 -> 6.5x */
+};
+
+/*
+ * VIA C3 (Ezra-T) [C5M].
+ */
+static int __initdata longhaul3_clock_ratio[32] = {
+ 100, /* 0000 -> 10.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 90, /* 0011 -> 9.0x */
+ 95, /* 0100 -> 9.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 55, /* 0111 -> 5.5x */
+ 60, /* 1000 -> 6.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 50, /* 1011 -> 5.0x */
+ 65, /* 1100 -> 6.5x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 120, /* 1111 -> 12.0x */
+
+ -1, /* 0000 -> RESERVED (10.0x) */
+ 110, /* 0001 -> 11.0x */
+ 120, /* 0010 -> 12.0x */
+ -1, /* 0011 -> RESERVED (9.0x)*/
+ 105, /* 0100 -> 10.5x */
+ 115, /* 0101 -> 11.5x */
+ 125, /* 0110 -> 12.5x */
+ 135, /* 0111 -> 13.5x */
+ 140, /* 1000 -> 14.0x */
+ 150, /* 1001 -> 15.0x */
+ 160, /* 1010 -> 16.0x */
+ 130, /* 1011 -> 13.0x */
+ 145, /* 1100 -> 14.5x */
+ 155, /* 1101 -> 15.5x */
+ -1, /* 1110 -> RESERVED (13.0x) */
+ -1, /* 1111 -> RESERVED (12.0x) */
+};
+
+static int __initdata c5m_eblcr[32] = {
+ 50, /* 0000 -> 5.0x */
+ 30, /* 0001 -> 3.0x */
+ 40, /* 0010 -> 4.0x */
+ 100, /* 0011 -> 10.0x */
+ 55, /* 0100 -> 5.5x */
+ 35, /* 0101 -> 3.5x */
+ 45, /* 0110 -> 4.5x */
+ 95, /* 0111 -> 9.5x */
+ 90, /* 1000 -> 9.0x */
+ 70, /* 1001 -> 7.0x */
+ 80, /* 1010 -> 8.0x */
+ 60, /* 1011 -> 6.0x */
+ 120, /* 1100 -> 12.0x */
+ 75, /* 1101 -> 7.5x */
+ 85, /* 1110 -> 8.5x */
+ 65, /* 1111 -> 6.5x */
+
+ -1, /* 0000 -> RESERVED (9.0x) */
+ 110, /* 0001 -> 11.0x */
+ 120, /* 0010 -> 12.0x */
+ -1, /* 0011 -> RESERVED (10.0x)*/
+ 135, /* 0100 -> 13.5x */
+ 115, /* 0101 -> 11.5x */
+ 125, /* 0110 -> 12.5x */
+ 105, /* 0111 -> 10.5x */
+ 130, /* 1000 -> 13.0x */
+ 150, /* 1001 -> 15.0x */
+ 160, /* 1010 -> 16.0x */
+ 140, /* 1011 -> 14.0x */
+ -1, /* 1100 -> RESERVED (12.0x) */
+ 155, /* 1101 -> 15.5x */
+ -1, /* 1110 -> RESERVED (13.0x) */
+ 145, /* 1111 -> 14.5x */
+};
+
+
+/*
+ * Voltage scales. Div/Mod by 1000 to get actual voltage.
+ * Which scale to use depends on the VRM type in use.
+ */
+static int __initdata vrm85scales[32] = {
+ 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,
+ 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300,
+ 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725,
+ 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325,
+};
+
+static int __initdata mobilevrmscales[32] = {
+ 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
+ 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1,
+ 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
+ 1075, 1050, 1025, 1000, 975, 950, 925, -1,
+};
+
diff --git a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
index 2adb51a8d3d4..8633cf069d07 100644
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c
@@ -120,7 +120,8 @@ static int longrun_verify_policy(struct cpufreq_policy *policy)
policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
- if (policy->policy == CPUFREQ_POLICY_GOVERNOR)
+ if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
+ (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
return -EINVAL;
return 0;
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index a1d257e3fa29..4bf4fee0d372 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -211,7 +211,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
/* cpuinfo and default policy values */
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 1000;
policy->cur = stock_freq;
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
index 5d967dfe4dbc..bfb2b6b5468c 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
@@ -157,7 +157,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
}
/* cpuinfo and default policy values */
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = busfreq * max_multiplier;
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index bf923ee095fe..c0b9bf22b7e9 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -1,6 +1,7 @@
/*
* AMD K7 Powernow driver.
* (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
+ * (C) 2003 Dave Jones <davej@redhat.com>
*
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD.
@@ -325,6 +326,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
p+=2;
}
}
+ printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple);
+ printk ("This is indicative of a broken BIOS. Email davej@redhat.com\n");
return -EINVAL;
}
p++;
@@ -372,7 +375,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
minimum_speed, maximum_speed);
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = latency;
policy->cur = maximum_speed;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 19c7821cc15c..2653cc2f3b0c 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -201,9 +201,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
freq = get_cur_freq();
- policy->policy = (freq == centrino_model->max_freq) ?
- CPUFREQ_POLICY_PERFORMANCE :
- CPUFREQ_POLICY_POWERSAVE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 10; /* 10uS transition latency */
policy->cur = freq;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index 500b95d66a79..aeeaefd33789 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -299,8 +299,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
(speed / 1000));
/* cpuinfo and default policy values */
- policy->policy = (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ?
- CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = speed;
@@ -309,7 +308,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
static struct cpufreq_driver speedstep_driver = {
- .name = "speedstep",
+ .name = "speedstep-ich",
.verify = speedstep_verify,
.target = speedstep_target,
.init = speedstep_cpu_init,
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
index 9e8ff72c542f..8db66f34640f 100644
--- a/arch/i386/pci/pcbios.c
+++ b/arch/i386/pci/pcbios.c
@@ -430,7 +430,8 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
"xor %%ah, %%ah\n"
"1:"
: "=a" (ret),
- "=b" (map)
+ "=b" (map),
+ "+m" (opt)
: "0" (PCIBIOS_GET_ROUTING_OPTIONS),
"1" (0),
"D" ((long) &opt),
diff --git a/arch/ia64/sn/io/hwgfs/ramfs.c b/arch/ia64/sn/io/hwgfs/ramfs.c
index 0ec5807cc73a..5a112ccbfd27 100644
--- a/arch/ia64/sn/io/hwgfs/ramfs.c
+++ b/arch/ia64/sn/io/hwgfs/ramfs.c
@@ -56,7 +56,7 @@ static struct backing_dev_info hwgfs_backing_dev_info = {
.memory_backed = 1, /* Does not contribute to dirty memory */
};
-struct inode *hwgfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+static struct inode *hwgfs_get_inode(struct super_block *sb, int mode, dev_t dev)
{
struct inode * inode = new_inode(sb);
@@ -66,7 +66,6 @@ struct inode *hwgfs_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &hwgfs_aops;
inode->i_mapping->backing_dev_info = &hwgfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 95152f2f2c65..3e3531a38a13 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -34,12 +34,6 @@
#include <linux/swapops.h>
-#ifdef CONFIG_STRAM_SWAP
-#define MAJOR_NR Z2RAM_MAJOR
-#define do_z2_request do_stram_request
-#define DEVICE_NR(device) (minor(device))
-#endif
-
#undef DEBUG
#ifdef DEBUG
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index a748cb0109db..be861eebab62 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -257,8 +257,7 @@ pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -ENODEV;
- policy->policy = (cur_freq == low_freq) ?
- CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = cur_freq;
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
index 15de29c7b588..189e8d0d18b8 100644
--- a/arch/ppc/platforms/pmac_setup.c
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -399,7 +399,7 @@ note_scsi_host(struct device_node *node, void *host)
#endif
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
-dev_t __init
+static dev_t __init
find_ide_boot(void)
{
char *p;
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index 4a5330f0479f..85516164e866 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -160,7 +160,7 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
sh_freqs[SH_FREQ_MIN].frequency = min_freq;
/* cpuinfo and default policy values */
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = max_freq;
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index 74926fbbe52e..7aae0a18aabe 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -309,7 +309,7 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
table[2].index = 5;
table[3].frequency = CPUFREQ_TABLE_END;
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 0;
policy->cur = clock_tick;
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index b5475e7295ef..18fe54b8aa55 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -163,7 +163,7 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
table[3].index = 0;
table[3].frequency = CPUFREQ_TABLE_END;
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 0;
policy->cur = clock_tick;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 39fa46ec2db6..0c3890b3ea12 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -55,9 +55,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
#define MAX_DEV (8)
-#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
-
-#define DEVICE_NR(n) (minor(n) >> UBD_SHIFT)
static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index c0474ff8674b..d9870aaa4833 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -561,7 +561,7 @@ CONFIG_RTC=y
#
# CONFIG_FTAPE is not set
CONFIG_AGP=y
-CONFIG_AGP_AMD_8151=y
+CONFIG_AGP_AMD64=y
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
CONFIG_RAW_DRIVER=y
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 6842d5823465..3510604677d8 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -675,7 +675,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
return -1;
}
-extern int agp_amdk8_init(void);
+extern int agp_amd64_init(void);
static int __init pci_iommu_init(void)
{
@@ -690,7 +690,7 @@ static int __init pci_iommu_init(void)
/* Makefile puts PCI initialization via subsys_initcall first. */
/* Add other K8 AGP bridge drivers here */
no_agp = no_agp ||
- (agp_amdk8_init() < 0) ||
+ (agp_amd64_init() < 0) ||
(agp_copy_info(&info) < 0);
#endif
diff --git a/crypto/Makefile b/crypto/Makefile
index f3325db1ee76..8326b4fb5be4 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -2,11 +2,10 @@
# Cryptographic API
#
-autoload-crypto-$(CONFIG_KMOD) = autoload.o
proc-crypto-$(CONFIG_PROC_FS) = proc.o
obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o \
- $(autoload-crypto-y) $(proc-crypto-y)
+ $(proc-crypto-y)
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
diff --git a/crypto/autoload.c b/crypto/autoload.c
deleted file mode 100644
index 7cda40b39ddf..000000000000
--- a/crypto/autoload.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Algorithm autoloader.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- */
-#include <linux/kernel.h>
-#include <linux/crypto.h>
-#include <linux/string.h>
-#include <linux/kmod.h>
-#include "internal.h"
-
-/*
- * A far more intelligent version of this is planned. For now, just
- * try an exact match on the name of the algorithm.
- */
-void crypto_alg_autoload(const char *name)
-{
- request_module("%s", name);
-}
-
-struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
- struct crypto_alg *alg = crypto_alg_lookup(name);
- if (alg == NULL) {
- crypto_alg_autoload(name);
- alg = crypto_alg_lookup(name);
- }
- return alg;
-}
diff --git a/crypto/internal.h b/crypto/internal.h
index 10880d149afe..8ba30b772ee3 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -15,6 +15,7 @@
#include <linux/highmem.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/kmod.h>
#include <asm/hardirq.h>
#include <asm/kmap_types.h>
@@ -48,15 +49,12 @@ static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
struct crypto_alg *crypto_alg_lookup(const char *name);
-#ifdef CONFIG_KMOD
-void crypto_alg_autoload(const char *name);
-struct crypto_alg *crypto_alg_mod_lookup(const char *name);
-#else
+/* A far more intelligent version of this is planned. For now, just
+ * try an exact match on the name of the algorithm. */
static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
{
- return crypto_alg_lookup(name);
+ return try_then_request_module(crypto_alg_lookup(name), name);
}
-#endif
#ifdef CONFIG_CRYPTO_HMAC
int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
diff --git a/drivers/base/map.c b/drivers/base/map.c
index 0fc8e3a10756..af7ae91d8145 100644
--- a/drivers/base/map.c
+++ b/drivers/base/map.c
@@ -28,11 +28,6 @@ struct kobj_map {
struct rw_semaphore *sem;
};
-static inline int dev_to_index(dev_t dev)
-{
- return MAJOR(dev) % 255;
-}
-
int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
struct module *module, kobj_probe_t *probe,
int (*lock)(dev_t, void *), void *data)
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 14b90438a30f..28fb52af3af4 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2063,38 +2063,6 @@ extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
#define DAC960_MaxPartitions 8
#define DAC960_MaxPartitionsBits 3
-
-/*
- Define macros to extract the Controller Number, Logical Drive Number, and
- Partition Number from a Kernel Device, and to construct a Major Number, Minor
- Number, and Kernel Device from the Controller Number, Logical Drive Number,
- and Partition Number. There is one Major Number assigned to each Controller.
- The associated Minor Number is divided into the Logical Drive Number and
- Partition Number.
-*/
-
-#define DAC960_ControllerNumber(Device) \
- (major(Device) - DAC960_MAJOR)
-
-#define DAC960_LogicalDriveNumber(Device) \
- (minor(Device) >> DAC960_MaxPartitionsBits)
-
-#define DAC960_MajorNumber(ControllerNumber) \
- (DAC960_MAJOR + (ControllerNumber))
-
-#define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
- (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
-
-#define DAC960_MinorCount (DAC960_MaxLogicalDrives \
- * DAC960_MaxPartitions)
-
-#define DAC960_KernelDevice(ControllerNumber, \
- LogicalDriveNumber, \
- PartitionNumber) \
- mk_kdev(DAC960_MajorNumber(ControllerNumber), \
- DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
-
-
/*
Define the DAC960 Controller fixed Block Size and Block Size Bits.
*/
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 27384d27b566..3d9c58788373 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -255,7 +255,7 @@ static void as_remove_merge_hints(request_queue_t *q, struct as_rq *arq)
{
as_del_arq_hash(arq);
- if (q->last_merge == &arq->request->queuelist)
+ if (q->last_merge == arq->request)
q->last_merge = NULL;
}
@@ -1347,50 +1347,39 @@ static void as_requeue_request(request_queue_t *q, struct request *rq)
}
static void
-as_insert_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+as_insert_request(request_queue_t *q, struct request *rq, int where)
{
struct as_data *ad = q->elevator.elevator_data;
struct as_rq *arq = RQ_DATA(rq);
- if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) {
- q->last_merge = NULL;
-
- if (insert_here != ad->dispatch) {
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
while (ad->next_arq[REQ_SYNC])
as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
while (ad->next_arq[REQ_ASYNC])
as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
- }
-
- if (!insert_here)
- insert_here = ad->dispatch->prev;
- }
-
- if (unlikely(!blk_fs_request(rq))) {
- if (!insert_here)
- insert_here = ad->dispatch;
- }
-
- if (insert_here) {
- list_add(&rq->queuelist, insert_here);
-
- /* Stop anticipating - let this request get through */
- if (list_empty(ad->dispatch))
+ list_add_tail(&rq->queuelist, ad->dispatch);
+ break;
+ case ELEVATOR_INSERT_FRONT:
+ list_add(&rq->queuelist, ad->dispatch);
as_antic_stop(ad);
-
- return;
+ break;
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ as_add_request(ad, arq);
+ break;
+ default:
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
}
if (rq_mergeable(rq)) {
as_add_arq_hash(ad, arq);
if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
-
- as_add_request(ad, arq);
}
/*
@@ -1438,7 +1427,7 @@ as_latter_request(request_queue_t *q, struct request *rq)
}
static int
-as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+as_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct as_data *ad = q->elevator.elevator_data;
sector_t rb_key = bio->bi_sector + bio_sectors(bio);
@@ -1450,7 +1439,7 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
*/
ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) {
- __rq = list_entry_rq(q->last_merge);
+ __rq = q->last_merge;
goto out_insert;
}
@@ -1482,11 +1471,11 @@ as_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = &__rq->queuelist;
+ q->last_merge = __rq;
out_insert:
if (ret)
as_hot_arq_hash(ad, RQ_DATA(__rq));
- *insert = &__rq->queuelist;
+ *req = __rq;
return ret;
}
@@ -1514,7 +1503,7 @@ static void as_merged_request(request_queue_t *q, struct request *req)
*/
}
- q->last_merge = &req->queuelist;
+ q->last_merge = req;
}
static void
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index ce0927b36889..8d2fd57b1b3a 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -120,10 +120,10 @@ static int cciss_release(struct inode *inode, struct file *filep);
static int cciss_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg);
-static int revalidate_allvol(kdev_t dev);
+static int revalidate_allvol(ctlr_info_t *host);
static int cciss_revalidate(struct gendisk *disk);
-static int deregister_disk(int ctlr, int logvol);
-static int register_new_disk(int cltr);
+static int deregister_disk(struct gendisk *disk);
+static int register_new_disk(ctlr_info_t *h);
static void cciss_getgeometry(int cntl_num);
@@ -351,34 +351,42 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
}
}
+static inline ctlr_info_t *get_host(struct gendisk *disk)
+{
+ return disk->queue->queuedata;
+}
+
+static inline drive_info_struct *get_drv(struct gendisk *disk)
+{
+ return disk->private_data;
+}
+
/*
* Open. Make sure the device is really there.
*/
static int cciss_open(struct inode *inode, struct file *filep)
{
- int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR;
- int dsk = iminor(inode) >> NWD_SHIFT;
+ ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+ drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "cciss_open %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk);
+ printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */
- if (ctlr >= MAX_CTLR || hba[ctlr] == NULL)
- return -ENXIO;
/*
* Root is allowed to open raw volume zero even if it's not configured
* so array config can still work. I don't think I really like this,
* but I'm already using way to many device nodes to claim another one
* for "raw controller".
*/
- if (hba[ctlr]->drv[dsk].nr_blocks == 0) {
+ if (drv->nr_blocks == 0) {
if (iminor(inode) != 0)
return -ENXIO;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
}
- hba[ctlr]->drv[dsk].usage_count++;
- hba[ctlr]->usage_count++;
+ drv->usage_count++;
+ host->usage_count++;
return 0;
}
/*
@@ -386,17 +394,15 @@ static int cciss_open(struct inode *inode, struct file *filep)
*/
static int cciss_release(struct inode *inode, struct file *filep)
{
- int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR;
- int dsk = iminor(inode) >> NWD_SHIFT;
+ ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+ drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);
#ifdef CCISS_DEBUG
- printk(KERN_DEBUG "cciss_release %s (%x:%x)\n", inode->i_bdev->bd_disk->disk_name, ctlr, dsk);
+ printk(KERN_DEBUG "cciss_release %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */
- /* fsync_dev(inode->i_rdev); */
-
- hba[ctlr]->drv[dsk].usage_count--;
- hba[ctlr]->usage_count--;
+ drv->usage_count--;
+ host->usage_count--;
return 0;
}
@@ -406,8 +412,11 @@ static int cciss_release(struct inode *inode, struct file *filep)
static int cciss_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
- int ctlr = imajor(inode) - COMPAQ_CISS_MAJOR;
- int dsk = iminor(inode) >> NWD_SHIFT;
+ struct block_device *bdev = inode->i_bdev;
+ struct gendisk *disk = bdev->bd_disk;
+ ctlr_info_t *host = get_host(disk);
+ drive_info_struct *drv = get_drv(disk);
+ int ctlr = host->ctlr;
#ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
@@ -417,14 +426,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case HDIO_GETGEO:
{
struct hd_geometry driver_geo;
- if (hba[ctlr]->drv[dsk].cylinders) {
- driver_geo.heads = hba[ctlr]->drv[dsk].heads;
- driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
- driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
+ if (drv->cylinders) {
+ driver_geo.heads = drv->heads;
+ driver_geo.sectors = drv->sectors;
+ driver_geo.cylinders = drv->cylinders;
} else {
driver_geo.heads = 0xff;
driver_geo.sectors = 0x3f;
- driver_geo.cylinders = (int)hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f);
+ driver_geo.cylinders = (int)drv->nr_blocks / (0xff*0x3f);
}
driver_geo.start= get_start_sect(inode->i_bdev);
if (copy_to_user((void *) arg, &driver_geo,
@@ -438,9 +447,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
cciss_pci_info_struct pciinfo;
if (!arg) return -EINVAL;
- pciinfo.bus = hba[ctlr]->pdev->bus->number;
- pciinfo.dev_fn = hba[ctlr]->pdev->devfn;
- pciinfo.board_id = hba[ctlr]->board_id;
+ pciinfo.bus = host->pdev->bus->number;
+ pciinfo.dev_fn = host->pdev->devfn;
+ pciinfo.board_id = host->board_id;
if (copy_to_user((void *) arg, &pciinfo, sizeof( cciss_pci_info_struct )))
return -EFAULT;
return(0);
@@ -448,11 +457,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETINTINFO:
{
cciss_coalint_struct intinfo;
- ctlr_info_t *c = hba[ctlr];
-
if (!arg) return -EINVAL;
- intinfo.delay = readl(&c->cfgtable->HostWrite.CoalIntDelay);
- intinfo.count = readl(&c->cfgtable->HostWrite.CoalIntCount);
+ intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay);
+ intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount);
if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct )))
return -EFAULT;
return(0);
@@ -460,7 +467,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_SETINTINFO:
{
cciss_coalint_struct intinfo;
- ctlr_info_t *c = hba[ctlr];
unsigned long flags;
int i;
@@ -477,13 +483,13 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* Update the field, and then ring the doorbell */
writel( intinfo.delay,
- &(c->cfgtable->HostWrite.CoalIntDelay));
+ &(host->cfgtable->HostWrite.CoalIntDelay));
writel( intinfo.count,
- &(c->cfgtable->HostWrite.CoalIntCount));
- writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
+ &(host->cfgtable->HostWrite.CoalIntCount));
+ writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
- if (!(readl(c->vaddr + SA5_DOORBELL)
+ if (!(readl(host->vaddr + SA5_DOORBELL)
& CFGTBL_ChangeReq))
break;
/* delay and try again */
@@ -497,12 +503,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETNODENAME:
{
NodeName_type NodeName;
- ctlr_info_t *c = hba[ctlr];
int i;
if (!arg) return -EINVAL;
for(i=0;i<16;i++)
- NodeName[i] = readb(&c->cfgtable->ServerName[i]);
+ NodeName[i] = readb(&host->cfgtable->ServerName[i]);
if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type)))
return -EFAULT;
return(0);
@@ -510,7 +515,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_SETNODENAME:
{
NodeName_type NodeName;
- ctlr_info_t *c = hba[ctlr];
unsigned long flags;
int i;
@@ -524,12 +528,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* Update the field, and then ring the doorbell */
for(i=0;i<16;i++)
- writeb( NodeName[i], &c->cfgtable->ServerName[i]);
+ writeb( NodeName[i], &host->cfgtable->ServerName[i]);
- writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
+ writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);
for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
- if (!(readl(c->vaddr + SA5_DOORBELL)
+ if (!(readl(host->vaddr + SA5_DOORBELL)
& CFGTBL_ChangeReq))
break;
/* delay and try again */
@@ -544,10 +548,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETHEARTBEAT:
{
Heartbeat_type heartbeat;
- ctlr_info_t *c = hba[ctlr];
if (!arg) return -EINVAL;
- heartbeat = readl(&c->cfgtable->HeartBeat);
+ heartbeat = readl(&host->cfgtable->HeartBeat);
if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type)))
return -EFAULT;
return(0);
@@ -555,10 +558,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case CCISS_GETBUSTYPES:
{
BusTypes_type BusTypes;
- ctlr_info_t *c = hba[ctlr];
if (!arg) return -EINVAL;
- BusTypes = readl(&c->cfgtable->BusTypes);
+ BusTypes = readl(&host->cfgtable->BusTypes);
if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) ))
return -EFAULT;
return(0);
@@ -568,7 +570,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
FirmwareVer_type firmware;
if (!arg) return -EINVAL;
- memcpy(firmware, hba[ctlr]->firm_ver, 4);
+ memcpy(firmware, host->firm_ver, 4);
if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type)))
return -EFAULT;
@@ -586,12 +588,12 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
}
case CCISS_REVALIDVOLS:
- return( revalidate_allvol(inode->i_rdev));
+ if (bdev != bdev->bd_contains || drv != host->drv)
+ return -ENXIO;
+ return revalidate_allvol(host);
case CCISS_GETLUNINFO: {
LogvolInfo_struct luninfo;
- struct gendisk *disk = hba[ctlr]->gendisk[dsk];
- drive_info_struct *drv = &hba[ctlr]->drv[dsk];
int i;
luninfo.LunID = drv->LunID;
@@ -610,16 +612,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return(0);
}
case CCISS_DEREGDISK:
- return( deregister_disk(ctlr,dsk));
+ return deregister_disk(disk);
case CCISS_REGNEWD:
- {
- return(register_new_disk(ctlr));
- }
+ return register_new_disk(host);
+
case CCISS_PASSTHRU:
{
IOCTL_Command_struct iocommand;
- ctlr_info_t *h = hba[ctlr];
CommandList_struct *c;
char *buff = NULL;
u64bit temp64;
@@ -655,7 +655,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
return -EFAULT;
}
}
- if ((c = cmd_alloc(h , 0)) == NULL)
+ if ((c = cmd_alloc(host , 0)) == NULL)
{
kfree(buff);
return -ENOMEM;
@@ -682,7 +682,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
// Fill in the scatter gather information
if (iocommand.buf_size > 0 )
{
- temp64.val = pci_map_single( h->pdev, buff,
+ temp64.val = pci_map_single( host->pdev, buff,
iocommand.buf_size,
PCI_DMA_BIDIRECTIONAL);
c->SG[0].Addr.lower = temp64.val32.lower;
@@ -694,9 +694,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* Put the request on the tail of the request queue */
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
- addQ(&h->reqQ, c);
- h->Qdepth++;
- start_io(h);
+ addQ(&host->reqQ, c);
+ host->Qdepth++;
+ start_io(host);
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
wait_for_completion(&wait);
@@ -704,7 +704,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
/* unlock the buffers from DMA */
temp64.val32.lower = c->SG[0].Addr.lower;
temp64.val32.upper = c->SG[0].Addr.upper;
- pci_unmap_single( h->pdev, (dma_addr_t) temp64.val,
+ pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,
iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
/* Copy the error information out */
@@ -712,7 +712,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
{
kfree(buff);
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
return( -EFAULT);
}
@@ -722,17 +722,16 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if (copy_to_user(iocommand.buf, buff, iocommand.buf_size))
{
kfree(buff);
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
return -EFAULT;
}
}
kfree(buff);
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
return(0);
}
case CCISS_BIG_PASSTHRU: {
BIG_IOCTL_Command_struct *ioc;
- ctlr_info_t *h = hba[ctlr];
CommandList_struct *c;
unsigned char **buff = NULL;
int *buff_size = NULL;
@@ -798,7 +797,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
data_ptr += sz;
sg_used++;
}
- if ((c = cmd_alloc(h , 0)) == NULL) {
+ if ((c = cmd_alloc(host , 0)) == NULL) {
status = -ENOMEM;
goto cleanup1;
}
@@ -819,7 +818,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
if (ioc->buf_size > 0 ) {
int i;
for(i=0; i<sg_used; i++) {
- temp64.val = pci_map_single( h->pdev, buff[i],
+ temp64.val = pci_map_single( host->pdev, buff[i],
buff_size[i],
PCI_DMA_BIDIRECTIONAL);
c->SG[i].Addr.lower = temp64.val32.lower;
@@ -831,22 +830,22 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
c->waiting = &wait;
/* Put the request on the tail of the request queue */
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
- addQ(&h->reqQ, c);
- h->Qdepth++;
- start_io(h);
+ addQ(&host->reqQ, c);
+ host->Qdepth++;
+ start_io(host);
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
wait_for_completion(&wait);
/* unlock the buffers from DMA */
for(i=0; i<sg_used; i++) {
temp64.val32.lower = c->SG[i].Addr.lower;
temp64.val32.upper = c->SG[i].Addr.upper;
- pci_unmap_single( h->pdev, (dma_addr_t) temp64.val,
+ pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,
buff_size[i], PCI_DMA_BIDIRECTIONAL);
}
/* Copy the error information out */
ioc->error_info = *(c->err_info);
if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
status = -EFAULT;
goto cleanup1;
}
@@ -855,14 +854,14 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
BYTE *ptr = (BYTE *) ioc->buf;
for(i=0; i< sg_used; i++) {
if (copy_to_user(ptr, buff[i], buff_size[i])) {
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
status = -EFAULT;
goto cleanup1;
}
ptr += buff_size[i];
}
}
- cmd_free(h, c, 0);
+ cmd_free(host, c, 0);
status = 0;
cleanup1:
if (buff) {
@@ -901,27 +900,23 @@ static int cciss_revalidate(struct gendisk *disk)
* particualar logical volume (instead of all of them on a particular
* controller).
*/
-static int revalidate_allvol(kdev_t dev)
+static int revalidate_allvol(ctlr_info_t *host)
{
- int ctlr, i;
+ int ctlr = host->ctlr, i;
unsigned long flags;
- ctlr = major(dev) - COMPAQ_CISS_MAJOR;
- if (minor(dev) != 0)
- return -ENXIO;
-
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
- if (hba[ctlr]->usage_count > 1) {
+ if (host->usage_count > 1) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
printk(KERN_WARNING "cciss: Device busy for volume"
- " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
+ " revalidation (usage=%d)\n", host->usage_count);
return -EBUSY;
}
- hba[ctlr]->usage_count++;
+ host->usage_count++;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
for(i=0; i< NWD; i++) {
- struct gendisk *disk = hba[ctlr]->gendisk[i];
+ struct gendisk *disk = host->gendisk[i];
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
}
@@ -930,54 +925,55 @@ static int revalidate_allvol(kdev_t dev)
* Set the partition and block size structures for all volumes
* on this controller to zero. We will reread all of this data
*/
- memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct)
+ memset(host->drv, 0, sizeof(drive_info_struct)
* CISS_MAX_LUN);
/*
* Tell the array controller not to give us any interrupts while
* we check the new geometry. Then turn interrupts back on when
* we're done.
*/
- hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_OFF);
+ host->access.set_intr_mask(host, CCISS_INTR_OFF);
cciss_getgeometry(ctlr);
- hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON);
+ host->access.set_intr_mask(host, CCISS_INTR_ON);
/* Loop through each real device */
for (i = 0; i < NWD; i++) {
- struct gendisk *disk = hba[ctlr]->gendisk[i];
- drive_info_struct *drv = &(hba[ctlr]->drv[i]);
+ struct gendisk *disk = host->gendisk[i];
+ drive_info_struct *drv = &(host->drv[i]);
if (!drv->nr_blocks)
continue;
- blk_queue_hardsect_size(hba[ctlr]->queue, drv->block_size);
+ blk_queue_hardsect_size(host->queue, drv->block_size);
set_capacity(disk, drv->nr_blocks);
add_disk(disk);
}
- hba[ctlr]->usage_count--;
+ host->usage_count--;
return 0;
}
-static int deregister_disk(int ctlr, int logvol)
+static int deregister_disk(struct gendisk *disk)
{
unsigned long flags;
- struct gendisk *disk = hba[ctlr]->gendisk[logvol];
- ctlr_info_t *h = hba[ctlr];
+ ctlr_info_t *h = get_host(disk);
+ drive_info_struct *drv = get_drv(disk);
+ int ctlr = h->ctlr;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
/* make sure logical volume is NOT is use */
- if( h->drv[logvol].usage_count > 1) {
+ if( drv->usage_count > 1) {
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
return -EBUSY;
}
- h->drv[logvol].usage_count++;
+ drv->usage_count++;
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
/* invalidate the devices and deregister the disk */
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
/* check to see if it was the last disk */
- if (logvol == h->highest_lun) {
+ if (drv == h->drv + h->highest_lun) {
/* if so, find the new hightest lun */
int i, newhighest =-1;
for(i=0; i<h->highest_lun; i++) {
@@ -990,10 +986,10 @@ static int deregister_disk(int ctlr, int logvol)
}
--h->num_luns;
/* zero out the disk size info */
- h->drv[logvol].nr_blocks = 0;
- h->drv[logvol].block_size = 0;
- h->drv[logvol].cylinders = 0;
- h->drv[logvol].LunID = 0;
+ drv->nr_blocks = 0;
+ drv->block_size = 0;
+ drv->cylinders = 0;
+ drv->LunID = 0;
return(0);
}
static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
@@ -1304,10 +1300,10 @@ cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
*total_size, *block_size);
return;
}
-static int register_new_disk(int ctlr)
+static int register_new_disk(ctlr_info_t *h)
{
struct gendisk *disk;
- ctlr_info_t *h = hba[ctlr];
+ int ctlr = h->ctlr;
int i;
int num_luns;
int logvol;
@@ -1417,7 +1413,7 @@ static int register_new_disk(int ctlr)
#ifdef CCISS_DEBUG
printk("Checking Index %d\n", i);
#endif /* CCISS_DEBUG */
- if(hba[ctlr]->drv[i].LunID == 0)
+ if(h->drv[i].LunID == 0)
{
#ifdef CCISS_DEBUG
printk("free index found at %d\n", i);
@@ -1434,19 +1430,19 @@ static int register_new_disk(int ctlr)
}
logvol = free_index;
- hba[ctlr]->drv[logvol].LunID = lunid;
+ h->drv[logvol].LunID = lunid;
/* there could be gaps in lun numbers, track hightest */
- if(hba[ctlr]->highest_lun < lunid)
- hba[ctlr]->highest_lun = logvol;
+ if(h->highest_lun < lunid)
+ h->highest_lun = logvol;
cciss_read_capacity(ctlr, logvol, size_buff, 1,
&total_size, &block_size);
cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size,
- inq_buff, &hba[ctlr]->drv[logvol]);
- hba[ctlr]->drv[logvol].usage_count = 0;
- ++hba[ctlr]->num_luns;
+ inq_buff, &h->drv[logvol]);
+ h->drv[logvol].usage_count = 0;
+ ++h->num_luns;
/* setup partitions per disk */
- disk = hba[ctlr]->gendisk[logvol];
- set_capacity(disk, hba[ctlr]->drv[logvol].nr_blocks);
+ disk = h->gendisk[logvol];
+ set_capacity(disk, h->drv[logvol].nr_blocks);
add_disk(disk);
freeret:
kfree(ld_buff);
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index dc2b121a9239..8bb37f65d536 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -33,13 +33,7 @@ static const int deadline_hash_shift = 5;
#define DL_HASH_ENTRIES (1 << deadline_hash_shift)
#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
#define list_entry_hash(ptr) list_entry((ptr), struct deadline_rq, hash)
-#define ON_HASH(drq) (drq)->hash_valid_count
-
-#define DL_INVALIDATE_HASH(dd) \
- do { \
- if (!++(dd)->hash_valid_count) \
- (dd)->hash_valid_count = 1; \
- } while (0)
+#define ON_HASH(drq) (drq)->on_hash
struct deadline_data {
/*
@@ -58,7 +52,6 @@ struct deadline_data {
struct deadline_rq *next_drq[2];
struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */
- unsigned long hash_valid_count; /* barrier hash count */
unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */
unsigned int starved; /* times reads have starved writes */
@@ -90,7 +83,7 @@ struct deadline_rq {
* request hash, key is the ending offset (for back merge lookup)
*/
struct list_head hash;
- unsigned long hash_valid_count;
+ char on_hash;
/*
* expire fifo
@@ -110,7 +103,7 @@ static kmem_cache_t *drq_pool;
*/
static inline void __deadline_del_drq_hash(struct deadline_rq *drq)
{
- drq->hash_valid_count = 0;
+ drq->on_hash = 0;
list_del_init(&drq->hash);
}
@@ -125,7 +118,7 @@ deadline_remove_merge_hints(request_queue_t *q, struct deadline_rq *drq)
{
deadline_del_drq_hash(drq);
- if (q->last_merge == &drq->request->queuelist)
+ if (q->last_merge == drq->request)
q->last_merge = NULL;
}
@@ -136,7 +129,7 @@ deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
BUG_ON(ON_HASH(drq));
- drq->hash_valid_count = dd->hash_valid_count;
+ drq->on_hash = 1;
list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]);
}
@@ -169,8 +162,7 @@ deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
BUG_ON(!ON_HASH(drq));
- if (!rq_mergeable(__rq)
- || drq->hash_valid_count != dd->hash_valid_count) {
+ if (!rq_mergeable(__rq)) {
__deadline_del_drq_hash(drq);
continue;
}
@@ -324,7 +316,7 @@ static void deadline_remove_request(request_queue_t *q, struct request *rq)
}
static int
-deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
+deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
struct deadline_data *dd = q->elevator.elevator_data;
struct request *__rq;
@@ -335,7 +327,7 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
*/
ret = elv_try_last_merge(q, bio);
if (ret != ELEVATOR_NO_MERGE) {
- __rq = list_entry_rq(q->last_merge);
+ __rq = q->last_merge;
goto out_insert;
}
@@ -371,11 +363,11 @@ deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
return ELEVATOR_NO_MERGE;
out:
- q->last_merge = &__rq->queuelist;
+ q->last_merge = __rq;
out_insert:
if (ret)
deadline_hot_drq_hash(dd, RQ_DATA(__rq));
- *insert = &__rq->queuelist;
+ *req = __rq;
return ret;
}
@@ -398,7 +390,7 @@ static void deadline_merged_request(request_queue_t *q, struct request *req)
deadline_add_drq_rb(dd, drq);
}
- q->last_merge = &req->queuelist;
+ q->last_merge = req;
}
static void
@@ -621,43 +613,35 @@ dispatch:
}
static void
-deadline_insert_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+deadline_insert_request(request_queue_t *q, struct request *rq, int where)
{
struct deadline_data *dd = q->elevator.elevator_data;
struct deadline_rq *drq = RQ_DATA(rq);
- if (unlikely(rq->flags & (REQ_HARDBARRIER|REQ_SOFTBARRIER))) {
- DL_INVALIDATE_HASH(dd);
- q->last_merge = NULL;
-
- if (insert_here != dd->dispatch) {
+ switch (where) {
+ case ELEVATOR_INSERT_BACK:
while (deadline_dispatch_requests(dd))
;
- }
-
- if (!insert_here)
- insert_here = dd->dispatch->prev;
- }
-
- if (unlikely(!blk_fs_request(rq))) {
- if (!insert_here)
- insert_here = dd->dispatch;
- }
-
- if (insert_here) {
- list_add(&rq->queuelist, insert_here);
- return;
+ list_add_tail(&rq->queuelist, dd->dispatch);
+ break;
+ case ELEVATOR_INSERT_FRONT:
+ list_add(&rq->queuelist, dd->dispatch);
+ break;
+ case ELEVATOR_INSERT_SORT:
+ BUG_ON(!blk_fs_request(rq));
+ deadline_add_request(dd, drq);
+ break;
+ default:
+ printk("%s: bad insert point %d\n", __FUNCTION__,where);
+ return;
}
if (rq_mergeable(rq)) {
deadline_add_drq_hash(dd, drq);
if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
-
- deadline_add_request(dd, drq);
}
static int deadline_queue_empty(request_queue_t *q)
@@ -748,7 +732,6 @@ static int deadline_init(request_queue_t *q, elevator_t *e)
dd->dispatch = &q->queue_head;
dd->fifo_expire[READ] = read_expire;
dd->fifo_expire[WRITE] = write_expire;
- dd->hash_valid_count = 1;
dd->writes_starved = writes_starved;
dd->front_merges = 1;
dd->fifo_batch = fifo_batch;
@@ -779,7 +762,7 @@ deadline_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
drq->request = rq;
INIT_LIST_HEAD(&drq->hash);
- drq->hash_valid_count = 0;
+ drq->on_hash = 0;
INIT_LIST_HEAD(&drq->fifo);
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 4654fddecd7d..fcb00cfa4fd7 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -81,7 +81,7 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
{
if (q->last_merge)
- return elv_try_merge(list_entry_rq(q->last_merge), bio);
+ return elv_try_merge(q->last_merge, bio);
return ELEVATOR_NO_MERGE;
}
@@ -117,12 +117,12 @@ int elevator_global_init(void)
return 0;
}
-int elv_merge(request_queue_t *q, struct list_head **entry, struct bio *bio)
+int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = &q->elevator;
if (e->elevator_merge_fn)
- return e->elevator_merge_fn(q, entry, bio);
+ return e->elevator_merge_fn(q, req, bio);
return ELEVATOR_NO_MERGE;
}
@@ -140,7 +140,7 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
{
elevator_t *e = &q->elevator;
- if (q->last_merge == &next->queuelist)
+ if (q->last_merge == next)
q->last_merge = NULL;
if (e->elevator_merge_req_fn)
@@ -156,29 +156,25 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
if (q->elevator.elevator_requeue_req_fn)
q->elevator.elevator_requeue_req_fn(q, rq);
else
- __elv_add_request(q, rq, 0, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
}
-void __elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
- struct list_head *insert = NULL;
-
- if (!at_end)
- insert = &q->queue_head;
if (plug)
blk_plug_device(q);
- q->elevator.elevator_add_req_fn(q, rq, insert);
+ q->elevator.elevator_add_req_fn(q, rq, where);
}
-void elv_add_request(request_queue_t *q, struct request *rq, int at_end,
+void elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
- __elv_add_request(q, rq, at_end, plug);
+ __elv_add_request(q, rq, where, plug);
spin_unlock_irqrestore(q->queue_lock, flags);
}
@@ -200,7 +196,7 @@ struct request *elv_next_request(request_queue_t *q)
*/
rq->flags |= REQ_STARTED;
- if (&rq->queuelist == q->last_merge)
+ if (rq == q->last_merge)
q->last_merge = NULL;
if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
@@ -238,7 +234,7 @@ void elv_remove_request(request_queue_t *q, struct request *rq)
* deleted without ever being given to driver (merged with another
* request).
*/
- if (&rq->queuelist == q->last_merge)
+ if (rq == q->last_merge)
q->last_merge = NULL;
if (e->elevator_remove_req_fn)
diff --git a/drivers/block/floppy98.c b/drivers/block/floppy98.c
index d861fdbc3466..9513de5f11cf 100644
--- a/drivers/block/floppy98.c
+++ b/drivers/block/floppy98.c
@@ -4249,6 +4249,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
return NULL;
if (((*part>>2) & 0x1f) >= NUMBER(floppy_type))
return NULL;
+ *part = 0;
return get_disk(disks[drive]);
}
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index c57d8d0f42c2..541b45c519ef 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -703,7 +703,7 @@ void blk_queue_invalidate_tags(request_queue_t *q)
blk_queue_end_tag(q, rq);
rq->flags &= ~REQ_STARTED;
- __elv_add_request(q, rq, 0, 0);
+ __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
}
}
@@ -1632,11 +1632,16 @@ void blk_insert_request(request_queue_t *q, struct request *rq,
if(reinsert) {
blk_requeue_request(q, rq);
} else {
+ int where = ELEVATOR_INSERT_BACK;
+
+ if (at_head)
+ where = ELEVATOR_INSERT_FRONT;
+
if (blk_rq_tagged(rq))
blk_queue_end_tag(q, rq);
drive_stat_acct(rq, rq->nr_sectors, 1);
- __elv_add_request(q, rq, !at_head, 0);
+ __elv_add_request(q, rq, where, 0);
}
q->request_fn(q);
spin_unlock_irqrestore(q->queue_lock, flags);
@@ -1669,8 +1674,7 @@ void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
* queue lock is held and interrupts disabled, as we muck with the
* request queue list.
*/
-static inline void add_request(request_queue_t * q, struct request * req,
- struct list_head *insert_here)
+static inline void add_request(request_queue_t * q, struct request * req)
{
drive_stat_acct(req, req->nr_sectors, 1);
@@ -1681,7 +1685,7 @@ static inline void add_request(request_queue_t * q, struct request * req,
* elevator indicated where it wants this request to be
* inserted at elevator_merge time
*/
- __elv_add_request_pos(q, req, insert_here);
+ __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0);
}
/*
@@ -1880,7 +1884,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req, *freereq = NULL;
int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, ra;
- struct list_head *insert_here;
sector_t sector;
sector = bio->bi_sector;
@@ -1903,7 +1906,6 @@ static int __make_request(request_queue_t *q, struct bio *bio)
ra = bio->bi_rw & (1 << BIO_RW_AHEAD);
again:
- insert_here = NULL;
spin_lock_irq(q->queue_lock);
if (elv_queue_empty(q)) {
@@ -1913,17 +1915,13 @@ again:
if (barrier)
goto get_rq;
- el_ret = elv_merge(q, &insert_here, bio);
+ el_ret = elv_merge(q, &req, bio);
switch (el_ret) {
case ELEVATOR_BACK_MERGE:
- req = list_entry_rq(insert_here);
-
BUG_ON(!rq_mergeable(req));
- if (!q->back_merge_fn(q, req, bio)) {
- insert_here = &req->queuelist;
+ if (!q->back_merge_fn(q, req, bio))
break;
- }
req->biotail->bi_next = bio;
req->biotail = bio;
@@ -1934,14 +1932,10 @@ again:
goto out;
case ELEVATOR_FRONT_MERGE:
- req = list_entry_rq(insert_here);
-
BUG_ON(!rq_mergeable(req));
- if (!q->front_merge_fn(q, req, bio)) {
- insert_here = req->queuelist.prev;
+ if (!q->front_merge_fn(q, req, bio))
break;
- }
bio->bi_next = req->bio;
req->cbio = req->bio = bio;
@@ -2029,7 +2023,7 @@ get_rq:
req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies;
- add_request(q, req, insert_here);
+ add_request(q, req);
out:
if (freereq)
__blk_put_request(q, freereq);
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
index 2eadd041914b..7511b955de70 100644
--- a/drivers/block/noop-iosched.c
+++ b/drivers/block/noop-iosched.c
@@ -17,17 +17,15 @@
/*
* See if we can find a request that this buffer can be coalesced with.
*/
-int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
+int elevator_noop_merge(request_queue_t *q, struct request **req,
struct bio *bio)
{
struct list_head *entry = &q->queue_head;
struct request *__rq;
int ret;
- if ((ret = elv_try_last_merge(q, bio))) {
- *insert = q->last_merge;
+ if ((ret = elv_try_last_merge(q, bio)))
return ret;
- }
while ((entry = entry->prev) != &q->queue_head) {
__rq = list_entry_rq(entry);
@@ -41,8 +39,8 @@ int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
continue;
if ((ret = elv_try_merge(__rq, bio))) {
- *insert = &__rq->queuelist;
- q->last_merge = &__rq->queuelist;
+ *req = __rq;
+ q->last_merge = __rq;
return ret;
}
}
@@ -57,8 +55,13 @@ void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
}
void elevator_noop_add_request(request_queue_t *q, struct request *rq,
- struct list_head *insert_here)
+ int where)
{
+ struct list_head *insert = q->queue_head.prev;
+
+ if (where == ELEVATOR_INSERT_FRONT)
+ insert = &q->queue_head;
+
list_add_tail(&rq->queuelist, &q->queue_head);
/*
@@ -67,7 +70,7 @@ void elevator_noop_add_request(request_queue_t *q, struct request *rq,
if (rq->flags & REQ_HARDBARRIER)
q->last_merge = NULL;
else if (!q->last_merge)
- q->last_merge = &rq->queuelist;
+ q->last_merge = rq;
}
struct request *elevator_noop_next_request(request_queue_t *q)
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index feb1d9950dc7..7db4fc7584c0 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -126,7 +126,6 @@ static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
-static int pt_drive_count;
#define D_PRT 0
#define D_PRO 1
@@ -218,9 +217,7 @@ static ssize_t pt_write(struct file *filp, const char *buf,
size_t count, loff_t * ppos);
static int pt_detect(void);
-static int pt_identify(int unit);
-
-/* bits in PT.flags */
+/* bits in tape->flags */
#define PT_MEDIA 1
#define PT_WRITE_OK 2
@@ -246,12 +243,9 @@ struct pt_unit {
char name[PT_NAMELEN]; /* pf0, pf1, ... */
};
-struct pt_unit pt[PT_UNITS];
-
-/* 'unit' must be defined in all functions - either as a local or a param */
+static int pt_identify(struct pt_unit *tape);
-#define PT pt[unit]
-#define PI PT.pi
+struct pt_unit pt[PT_UNITS];
static char pt_scratch[512]; /* scratch block buffer */
@@ -266,156 +260,139 @@ static struct file_operations pt_fops = {
.release = pt_release,
};
-static void pt_init_units(void)
+static inline int status_reg(struct pi_adapter *pi)
{
- int unit, j;
-
- pt_drive_count = 0;
- for (unit = 0; unit < PT_UNITS; unit++) {
- PT.pi = &PT.pia;
- atomic_set(&PT.available, 1);
- PT.flags = 0;
- PT.last_sense = 0;
- PT.present = 0;
- PT.bufptr = NULL;
- PT.drive = DU[D_SLV];
- j = 0;
- while ((j < PT_NAMELEN - 2) && (PT.name[j] = name[j]))
- j++;
- PT.name[j++] = '0' + unit;
- PT.name[j] = 0;
- if (DU[D_PRT])
- pt_drive_count++;
- }
+ return pi_read_regr(pi, 1, 6);
}
-static inline int status_reg(int unit)
+static inline int read_reg(struct pi_adapter *pi, int reg)
{
- return pi_read_regr(PI, 1, 6);
+ return pi_read_regr(pi, 0, reg);
}
-static inline int read_reg(int unit, int reg)
+static inline void write_reg(struct pi_adapter *pi, int reg, int val)
{
- return pi_read_regr(PI, 0, reg);
+ pi_write_regr(pi, 0, reg, val);
}
-static inline void write_reg(int unit, int reg, int val)
+static inline u8 DRIVE(struct pt_unit *tape)
{
- pi_write_regr(PI, 0, reg, val);
+ return 0xa0+0x10*tape->drive;
}
-#define DRIVE (0xa0+0x10*PT.drive)
-
-static int pt_wait(int unit, int go, int stop, char *fun, char *msg)
+static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
{
int j, r, e, s, p;
+ struct pi_adapter *pi = tape->pi;
j = 0;
- while ((((r = status_reg(unit)) & go) || (stop && (!(r & stop))))
+ while ((((r = status_reg(pi)) & go) || (stop && (!(r & stop))))
&& (j++ < PT_SPIN))
udelay(PT_SPIN_DEL);
if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
- s = read_reg(unit, 7);
- e = read_reg(unit, 1);
- p = read_reg(unit, 2);
+ s = read_reg(pi, 7);
+ e = read_reg(pi, 1);
+ p = read_reg(pi, 2);
if (j >= PT_SPIN)
e |= 0x100;
if (fun)
printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
" loop=%d phase=%d\n",
- PT.name, fun, msg, r, s, e, j, p);
+ tape->name, fun, msg, r, s, e, j, p);
return (e << 8) + s;
}
return 0;
}
-static int pt_command(int unit, char *cmd, int dlen, char *fun)
+static int pt_command(struct pt_unit *tape, char *cmd, int dlen, char *fun)
{
- pi_connect(PI);
+ struct pi_adapter *pi = tape->pi;
+ pi_connect(pi);
- write_reg(unit, 6, DRIVE);
+ write_reg(pi, 6, DRIVE(tape));
- if (pt_wait(unit, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
- pi_disconnect(PI);
+ if (pt_wait(tape, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
+ pi_disconnect(pi);
return -1;
}
- write_reg(unit, 4, dlen % 256);
- write_reg(unit, 5, dlen / 256);
- write_reg(unit, 7, 0xa0); /* ATAPI packet command */
+ write_reg(pi, 4, dlen % 256);
+ write_reg(pi, 5, dlen / 256);
+ write_reg(pi, 7, 0xa0); /* ATAPI packet command */
- if (pt_wait(unit, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
- pi_disconnect(PI);
+ if (pt_wait(tape, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
+ pi_disconnect(pi);
return -1;
}
- if (read_reg(unit, 2) != 1) {
- printk("%s: %s: command phase error\n", PT.name, fun);
- pi_disconnect(PI);
+ if (read_reg(pi, 2) != 1) {
+ printk("%s: %s: command phase error\n", tape->name, fun);
+ pi_disconnect(pi);
return -1;
}
- pi_write_block(PI, cmd, 12);
+ pi_write_block(pi, cmd, 12);
return 0;
}
-static int pt_completion(int unit, char *buf, char *fun)
+static int pt_completion(struct pt_unit *tape, char *buf, char *fun)
{
+ struct pi_adapter *pi = tape->pi;
int r, s, n, p;
- r = pt_wait(unit, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
+ r = pt_wait(tape, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
fun, "completion");
- if (read_reg(unit, 7) & STAT_DRQ) {
- n = (((read_reg(unit, 4) + 256 * read_reg(unit, 5)) +
+ if (read_reg(pi, 7) & STAT_DRQ) {
+ n = (((read_reg(pi, 4) + 256 * read_reg(pi, 5)) +
3) & 0xfffc);
- p = read_reg(unit, 2) & 3;
+ p = read_reg(pi, 2) & 3;
if (p == 0)
- pi_write_block(PI, buf, n);
+ pi_write_block(pi, buf, n);
if (p == 2)
- pi_read_block(PI, buf, n);
+ pi_read_block(pi, buf, n);
}
- s = pt_wait(unit, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
+ s = pt_wait(tape, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
- pi_disconnect(PI);
+ pi_disconnect(pi);
return (r ? r : s);
}
-static void pt_req_sense(int unit, int quiet)
+static void pt_req_sense(struct pt_unit *tape, int quiet)
{
char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
char buf[16];
int r;
- r = pt_command(unit, rs_cmd, 16, "Request sense");
+ r = pt_command(tape, rs_cmd, 16, "Request sense");
mdelay(1);
if (!r)
- pt_completion(unit, buf, "Request sense");
+ pt_completion(tape, buf, "Request sense");
- PT.last_sense = -1;
+ tape->last_sense = -1;
if (!r) {
if (!quiet)
printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
- PT.name, buf[2] & 0xf, buf[12], buf[13]);
- PT.last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
+ tape->name, buf[2] & 0xf, buf[12], buf[13]);
+ tape->last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
| ((buf[13] & 0xff) << 16);
}
}
-static int pt_atapi(int unit, char *cmd, int dlen, char *buf, char *fun)
+static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *fun)
{
int r;
- r = pt_command(unit, cmd, dlen, fun);
+ r = pt_command(tape, cmd, dlen, fun);
mdelay(1);
if (!r)
- r = pt_completion(unit, buf, fun);
+ r = pt_completion(tape, buf, fun);
if (r)
- pt_req_sense(unit, !fun);
+ pt_req_sense(tape, !fun);
return r;
}
@@ -426,8 +403,9 @@ static void pt_sleep(int cs)
schedule_timeout(cs);
}
-static int pt_poll_dsc(int unit, int pause, int tmo, char *msg)
+static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg)
{
+ struct pi_adapter *pi = tape->pi;
int k, e, s;
k = 0;
@@ -436,94 +414,95 @@ static int pt_poll_dsc(int unit, int pause, int tmo, char *msg)
while (k < tmo) {
pt_sleep(pause);
k++;
- pi_connect(PI);
- write_reg(unit, 6, DRIVE);
- s = read_reg(unit, 7);
- e = read_reg(unit, 1);
- pi_disconnect(PI);
+ pi_connect(pi);
+ write_reg(pi, 6, DRIVE(tape));
+ s = read_reg(pi, 7);
+ e = read_reg(pi, 1);
+ pi_disconnect(pi);
if (s & (STAT_ERR | STAT_SEEK))
break;
}
if ((k >= tmo) || (s & STAT_ERR)) {
if (k >= tmo)
- printk("%s: %s DSC timeout\n", PT.name, msg);
+ printk("%s: %s DSC timeout\n", tape->name, msg);
else
- printk("%s: %s stat=0x%x err=0x%x\n", PT.name, msg, s,
+ printk("%s: %s stat=0x%x err=0x%x\n", tape->name, msg, s,
e);
- pt_req_sense(unit, 0);
+ pt_req_sense(tape, 0);
return 0;
}
return 1;
}
-static void pt_media_access_cmd(int unit, int tmo, char *cmd, char *fun)
+static void pt_media_access_cmd(struct pt_unit *tape, int tmo, char *cmd, char *fun)
{
- if (pt_command(unit, cmd, 0, fun)) {
- pt_req_sense(unit, 0);
+ if (pt_command(tape, cmd, 0, fun)) {
+ pt_req_sense(tape, 0);
return;
}
- pi_disconnect(PI);
- pt_poll_dsc(unit, HZ, tmo, fun);
+ pi_disconnect(tape->pi);
+ pt_poll_dsc(tape, HZ, tmo, fun);
}
-static void pt_rewind(int unit)
+static void pt_rewind(struct pt_unit *tape)
{
char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- pt_media_access_cmd(unit, PT_REWIND_TMO, rw_cmd, "rewind");
+ pt_media_access_cmd(tape, PT_REWIND_TMO, rw_cmd, "rewind");
}
-static void pt_write_fm(int unit)
+static void pt_write_fm(struct pt_unit *tape)
{
char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
- pt_media_access_cmd(unit, PT_TMO, wm_cmd, "write filemark");
+ pt_media_access_cmd(tape, PT_TMO, wm_cmd, "write filemark");
}
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
-static int pt_reset(int unit)
+static int pt_reset(struct pt_unit *tape)
{
+ struct pi_adapter *pi = tape->pi;
int i, k, flg;
int expect[5] = { 1, 1, 1, 0x14, 0xeb };
- pi_connect(PI);
- write_reg(unit, 6, DRIVE);
- write_reg(unit, 7, 8);
+ pi_connect(pi);
+ write_reg(pi, 6, DRIVE(tape));
+ write_reg(pi, 7, 8);
pt_sleep(20 * HZ / 1000);
k = 0;
- while ((k++ < PT_RESET_TMO) && (status_reg(unit) & STAT_BUSY))
+ while ((k++ < PT_RESET_TMO) && (status_reg(pi) & STAT_BUSY))
pt_sleep(HZ / 10);
flg = 1;
for (i = 0; i < 5; i++)
- flg &= (read_reg(unit, i + 1) == expect[i]);
+ flg &= (read_reg(pi, i + 1) == expect[i]);
if (verbose) {
- printk("%s: Reset (%d) signature = ", PT.name, k);
+ printk("%s: Reset (%d) signature = ", tape->name, k);
for (i = 0; i < 5; i++)
- printk("%3x", read_reg(unit, i + 1));
+ printk("%3x", read_reg(pi, i + 1));
if (!flg)
printk(" (incorrect)");
printk("\n");
}
- pi_disconnect(PI);
+ pi_disconnect(pi);
return flg - 1;
}
-static int pt_ready_wait(int unit, int tmo)
+static int pt_ready_wait(struct pt_unit *tape, int tmo)
{
char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int k, p;
k = 0;
while (k < tmo) {
- PT.last_sense = 0;
- pt_atapi(unit, tr_cmd, 0, NULL, DBMSG("test unit ready"));
- p = PT.last_sense;
+ tape->last_sense = 0;
+ pt_atapi(tape, tr_cmd, 0, NULL, DBMSG("test unit ready"));
+ p = tape->last_sense;
if (!p)
return 0;
if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
@@ -558,7 +537,7 @@ static int xn(char *buf, int offs, int size)
return v;
}
-static int pt_identify(int unit)
+static int pt_identify(struct pt_unit *tape)
{
int dt, s;
char *ms[2] = { "master", "slave" };
@@ -570,7 +549,7 @@ static int pt_identify(int unit)
{ ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 };
char buf[36];
- s = pt_atapi(unit, id_cmd, 36, buf, "identify");
+ s = pt_atapi(tape, id_cmd, 36, buf, "identify");
if (s)
return -1;
@@ -578,36 +557,36 @@ static int pt_identify(int unit)
if (dt != 1) {
if (verbose)
printk("%s: Drive %d, unsupported type %d\n",
- PT.name, PT.drive, dt);
+ tape->name, tape->drive, dt);
return -1;
}
xs(buf, mf, 8, 8);
xs(buf, id, 16, 16);
- PT.flags = 0;
- PT.capacity = 0;
- PT.bs = 0;
+ tape->flags = 0;
+ tape->capacity = 0;
+ tape->bs = 0;
- if (!pt_ready_wait(unit, PT_READY_TMO))
- PT.flags |= PT_MEDIA;
+ if (!pt_ready_wait(tape, PT_READY_TMO))
+ tape->flags |= PT_MEDIA;
- if (!pt_atapi(unit, ms_cmd, 36, buf, "mode sense")) {
+ if (!pt_atapi(tape, ms_cmd, 36, buf, "mode sense")) {
if (!(buf[2] & 0x80))
- PT.flags |= PT_WRITE_OK;
- PT.bs = xn(buf, 10, 2);
+ tape->flags |= PT_WRITE_OK;
+ tape->bs = xn(buf, 10, 2);
}
- if (!pt_atapi(unit, ls_cmd, 36, buf, "log sense"))
- PT.capacity = xn(buf, 24, 4);
+ if (!pt_atapi(tape, ls_cmd, 36, buf, "log sense"))
+ tape->capacity = xn(buf, 24, 4);
- printk("%s: %s %s, %s", PT.name, mf, id, ms[PT.drive]);
- if (!(PT.flags & PT_MEDIA))
+ printk("%s: %s %s, %s", tape->name, mf, id, ms[tape->drive]);
+ if (!(tape->flags & PT_MEDIA))
printk(", no media\n");
else {
- if (!(PT.flags & PT_WRITE_OK))
+ if (!(tape->flags & PT_WRITE_OK))
printk(", RO");
- printk(", blocksize %d, %d MB\n", PT.bs, PT.capacity / 1024);
+ printk(", blocksize %d, %d MB\n", tape->bs, tape->capacity / 1024);
}
return 0;
@@ -618,109 +597,117 @@ static int pt_identify(int unit)
* returns 0, with id set if drive is detected
* -1, if drive detection failed
*/
-static int pt_probe(int unit)
+static int pt_probe(struct pt_unit *tape)
{
- if (PT.drive == -1) {
- for (PT.drive = 0; PT.drive <= 1; PT.drive++)
- if (!pt_reset(unit))
- return pt_identify(unit);
+ if (tape->drive == -1) {
+ for (tape->drive = 0; tape->drive <= 1; tape->drive++)
+ if (!pt_reset(tape))
+ return pt_identify(tape);
} else {
- if (!pt_reset(unit))
- return pt_identify(unit);
+ if (!pt_reset(tape))
+ return pt_identify(tape);
}
return -1;
}
static int pt_detect(void)
{
- int k, unit;
+ struct pt_unit *tape;
+ int specified = 0, found = 0;
+ int unit;
printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
- k = 0;
- if (pt_drive_count == 0) {
- unit = 0;
- if (pi_init(PI, 1, -1, -1, -1, -1, -1, pt_scratch,
- PI_PT, verbose, PT.name)) {
- if (!pt_probe(unit)) {
- PT.present = 1;
- k++;
+ specified = 0;
+ for (unit = 0; unit < PT_UNITS; unit++) {
+ struct pt_unit *tape = &pt[unit];
+ tape->pi = &tape->pia;
+ atomic_set(&tape->available, 1);
+ tape->flags = 0;
+ tape->last_sense = 0;
+ tape->present = 0;
+ tape->bufptr = NULL;
+ tape->drive = DU[D_SLV];
+ snprintf(tape->name, PT_NAMELEN, "%s%d", name, unit);
+ if (!DU[D_PRT])
+ continue;
+ specified++;
+ if (pi_init(tape->pi, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
+ DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
+ verbose, tape->name)) {
+ if (!pt_probe(tape)) {
+ tape->present = 1;
+ found++;
} else
- pi_release(PI);
+ pi_release(tape->pi);
+ }
+ }
+ if (specified == 0) {
+ tape = pt;
+ if (pi_init(tape->pi, 1, -1, -1, -1, -1, -1, pt_scratch,
+ PI_PT, verbose, tape->name)) {
+ if (!pt_probe(tape)) {
+ tape->present = 1;
+ found++;
+ } else
+ pi_release(tape->pi);
}
- } else
- for (unit = 0; unit < PT_UNITS; unit++)
- if (DU[D_PRT])
- if (pi_init
- (PI, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
- DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
- verbose, PT.name)) {
- if (!pt_probe(unit)) {
- PT.present = 1;
- k++;
- } else
- pi_release(PI);
- }
-
- if (k)
+ }
+ if (found)
return 0;
printk("%s: No ATAPI tape drive detected\n", name);
return -1;
}
-#define DEVICE_NR(inode) (iminor(inode) & 0x7F)
-
static int pt_open(struct inode *inode, struct file *file)
{
- int unit = DEVICE_NR(inode);
+ int unit = iminor(inode) & 0x7F;
+ struct pt_unit *tape = pt + unit;
+ int err;
- if ((unit >= PT_UNITS) || (!PT.present))
+ if (unit >= PT_UNITS || (!tape->present))
return -ENODEV;
- if (!atomic_dec_and_test(&PT.available)) {
- atomic_inc(&PT.available);
- return -EBUSY;
- }
+ err = -EBUSY;
+ if (!atomic_dec_and_test(&tape->available))
+ goto out;
- pt_identify(unit);
+ pt_identify(tape);
- if (!PT.flags & PT_MEDIA) {
- atomic_inc(&PT.available);
- return -ENODEV;
- }
+ err = -ENODEV;
+ if (!tape->flags & PT_MEDIA)
+ goto out;
- if ((!PT.flags & PT_WRITE_OK) && (file->f_mode & 2)) {
- atomic_inc(&PT.available);
- return -EROFS;
- }
+ err = -EROFS;
+ if ((!tape->flags & PT_WRITE_OK) && (file->f_mode & 2))
+ goto out;
if (!(iminor(inode) & 128))
- PT.flags |= PT_REWIND;
+ tape->flags |= PT_REWIND;
- PT.bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
- if (PT.bufptr == NULL) {
- atomic_inc(&PT.available);
- printk("%s: buffer allocation failed\n", PT.name);
- return -ENOMEM;
+ err = -ENOMEM;
+ tape->bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
+ if (tape->bufptr == NULL) {
+ printk("%s: buffer allocation failed\n", tape->name);
+ goto out;
}
+ file->private_data = tape;
return 0;
+
+out:
+ atomic_inc(&tape->available);
+ return err;
}
static int pt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int unit;
+ struct pt_unit *tape = file->private_data;
struct mtop mtop;
- unit = DEVICE_NR(inode);
- if (unit >= PT_UNITS)
- return -EINVAL;
- if (!PT.present)
- return -ENODEV;
-
switch (cmd) {
case MTIOCTOP:
if (copy_from_user((char *) &mtop, (char *) arg,
@@ -730,21 +717,21 @@ static int pt_ioctl(struct inode *inode, struct file *file,
switch (mtop.mt_op) {
case MTREW:
- pt_rewind(unit);
+ pt_rewind(tape);
return 0;
case MTWEOF:
- pt_write_fm(unit);
+ pt_write_fm(tape);
return 0;
default:
- printk("%s: Unimplemented mt_op %d\n", PT.name,
+ printk("%s: Unimplemented mt_op %d\n", tape->name,
mtop.mt_op);
return -EINVAL;
}
default:
- printk("%s: Unimplemented ioctl 0x%x\n", PT.name, cmd);
+ printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd);
return -EINVAL;
}
@@ -753,21 +740,21 @@ static int pt_ioctl(struct inode *inode, struct file *file,
static int
pt_release(struct inode *inode, struct file *file)
{
- int unit = DEVICE_NR(inode);
+ struct pt_unit *tape = file->private_data;
- if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1))
+ if (atomic_read(&tape->available) > 1)
return -EINVAL;
- if (PT.flags & PT_WRITING)
- pt_write_fm(unit);
+ if (tape->flags & PT_WRITING)
+ pt_write_fm(tape);
- if (PT.flags & PT_REWIND)
- pt_rewind(unit);
+ if (tape->flags & PT_REWIND)
+ pt_rewind(tape);
- kfree(PT.bufptr);
- PT.bufptr = NULL;
+ kfree(tape->bufptr);
+ tape->bufptr = NULL;
- atomic_inc(&PT.available);
+ atomic_inc(&tape->available);
return 0;
@@ -775,70 +762,70 @@ pt_release(struct inode *inode, struct file *file)
static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
{
- struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino);
+ struct pt_unit *tape = filp->private_data;
+ struct pi_adapter *pi = tape->pi;
char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int k, n, r, p, s, t, b;
- if (!(PT.flags & (PT_READING | PT_WRITING))) {
- PT.flags |= PT_READING;
- if (pt_atapi(unit, rd_cmd, 0, NULL, "start read-ahead"))
+ if (!(tape->flags & (PT_READING | PT_WRITING))) {
+ tape->flags |= PT_READING;
+ if (pt_atapi(tape, rd_cmd, 0, NULL, "start read-ahead"))
return -EIO;
- } else if (PT.flags & PT_WRITING)
+ } else if (tape->flags & PT_WRITING)
return -EIO;
- if (PT.flags & PT_EOF)
+ if (tape->flags & PT_EOF)
return 0;
t = 0;
while (count > 0) {
- if (!pt_poll_dsc(unit, HZ / 100, PT_TMO, "read"))
+ if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "read"))
return -EIO;
n = count;
if (n > 32768)
n = 32768; /* max per command */
- b = (n - 1 + PT.bs) / PT.bs;
- n = b * PT.bs; /* rounded up to even block */
+ b = (n - 1 + tape->bs) / tape->bs;
+ n = b * tape->bs; /* rounded up to even block */
rd_cmd[4] = b;
- r = pt_command(unit, rd_cmd, n, "read");
+ r = pt_command(tape, rd_cmd, n, "read");
mdelay(1);
if (r) {
- pt_req_sense(unit, 0);
+ pt_req_sense(tape, 0);
return -EIO;
}
while (1) {
- r = pt_wait(unit, STAT_BUSY,
+ r = pt_wait(tape, STAT_BUSY,
STAT_DRQ | STAT_ERR | STAT_READY,
DBMSG("read DRQ"), "");
if (r & STAT_SENSE) {
- pi_disconnect(PI);
- pt_req_sense(unit, 0);
+ pi_disconnect(pi);
+ pt_req_sense(tape, 0);
return -EIO;
}
if (r)
- PT.flags |= PT_EOF;
+ tape->flags |= PT_EOF;
- s = read_reg(unit, 7);
+ s = read_reg(pi, 7);
if (!(s & STAT_DRQ))
break;
- n = (read_reg(unit, 4) + 256 * read_reg(unit, 5));
- p = (read_reg(unit, 2) & 3);
+ n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
+ p = (read_reg(pi, 2) & 3);
if (p != 2) {
- pi_disconnect(PI);
- printk("%s: Phase error on read: %d\n", PT.name,
+ pi_disconnect(pi);
+ printk("%s: Phase error on read: %d\n", tape->name,
p);
return -EIO;
}
@@ -847,13 +834,13 @@ static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos
k = n;
if (k > PT_BUFSIZE)
k = PT_BUFSIZE;
- pi_read_block(PI, PT.bufptr, k);
+ pi_read_block(pi, tape->bufptr, k);
n -= k;
b = k;
if (b > count)
b = count;
- if (copy_to_user(buf + t, PT.bufptr, b)) {
- pi_disconnect(PI);
+ if (copy_to_user(buf + t, tape->bufptr, b)) {
+ pi_disconnect(pi);
return -EFAULT;
}
t += b;
@@ -861,8 +848,8 @@ static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos
}
}
- pi_disconnect(PI);
- if (PT.flags & PT_EOF)
+ pi_disconnect(pi);
+ if (tape->flags & PT_EOF)
break;
}
@@ -872,75 +859,75 @@ static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos
static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
{
- struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino);
+ struct pt_unit *tape = filp->private_data;
+ struct pi_adapter *pi = tape->pi;
char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int k, n, r, p, s, t, b;
- if (!(PT.flags & PT_WRITE_OK))
+ if (!(tape->flags & PT_WRITE_OK))
return -EROFS;
- if (!(PT.flags & (PT_READING | PT_WRITING))) {
- PT.flags |= PT_WRITING;
+ if (!(tape->flags & (PT_READING | PT_WRITING))) {
+ tape->flags |= PT_WRITING;
if (pt_atapi
- (unit, wr_cmd, 0, NULL, "start buffer-available mode"))
+ (tape, wr_cmd, 0, NULL, "start buffer-available mode"))
return -EIO;
- } else if (PT.flags & PT_READING)
+ } else if (tape->flags & PT_READING)
return -EIO;
- if (PT.flags & PT_EOF)
+ if (tape->flags & PT_EOF)
return -ENOSPC;
t = 0;
while (count > 0) {
- if (!pt_poll_dsc(unit, HZ / 100, PT_TMO, "write"))
+ if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "write"))
return -EIO;
n = count;
if (n > 32768)
n = 32768; /* max per command */
- b = (n - 1 + PT.bs) / PT.bs;
- n = b * PT.bs; /* rounded up to even block */
+ b = (n - 1 + tape->bs) / tape->bs;
+ n = b * tape->bs; /* rounded up to even block */
wr_cmd[4] = b;
- r = pt_command(unit, wr_cmd, n, "write");
+ r = pt_command(tape, wr_cmd, n, "write");
mdelay(1);
if (r) { /* error delivering command only */
- pt_req_sense(unit, 0);
+ pt_req_sense(tape, 0);
return -EIO;
}
while (1) {
- r = pt_wait(unit, STAT_BUSY,
+ r = pt_wait(tape, STAT_BUSY,
STAT_DRQ | STAT_ERR | STAT_READY,
DBMSG("write DRQ"), NULL);
if (r & STAT_SENSE) {
- pi_disconnect(PI);
- pt_req_sense(unit, 0);
+ pi_disconnect(pi);
+ pt_req_sense(tape, 0);
return -EIO;
}
if (r)
- PT.flags |= PT_EOF;
+ tape->flags |= PT_EOF;
- s = read_reg(unit, 7);
+ s = read_reg(pi, 7);
if (!(s & STAT_DRQ))
break;
- n = (read_reg(unit, 4) + 256 * read_reg(unit, 5));
- p = (read_reg(unit, 2) & 3);
+ n = (read_reg(pi, 4) + 256 * read_reg(pi, 5));
+ p = (read_reg(pi, 2) & 3);
if (p != 0) {
- pi_disconnect(PI);
+ pi_disconnect(pi);
printk("%s: Phase error on write: %d \n",
- PT.name, p);
+ tape->name, p);
return -EIO;
}
@@ -951,19 +938,19 @@ static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t
b = k;
if (b > count)
b = count;
- if (copy_from_user(PT.bufptr, buf + t, b)) {
- pi_disconnect(PI);
+ if (copy_from_user(tape->bufptr, buf + t, b)) {
+ pi_disconnect(pi);
return -EFAULT;
}
- pi_write_block(PI, PT.bufptr, k);
+ pi_write_block(pi, tape->bufptr, k);
t += b;
count -= b;
n -= k;
}
}
- pi_disconnect(PI);
- if (PT.flags & PT_EOF)
+ pi_disconnect(pi);
+ if (tape->flags & PT_EOF)
break;
}
@@ -977,22 +964,20 @@ static int __init pt_init(void)
if (disable)
return -1;
- pt_init_units();
-
if (pt_detect())
return -1;
if (register_chrdev(major, name, &pt_fops)) {
printk("pt_init: unable to get major number %d\n", major);
for (unit = 0; unit < PT_UNITS; unit++)
- if (PT.present)
- pi_release(PI);
+ if (pt[unit].present)
+ pi_release(pt[unit].pi);
return -1;
}
devfs_mk_dir("pt");
for (unit = 0; unit < PT_UNITS; unit++)
- if (PT.present) {
+ if (pt[unit].present) {
devfs_mk_cdev(MKDEV(major, unit),
S_IFCHR | S_IRUSR | S_IWUSR,
"pt/%d", unit);
@@ -1007,15 +992,15 @@ static void __exit pt_exit(void)
{
int unit;
for (unit = 0; unit < PT_UNITS; unit++)
- if (PT.present) {
+ if (pt[unit].present) {
devfs_remove("pt/%d", unit);
devfs_remove("pt/%dn", unit);
}
devfs_remove("pt");
unregister_chrdev(major, name);
for (unit = 0; unit < PT_UNITS; unit++)
- if (PT.present)
- pi_release(PI);
+ if (pt[unit].present)
+ pi_release(pt[unit].pi);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
index 94574b14f30b..3d18a7a70108 100644
--- a/drivers/block/scsi_ioctl.c
+++ b/drivers/block/scsi_ioctl.c
@@ -68,7 +68,7 @@ static int blk_do_rq(request_queue_t *q, struct block_device *bdev,
rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
- elv_add_request(q, rq, 1, 1);
+ elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
generic_unplug_device(q);
wait_for_completion(&wait);
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 7358eed7a348..3e30720a167c 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -63,8 +63,7 @@ config AGP_AMD
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
-# RED-PEN this option is misnamed, it's not 8151 specific
-config AGP_AMD_8151
+config AGP_AMD64
tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
depends on AGP && X86
default y if GART_IOMMU
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index b537a8394cf1..16194948cc54 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP_ALI) += ali-agp.o
obj-$(CONFIG_AGP_ATI) += ati-agp.o
obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
-obj-$(CONFIG_AGP_AMD_8151) += amd-k8-agp.o
+obj-$(CONFIG_AGP_AMD64) += amd64-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_I460) += i460-agp.o
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 2a4b9e0dc363..ee679cbdf6d2 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -302,7 +302,7 @@ struct agp_bridge_data {
#define AMD64_GARTAPERTUREBASE 0x94
#define AMD64_GARTTABLEBASE 0x98
#define AMD64_GARTCACHECTL 0x9c
-#define AMD64_GARTEN 1<<0
+#define AMD64_GARTEN (1<<0)
/* ALi registers */
#define ALI_AGPCTRL 0xb8
diff --git a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd64-agp.c
index d147b09056bc..f60cb63720d8 100644
--- a/drivers/char/agp/amd-k8-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -14,7 +14,7 @@
#include <linux/agp_backend.h>
#include "agp.h"
-/* Will need to be increased if hammer ever goes >8-way. */
+/* Will need to be increased if AMD64 ever goes >8-way. */
#ifdef CONFIG_SMP
#define MAX_HAMMER_GARTS 8
#else
@@ -26,13 +26,13 @@
#define GPTE_COHERENT 2
/* Aperture control register bits. */
-#define GARTEN 1<<0
-#define DISGARTCPU 1<<4
-#define DISGARTIO 1<<5
+#define GARTEN (1<<0)
+#define DISGARTCPU (1<<4)
+#define DISGARTIO (1<<5)
/* GART cache control register bits. */
-#define INVGART 1<<0
-#define GARTPTEERR 1<<1
+#define INVGART (1<<0)
+#define GARTPTEERR (1<<1)
static int nr_garts;
static struct pci_dev * hammers[MAX_HAMMER_GARTS];
@@ -42,7 +42,7 @@ static int __initdata agp_try_unsupported;
static int gart_iterator;
#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
-static void flush_x86_64_tlb(struct pci_dev *dev)
+static void flush_amd64_tlb(struct pci_dev *dev)
{
u32 tmp;
@@ -51,13 +51,13 @@ static void flush_x86_64_tlb(struct pci_dev *dev)
pci_write_config_dword (dev, AMD64_GARTCACHECTL, tmp);
}
-static void amd_x86_64_tlbflush(struct agp_memory *temp)
+static void amd64_tlbflush(struct agp_memory *temp)
{
for_each_nb()
- flush_x86_64_tlb(hammers[gart_iterator]);
+ flush_amd64_tlb(hammers[gart_iterator]);
}
-static int x86_64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
+static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j, num_entries;
long tmp;
@@ -97,7 +97,7 @@ static int x86_64_insert_memory(struct agp_memory *mem, off_t pg_start, int type
agp_bridge->gatt_table[j] = pte;
}
- amd_x86_64_tlbflush(mem);
+ amd64_tlbflush(mem);
return 0;
}
@@ -106,7 +106,7 @@ static int x86_64_insert_memory(struct agp_memory *mem, off_t pg_start, int type
* to the size of a long. It sucks. I totally disown this, even
* though it does appear to work for the most part.
*/
-static struct aper_size_info_32 x86_64_aperture_sizes[7] =
+static struct aper_size_info_32 amd64_aperture_sizes[7] =
{
{32, 8192, 3+(sizeof(long)/8), 0 },
{64, 16384, 4+(sizeof(long)/8), 1<<1 },
@@ -124,7 +124,7 @@ static struct aper_size_info_32 x86_64_aperture_sizes[7] =
* the value from the first one we find. The set_size functions
* keep the rest coherent anyway. Or at least should do.
*/
-static int amd_x86_64_fetch_size(void)
+static int amd64_fetch_size(void)
{
struct pci_dev *dev;
int i;
@@ -137,7 +137,7 @@ static int amd_x86_64_fetch_size(void)
pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &temp);
temp = (temp & 0xe);
- values = A_SIZE_32(x86_64_aperture_sizes);
+ values = A_SIZE_32(amd64_aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
@@ -155,7 +155,7 @@ static int amd_x86_64_fetch_size(void)
* In a multiprocessor x86-64 system, this function gets
* called once for each CPU.
*/
-static u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
+static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table)
{
u64 aperturebase;
u32 tmp;
@@ -180,7 +180,7 @@ static u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp);
/* keep CPU's coherent. */
- flush_x86_64_tlb (hammer);
+ flush_amd64_tlb (hammer);
return aper_base;
}
@@ -204,13 +204,13 @@ static int amd_8151_configure(void)
/* Configure AGP regs in each x86-64 host bridge. */
for_each_nb() {
agp_bridge->gart_bus_addr =
- amd_x86_64_configure(hammers[gart_iterator],gatt_bus);
+ amd64_configure(hammers[gart_iterator],gatt_bus);
}
return 0;
}
-static void amd_8151_cleanup(void)
+static void amd64_cleanup(void)
{
u32 tmp;
@@ -229,16 +229,16 @@ struct agp_bridge_driver amd_8151_driver = {
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = amd_8151_configure,
- .fetch_size = amd_x86_64_fetch_size,
- .cleanup = amd_8151_cleanup,
- .tlb_flush = amd_x86_64_tlbflush,
+ .fetch_size = amd64_fetch_size,
+ .cleanup = amd64_cleanup,
+ .tlb_flush = amd64_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
- .insert_memory = x86_64_insert_memory,
+ .insert_memory = amd64_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
@@ -364,13 +364,13 @@ static __init int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
return i == 0 ? -1 : 0;
}
-static int __init agp_amdk8_probe(struct pci_dev *pdev,
+static int __init agp_amd64_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 rev_id;
u8 cap_ptr;
- char *revstring=" ";
+ char *revstring=NULL;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
@@ -431,17 +431,17 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
return agp_add_bridge(bridge);
}
-static void __devexit agp_amdk8_remove(struct pci_dev *pdev)
+static void __devexit agp_amd64_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
release_mem_region(virt_to_phys(bridge->gatt_table_real),
- x86_64_aperture_sizes[bridge->aperture_size_idx].size);
+ amd64_aperture_sizes[bridge->aperture_size_idx].size);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
-static struct pci_device_id agp_amdk8_pci_table[] = {
+static struct pci_device_id agp_amd64_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
@@ -479,23 +479,23 @@ static struct pci_device_id agp_amdk8_pci_table[] = {
{ }
};
-MODULE_DEVICE_TABLE(pci, agp_amdk8_pci_table);
+MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
-static struct pci_driver agp_amdk8_pci_driver = {
- .name = "agpgart-amd-k8",
- .id_table = agp_amdk8_pci_table,
- .probe = agp_amdk8_probe,
- .remove = agp_amdk8_remove,
+static struct pci_driver agp_amd64_pci_driver = {
+ .name = "agpgart-amd64",
+ .id_table = agp_amd64_pci_table,
+ .probe = agp_amd64_probe,
+ .remove = agp_amd64_remove,
};
/* Not static due to IOMMU code calling it early. */
-int __init agp_amdk8_init(void)
+int __init agp_amd64_init(void)
{
int err = 0;
if (agp_off)
return -EINVAL;
- if (pci_module_init(&agp_amdk8_pci_driver) == 0) {
+ if (pci_module_init(&agp_amd64_pci_driver) == 0) {
struct pci_dev *dev;
if (!agp_try_unsupported && !agp_try_unsupported_boot) {
printk(KERN_INFO "No supported AGP bridge found.\n");
@@ -507,7 +507,7 @@ int __init agp_amdk8_init(void)
return -ENODEV;
}
- /* First check that we have at least one K8 NB */
+ /* First check that we have at least one AMD64 NB */
if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL))
return -ENODEV;
@@ -518,7 +518,7 @@ int __init agp_amdk8_init(void)
if (!pci_find_capability(dev, PCI_CAP_ID_AGP))
continue;
/* Only one bridge supported right now */
- if (agp_amdk8_probe(dev, NULL) == 0) {
+ if (agp_amd64_probe(dev, NULL) == 0) {
err = 0;
break;
}
@@ -527,16 +527,16 @@ int __init agp_amdk8_init(void)
return err;
}
-static void __exit agp_amdk8_cleanup(void)
+static void __exit agp_amd64_cleanup(void)
{
- pci_unregister_driver(&agp_amdk8_pci_driver);
+ pci_unregister_driver(&agp_amd64_pci_driver);
}
-/* On x86-64 the PCI driver needs to initialize this driver early
+/* On AMD64 the PCI driver needs to initialize this driver early
for the IOMMU, so it has to be called via a backdoor. */
#ifndef CONFIG_GART_IOMMU
-module_init(agp_amdk8_init);
-module_exit(agp_amdk8_cleanup);
+module_init(agp_amd64_init);
+module_exit(agp_amd64_cleanup);
#endif
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 336fdda5fe91..2f70f417f221 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -128,7 +128,7 @@ static int i460_fetch_size (void)
if (temp & I460_BAPBASE_ENABLE)
i460.dynamic_apbase = INTEL_I460_BAPBASE;
else
- i460.dynamic_apbase = INTEL_I460_APBASE;
+ i460.dynamic_apbase = AGP_APBASE;
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
/*
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index b410b22f907e..2cfca61b9801 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -158,10 +158,6 @@
/** \name Backward compatibility section */
/*@{*/
-#ifndef minor
-#define minor(x) MINOR((x))
-#endif
-
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(x)
#endif
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 883066efbd72..6cc938bbbf30 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -50,9 +50,6 @@
#include <asm/system.h>
#include <asm/bitops.h>
-#define IS_CONSOLE_DEV(dev) (kdev_val(dev) == __mkdev(TTY_MAJOR,0))
-#define IS_SYSCONS_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,1))
-
/* number of characters left in xmit buffer before select has we have room */
#define WAKEUP_CHARS 256
@@ -951,6 +948,8 @@ static inline int copy_from_read_buf(struct tty_struct *tty,
return retval;
}
+extern ssize_t redirected_tty_write(struct file *,const char *,size_t,loff_t *);
+
static ssize_t read_chan(struct tty_struct *tty, struct file *file,
unsigned char *buf, size_t nr)
{
@@ -975,9 +974,7 @@ do_it_again:
/* NOTE: not yet done after every sleep pending a thorough
check of the logic of this change. -- jlc */
/* don't stop on /dev/console */
- if (!IS_CONSOLE_DEV(file->f_dentry->d_inode->i_rdev) &&
- !IS_SYSCONS_DEV(file->f_dentry->d_inode->i_rdev) &&
- current->tty == tty) {
+ if (file->f_op->write != redirected_tty_write && current->tty == tty) {
if (tty->pgrp <= 0)
printk("read_chan: tty->pgrp <= 0!\n");
else if (current->pgrp != tty->pgrp) {
@@ -1168,9 +1165,7 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
ssize_t retval = 0;
/* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
- if (L_TOSTOP(tty) &&
- !IS_CONSOLE_DEV(file->f_dentry->d_inode->i_rdev) &&
- !IS_SYSCONS_DEV(file->f_dentry->d_inode->i_rdev)) {
+ if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
retval = tty_check_change(tty);
if (retval)
return retval;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 3ecc2b9a666e..e14a3ce8928d 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/pcmcia/synclink_cs.c
*
- * $Id: synclink_cs.c,v 4.13 2003/06/18 15:29:32 paulkf Exp $
+ * $Id: synclink_cs.c,v 4.15 2003/09/05 15:26:02 paulkf Exp $
*
* Device driver for Microgate SyncLink PC Card
* multiprotocol serial adapter.
@@ -491,7 +491,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
MODULE_LICENSE("GPL");
static char *driver_name = "SyncLink PC Card driver";
-static char *driver_version = "$Revision: 4.13 $";
+static char *driver_version = "$Revision: 4.15 $";
static struct tty_driver *serial_driver;
@@ -838,6 +838,9 @@ static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 4275bb8521f0..8f969928c68b 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -1460,17 +1460,6 @@ static int rp_ioctl(struct tty_struct *tty, struct file *file,
return 0;
}
-#if (defined(ROCKET_DEBUG_FLOW) || defined(ROCKET_DEBUG_THROTTLE))
-static char *rp_tty_name(struct tty_struct *tty, char *buf)
-{
- if (tty)
- sprintf(buf, "%s%d", TTY_DRIVER_NAME(tty), MINOR(tty->device) - TTY_DRIVER_MINOR_START(tty) + TTY_DRIVER_NAME_BASE);
- else
- strcpy(buf, "NULL tty");
- return buf;
-}
-#endif
-
static void rp_send_xchar(struct tty_struct *tty, char ch)
{
struct r_port *info = (struct r_port *) tty->driver_data;
@@ -1490,10 +1479,9 @@ static void rp_throttle(struct tty_struct *tty)
{
struct r_port *info = (struct r_port *) tty->driver_data;
CHANNEL_t *cp;
-#ifdef ROCKET_DEBUG_THROTTLE
- char buf[64];
- printk(KERN_INFO "throttle %s: %d....\n", rp_tty_name(tty, buf),
+#ifdef ROCKET_DEBUG_THROTTLE
+ printk(KERN_INFO "throttle %s: %d....\n", tty->name,
tty->ldisc.chars_in_buffer(tty));
#endif
@@ -1512,9 +1500,7 @@ static void rp_unthrottle(struct tty_struct *tty)
struct r_port *info = (struct r_port *) tty->driver_data;
CHANNEL_t *cp;
#ifdef ROCKET_DEBUG_THROTTLE
- char buf[64];
-
- printk(KERN_INFO "unthrottle %s: %d....\n", rp_tty_name(tty, buf),
+ printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
tty->ldisc.chars_in_buffer(tty));
#endif
@@ -1539,10 +1525,9 @@ static void rp_unthrottle(struct tty_struct *tty)
static void rp_stop(struct tty_struct *tty)
{
struct r_port *info = (struct r_port *) tty->driver_data;
-#ifdef ROCKET_DEBUG_FLOW
- char buf[64];
- printk(KERN_INFO "stop %s: %d %d....\n", rp_tty_name(tty, buf),
+#ifdef ROCKET_DEBUG_FLOW
+ printk(KERN_INFO "stop %s: %d %d....\n", tty->name,
info->xmit_cnt, info->xmit_fifo_room);
#endif
@@ -1556,10 +1541,9 @@ static void rp_stop(struct tty_struct *tty)
static void rp_start(struct tty_struct *tty)
{
struct r_port *info = (struct r_port *) tty->driver_data;
-#ifdef ROCKET_DEBUG_FLOW
- char buf[64];
- printk(KERN_INFO "start %s: %d %d....\n", rp_tty_name(tty, buf),
+#ifdef ROCKET_DEBUG_FLOW
+ printk(KERN_INFO "start %s: %d %d....\n", tty->name,
info->xmit_cnt, info->xmit_fifo_room);
#endif
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index bf80e670091d..e55e9abb184d 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.12 2003/06/18 15:29:32 paulkf Exp $
+ * $Id: synclink.c,v 4.16 2003/09/05 15:26:02 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -261,6 +261,7 @@ struct mgsl_struct {
int rx_enabled;
int rx_overflow;
+ int rx_rcc_underrun;
int tx_enabled;
int tx_active;
@@ -910,7 +911,7 @@ MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.12 $";
+static char *driver_version = "$Revision: 4.16 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
@@ -983,6 +984,9 @@ static inline int mgsl_paranoia_check(struct mgsl_struct *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
@@ -1125,7 +1129,16 @@ void mgsl_bh_receive(struct mgsl_struct *info)
printk( "%s(%d):mgsl_bh_receive(%s)\n",
__FILE__,__LINE__,info->device_name);
- while( (get_rx_frame)(info) );
+ do
+ {
+ if (info->rx_rcc_underrun) {
+ unsigned long flags;
+ spin_lock_irqsave(&info->irq_spinlock,flags);
+ usc_start_receiver(info);
+ spin_unlock_irqrestore(&info->irq_spinlock,flags);
+ return;
+ }
+ } while(get_rx_frame(info));
}
void mgsl_bh_transmit(struct mgsl_struct *info)
@@ -1567,6 +1580,21 @@ void mgsl_isr_misc( struct mgsl_struct *info )
printk("%s(%d):mgsl_isr_misc status=%04X\n",
__FILE__,__LINE__,status);
+ if ((status & MISCSTATUS_RCC_UNDERRUN) &&
+ (info->params.mode == MGSL_MODE_HDLC)) {
+
+ /* turn off receiver and rx DMA */
+ usc_EnableReceiver(info,DISABLE_UNCONDITIONAL);
+ usc_DmaCmd(info, DmaCmd_ResetRxChannel);
+ usc_UnlatchRxstatusBits(info, RXSTATUS_ALL);
+ usc_ClearIrqPendingBits(info, RECEIVE_DATA + RECEIVE_STATUS);
+ usc_DisableInterrupts(info, RECEIVE_DATA + RECEIVE_STATUS);
+
+ /* schedule BH handler to restart receiver */
+ info->pending_bh |= BH_RECEIVE;
+ info->rx_rcc_underrun = 1;
+ }
+
usc_ClearIrqPendingBits( info, MISC );
usc_UnlatchMiscstatusBits( info, status );
@@ -3625,7 +3653,7 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
if (info->icount.rxover)
ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+ ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
} else {
ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
@@ -5190,7 +5218,11 @@ void usc_set_sdlc_mode( struct mgsl_struct *info )
usc_EnableMasterIrqBit( info );
usc_ClearIrqPendingBits( info, RECEIVE_STATUS + RECEIVE_DATA +
- TRANSMIT_STATUS + TRANSMIT_DATA );
+ TRANSMIT_STATUS + TRANSMIT_DATA + MISC);
+
+ /* arm RCC underflow interrupt */
+ usc_OutReg(info, SICR, (u16)(usc_InReg(info,SICR) | BIT3));
+ usc_EnableInterrupts(info, MISC);
info->mbre_bit = 0;
outw( 0, info->io_base ); /* clear Master Bus Enable (DCAR) */
@@ -5628,6 +5660,7 @@ void usc_stop_receiver( struct mgsl_struct *info )
info->rx_enabled = 0;
info->rx_overflow = 0;
+ info->rx_rcc_underrun = 0;
} /* end of stop_receiver() */
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index ae3d9c41b668..587dcb3a669d 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1,5 +1,5 @@
/*
- * $Id: synclinkmp.c,v 4.12 2003/06/18 15:29:33 paulkf Exp $
+ * $Id: synclinkmp.c,v 4.14 2003/09/05 15:26:03 paulkf Exp $
*
* Device driver for Microgate SyncLink Multiport
* high speed multiprotocol serial adapter.
@@ -496,7 +496,7 @@ MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");
MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");
static char *driver_name = "SyncLink MultiPort driver";
-static char *driver_version = "$Revision: 4.12 $";
+static char *driver_version = "$Revision: 4.14 $";
static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
static void synclinkmp_remove_one(struct pci_dev *dev);
@@ -713,6 +713,9 @@ static inline int sanity_check(SLMP_INFO *info,
printk(badmagic, name, routine);
return 1;
}
+#else
+ if (!info)
+ return 1;
#endif
return 0;
}
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 660f7b0f1487..fc1558cab6e0 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -74,7 +74,6 @@
#define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
#if LINUX_VERSION_CODE < VERSION(2,5,0)
-# define minor(x) MINOR(x)
# define need_resched() (current->need_resched)
#endif
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index aab1780082fc..8d1f8c6d3c23 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -103,11 +103,6 @@
#include <linux/kmod.h>
-#define IS_CONSOLE_DEV(dev) (kdev_val(dev) == __mkdev(TTY_MAJOR,0))
-#define IS_TTY_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,0))
-#define IS_SYSCONS_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,1))
-#define IS_PTMX_DEV(dev) (kdev_val(dev) == __mkdev(TTYAUX_MAJOR,2))
-
#undef TTY_DEBUG_HANGUP
#define TTY_PARANOIA_CHECK 1
@@ -136,6 +131,7 @@ static void initialize_tty_struct(struct tty_struct *tty);
static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
+ssize_t redirected_tty_write(struct file *, const char *, size_t, loff_t *);
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
static int tty_release(struct inode *, struct file *);
@@ -181,17 +177,16 @@ inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
const char *routine)
{
#ifdef TTY_PARANOIA_CHECK
- static const char badmagic[] = KERN_WARNING
- "Warning: bad magic number for tty struct (%s) in %s\n";
- static const char badtty[] = KERN_WARNING
- "Warning: null TTY for (%s) in %s\n";
-
if (!tty) {
- printk(badtty, cdevname(inode->i_rdev), routine);
+ printk(KERN_WARNING
+ "null TTY for (%d:%d) in %s\n",
+ imajor(inode), iminor(inode), routine);
return 1;
}
if (tty->magic != TTY_MAGIC) {
- printk(badmagic, cdevname(inode->i_rdev), routine);
+ printk(KERN_WARNING
+ "bad magic number for tty struct (%d:%d) in %s\n",
+ imajor(inode), iminor(inode), routine);
return 1;
}
#endif
@@ -383,6 +378,17 @@ static struct file_operations tty_fops = {
.fasync = tty_fasync,
};
+static struct file_operations console_fops = {
+ .llseek = no_llseek,
+ .read = tty_read,
+ .write = redirected_tty_write,
+ .poll = tty_poll,
+ .ioctl = tty_ioctl,
+ .open = tty_open,
+ .release = tty_release,
+ .fasync = tty_fasync,
+};
+
static struct file_operations hung_up_tty_fops = {
.llseek = no_llseek,
.read = hung_up_tty_read,
@@ -426,12 +432,9 @@ void do_tty_hangup(void *data)
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
list_for_each_entry(filp, &tty->tty_files, f_list) {
- if (IS_CONSOLE_DEV(filp->f_dentry->d_inode->i_rdev) ||
- IS_SYSCONS_DEV(filp->f_dentry->d_inode->i_rdev)) {
+ if (filp->f_op->write == redirected_tty_write)
cons_filp = filp;
- continue;
- }
- if (filp->f_op != &tty_fops)
+ if (filp->f_op->write != tty_write)
continue;
closecount++;
tty_fasync(-1, filp, 0); /* can't block */
@@ -651,22 +654,6 @@ static ssize_t tty_read(struct file * file, char * buf, size_t count,
if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
return -EIO;
- /* This check not only needs to be done before reading, but also
- whenever read_chan() gets woken up after sleeping, so I've
- moved it to there. This should only be done for the N_TTY
- line discipline, anyway. Same goes for write_chan(). -- jlc. */
-#if 0
- if (!IS_CONSOLE_DEV(inode->i_rdev) && /* don't stop on /dev/console */
- (tty->pgrp > 0) &&
- (current->tty == tty) &&
- (tty->pgrp != current->pgrp))
- if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp))
- return -EIO;
- else {
- (void) kill_pg(current->pgrp, SIGTTIN, 1);
- return -ERESTARTSYS;
- }
-#endif
lock_kernel();
if (tty->ldisc.read)
i = (tty->ldisc.read)(tty,file,buf,count);
@@ -731,37 +718,13 @@ static inline ssize_t do_tty_write(
static ssize_t tty_write(struct file * file, const char * buf, size_t count,
loff_t *ppos)
{
- int is_console;
struct tty_struct * tty;
struct inode *inode = file->f_dentry->d_inode;
- /*
- * For now, we redirect writes from /dev/console as
- * well as /dev/tty0.
- */
- is_console = IS_SYSCONS_DEV(inode->i_rdev) ||
- IS_CONSOLE_DEV(inode->i_rdev);
/* Can't seek (pwrite) on ttys. */
if (ppos != &file->f_pos)
return -ESPIPE;
- if (is_console) {
- struct file *p = NULL;
-
- spin_lock(&redirect_lock);
- if (redirect) {
- get_file(redirect);
- p = redirect;
- }
- spin_unlock(&redirect_lock);
-
- if (p) {
- ssize_t res = vfs_write(p, buf, count, &p->f_pos);
- fput(p);
- return res;
- }
- }
-
tty = (struct tty_struct *)file->private_data;
if (tty_paranoia_check(tty, inode, "tty_write"))
return -EIO;
@@ -773,6 +736,31 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count,
(const unsigned char *)buf, count);
}
+ssize_t redirected_tty_write(struct file * file, const char * buf, size_t count,
+ loff_t *ppos)
+{
+ struct file *p = NULL;
+
+ spin_lock(&redirect_lock);
+ if (redirect) {
+ get_file(redirect);
+ p = redirect;
+ }
+ spin_unlock(&redirect_lock);
+
+ if (p) {
+ ssize_t res;
+ /* Can't seek (pwrite) on ttys. */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ res = vfs_write(p, buf, count, &p->f_pos);
+ fput(p);
+ return res;
+ }
+
+ return tty_write(file, buf, count, ppos);
+}
+
/* Semaphore to protect creating and releasing a tty */
static DECLARE_MUTEX(tty_sem);
@@ -1307,14 +1295,11 @@ static int tty_open(struct inode * inode, struct file * filp)
int noctty, retval;
struct tty_driver *driver;
int index;
- kdev_t device;
- unsigned short saved_flags;
-
- saved_flags = filp->f_flags;
+ dev_t device = inode->i_rdev;
+ unsigned short saved_flags = filp->f_flags;
retry_open:
noctty = filp->f_flags & O_NOCTTY;
- device = inode->i_rdev;
- if (IS_TTY_DEV(device)) {
+ if (device == MKDEV(TTYAUX_MAJOR,0)) {
if (!current->tty)
return -ENXIO;
driver = current->tty->driver;
@@ -1324,7 +1309,7 @@ retry_open:
goto got_driver;
}
#ifdef CONFIG_VT
- if (IS_CONSOLE_DEV(device)) {
+ if (device == MKDEV(TTY_MAJOR,0)) {
extern int fg_console;
extern struct tty_driver *console_driver;
driver = console_driver;
@@ -1333,7 +1318,7 @@ retry_open:
goto got_driver;
}
#endif
- if (IS_SYSCONS_DEV(device)) {
+ if (device == MKDEV(TTYAUX_MAJOR,1)) {
struct console *c = console_drivers;
for (c = console_drivers; c; c = c->next) {
if (!c->device)
@@ -1349,7 +1334,7 @@ retry_open:
return -ENODEV;
}
- if (IS_PTMX_DEV(device)) {
+ if (device == MKDEV(TTYAUX_MAJOR,2)) {
#ifdef CONFIG_UNIX98_PTYS
/* find a device that is not in use. */
retval = -1;
@@ -1366,7 +1351,7 @@ retry_open:
return -ENODEV;
#endif /* CONFIG_UNIX_98_PTYS */
} else {
- driver = get_tty_driver(kdev_t_to_nr(device), &index);
+ driver = get_tty_driver(device, &index);
if (!driver)
return -ENODEV;
got_driver:
@@ -1408,7 +1393,8 @@ got_driver:
/*
* Need to reset f_op in case a hangup happened.
*/
- filp->f_op = &tty_fops;
+ if (filp->f_op == &hung_up_tty_fops)
+ filp->f_op = &tty_fops;
goto retry_open;
}
if (!noctty &&
@@ -1517,10 +1503,9 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
return 0;
}
-static int tioccons(struct inode *inode, struct file *file)
+static int tioccons(struct file *file)
{
- if (IS_SYSCONS_DEV(inode->i_rdev) ||
- IS_CONSOLE_DEV(inode->i_rdev)) {
+ if (file->f_op->write == redirected_tty_write) {
struct file *f;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -1787,7 +1772,7 @@ int tty_ioctl(struct inode * inode, struct file * file,
case TIOCSWINSZ:
return tiocswinsz(tty, real_tty, (struct winsize *) arg);
case TIOCCONS:
- return real_tty!=tty ? -EINVAL : tioccons(inode, file);
+ return real_tty!=tty ? -EINVAL : tioccons(file);
case FIONBIO:
return fionbio(file, (int *) arg);
case TIOCEXCL:
@@ -1918,8 +1903,10 @@ static void __do_SAK(void *arg)
spin_lock(&p->files->file_lock);
for (i=0; i < p->files->max_fds; i++) {
filp = fcheck_files(p->files, i);
- if (filp && (filp->f_op == &tty_fops) &&
- (filp->private_data == tty)) {
+ if (!filp)
+ continue;
+ if (filp->f_op->read == tty_read &&
+ filp->private_data == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): fd#%d opened to the tty\n",
p->pid, p->comm, i);
@@ -2140,7 +2127,7 @@ error:
kfree(tty_dev);
}
-void tty_remove_class_device(dev_t dev)
+static void tty_remove_class_device(dev_t dev)
{
struct tty_dev *tty_dev = NULL;
struct list_head *tmp;
@@ -2149,19 +2136,15 @@ void tty_remove_class_device(dev_t dev)
spin_lock(&tty_dev_list_lock);
list_for_each (tmp, &tty_dev_list) {
tty_dev = list_entry(tmp, struct tty_dev, node);
- if ((MAJOR(tty_dev->dev) == MAJOR(dev)) &&
- (MINOR(tty_dev->dev) == MINOR(dev))) {
+ if (tty_dev->dev == dev) {
+ list_del(&tty_dev->node);
found = 1;
break;
}
}
- if (found) {
- list_del(&tty_dev->node);
- spin_unlock(&tty_dev_list_lock);
+ spin_unlock(&tty_dev_list_lock);
+ if (found)
class_device_unregister(&tty_dev->class_dev);
- } else {
- spin_unlock(&tty_dev_list_lock);
- }
}
/**
@@ -2451,7 +2434,7 @@ void __init tty_init(void)
tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL);
strcpy(console_cdev.kobj.name, "dev.console");
- cdev_init(&console_cdev, &tty_fops);
+ cdev_init(&console_cdev, &console_fops);
if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
panic("Couldn't register /dev/console driver\n");
@@ -2473,7 +2456,7 @@ void __init tty_init(void)
#ifdef CONFIG_VT
strcpy(vc0_cdev.kobj.name, "dev.vc0");
- cdev_init(&vc0_cdev, &tty_fops);
+ cdev_init(&vc0_cdev, &console_fops);
if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
panic("Couldn't register /dev/tty0 driver\n");
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 88686c3d71f0..d6fc18d3c927 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -10,9 +10,54 @@ config CPU_FREQ_PROC_INTF
If in doubt, say N.
+choice
+ prompt "Default CPUFreq governor"
+ depends on CPU_FREQ
+ default CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+ help
+ This option sets which CPUFreq governor shall be loaded at
+ startup. If in doubt, select 'performance'.
+
+config CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+ bool "performance"
+ select CPU_FREQ_GOV_PERFORMANCE
+ help
+ Use the CPUFreq governor 'performance' as default. This sets
+ the frequency statically to the highest frequency supported by
+ the CPU.
+
+config CPU_FREQ_DEFAULT_GOV_USERSPACE
+ bool "userspace"
+ select CPU_FREQ_GOV_USERSPACE
+ help
+ Use the CPUFreq governor 'userspace' as default. This allows
+ you to set the CPU frequency manually or when an userspace
+ programm shall be able to set the CPU dynamically without having
+ to enable the userspace governor manually.
+
+endchoice
+
+config CPU_FREQ_GOV_PERFORMANCE
+ tristate "'performance' governor"
+ depends on CPU_FREQ
+ help
+ This cpufreq governors set the frequency statically to the
+ highest available CPU frequency.
+
+ If in doubt, say Y.
+
+config CPU_FREQ_GOV_POWERSAVE
+ tristate "'powersave' governor"
+ depends on CPU_FREQ
+ help
+ Theis cpufreq governors set the frequency statically to the
+ lowest available CPU frequency.
+
+ If in doubt, say Y.
+
config CPU_FREQ_GOV_USERSPACE
tristate "'userspace' governor for userspace frequency scaling"
- depends on CPU_FREQ
+ depends on CPU_FREQ
help
Enable this cpufreq governor when you either want to set the
CPU frequency manually or when an userspace programm shall
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 85b512348acd..1eebf3c6edc3 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -1,5 +1,10 @@
+# CPUfreq core
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+
# CPUfreq governors
-obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += userspace.o
+obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o
+obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
+obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
# CPUfreq cross-arch helpers
obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
diff --git a/kernel/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 7f80c321c785..04cfcc54fa1f 100644
--- a/kernel/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -109,13 +109,18 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data)
int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
struct cpufreq_governor **governor)
{
- if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
- *policy = CPUFREQ_POLICY_PERFORMANCE;
- return 0;
- } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
- *policy = CPUFREQ_POLICY_POWERSAVE;
- return 0;
- } else {
+ if (!cpufreq_driver)
+ return -EINVAL;
+ if (cpufreq_driver->setpolicy) {
+ if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
+ *policy = CPUFREQ_POLICY_PERFORMANCE;
+ return 0;
+ } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
+ *policy = CPUFREQ_POLICY_POWERSAVE;
+ return 0;
+ }
+ return -EINVAL;
+ } else {
struct cpufreq_governor *t;
down(&cpufreq_governor_sem);
if (!cpufreq_driver || !cpufreq_driver->target)
@@ -123,7 +128,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
*governor = t;
- *policy = CPUFREQ_POLICY_GOVERNOR;
up(&cpufreq_governor_sem);
return 0;
}
@@ -190,16 +194,13 @@ store_one(scaling_max_freq,max);
*/
static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
{
- switch (policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
+ if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
return sprintf(buf, "powersave\n");
- case CPUFREQ_POLICY_PERFORMANCE:
+ else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
return sprintf(buf, "performance\n");
- case CPUFREQ_POLICY_GOVERNOR:
+ else if (policy->governor)
return snprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
- default:
- return -EINVAL;
- }
+ return -EINVAL;
}
@@ -246,15 +247,15 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
ssize_t i = 0;
struct cpufreq_governor *t;
- i += sprintf(buf, "performance powersave");
-
- if (!cpufreq_driver->target)
+ if (!cpufreq_driver->target) {
+ i += sprintf(buf, "performance powersave");
goto out;
+ }
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
goto out;
- i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name);
+ i += snprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
}
out:
i += sprintf(&buf[i], "\n");
@@ -396,10 +397,12 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpufreq_cpu_data[cpu] = policy;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
+ policy->governor = NULL; /* to assure that the starting sequence is
+ * run in cpufreq_set_policy */
up(&policy->lock);
/* set default policy */
+
ret = cpufreq_set_policy(&new_policy);
if (ret)
goto err_out_unregister;
@@ -492,6 +495,13 @@ static int cpufreq_resume(struct sys_device * sysdev)
if (!cpu_policy)
return -EINVAL;
+ if (cpufreq_driver->resume)
+ ret = cpufreq_driver->resume(cpu_policy);
+ if (ret) {
+ printk(KERN_ERR "cpufreq: resume failed in ->resume step on CPU %u\n", cpu_policy->cpu);
+ goto out;
+ }
+
if (cpufreq_driver->setpolicy)
ret = cpufreq_driver->setpolicy(cpu_policy);
else
@@ -500,6 +510,12 @@ static int cpufreq_resume(struct sys_device * sysdev)
*/
ret = cpufreq_driver->target(cpu_policy, cpu_policy->cur, CPUFREQ_RELATION_H);
+ if (ret) {
+ printk(KERN_ERR "cpufreq: resume failed in ->setpolicy/target step on CPU %u\n", cpu_policy->cpu);
+ goto out;
+ }
+
+ out:
cpufreq_cpu_put(cpu_policy);
return ret;
@@ -622,33 +638,18 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target);
static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
{
- int ret = 0;
+ int ret = -EINVAL;
- switch (policy->policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
- ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
- }
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
- ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
- }
- break;
- case CPUFREQ_POLICY_GOVERNOR:
- ret = -EINVAL;
- if (!try_module_get(policy->governor->owner))
- break;
- ret = policy->governor->governor(policy, event);
- /* we keep one module reference alive for each CPU governed by this CPU */
- if ((event != CPUFREQ_GOV_START) || ret)
- module_put(policy->governor->owner);
- if ((event == CPUFREQ_GOV_STOP) && !ret)
- module_put(policy->governor->owner);
- break;
- default:
- ret = -EINVAL;
- }
+ if (!try_module_get(policy->governor->owner))
+ return -EINVAL;
+
+ ret = policy->governor->governor(policy, event);
+
+ /* we keep one module reference alive for each CPU governed by this CPU */
+ if ((event != CPUFREQ_GOV_START) || ret)
+ module_put(policy->governor->owner);
+ if ((event == CPUFREQ_GOV_STOP) && !ret)
+ module_put(policy->governor->owner);
return ret;
}
@@ -680,11 +681,6 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
if (!governor)
return -EINVAL;
- if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN))
- return -EBUSY;
- if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN))
- return -EBUSY;
-
down(&cpufreq_governor_sem);
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
@@ -808,23 +804,24 @@ int cpufreq_set_policy(struct cpufreq_policy *policy)
data->policy = policy->policy;
ret = cpufreq_driver->setpolicy(policy);
} else {
- if ((policy->policy != data->policy) ||
- ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != data->governor))) {
+ if (policy->governor != data->governor) {
/* save old, working values */
- unsigned int old_pol = data->policy;
struct cpufreq_governor *old_gov = data->governor;
/* end old governor */
- __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+ if (data->governor)
+ __cpufreq_governor(data, CPUFREQ_GOV_STOP);
/* start new governor */
- data->policy = policy->policy;
data->governor = policy->governor;
if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
/* new governor failed, so re-start old one */
- data->policy = old_pol;
- data->governor = old_gov;
- __cpufreq_governor(data, CPUFREQ_GOV_START);
+ if (old_gov) {
+ data->governor = old_gov;
+ __cpufreq_governor(data, CPUFREQ_GOV_START);
+ }
+ ret = -EINVAL;
+ goto error_out;
}
/* might be a policy change, too, so fall through */
}
diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c
new file mode 100644
index 000000000000..f2348e790569
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_performance.c
@@ -0,0 +1,57 @@
+/*
+ * linux/drivers/cpufreq/cpufreq_performance.c
+ *
+ * Copyright (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+
+static int cpufreq_governor_performance(struct cpufreq_policy *policy,
+ unsigned int event)
+{
+ switch (event) {
+ case CPUFREQ_GOV_START:
+ case CPUFREQ_GOV_LIMITS:
+ __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+struct cpufreq_governor cpufreq_gov_performance = {
+ .name = "performance",
+ .governor = cpufreq_governor_performance,
+ .owner = THIS_MODULE,
+};
+EXPORT_SYMBOL(cpufreq_gov_performance);
+
+
+static int __init cpufreq_gov_performance_init(void)
+{
+ return cpufreq_register_governor(&cpufreq_gov_performance);
+}
+
+
+static void __exit cpufreq_gov_performance_exit(void)
+{
+ cpufreq_unregister_governor(&cpufreq_gov_performance);
+}
+
+
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("CPUfreq policy governor 'performance'");
+MODULE_LICENSE("GPL");
+
+fs_initcall(cpufreq_gov_performance_init);
+module_exit(cpufreq_gov_performance_exit);
diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c
new file mode 100644
index 000000000000..ec8544885693
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_powersave.c
@@ -0,0 +1,56 @@
+/*
+ * linux/drivers/cpufreq/cpufreq_powersave.c
+ *
+ * Copyright (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+
+static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
+ unsigned int event)
+{
+ switch (event) {
+ case CPUFREQ_GOV_START:
+ case CPUFREQ_GOV_LIMITS:
+ __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct cpufreq_governor cpufreq_gov_powersave = {
+ .name = "powersave",
+ .governor = cpufreq_governor_powersave,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init cpufreq_gov_powersave_init(void)
+{
+ return cpufreq_register_governor(&cpufreq_gov_powersave);
+}
+
+
+static void __exit cpufreq_gov_powersave_exit(void)
+{
+ cpufreq_unregister_governor(&cpufreq_gov_powersave);
+}
+
+
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("CPUfreq policy governor 'powersave'");
+MODULE_LICENSE("GPL");
+
+module_init(cpufreq_gov_powersave_init);
+module_exit(cpufreq_gov_powersave_exit);
diff --git a/drivers/cpufreq/userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 7df32a97c50a..9f51fbe9b149 100644
--- a/drivers/cpufreq/userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -498,9 +498,9 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
unsigned int cpu = policy->cpu;
switch (event) {
case CPUFREQ_GOV_START:
- if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE)) ||
- !policy->cur)
+ if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE)))
return -EINVAL;
+ BUG_ON(!policy->cur);
down(&userspace_sem);
cpu_is_managed[cpu] = 1;
cpu_min_freq[cpu] = policy->min;
@@ -551,7 +551,7 @@ static void cpufreq_sa11x0_compat(void)
#endif
-static struct cpufreq_governor cpufreq_gov_userspace = {
+struct cpufreq_governor cpufreq_gov_userspace = {
.name = "userspace",
.governor = cpufreq_governor_userspace,
.owner = THIS_MODULE,
@@ -587,5 +587,5 @@ MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.
MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
MODULE_LICENSE ("GPL");
-module_init(cpufreq_gov_userspace_init);
+fs_initcall(cpufreq_gov_userspace_init);
module_exit(cpufreq_gov_userspace_exit);
diff --git a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c
index d314e526af9c..b8d6b056051a 100644
--- a/drivers/cpufreq/proc_intf.c
+++ b/drivers/cpufreq/proc_intf.c
@@ -126,20 +126,20 @@ static int cpufreq_proc_read (
p += sprintf(p, "CPU%3d %9d kHz (%3d %%) - %9d kHz (%3d %%) - ",
i , policy.min, min_pctg, policy.max, max_pctg);
- switch (policy.policy) {
- case CPUFREQ_POLICY_POWERSAVE:
- p += sprintf(p, "powersave\n");
- break;
- case CPUFREQ_POLICY_PERFORMANCE:
- p += sprintf(p, "performance\n");
- break;
- case CPUFREQ_POLICY_GOVERNOR:
+ if (policy.policy) {
+ switch (policy.policy) {
+ case CPUFREQ_POLICY_POWERSAVE:
+ p += sprintf(p, "powersave\n");
+ break;
+ case CPUFREQ_POLICY_PERFORMANCE:
+ p += sprintf(p, "performance\n");
+ break;
+ default:
+ p += sprintf(p, "INVALID\n");
+ break;
+ }
+ } else
p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
- break;
- default:
- p += sprintf(p, "INVALID\n");
- break;
- }
}
end:
len = (p - page);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 39693bcc7d0f..8bf402224197 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1689,7 +1689,8 @@ static void idedisk_setup (ide_drive_t *drive)
write_cache(drive, (id->cfs_enable_2 & 0x3000));
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
- HWIF(drive)->ide_dma_queued_on(drive);
+ if (drive->using_dma)
+ HWIF(drive)->ide_dma_queued_on(drive);
#endif
}
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2b94c9450336..0d9fff1f883d 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1387,7 +1387,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
DECLARE_COMPLETION(wait);
- int insert_end = 1, err;
+ int where = ELEVATOR_INSERT_BACK, err;
int must_wait = (action == ide_wait || action == ide_head_wait);
#ifdef CONFIG_BLK_DEV_PDC4030
@@ -1419,10 +1419,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
spin_lock_irqsave(&ide_lock, flags);
if (action == ide_preempt || action == ide_head_wait) {
hwgroup->rq = NULL;
- insert_end = 0;
+ where = ELEVATOR_INSERT_FRONT;
rq->flags |= REQ_PREEMPT;
}
- __elv_add_request(drive->queue, rq, insert_end, 0);
+ __elv_add_request(drive->queue, rq, where, 0);
ide_do_request(hwgroup, IDE_NO_IRQ);
spin_unlock_irqrestore(&ide_lock, flags);
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
index e2e8ec8d78a5..60efa9ec9a07 100644
--- a/drivers/ieee1394/ieee1394_types.h
+++ b/drivers/ieee1394/ieee1394_types.h
@@ -16,10 +16,6 @@
/* The great kdev_t changeover in 2.5.x */
#include <linux/kdev_t.h>
-#ifndef minor
-#define minor(dev) MINOR(dev)
-#endif
-
/* Transaction Label handling */
struct hpsb_tlabel_pool {
diff --git a/drivers/md/dm-ioctl-v1.c b/drivers/md/dm-ioctl-v1.c
index 3afe5e55ae66..0dc24d76de3f 100644
--- a/drivers/md/dm-ioctl-v1.c
+++ b/drivers/md/dm-ioctl-v1.c
@@ -577,7 +577,7 @@ static int create(struct dm_ioctl *param, struct dm_ioctl *user)
}
if (param->flags & DM_PERSISTENT_DEV_FLAG)
- r = dm_create_with_minor(minor(to_kdev_t(param->dev)), &md);
+ r = dm_create_with_minor(MINOR(param->dev), &md);
else
r = dm_create(&md);
diff --git a/drivers/md/dm-ioctl-v4.c b/drivers/md/dm-ioctl-v4.c
index 2c8243aab6f5..0ea9a58b8daf 100644
--- a/drivers/md/dm-ioctl-v4.c
+++ b/drivers/md/dm-ioctl-v4.c
@@ -481,7 +481,7 @@ static int dev_create(struct dm_ioctl *param, size_t param_size)
return r;
if (param->flags & DM_PERSISTENT_DEV_FLAG)
- r = dm_create_with_minor(minor(to_kdev_t(param->dev)), &md);
+ r = dm_create_with_minor(MINOR(param->dev), &md);
else
r = dm_create(&md);
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 5d0e4c662599..aae61522d1f7 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -312,7 +312,7 @@ static int lookup_device(const char *path, dev_t *dev)
goto out;
}
- *dev = kdev_t_to_nr(inode->i_rdev);
+ *dev = inode->i_rdev;
out:
path_release(&nd);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 9da446a143ec..322782c4cda2 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -25,7 +25,6 @@
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
-#define DEVICE_NR(device) (minor(device))
/*
* find which device holds a particular offset
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b95a323cdf41..6a67e10393e2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -50,7 +50,6 @@
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
-#define DEVICE_NR(device) (minor(device))
#define DEBUG 0
#define dprintk(x...) ((void)(DEBUG && printk(x)))
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 4d19a4bd6808..afa7e3e87b21 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -29,7 +29,6 @@
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
-#define DEVICE_NR(device) (minor(device))
#define MAX_WORK_PER_DISK 128
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index eb4368751307..ad7a468c6831 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -24,7 +24,6 @@
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
-#define DEVICE_NR(device) (minor(device))
static int create_strip_zones (mddev_t *mddev)
{
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index cb7acbfb87cf..83533c262986 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -27,7 +27,6 @@
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
-#define DEVICE_NR(device) (minor(device))
/*
* Number of guaranteed r1bios in case of extreme VM load:
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 777f59a1f6c9..e7d60fcfbb12 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -52,7 +52,7 @@ static ssize_t show_dev(struct class_device *cd, char *buf)
{
struct video_device *vfd = container_of(cd, struct video_device, class_dev);
dev_t dev = MKDEV(VIDEO_MAJOR, vfd->minor);
- return sprintf(buf,"%04x\n",(int)dev);
+ return sprintf(buf,"%04x\n",old_encode_dev(dev));
}
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index bd5b10bbc08d..6cc67f746eb2 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -1265,7 +1265,7 @@ static int
zoran_open (struct inode *inode,
struct file *file)
{
- unsigned int minor = minor(inode->i_rdev);
+ unsigned int minor = iminor(inode);
struct zoran *zr = NULL;
struct zoran_fh *fh;
int i, res, first_open = 0, have_module_locks = 0;
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 1963e60de0b2..be24e20a5cb1 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -97,15 +97,9 @@ extern int macsonic_probe(struct net_device *dev);
extern int mac8390_probe(struct net_device *dev);
extern int mac89x0_probe(struct net_device *dev);
extern int mc32_probe(struct net_device *dev);
-#ifdef CONFIG_SDLA
extern struct net_device *sdla_init(void);
-#endif
-#ifdef CONFIG_COPS
extern struct net_device *cops_probe(int unit);
-#endif
-#ifdef CONFIG_LTPC
extern struct net_device *ltpc_probe(void);
-#endif
/* Detachable devices ("pocket adaptors") */
extern int de620_probe(struct net_device *);
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 49e75710594c..df80c5c25e37 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -465,7 +465,7 @@ config DLCI_MAX
config SDLA
tristate "SDLA (Sangoma S502/S508) support"
- depends on DLCI && ISA && BROKEN_ON_SMP
+ depends on DLCI && ISA
help
Say Y here if you need a driver for the Sangoma S502A, S502E, and
S508 Frame Relay Access Devices. These are multi-protocol cards, but
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index d445e916a18b..8a440eea9c60 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -357,11 +357,7 @@ static void debug_status_out(struct cosa_data *cosa, int status);
/* ---------- Initialization stuff ---------- */
-#ifdef MODULE
-int init_module(void)
-#else
static int __init cosa_init(void)
-#endif
{
int i;
@@ -398,9 +394,9 @@ static int __init cosa_init(void)
}
return 0;
}
+module_init(cosa_init);
-#ifdef MODULE
-void cleanup_module (void)
+static void __exit cosa_exit(void)
{
struct cosa_data *cosa;
int i;
@@ -424,7 +420,7 @@ void cleanup_module (void)
}
unregister_chrdev(cosa_major, "cosa");
}
-#endif
+module_exit(cosa_exit);
/*
* This function should register all the net devices needed for the
@@ -513,7 +509,6 @@ static int cosa_probe(int base, int irq, int dma)
if (irq < 0) {
unsigned long irqs;
/* printk(KERN_INFO "IRQ autoprobe\n"); */
- sti();
irqs = probe_irq_on();
/*
* Enable interrupt on tx buffer empty (it sure is)
@@ -624,6 +619,7 @@ static void sppp_channel_init(struct channel_data *chan)
if (register_netdev(d) == -1) {
printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
sppp_detach(chan->pppdev.dev);
+ free_netdev(chan->pppdev.dev);
return;
}
}
@@ -658,7 +654,6 @@ static int cosa_sppp_open(struct net_device *d)
chan->rx_done = sppp_rx_done;
chan->usage=-1;
chan->cosa->usage++;
- MOD_INC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
err = sppp_open(d);
@@ -666,7 +661,6 @@ static int cosa_sppp_open(struct net_device *d)
spin_lock_irqsave(&chan->cosa->lock, flags);
chan->usage=0;
chan->cosa->usage--;
- MOD_DEC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
return err;
@@ -726,7 +720,6 @@ static int cosa_sppp_close(struct net_device *d)
}
chan->usage=0;
chan->cosa->usage--;
- MOD_DEC_USE_COUNT;
spin_unlock_irqrestore(&chan->cosa->lock, flags);
return 0;
}
@@ -1187,21 +1180,6 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
return cosa_gettype(cosa, (char *)arg);
case COSAIORIDSTR:
return cosa_getidstr(cosa, (char *)arg);
-/*
- * These two are _very_ugly_hack_(tm). Don't even look at this.
- * Implementing this saved me few reboots after some process segfaulted
- * inside this module.
- */
-#ifdef MODULE
-#if 0
- case COSAIOMINC:
- MOD_INC_USE_COUNT;
- return 0;
- case COSAIOMDEC:
- MOD_DEC_USE_COUNT;
- return 0;
-#endif
-#endif
case COSAIONRCARDS:
return nr_cards;
case COSAIONRCHANS:
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index c91e59da2ed9..e11984b2bb03 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -1633,12 +1633,26 @@ static void setup_sdla(struct net_device *dev)
dev->mtu = SDLA_MAX_MTU;
}
+static int frad_registered;
+
struct net_device * __init sdla_init(void)
{
struct net_device *dev;
struct frad_local *flp;
int err = -ENOMEM;
+ if (!frad_registered) {
+ err = register_frad(devname);
+ if (err) {
+ printk(KERN_ERR "%s: frad registration failed %d\n",
+ devname, err);
+ return ERR_PTR(err);
+ }
+ frad_registered = 1;
+ printk("%s.\n", version);
+ }
+
+
dev = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
if (!dev)
goto out;
@@ -1677,39 +1691,35 @@ out:
return ERR_PTR(err);
}
-int __init sdla_c_setup(void)
-{
- printk("%s.\n", version);
- register_frad(devname);
- return 0;
-}
-
#ifdef MODULE
static struct net_device *sdla0;
-#endif /* MODULE */
static int __init init_sdla(void)
{
int result = 0;
- sdla_c_setup();
-#ifdef MODULE
sdla0 = sdla_init();
if (IS_ERR(sdla0))
result = PTR_ERR(sdla0);
-#endif
+
return result;
}
static void __exit exit_sdla(void)
{
-#ifdef MODULE
+ struct frad_local *flp;
+
unregister_netdev(sdla0);
if (sdla0->irq)
free_irq(sdla0->irq, sdla0);
+
+ flp = sdla0->priv;
+ del_timer_sync(&flp->timer);
free_netdev(sdla0);
-#endif
+
+ unregister_frad(devname);
}
+#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 7656f1eddc6e..48fb7e002944 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -178,7 +178,7 @@ tape_assign_minor(struct tape_device *device)
break;
minor += TAPE_MINORS_PER_DEV;
}
- if (minor >= (1 << KDEV_MINOR_BITS)) {
+ if (minor >= 256) {
write_unlock(&tape_device_lock);
return -ENODEV;
}
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index da3a4d3ed310..5857f846101f 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -80,7 +80,7 @@ static int tape_proc_show(struct seq_file *m, void *v)
static void *tape_proc_start(struct seq_file *m, loff_t *pos)
{
- if (*pos >= (1 << KDEV_MINOR_BITS) / TAPE_MINORS_PER_DEV)
+ if (*pos >= 256 / TAPE_MINORS_PER_DEV)
return NULL;
return (void *)((unsigned long) *pos + 1);
}
diff --git a/drivers/s390/char/tubio.h b/drivers/s390/char/tubio.h
index 92cd4fe8dbd1..cd04879e4048 100644
--- a/drivers/s390/char/tubio.h
+++ b/drivers/s390/char/tubio.h
@@ -158,7 +158,6 @@ enum tubwhat { /* echo what= proc actions */
#define TUBMAXMINS 256
-#define TUB_DEV MKDEV(IBM_FS3270_MAJ, 0) /* Generic /dev/3270/tub */
#define _GEOM_ROWS 24
#define _GEOM_COLS 80
#define GEOM_ROWS (tubp->geom_rows)
@@ -294,23 +293,6 @@ typedef struct tub_s {
#define TUB_UE_BUSY 0x0800
#define TUB_INPUT_HACK 0x1000 /* Early init of command line */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
-#define S390_CONSOLE_DEV MKDEV(TTY_MAJOR, 64)
-#define tub_major(x) MAJOR(x)
-#define tub_minor(x) MINOR(x)
-#define tub_mkdev(x, y) MKDEV(x, y)
-#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#define S390_CONSOLE_DEV MKDEV(TTYAUX_MAJOR, 1)
-#define tub_major(x) MAJOR(x)
-#define tub_minor(x) MINOR(x)
-#define tub_mkdev(x, y) MKDEV(x, y)
-#else
-#define S390_CONSOLE_DEV mk_kdev(TTYAUX_MAJOR, 1)
-#define tub_major(x) major(x)
-#define tub_minor(x) minor(x)
-#define tub_mkdev(x, y) mk_kdev(x, y)
-#endif
-
/*
* Extra stuff for 3270 console support
*/
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0a5497ea2389..facb6f9fee35 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -83,7 +83,7 @@ static void sg_proc_cleanup(void);
#define SG_ALLOW_DIO_DEF 0
#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
-#define SG_MAX_DEVS_MASK ((1U << KDEV_MINOR_BITS) - 1)
+#define SG_MAX_DEVS_MASK (256 - 1)
/*
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 089510b7a819..d3a646260380 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -59,7 +59,7 @@
MODULE_PARM(xa_test, "i"); /* see sr_ioctl.c */
-#define SR_DISKS (1 << KDEV_MINOR_BITS)
+#define SR_DISKS 256
#define MAX_RETRIES 3
#define SR_TIMEOUT (30 * HZ)
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 870900b513da..8474deb3f277 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -152,7 +152,6 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t de
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index a58e32b26acb..1c83000f2c3d 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -68,7 +68,6 @@ static int afs_inode_map_status(afs_vnode_t *vnode)
inode->i_nlink = vnode->status.nlink;
inode->i_uid = vnode->status.owner;
inode->i_gid = 0;
- inode->i_rdev = NODEV;
inode->i_size = vnode->status.size;
inode->i_atime.tv_sec = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = vnode->status.mtime_server;
inode->i_atime.tv_nsec =
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 090a7e961c08..35647d8eca94 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -298,7 +298,6 @@ struct inode *autofs4_get_inode(struct super_block *sb,
}
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
if (S_ISDIR(inf->mode)) {
diff --git a/fs/block_dev.c b/fs/block_dev.c
index ddfcb6284b5a..e08095251aab 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -345,7 +345,7 @@ struct block_device *bdget(dev_t dev)
bdev->bd_part_count = 0;
bdev->bd_invalidated = 0;
inode->i_mode = S_IFBLK;
- inode->i_rdev = to_kdev_t(dev);
+ inode->i_rdev = dev;
inode->i_bdev = bdev;
inode->i_data.a_ops = &def_blk_aops;
mapping_set_gfp_mask(&inode->i_data, GFP_USER);
@@ -386,7 +386,7 @@ int bd_acquire(struct inode *inode)
return 0;
}
spin_unlock(&bdev_lock);
- bdev = bdget(kdev_t_to_nr(inode->i_rdev));
+ bdev = bdget(inode->i_rdev);
if (!bdev)
return -ENOMEM;
spin_lock(&bdev_lock);
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 3c6258c73384..44303f85e624 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -265,7 +265,7 @@ int chrdev_open(struct inode * inode, struct file * filp)
struct kobject *kobj;
int idx;
spin_unlock(&cdev_lock);
- kobj = kobj_lookup(cdev_map, kdev_t_to_nr(inode->i_rdev), &idx);
+ kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -ENODEV;
new = container_of(kobj, struct cdev, kobj);
@@ -328,27 +328,6 @@ struct file_operations def_chr_fops = {
.open = chrdev_open,
};
-const char *cdevname(kdev_t dev)
-{
- static char buffer[40];
- const char *name = "unknown-char";
- unsigned int major = major(dev);
- unsigned int minor = minor(dev);
- int i = major_to_index(major);
- struct char_device_struct *cd;
-
- read_lock(&chrdevs_lock);
- for (cd = chrdevs[i]; cd; cd = cd->next)
- if (cd->major == major)
- break;
- if (cd)
- name = cd->name;
- sprintf(buffer, "%s(%d,%d)", name, major, minor);
- read_unlock(&chrdevs_lock);
-
- return buffer;
-}
-
static struct kobject *exact_match(dev_t dev, int *part, void *data)
{
struct cdev *p = data;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 8873ca0447c9..b1245a53db80 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -265,6 +265,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
char *full_path = NULL;
struct inode * newinode = NULL;
+ if (!old_valid_dev(device_number))
+ return -EINVAL;
+
xid = GetXid();
cifs_sb = CIFS_SB(inode->i_sb);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 247a39b899b3..5e223961e9fb 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1024,7 +1024,7 @@ fill_in_inode(struct inode *tmp_inode,
} else {
cFYI(1, (" Init special inode "));
init_special_inode(tmp_inode, tmp_inode->i_mode,
- kdev_t_to_nr(tmp_inode->i_rdev));
+ tmp_inode->i_rdev);
}
}
@@ -1094,7 +1094,7 @@ unix_fill_in_inode(struct inode *tmp_inode,
} else {
cFYI(1, (" Init special inode "));
init_special_inode(tmp_inode, tmp_inode->i_mode,
- kdev_t_to_nr(tmp_inode->i_rdev));
+ tmp_inode->i_rdev);
}
}
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 3625916ca351..6524d6d1f883 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -154,7 +154,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
} else {
cFYI(1, (" Init special inode "));
init_special_inode(inode, inode->i_mode,
- kdev_t_to_nr(inode->i_rdev));
+ inode->i_rdev);
}
}
FreeXid(xid);
@@ -298,7 +298,7 @@ cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
inode->i_op = &cifs_symlink_inode_ops;
} else {
init_special_inode(inode, inode->i_mode,
- kdev_t_to_nr(inode->i_rdev));
+ inode->i_rdev);
}
}
if(buf)
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 2917ab9f4976..4c75d774e0dd 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -242,6 +242,9 @@ static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev
if ( coda_hasmknod == 0 )
return -EIO;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
lock_kernel();
coda_vfs_stat.create++;
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 1789afd1298d..8fcd03bec9f7 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -71,7 +71,8 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
inode->i_data.a_ops = &cramfs_aops;
} else {
inode->i_size = 0;
- init_special_inode(inode, inode->i_mode, cramfs_inode->size);
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(cramfs_inode->size));
}
}
return inode;
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 69a91269e0e9..fda21d6af987 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2010,14 +2010,13 @@ static struct inode *_devfs_get_vfs_inode (struct super_block *sb,
inode->i_blksize = FAKE_BLOCK_SIZE;
inode->i_op = &devfs_iops;
inode->i_fop = &devfs_fops;
- inode->i_rdev = NODEV;
if ( S_ISCHR (de->mode) )
{
- inode->i_rdev = to_kdev_t(de->u.cdev.dev);
+ inode->i_rdev = de->u.cdev.dev;
}
else if ( S_ISBLK (de->mode) )
{
- inode->i_rdev = to_kdev_t(de->u.bdev.dev);
+ inode->i_rdev = de->u.bdev.dev;
if (bd_acquire (inode) != 0)
PRINTK ("(%d): no block device from bdget()\n",(int)inode->i_ino);
}
@@ -2494,8 +2493,8 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
struct devfs_entry *parent, *de;
struct inode *inode;
- DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %d\n",
- dentry->d_name.name, mode, rdev);
+ DPRINTK (DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %u:%u\n",
+ dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
parent = get_devfs_entry_from_vfs_inode (dir);
if (parent == NULL) return -ENOENT;
de = _devfs_alloc_entry (dentry->d_name.name, dentry->d_name.len, mode);
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index e0a73e28e004..5901ab61e0b1 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -117,7 +117,7 @@ void efs_read_inode(struct inode *inode) {
* to see whether odev contains 65535. if this is the case then we
* should then do device = be32_to_cpu(efs_inode->di_u.di_dev.ndev).
*/
- device = be16_to_cpu(efs_inode->di_u.di_dev.odev);
+ device = old_decode_dev(be16_to_cpu(efs_inode->di_u.di_dev.odev));
/* get the number of extents for this object */
in->numextents = be16_to_cpu(efs_inode->di_numextents);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 8a009a159469..9247dc703f31 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1127,7 +1127,7 @@ void ext2_read_inode (struct inode * inode)
} else {
inode->i_op = &ext2_special_inode_operations;
init_special_inode(inode, inode->i_mode,
- le32_to_cpu(raw_inode->i_block[0]));
+ old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
}
brelse (bh);
ext2_set_inode_flags(inode);
@@ -1216,7 +1216,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
raw_inode->i_generation = cpu_to_le32(inode->i_generation);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
+ raw_inode->i_block[0] = cpu_to_le32(old_encode_dev(inode->i_rdev));
else for (n = 0; n < EXT2_N_BLOCKS; n++)
raw_inode->i_block[n] = ei->i_data[n];
mark_buffer_dirty(bh);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 72d5690b2450..8079e2ee4684 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -139,8 +139,14 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st
static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{
- struct inode * inode = ext2_new_inode (dir, mode);
- int err = PTR_ERR(inode);
+ struct inode * inode;
+ int err;
+
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
+ inode = ext2_new_inode (dir, mode);
+ err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, inode->i_mode, rdev);
#ifdef CONFIG_EXT2_FS_XATTR
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 84f41589a02a..c4fc83552763 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2566,7 +2566,7 @@ void ext3_read_inode(struct inode * inode)
} else {
inode->i_op = &ext3_special_inode_operations;
init_special_inode(inode, inode->i_mode,
- le32_to_cpu(raw_inode->i_block[0]));
+ old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
}
brelse (iloc.bh);
ext3_set_inode_flags(inode);
@@ -2668,7 +2668,7 @@ static int ext3_do_update_inode(handle_t *handle,
raw_inode->i_generation = cpu_to_le32(inode->i_generation);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_block[0] =
- cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
+ cpu_to_le32(old_encode_dev(inode->i_rdev));
else for (block = 0; block < EXT3_N_BLOCKS; block++)
raw_inode->i_block[block] = ei->i_data[block];
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 78daed5cee0f..769392cf8ea9 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1659,6 +1659,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
struct inode *inode;
int err;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
if (IS_ERR(handle))
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 4ac414b82e68..e5148cb001d8 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1603,7 +1603,7 @@ static int ext3_load_journal(struct super_block * sb,
{
journal_t *journal;
int journal_inum = le32_to_cpu(es->s_journal_inum);
- dev_t journal_dev = le32_to_cpu(es->s_journal_dev);
+ dev_t journal_dev = old_decode_dev(le32_to_cpu(es->s_journal_dev));
int err = 0;
int really_read_only;
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 06d7fe84a421..bbaeef8b63d2 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -333,7 +333,7 @@ vxfs_read_inode(struct inode *ip)
} else
ip->i_op = &vxfs_immed_symlink_iops;
} else
- init_special_inode(ip, ip->i_mode, vip->vii_rdev);
+ init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev));
return;
}
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 21f14fcf8ccf..398de286c3e7 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -322,7 +322,6 @@ struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,
/* Initialize the inode */
struct hfs_sb_info *hsb = HFS_SB(sb);
- inode->i_rdev = NODEV;
inode->i_ctime.tv_sec = inode->i_atime.tv_sec = inode->i_mtime.tv_sec =
hfs_m_to_utime(entry->modify_date);
inode->i_ctime.tv_nsec = 0;
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index 2d4042ac2ae0..7b0a4f1c7fbc 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -114,14 +114,14 @@ void hpfs_read_inode(struct inode *i)
if (hpfs_sb(i->i_sb)->sb_eas) {
if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) {
if (ea_size == 2) {
- i->i_uid = ea[0] + (ea[1] << 8);
+ i->i_uid = le16_to_cpu(*(u16*)ea);
hpfs_inode->i_ea_uid = 1;
}
kfree(ea);
}
if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) {
if (ea_size == 2) {
- i->i_gid = ea[0] + (ea[1] << 8);
+ i->i_gid = le16_to_cpu(*(u16*)ea);
hpfs_inode->i_ea_gid = 1;
}
kfree(ea);
@@ -141,7 +141,7 @@ void hpfs_read_inode(struct inode *i)
int rdev = 0;
umode_t mode = hpfs_sb(sb)->sb_mode;
if (ea_size == 2) {
- mode = ea[0] + (ea[1] << 8);
+ mode = le16_to_cpu(*(u16*)ea);
hpfs_inode->i_ea_mode = 1;
}
kfree(ea);
@@ -149,7 +149,7 @@ void hpfs_read_inode(struct inode *i)
if (S_ISBLK(mode) || S_ISCHR(mode)) {
if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) {
if (ea_size == 4)
- rdev = ea[0] + (ea[1] << 8) + (ea[2] << 16) + (ea[3] << 24);
+ rdev = le32_to_cpu(*(u32*)ea);
kfree(ea);
}
}
@@ -158,7 +158,8 @@ void hpfs_read_inode(struct inode *i)
i->i_nlink = 1;
i->i_size = 0;
i->i_blocks = 1;
- init_special_inode(i, mode, rdev);
+ init_special_inode(i, mode,
+ old_decode_dev(rdev));
return;
}
}
@@ -201,17 +202,15 @@ void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
we'd better not overwrite them */
hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino);
} else if (hpfs_sb(i->i_sb)->sb_eas >= 2) {
- unsigned char ea[4];
+ u32 ea;
if ((i->i_uid != hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) {
- ea[0] = i->i_uid & 0xff;
- ea[1] = i->i_uid >> 8;
- hpfs_set_ea(i, fnode, "UID", ea, 2);
+ ea = cpu_to_le32(i->i_uid);
+ hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2);
hpfs_inode->i_ea_uid = 1;
}
if ((i->i_gid != hpfs_sb(i->i_sb)->sb_gid) || hpfs_inode->i_ea_gid) {
- ea[0] = i->i_gid & 0xff;
- ea[1] = i->i_gid >> 8;
- hpfs_set_ea(i, fnode, "GID", ea, 2);
+ ea = cpu_to_le32(i->i_gid);
+ hpfs_set_ea(i, fnode, "GID", (char *)&ea, 2);
hpfs_inode->i_ea_gid = 1;
}
if (!S_ISLNK(i->i_mode))
@@ -219,18 +218,13 @@ void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
| (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))
&& i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0222 : 0333))
| (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))) || hpfs_inode->i_ea_mode) {
- ea[0] = i->i_mode & 0xff;
- ea[1] = i->i_mode >> 8;
- hpfs_set_ea(i, fnode, "MODE", ea, 2);
+ ea = cpu_to_le32(i->i_mode);
+ hpfs_set_ea(i, fnode, "MODE", (char *)&ea, 2);
hpfs_inode->i_ea_mode = 1;
}
if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) {
- int d = kdev_t_to_nr(i->i_rdev);
- ea[0] = d & 0xff;
- ea[1] = (d >> 8) & 0xff;
- ea[2] = (d >> 16) & 0xff;
- ea[3] = d >> 24;
- hpfs_set_ea(i, fnode, "DEV", ea, 4);
+ ea = cpu_to_le32(old_encode_dev(i->i_rdev));
+ hpfs_set_ea(i, fnode, "DEV", (char *)&ea, 4);
}
}
}
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index 18f8b1c00e93..030d3de7d01f 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -194,6 +194,8 @@ int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
int err;
if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
lock_kernel();
if (!(fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh))) goto bail;
memset(&dee, 0, sizeof dee);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 7b196a5024ae..effaa5bc5a96 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -406,7 +406,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
inode->i_gid = gid;
inode->i_blksize = HPAGE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &hugetlbfs_aops;
inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
diff --git a/fs/inode.c b/fs/inode.c
index bd116dc1fadc..df29026f21c1 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -130,7 +130,7 @@ static struct inode *alloc_inode(struct super_block *sb)
inode->i_pipe = NULL;
inode->i_bdev = NULL;
inode->i_cdev = NULL;
- inode->i_rdev = to_kdev_t(0);
+ inode->i_rdev = 0;
inode->i_security = NULL;
if (security_inode_alloc(inode)) {
if (inode->i_sb->s_op->destroy_inode)
@@ -1363,10 +1363,10 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev)
inode->i_mode = mode;
if (S_ISCHR(mode)) {
inode->i_fop = &def_chr_fops;
- inode->i_rdev = to_kdev_t(rdev);
+ inode->i_rdev = rdev;
} else if (S_ISBLK(mode)) {
inode->i_fop = &def_blk_fops;
- inode->i_rdev = to_kdev_t(rdev);
+ inode->i_rdev = rdev;
} else if (S_ISFIFO(mode))
inode->i_fop = &def_fifo_fops;
else if (S_ISSOCK(mode))
diff --git a/fs/intermezzo/dir.c b/fs/intermezzo/dir.c
index 4794ee0a3822..b07d6ae8bb74 100644
--- a/fs/intermezzo/dir.c
+++ b/fs/intermezzo/dir.c
@@ -726,6 +726,9 @@ static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, de
struct dentry *parent = dentry->d_parent;
struct lento_vfs_context info;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
ENTRY;
error = presto_check_set_fsdata(dentry);
if ( error ) {
diff --git a/fs/intermezzo/journal.c b/fs/intermezzo/journal.c
index 0b62b1364855..74396076f10d 100644
--- a/fs/intermezzo/journal.c
+++ b/fs/intermezzo/journal.c
@@ -391,13 +391,11 @@ static inline char *log_version(char *buf, struct presto_version *pv)
static inline char *log_rollback(char *buf, struct izo_rollback_data *rb)
{
struct izo_rollback_data rollback;
-
- memcpy(&rollback, rb, sizeof(rollback));
- rollback.rb_mode = HTON__u32(rollback.rb_mode);
- rollback.rb_rdev = HTON__u32(rollback.rb_rdev);
- rollback.rb_uid = HTON__u64(rollback.rb_uid);
- rollback.rb_gid = HTON__u64(rollback.rb_gid);
+ rollback.rb_mode = HTON__u32(rb->rb_mode);
+ rollback.rb_rdev = HTON__u32(rb->rb_rdev);
+ rollback.rb_uid = HTON__u64(rb->rb_uid);
+ rollback.rb_gid = HTON__u64(rb->rb_gid);
return logit(buf, &rollback, sizeof(rollback));
}
diff --git a/fs/intermezzo/kml_reint.c b/fs/intermezzo/kml_reint.c
index f05915ee0dc0..f244abb962f9 100644
--- a/fs/intermezzo/kml_reint.c
+++ b/fs/intermezzo/kml_reint.c
@@ -236,7 +236,8 @@ static int reint_mknod(struct kml_rec *rec, struct file *dir,
struct lento_vfs_context *info)
{
struct run_ctxt saved_ctxt;
- int error, dev;
+ int error;
+ dev_t dev;
ENTRY;
@@ -245,7 +246,7 @@ static int reint_mknod(struct kml_rec *rec, struct file *dir,
info->updated_time.tv_nsec = rec->new_objectv->pv_ctime_nsec;
kmlreint_pre_secure(rec, dir, &saved_ctxt);
- dev = rec->rdev ?: MKDEV(rec->major, rec->minor);
+ dev = rec->rdev ? old_decode_dev(rec->rdev) : MKDEV(rec->major, rec->minor);
error = lento_mknod(rec->path, rec->mode, dev, info);
pop_ctxt(&saved_ctxt);
diff --git a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c
index 920ba2773961..40b08d332d25 100644
--- a/fs/intermezzo/vfs.c
+++ b/fs/intermezzo/vfs.c
@@ -290,7 +290,7 @@ int presto_settime(struct presto_file_set *fset,
void izo_get_rollback_data(struct inode *inode, struct izo_rollback_data *rb)
{
rb->rb_mode = (__u32)inode->i_mode;
- rb->rb_rdev = (__u32)kdev_t_to_nr(inode->i_rdev);
+ rb->rb_rdev = (__u32)old_encode_dev(inode->i_rdev);
rb->rb_uid = (__u64)inode->i_uid;
rb->rb_gid = (__u64)inode->i_gid;
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index a28d5f174b9b..bbff5798e2d3 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1329,8 +1329,7 @@ static void isofs_read_inode(struct inode * inode)
inode->i_data.a_ops = &isofs_symlink_aops;
} else
/* XXX - parse_rock_ridge_inode() had already set i_rdev. */
- init_special_inode(inode, inode->i_mode,
- kdev_t_to_nr(inode->i_rdev));
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
out:
if (tmpde)
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index 8d66d202f04e..ec218349feb1 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -228,9 +228,9 @@ int parse_rock_ridge_inode_internal(struct iso_directory_record * de,
* stored in the low field, and use that.
*/
if((low & ~0xff) && high == 0) {
- inode->i_rdev = mk_kdev(low >> 8, low & 0xff);
+ inode->i_rdev = MKDEV(low >> 8, low & 0xff);
} else {
- inode->i_rdev = mk_kdev(high, low);
+ inode->i_rdev = MKDEV(high, low);
}
}
break;
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 77b102d65299..915f3a57af46 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -362,7 +362,6 @@ jffs_new_inode(const struct inode * dir, struct jffs_raw_inode *raw_inode,
inode->i_nlink = raw_inode->nlink;
inode->i_uid = raw_inode->uid;
inode->i_gid = raw_inode->gid;
- inode->i_rdev = NODEV;
inode->i_size = raw_inode->dsize;
inode->i_atime.tv_sec = raw_inode->atime;
inode->i_mtime.tv_sec = raw_inode->mtime;
@@ -1080,13 +1079,13 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
struct jffs_control *c;
struct inode *inode;
int result = 0;
- u16 data;
+ u16 data = old_encode_dev(rdev);
int err;
- data = (MAJOR(rdev) << 8) | MINOR(rdev);
-
D1(printk("***jffs_mknod()\n"));
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
lock_kernel();
dir_f = (struct jffs_file *)dir->u.generic_ip;
c = dir_f->c;
@@ -1737,7 +1736,7 @@ jffs_read_inode(struct inode *inode)
u16 val;
jffs_read_data(f, (char *)val, 0, 2);
init_special_inode(inode, inode->i_mode,
- MKDEV((val >> 8) & 255, val & 255));
+ old_decode_dev(val));
}
D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 9a2df58cb486..93742552a9e9 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -594,6 +594,9 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
uint32_t writtenlen;
int ret;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
ri = jffs2_alloc_raw_inode();
if (!ri)
return -ENOMEM;
@@ -601,7 +604,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
c = JFFS2_SB_INFO(dir_i->i_sb);
if (S_ISBLK(mode) || S_ISCHR(mode)) {
- dev = cpu_to_je16((MAJOR(rdev) << 8) | MINOR(rdev));
+ dev = cpu_to_je16(old_encode_dev(rdev));
devlen = sizeof(dev);
}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 4c43d597d0aa..531d79dea640 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -147,7 +147,8 @@ void jffs2_read_inode (struct inode *inode)
case S_IFSOCK:
case S_IFIFO:
inode->i_op = &jffs2_file_inode_operations;
- init_special_inode(inode, inode->i_mode, kdev_t_to_nr(mk_kdev(je16_to_cpu(rdev)>>8, je16_to_cpu(rdev)&0xff)));
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(je16_to_cpu(rdev)));
break;
default:
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 8bc53c400875..991dcaf15c72 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -174,7 +174,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
int err;
struct nameidata nd;
int mtdnr;
- kdev_t dev;
+ dev_t dev;
if (!dev_name)
return ERR_PTR(-EINVAL);
@@ -240,14 +240,14 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
dev = nd.dentry->d_inode->i_rdev;
path_release(&nd);
- if (major(dev) != MTD_BLOCK_MAJOR) {
+ if (MAJOR(dev) != MTD_BLOCK_MAJOR) {
if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */
printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
dev_name);
return ERR_PTR(-EINVAL);
}
- return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, minor(dev));
+ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, MINOR(dev));
}
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 4ad780e83e73..989621a380b6 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -61,8 +61,7 @@ void jfs_read_inode(struct inode *inode)
inode->i_op = &jfs_symlink_inode_operations;
} else {
inode->i_op = &jfs_file_inode_operations;
- init_special_inode(inode, inode->i_mode,
- kdev_t_to_nr(inode->i_rdev));
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
}
}
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 847afd3030d8..cb40b149bd12 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -3041,9 +3041,10 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
+ jfs_ip->dev = le32_to_cpu(dip->di_rdev);
if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
- ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev));
+ ip->i_rdev = old_decode_dev(jfs_ip->dev);
if (S_ISDIR(ip->i_mode)) {
memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
@@ -3100,9 +3101,7 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip)
dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
dip->di_otime.tv_nsec = 0;
dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
-
- if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
- dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev));
+ dip->di_rdev = cpu_to_le32(jfs_ip->dev);
}
#ifdef _JFS_DEBUG_IMAP
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index 2164d5cdfc10..15a99b075387 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -93,6 +93,7 @@ struct jfs_inode_info {
unchar _inline_ea[128]; /* 128: inline extended attr */
} link;
} u;
+ u32 dev; /* will die when we get wide dev_t */
struct inode vfs_inode;
};
#define i_xtroot u.file._xtroot
@@ -143,7 +144,7 @@ struct jfs_sb_info {
short nbperpage; /* blocks per page */
short l2nbperpage; /* log2 blocks per page */
short l2niperblk; /* log2 inodes per page */
- u32 logdev; /* external log device */
+ dev_t logdev; /* external log device */
uint aggregate; /* volume identifier in log record */
pxd_t logpxd; /* pxd describing log */
pxd_t fsckpxd; /* pxd describing fsck wkspc */
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index b97311299412..4180b7c87d8d 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -395,7 +395,7 @@ static int chkSuper(struct super_block *sb)
if (sbi->mntflag & JFS_INLINELOG)
sbi->logpxd = j_sb->s_logpxd;
else {
- sbi->logdev = le32_to_cpu(j_sb->s_logdev);
+ sbi->logdev = old_decode_dev(le32_to_cpu(j_sb->s_logdev));
memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
}
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 5062dc50b02d..71f3ccf53b77 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1302,6 +1302,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
*/
int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
+ struct jfs_inode_info *jfs_ip;
struct btstack btstack;
struct component_name dname;
ino_t ino;
@@ -1311,6 +1312,9 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
tid_t tid;
struct tblock *tblk;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
jfs_info("jfs_mknod: %s", dentry->d_name.name);
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
@@ -1321,6 +1325,7 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
rc = -ENOSPC;
goto out1;
}
+ jfs_ip = JFS_IP(ip);
tid = txBegin(dir->i_sb, 0);
@@ -1339,6 +1344,7 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
goto out3;
ip->i_op = &jfs_file_inode_operations;
+ jfs_ip->dev = old_encode_dev(rdev);
init_special_inode(ip, ip->i_mode, rdev);
insert_inode_hash(ip);
diff --git a/fs/libfs.c b/fs/libfs.c
index befcf41b0e30..fbf1d0e6e3e4 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -3,6 +3,7 @@
* Library for filesystems writers.
*/
+#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/vfs.h>
@@ -428,3 +429,22 @@ void simple_release_fs(struct vfsmount **mount, int *count)
spin_unlock(&pin_fs_lock);
mntput(mnt);
}
+
+/* acceptable for old filesystems */
+int old_valid_dev(dev_t dev)
+{
+ return MAJOR(dev) < 256 && MINOR(dev) < 256;
+}
+EXPORT_SYMBOL(old_valid_dev);
+
+u16 old_encode_dev(dev_t dev)
+{
+ return (MAJOR(dev) << 8) | MINOR(dev);
+}
+EXPORT_SYMBOL(old_encode_dev);
+
+dev_t old_decode_dev(u16 val)
+{
+ return MKDEV((val >> 8) & 255, val & 255);
+}
+EXPORT_SYMBOL(old_decode_dev);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 710e46886609..946f5812efc1 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -392,7 +392,7 @@ static void V1_minix_read_inode(struct inode * inode)
inode->i_blocks = inode->i_blksize = 0;
for (i = 0; i < 9; i++)
minix_inode->u.i1_data[i] = raw_inode->i_zone[i];
- minix_set_inode(inode, raw_inode->i_zone[0]);
+ minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
brelse(bh);
}
@@ -425,7 +425,7 @@ static void V2_minix_read_inode(struct inode * inode)
inode->i_blocks = inode->i_blksize = 0;
for (i = 0; i < 10; i++)
minix_inode->u.i2_data[i] = raw_inode->i_zone[i];
- minix_set_inode(inode, raw_inode->i_zone[0]);
+ minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
brelse(bh);
}
@@ -460,7 +460,7 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
raw_inode->i_size = inode->i_size;
raw_inode->i_time = inode->i_mtime.tv_sec;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
+ raw_inode->i_zone[0] = old_encode_dev(inode->i_rdev);
else for (i = 0; i < 9; i++)
raw_inode->i_zone[i] = minix_inode->u.i1_data[i];
mark_buffer_dirty(bh);
@@ -489,7 +489,7 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
raw_inode->i_atime = inode->i_atime.tv_sec;
raw_inode->i_ctime = inode->i_ctime.tv_sec;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
+ raw_inode->i_zone[0] = old_encode_dev(inode->i_rdev);
else for (i = 0; i < 10; i++)
raw_inode->i_zone[i] = minix_inode->u.i2_data[i];
mark_buffer_dirty(bh);
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 2b9e6c64d25a..9f2682641f7f 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -78,7 +78,12 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, st
static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{
int error;
- struct inode * inode = minix_new_inode(dir, &error);
+ struct inode *inode;
+
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
+ inode = minix_new_inode(dir, &error);
if (inode) {
inode->i_mode = mode;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f10460e559a5..0e84d722cf0b 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -929,10 +929,10 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
finfo.access = opmode;
if (ncp_is_nfs_extras(server, finfo.volume)) {
finfo.i.nfs.mode = mode;
- finfo.i.nfs.rdev = rdev;
+ finfo.i.nfs.rdev = old_encode_dev(rdev);
if (ncp_modify_nfs_info(server, finfo.volume,
finfo.i.dirEntNum,
- mode, rdev) != 0)
+ mode, old_encode_dev(rdev)) != 0)
goto out;
}
@@ -1170,6 +1170,8 @@ out:
static int ncp_mknod(struct inode * dir, struct dentry *dentry,
int mode, dev_t rdev)
{
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode);
return ncp_create_new(dir, dentry, mode, rdev, 0);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 70eab7961377..f3fe78dbfb66 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -220,7 +220,6 @@ static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
inode->i_nlink = 1;
inode->i_uid = server->m.uid;
inode->i_gid = server->m.gid;
- inode->i_rdev = NODEV;
inode->i_blksize = NCP_BLOCK_SIZE;
ncp_update_dates(inode, &nwinfo->i);
@@ -262,7 +261,8 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
inode->i_fop = &ncp_dir_operations;
#ifdef CONFIG_NCPFS_NFS_NS
} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
- init_special_inode(inode, inode->i_mode, info->i.nfs.rdev);
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(info->i.nfs.rdev));
#endif
#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
} else if (S_ISLNK(inode->i_mode)) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e7ba8d084182..f9f494a60e4b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -859,6 +859,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id,
dir->i_ino, dentry->d_name.name);
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE;
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 1461252f66fe..d5f552dd7f4e 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -106,6 +106,7 @@ xdr_decode_time(u32 *p, struct timespec *timep)
static u32 *
xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
{
+ u32 rdev;
fattr->type = (enum nfs_ftype) ntohl(*p++);
fattr->mode = ntohl(*p++);
fattr->nlink = ntohl(*p++);
@@ -113,7 +114,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
fattr->gid = ntohl(*p++);
fattr->size = ntohl(*p++);
fattr->du.nfs2.blocksize = ntohl(*p++);
- fattr->rdev = ntohl(*p++);
+ rdev = ntohl(*p++);
fattr->du.nfs2.blocks = ntohl(*p++);
fattr->fsid_u.nfs3 = ntohl(*p++);
fattr->fileid = ntohl(*p++);
@@ -121,7 +122,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
p = xdr_decode_time(p, &fattr->mtime);
p = xdr_decode_time(p, &fattr->ctime);
fattr->valid |= NFS_ATTR_FATTR;
- if (fattr->type == NFCHR && fattr->rdev == NFS2_FIFO_DEV) {
+ fattr->rdev = old_decode_dev(rdev);
+ if (fattr->type == NFCHR && rdev == NFS2_FIFO_DEV) {
fattr->type = NFFIFO;
fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
fattr->rdev = 0;
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index b41f63972df7..c64ebaf8818e 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -242,7 +242,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
case S_IFCHR:
case S_IFBLK:
/* reserve rdev for later checking */
- attr->ia_size = kdev_t_to_nr(inode->i_rdev);
+ attr->ia_size = inode->i_rdev;
attr->ia_valid |= ATTR_SIZE;
/* FALLTHROUGH */
@@ -279,7 +279,8 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
int is_borc = 0;
u32 size = attr->ia_size;
- rdev = (dev_t) size;
+ /* may need to change when we widen dev_t */
+ rdev = old_decode_dev(size);
if (type != S_IFBLK && type != S_IFCHR) {
rdev = 0;
} else if (type == S_IFCHR && !(attr->ia_valid & ATTR_SIZE)) {
@@ -300,7 +301,7 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
/* Make sure the type and device matches */
nfserr = nfserr_exist;
if (inode && (type != (inode->i_mode & S_IFMT) ||
- (is_borc && kdev_t_to_nr(inode->i_rdev) != rdev)))
+ (is_borc && inode->i_rdev != rdev)))
goto out_unlock;
}
diff --git a/fs/partitions/nec98.c b/fs/partitions/nec98.c
index 5f78e5b4895c..08c72aecea1f 100644
--- a/fs/partitions/nec98.c
+++ b/fs/partitions/nec98.c
@@ -73,10 +73,9 @@ int nec98_partition(struct parsed_partitions *state, struct block_device *bdev)
const struct nec98_partition *part;
unsigned char *data;
int sector_size = bdev_hardsect_size(bdev);
- int major = MAJOR(bdev->bd_dev);
if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)&geo) != 0) {
- printk(" unsupported disk (major = %u)\n", major);
+ printk(" unsupported disk (%s)\n", bdev->bd_disk->disk_name);
return 0;
}
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 362ee3135e69..267691bb5174 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -58,7 +58,6 @@ static struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &ramfs_aops;
inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 3f621de0ba22..e33ddbab7552 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1003,7 +1003,7 @@ static void init_inode (struct inode * inode, struct path * path)
inode->i_mapping->a_ops = &reiserfs_address_space_operations;
} else {
inode->i_blocks = 0;
- init_special_inode(inode, inode->i_mode, rdev) ;
+ init_special_inode(inode, inode->i_mode, old_decode_dev(rdev));
}
}
@@ -1024,7 +1024,7 @@ static void inode2sd (void * sd, struct inode * inode)
set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
set_sd_v2_blocks(sd_v2, inode->i_blocks );
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) );
+ set_sd_v2_rdev(sd_v2, old_encode_dev(inode->i_rdev));
else
set_sd_v2_generation(sd_v2, inode->i_generation);
flags = REISERFS_I(inode)->i_attrs;
@@ -1048,7 +1048,7 @@ static void inode2sd_v1 (void * sd, struct inode * inode)
set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec );
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- set_sd_v1_rdev(sd_v1, kdev_t_to_nr(inode->i_rdev) );
+ set_sd_v1_rdev(sd_v1, old_encode_dev(inode->i_rdev));
else
set_sd_v1_blocks(sd_v1, inode->i_blocks );
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 55f12082022b..803d414747e3 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -1906,7 +1906,7 @@ static int journal_init_dev( struct super_block *super,
journal -> j_dev_bd = NULL;
journal -> j_dev_file = NULL;
jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
- SB_ONDISK_JOURNAL_DEVICE( super ) : super->s_dev;
+ old_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;
if (bdev_read_only(super->s_bdev))
blkdev_mode = FMODE_READ;
@@ -1939,7 +1939,6 @@ static int journal_init_dev( struct super_block *super,
result = -ENOMEM;
} else {
/* ok */
- jdev = jdev_inode -> i_bdev -> bd_dev;
set_blocksize(journal->j_dev_bd, super->s_blocksize);
}
} else {
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 85dddb7a83b3..8c1485504ffe 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -613,6 +613,9 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
struct reiserfs_transaction_handle th ;
int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
if (!(inode = new_inode(dir->i_sb))) {
return -ENOMEM ;
}
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 24cd428a521e..80b17af9bb0d 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -542,10 +542,8 @@ romfs_read_inode(struct inode *i)
default:
/* depending on MBZ for sock/fifos */
nextfh = ntohl(ri.spec);
- /* convert back and forth for typechecking and
- * source tagging */
- nextfh = kdev_t_to_nr(mk_kdev(nextfh>>16,nextfh&0xffff));
- init_special_inode(i, ino, nextfh);
+ init_special_inode(i, ino,
+ MKDEV(nextfh>>16,nextfh&0xffff));
}
}
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index f0b62740ae89..aa5974edc203 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -661,6 +661,9 @@ smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
attr.ia_uid = current->euid;
attr.ia_gid = current->egid;
+ if (!old_valid_dev(dev))
+ return -EINVAL;
+
smb_invalid_dir_cache(dir);
error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
if (!error) {
diff --git a/fs/stat.c b/fs/stat.c
index 7f034fa65d88..a1f3d7d874fa 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -24,7 +24,7 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
stat->nlink = inode->i_nlink;
stat->uid = inode->i_uid;
stat->gid = inode->i_gid;
- stat->rdev = kdev_t_to_nr(inode->i_rdev);
+ stat->rdev = inode->i_rdev;
stat->atime = inode->i_atime;
stat->mtime = inode->i_mtime;
stat->ctime = inode->i_ctime;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index c22313b1fa7a..965b5e9eaba1 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -33,7 +33,6 @@ struct inode * sysfs_new_inode(mode_t mode)
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_mapping->a_ops = &sysfs_aops;
inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 9a4564610aae..09c131fbb36f 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -164,10 +164,8 @@ static void sysv_read_inode(struct inode *inode)
struct buffer_head * bh;
struct sysv_inode * raw_inode;
struct sysv_inode_info * si;
- unsigned int block, ino;
- dev_t rdev = 0;
+ unsigned int block, ino = inode->i_ino;
- ino = inode->i_ino;
if (!ino || ino > sbi->s_ninodes) {
printk("Bad inode number on dev %s: %d is out of range\n",
inode->i_sb->s_id, ino);
@@ -198,10 +196,12 @@ static void sysv_read_inode(struct inode *inode)
read3byte(sbi, &raw_inode->i_data[3*block],
(u8 *)&si->i_data[block]);
brelse(bh);
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- rdev = (u16)fs32_to_cpu(sbi, si->i_data[0]);
si->i_dir_start_lookup = 0;
- sysv_set_inode(inode, rdev);
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+ sysv_set_inode(inode,
+ old_decode_dev(fs32_to_cpu(sbi, si->i_data[0])));
+ else
+ sysv_set_inode(inode, 0);
return;
bad_inode:
@@ -241,7 +241,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
si = SYSV_I(inode);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- si->i_data[0] = cpu_to_fs32(sbi, kdev_t_to_nr(inode->i_rdev));
+ si->i_data[0] = cpu_to_fs32(sbi, old_encode_dev(inode->i_rdev));
for (block = 0; block < 10+1+1+1; block++)
write3byte(sbi, (u8 *)&si->i_data[block],
&raw_inode->i_data[3*block]);
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index cbf08f04d07c..c24d0be87e74 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -85,8 +85,14 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, st
static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev)
{
- struct inode * inode = sysv_new_inode(dir, mode);
- int err = PTR_ERR(inode);
+ struct inode * inode;
+ int err;
+
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
+ inode = sysv_new_inode(dir, mode);
+ err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
sysv_set_inode(inode, rdev);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 2fa65ab370d7..d892081d73ab 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1234,9 +1234,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
if (dsea)
{
- init_special_inode(inode, inode->i_mode,
- ((le32_to_cpu(dsea->majorDeviceIdent)) << 8) |
- (le32_to_cpu(dsea->minorDeviceIdent) & 0xFF));
+ init_special_inode(inode, inode->i_mode, MKDEV(
+ le32_to_cpu(dsea->majorDeviceIdent),
+ le32_to_cpu(dsea->minorDeviceIdent)
+ ));
/* Developer ID ??? */
udf_release_data(tbh);
}
@@ -1392,8 +1393,8 @@ udf_update_inode(struct inode *inode, int do_sync)
strcpy(eid->ident, UDF_ID_DEVELOPER);
eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
eid->identSuffix[1] = UDF_OS_ID_LINUX;
- dsea->majorDeviceIdent = kdev_t_to_nr(inode->i_rdev) >> 8;
- dsea->minorDeviceIdent = kdev_t_to_nr(inode->i_rdev) & 0xFF;
+ dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
+ dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
mark_buffer_dirty_inode(tbh, inode);
udf_release_data(tbh);
}
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index d2ac88dae447..a7350413f9b8 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -677,6 +677,9 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
int err;
struct fileIdentDesc cfi, *fi;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
lock_kernel();
err = -EIO;
inode = udf_new_inode(dir, mode, &err);
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 442c28e17739..647c7bef9680 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -475,6 +475,7 @@ void ufs_read_inode (struct inode * inode)
struct ufs_sb_private_info * uspi;
struct ufs_inode * ufs_inode;
struct buffer_head * bh;
+ mode_t mode;
unsigned i;
unsigned flags;
@@ -500,7 +501,7 @@ void ufs_read_inode (struct inode * inode)
/*
* Copy data to the in-core inode.
*/
- inode->i_mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
+ inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
inode->i_nlink = fs16_to_cpu(sb, ufs_inode->ui_nlink);
if (inode->i_nlink == 0)
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
@@ -527,9 +528,7 @@ void ufs_read_inode (struct inode * inode)
ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag);
ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- ;
- else if (inode->i_blocks) {
+ if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) {
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i];
}
@@ -555,7 +554,7 @@ void ufs_read_inode (struct inode * inode)
}
} else
init_special_inode(inode, inode->i_mode,
- fs32_to_cpu(sb, ufs_inode->ui_u2.ui_addr.ui_db[0]));
+ old_decode_dev(fs32_to_cpu(sb, ufsi->i_u1.i_data[0])));
brelse (bh);
@@ -618,9 +617,10 @@ static int ufs_update_inode(struct inode * inode, int do_sync)
ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, ufsi->i_oeftflag);
}
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, kdev_t_to_nr(inode->i_rdev));
- else if (inode->i_blocks) {
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+ /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */
+ ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.i_data[0];
+ } else if (inode->i_blocks) {
for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++)
ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i];
}
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 82f391298c48..224d2c08d771 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -29,6 +29,7 @@
#include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include "swab.h" /* will go away - see comment in mknod() */
#undef UFS_NAMEI_DEBUG
@@ -111,10 +112,16 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{
- struct inode * inode = ufs_new_inode(dir, mode);
+ struct inode * inode;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+ inode = ufs_new_inode(dir, mode);
int err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
+ /* NOTE: that'll go when we get wide dev_t */
+ UFS_I(inode)->i_u1.i_data[0] = cpu_to_fs32(inode->i_sb,
+ old_encode_dev(rdev));
mark_inode_dirty(inode);
lock_kernel();
err = ufs_add_nondir(dentry, inode);
diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c
index 11eac5784afa..cb9bcdda6d01 100644
--- a/fs/xfs/linux/xfs_iops.c
+++ b/fs/xfs/linux/xfs_iops.c
@@ -113,6 +113,9 @@ linvfs_mknod(
xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS;
int error;
+ if (!old_valid_dev(rdev))
+ return -EINVAL;
+
if (test_default_acl && test_default_acl(dvp)) {
if (!_ACL_ALLOC(default_acl))
return -ENOMEM;
@@ -178,7 +181,7 @@ linvfs_mknod(
ip = LINVFS_GET_IP(vp);
if (S_ISCHR(mode) || S_ISBLK(mode))
- ip->i_rdev = to_kdev_t(rdev);
+ ip->i_rdev = rdev;
else if (S_ISDIR(mode))
validate_fields(ip);
d_instantiate(dentry, ip);
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 49c173f9e5d0..1bd4b3a4a604 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -154,7 +154,7 @@ xfs_set_inodeops(
} else {
inode->i_op = &linvfs_file_inode_operations;
init_special_inode(inode, inode->i_mode,
- kdev_t_to_nr(inode->i_rdev));
+ inode->i_rdev);
}
}
@@ -171,7 +171,7 @@ xfs_revalidate_inode(
inode->i_uid = ip->i_d.di_uid;
inode->i_gid = ip->i_d.di_gid;
if (((1 << vp->v_type) & ((1<<VBLK) | (1<<VCHR))) == 0) {
- inode->i_rdev = NODEV;
+ inode->i_rdev = 0;
} else {
xfs_dev_t dev = ip->i_df.if_u2.if_rdev;
inode->i_rdev = XFS_DEV_TO_KDEVT(dev);
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index bdb7ca141927..3c163b46160e 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -210,6 +210,6 @@ typedef enum {
#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
| (minor&XFS_DEV_MAXMIN)))
-#define XFS_DEV_TO_KDEVT(dev) mk_kdev(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
+#define XFS_DEV_TO_KDEVT(dev) MKDEV(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
#endif /* !__XFS_TYPES_H */
diff --git a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c
index 9d463a3e85cf..785c52cc23a5 100644
--- a/fs/xfs/xfsidbg.c
+++ b/fs/xfs/xfsidbg.c
@@ -1687,7 +1687,7 @@ static void printinode(struct inode *ip)
kdb_printf(
" i_mode = 0x%x i_nlink = %d i_rdev = 0x%x i_state = 0x%lx\n",
ip->i_mode, ip->i_nlink,
- kdev_t_to_nr(ip->i_rdev), ip->i_state);
+ ip->i_rdev, ip->i_state);
kdb_printf(" i_hash.nxt = 0x%p i_hash.prv = 0x%p\n",
ip->i_hash.next, ip->i_hash.prev);
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index c0fded995489..03f548536d6b 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -102,8 +102,6 @@ struct termio {
#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
-#define MODULE_ALIAS_LDISC(ldisc) \
- MODULE_ALIAS("tty-ldisc-" __stringify(ldisc))
#endif /* __KERNEL__ */
#endif /* _I386_TERMIOS_H */
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index 48ba080c0794..0a8ad4cac125 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -169,9 +169,6 @@ struct winsize {
0; \
})
-#define MODULE_ALIAS_LDISC(ldisc) \
- MODULE_ALIAS("tty-ldisc-" __stringify(ldisc))
-
#endif /* __KERNEL__ */
#endif /* _SPARC_TERMIOS_H */
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index 4e7fef518a25..8effce0da087 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -168,9 +168,6 @@ struct winsize {
0; \
})
-#define MODULE_ALIAS_LDISC(ldisc) \
- MODULE_ALIAS("tty-ldisc-" __stringify(ldisc))
-
#endif /* __KERNEL__ */
#endif /* _SPARC64_TERMIOS_H */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 9c7e6d86e810..285fd86e2b48 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -270,7 +270,7 @@ struct request_queue
* Together with queue_head for cacheline sharing
*/
struct list_head queue_head;
- struct list_head *last_merge;
+ struct request *last_merge;
elevator_t elevator;
/*
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 3d466f6680cb..f747117285f4 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -36,11 +36,13 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
#define CPUFREQ_POLICY_NOTIFIER (1)
-/********************** cpufreq policy notifiers *********************/
+/* if (cpufreq_driver->target) exists, the ->governor decides what frequency
+ * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
+ * two generic policies are available:
+ */
#define CPUFREQ_POLICY_POWERSAVE (1)
#define CPUFREQ_POLICY_PERFORMANCE (2)
-#define CPUFREQ_POLICY_GOVERNOR (3)
/* Frequency values here are CPU kHz so that hardware which doesn't run
* with some frequencies can complain without having to guess what per
@@ -151,6 +153,7 @@ int cpufreq_governor(unsigned int cpu, unsigned int event);
int cpufreq_register_governor(struct cpufreq_governor *governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+
/*********************************************************************
* CPUFREQ DRIVER INTERFACE *
*********************************************************************/
@@ -176,6 +179,7 @@ struct cpufreq_driver {
/* optional */
int (*exit) (struct cpufreq_policy *policy);
+ int (*resume) (struct cpufreq_policy *policy);
struct freq_attr **attr;
};
@@ -221,7 +225,6 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpu
/*********************************************************************
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
-extern struct cpufreq_governor cpufreq_gov_userspace;
int cpufreq_gov_userspace_init(void);
int cpufreq_setmax(unsigned int cpu);
@@ -280,6 +283,19 @@ enum {
/*********************************************************************
+ * CPUFREQ DEFAULT GOVERNOR *
+ *********************************************************************/
+
+
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+extern struct cpufreq_governor cpufreq_gov_performance;
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance
+#elif CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
+extern struct cpufreq_governor cpufreq_gov_userspace;
+#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
+#endif
+
+/*********************************************************************
* FREQUENCY TABLE HELPERS *
*********************************************************************/
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index ac30ae089069..e43d670c1371 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -1,7 +1,7 @@
#ifndef _LINUX_ELEVATOR_H
#define _LINUX_ELEVATOR_H
-typedef int (elevator_merge_fn) (request_queue_t *, struct list_head **,
+typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
struct bio *);
typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
@@ -10,7 +10,7 @@ typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
typedef struct request *(elevator_next_req_fn) (request_queue_t *);
-typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
+typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, int);
typedef int (elevator_queue_empty_fn) (request_queue_t *);
typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
@@ -62,7 +62,7 @@ struct elevator_s
*/
extern void elv_add_request(request_queue_t *, struct request *, int, int);
extern void __elv_add_request(request_queue_t *, struct request *, int, int);
-extern int elv_merge(request_queue_t *, struct list_head **, struct bio *);
+extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
@@ -79,9 +79,6 @@ extern void elv_completed_request(request_queue_t *, struct request *);
extern int elv_set_request(request_queue_t *, struct request *, int);
extern void elv_put_request(request_queue_t *, struct request *);
-#define __elv_add_request_pos(q, rq, pos) \
- (q)->elevator.elevator_add_req_fn((q), (rq), (pos))
-
/*
* noop I/O scheduler. always merges, always inserts new request at tail
*/
@@ -111,4 +108,11 @@ extern inline int elv_try_last_merge(request_queue_t *, struct bio *);
#define ELEVATOR_FRONT_MERGE 1
#define ELEVATOR_BACK_MERGE 2
+/*
+ * Insertion selection
+ */
+#define ELEVATOR_INSERT_FRONT 1
+#define ELEVATOR_INSERT_BACK 2
+#define ELEVATOR_INSERT_SORT 3
+
#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 87ae270bf96c..d10db09f6164 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -373,7 +373,7 @@ struct inode {
unsigned int i_nlink;
uid_t i_uid;
gid_t i_gid;
- kdev_t i_rdev;
+ dev_t i_rdev;
loff_t i_size;
struct timespec i_atime;
struct timespec i_mtime;
@@ -469,12 +469,12 @@ static inline void i_size_write(struct inode *inode, loff_t i_size)
static inline unsigned iminor(struct inode *inode)
{
- return minor(inode->i_rdev);
+ return MINOR(inode->i_rdev);
}
static inline unsigned imajor(struct inode *inode)
{
- return major(inode->i_rdev);
+ return MAJOR(inode->i_rdev);
}
struct fown_struct {
@@ -1156,7 +1156,6 @@ extern struct block_device *lookup_bdev(const char *);
extern struct block_device *open_bdev_excl(const char *, int, int, void *);
extern void close_bdev_excl(struct block_device *, int);
-extern const char * cdevname(kdev_t);
extern void init_special_inode(struct inode *, umode_t, dev_t);
/* Invalid inode operations -- fs/bad_inode.c */
@@ -1390,6 +1389,9 @@ struct tree_descr { char *name; struct file_operations *ops; int mode; };
extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count);
+extern int old_valid_dev(dev_t);
+extern u16 old_encode_dev(dev_t);
+extern dev_t old_decode_dev(u16);
extern int inode_change_ok(struct inode *, struct iattr *);
extern int inode_setattr(struct inode *, struct iattr *);
diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h
index 900a4a1e1282..f60508da024d 100644
--- a/include/linux/kdev_t.h
+++ b/include/linux/kdev_t.h
@@ -1,101 +1,6 @@
#ifndef _LINUX_KDEV_T_H
#define _LINUX_KDEV_T_H
#ifdef __KERNEL__
-/*
-As a preparation for the introduction of larger device numbers,
-we introduce a type kdev_t to hold them. No information about
-this type is known outside of this include file.
-
-Objects of type kdev_t designate a device. Outside of the kernel
-the corresponding things are objects of type dev_t - usually an
-integral type with the device major and minor in the high and low
-bits, respectively. Conversion is done by
-
-extern kdev_t to_kdev_t(int);
-
-It is up to the various file systems to decide how objects of type
-dev_t are stored on disk.
-The only other point of contact between kernel and outside world
-are the system calls stat and mknod, new versions of which will
-eventually have to be used in libc.
-
-[Unfortunately, the floppy control ioctls fail to hide the internal
-kernel structures, and the fd_device field of a struct floppy_drive_struct
-is user-visible. So, it remains a dev_t for the moment, with some ugly
-conversions in floppy.c.]
-
-Inside the kernel, we aim for a kdev_t type that is a pointer
-to a structure with information about the device (like major,
-minor, size, blocksize, sectorsize, name, read-only flag,
-struct file_operations etc.).
-
-However, for the time being we let kdev_t be almost the same as dev_t:
-
-typedef struct { unsigned short major, minor; } kdev_t;
-
-Admissible operations on an object of type kdev_t:
-- passing it along
-- comparing it for equality with another such object
-- storing it in inode->i_rdev or tty->device
-- using its bit pattern as argument in a hash function
-- finding its major and minor
-- complaining about it
-
-An object of type kdev_t is created only by the function MKDEV(),
-with the single exception of the constant 0 (no device).
-
-Right now the other information mentioned above is usually found
-in static arrays indexed by major or major,minor.
-
-An obstacle to immediately using
- typedef struct { ... (* lots of information *) } *kdev_t
-is the case of mknod used to create a block device that the
-kernel doesn't know about at present (but first learns about
-when some module is inserted).
-
-aeb - 950811
-*/
-
-
-/*
- * NOTE NOTE NOTE!
- *
- * The kernel-internal "kdev_t" will eventually have
- * 20 bits for minor numbers, and 12 bits for majors.
- *
- * HOWEVER, the external representation is still 8+8
- * bits, and there is no way to generate the extended
- * "kdev_t" format yet. Which is just as well, since
- * we still use "minor" as an index into various
- * static arrays, and they are sized for a 8-bit index.
- */
-typedef struct {
- unsigned short value;
-} kdev_t;
-
-#define KDEV_MINOR_BITS 8
-#define KDEV_MAJOR_BITS 8
-
-#define __mkdev(major,minor) (((major) << KDEV_MINOR_BITS) + (minor))
-
-#define mk_kdev(major, minor) ((kdev_t) { __mkdev(major,minor) } )
-
-/*
- * The "values" are just _cookies_, usable for
- * internal equality comparisons and for things
- * like NFS filehandle conversion.
- */
-static inline unsigned int kdev_val(kdev_t dev)
-{
- return dev.value;
-}
-
-#define NODEV (mk_kdev(0,0))
-
-/* Mask off the high bits for now.. */
-#define minor(dev) ((dev).value & 0xff)
-#define major(dev) (((dev).value >> KDEV_MINOR_BITS) & 0xff)
-
/* These are for user-level "dev_t" */
#define MINORBITS 8
#define MINORMASK ((1U << MINORBITS) - 1)
@@ -104,20 +9,6 @@ static inline unsigned int kdev_val(kdev_t dev)
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
-/*
- * Conversion functions
- */
-
-static inline int kdev_t_to_nr(kdev_t dev)
-{
- return MKDEV(major(dev), minor(dev));
-}
-
-static inline kdev_t to_kdev_t(int dev)
-{
- return mk_kdev(MAJOR(dev),MINOR(dev));
-}
-
#define print_dev_t(buffer, dev) \
sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev))
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 7fa02a737518..8412faeea0f7 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -29,7 +29,7 @@ extern int request_module(const char * name, ...) __attribute__ ((format (printf
static inline int request_module(const char * name, ...) { return -ENOSYS; }
#endif
-#define try_then_request_module(x, mod...) ((x) ?: request_module(mod), (x))
+#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
#ifdef CONFIG_HOTPLUG
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 445fc58751c7..9f9743146b54 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -110,6 +110,7 @@ struct vm_area_struct {
#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
#define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */
#define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */
+#define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */
#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
diff --git a/include/linux/mman.h b/include/linux/mman.h
index a8956f6588ad..cfb6ac61bbde 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -2,6 +2,7 @@
#define _LINUX_MMAN_H
#include <linux/config.h>
+#include <linux/mm.h>
#include <asm/atomic.h>
#include <asm/mman.h>
@@ -27,4 +28,32 @@ static inline void vm_unacct_memory(long pages)
vm_acct_memory(-pages);
}
+/* Optimisation macro. */
+#define _calc_vm_trans(x,bit1,bit2) \
+ ((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \
+ : ((x) & (bit1)) / ((bit1) / (bit2)))
+
+/*
+ * Combine the mmap "prot" argument into "vm_flags" used internally.
+ */
+static inline unsigned long
+calc_vm_prot_bits(unsigned long prot)
+{
+ return _calc_vm_trans(prot, PROT_READ, VM_READ ) |
+ _calc_vm_trans(prot, PROT_WRITE, VM_WRITE) |
+ _calc_vm_trans(prot, PROT_EXEC, VM_EXEC );
+}
+
+/*
+ * Combine the mmap "flags" argument into "vm_flags" used internally.
+ */
+static inline unsigned long
+calc_vm_flag_bits(unsigned long flags)
+{
+ return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
+ _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
+ _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
+ _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
+}
+
#endif /* _LINUX_MMAN_H */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 3d46a2caaade..88b705d8cefe 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -23,7 +23,7 @@ struct nfs_fattr {
__u64 used;
} nfs3;
} du;
- __u32 rdev;
+ dev_t rdev;
union {
__u64 nfs3; /* also nfs2 */
struct {
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 3e3a26916a12..fd8b35209ccc 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -3,9 +3,6 @@
#include <linux/netlink.h>
-#define RTNL_DEBUG 1
-
-
/****
* Routing/neighbour discovery messages.
****/
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 6ebaff34570c..6131e3c9aa45 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
@@ -42,6 +42,8 @@
* randall@sctp.chicago.il.us
* kmorneau@cisco.com
* qxie1@email.mot.com
+ * Sridhar Samudrala <sri@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -507,6 +509,11 @@ typedef struct sctp_cwr_chunk {
* The ASCONF Parameter Response is used in the ASCONF-ACK to
* report status of ASCONF processing.
*/
+typedef struct sctp_addip_param {
+ sctp_paramhdr_t param_hdr;
+ __u32 crr_id;
+}sctp_addip_param_t __attribute__((packed));
+
typedef struct sctp_addiphdr {
__u32 serial;
__u8 params[0];
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index ac8ac46845ba..c851b7dc997e 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -138,4 +138,7 @@ struct tty_ldisc {
#define LDISC_FLAG_DEFINED 0x00000001
+#define MODULE_ALIAS_LDISC(ldisc) \
+ MODULE_ALIAS("tty-ldisc-" __stringify(ldisc))
+
#endif /* _LINUX_TTY_LDISC_H */
diff --git a/include/linux/vcache.h b/include/linux/vcache.h
deleted file mode 100644
index 5708fe6a908a..000000000000
--- a/include/linux/vcache.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * virtual => physical mapping cache support.
- */
-#ifndef _LINUX_VCACHE_H
-#define _LINUX_VCACHE_H
-
-typedef struct vcache_s {
- unsigned long address;
- struct mm_struct *mm;
- struct list_head hash_entry;
- void (*callback)(struct vcache_s *data, struct page *new_page);
-} vcache_t;
-
-extern spinlock_t vcache_lock;
-
-extern void __attach_vcache(vcache_t *vcache,
- unsigned long address,
- struct mm_struct *mm,
- void (*callback)(struct vcache_s *data, struct page *new_page));
-
-extern void __detach_vcache(vcache_t *vcache);
-
-extern void invalidate_vcache(unsigned long address, struct mm_struct *mm,
- struct page *new_page);
-
-#endif
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 506fd2cb1305..3f21f1985699 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001-2003 Intel Corp.
*
* This file is part of the SCTP kernel reference Implementation
@@ -40,6 +40,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -145,6 +146,7 @@ int sctp_primitive_SHUTDOWN(struct sctp_association *, void *arg);
int sctp_primitive_ABORT(struct sctp_association *, void *arg);
int sctp_primitive_SEND(struct sctp_association *, void *arg);
int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
+int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
/*
* sctp/crc32c.c
@@ -404,6 +406,12 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
return result;
}
+/* Tests if the list has one and only one entry. */
+static inline int sctp_list_single_entry(struct list_head *head)
+{
+ return ((head->next != head) && (head->next == head->prev));
+}
+
/* Calculate the size (in bytes) occupied by the data of an iovec. */
static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
{
@@ -525,6 +533,19 @@ static inline int ipver2af(__u8 ipver)
};
}
+/* Convert from an address parameter type to an address family. */
+static inline int param_type2af(__u16 type)
+{
+ switch (type) {
+ case SCTP_PARAM_IPV4_ADDRESS:
+ return AF_INET;
+ case SCTP_PARAM_IPV6_ADDRESS:
+ return AF_INET6;
+ default:
+ return 0;
+ };
+}
+
/* Perform some sanity checks. */
static inline int sctp_sanity_check(void)
{
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 28d4c6409247..3eb9c18df0c5 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -41,6 +41,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -268,6 +269,9 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
struct sctp_chunk *asconf,
int vparam_len);
+struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+ union sctp_addr *addr);
+
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
@@ -330,12 +334,6 @@ void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
__u32 sctp_generate_tag(const struct sctp_endpoint *);
__u32 sctp_generate_tsn(const struct sctp_endpoint *);
-/* 4th level prototypes */
-void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *,
- __u16 port, int iif);
-int sctp_addr2sockaddr(const union sctp_params, union sctp_addr *);
-int sockaddr2sctp_addr(const union sctp_addr *, union sctp_addr_param *);
-
/* Extern declarations for major data structures. */
const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
extern const sctp_sm_table_entry_t
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index f77373f18e7e..7ba32701be00 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2003 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -45,6 +45,7 @@
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Anup Pemmaiah <pemmaiah@cc.usu.edu>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -217,86 +218,6 @@ extern struct sctp_globals {
#define sctp_local_addr_list (sctp_globals.local_addr_list)
#define sctp_local_addr_lock (sctp_globals.local_addr_lock)
-/*
- * Pointers to address related SCTP functions.
- * (i.e. things that depend on the address family.)
- */
-struct sctp_af {
- int (*sctp_xmit) (struct sk_buff *skb,
- struct sctp_transport *,
- int ipfragok);
- int (*setsockopt) (struct sock *sk,
- int level,
- int optname,
- char *optval,
- int optlen);
- int (*getsockopt) (struct sock *sk,
- int level,
- int optname,
- char *optval,
- int *optlen);
- struct dst_entry *(*get_dst) (struct sctp_association *asoc,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
- void (*get_saddr) (struct sctp_association *asoc,
- struct dst_entry *dst,
- union sctp_addr *daddr,
- union sctp_addr *saddr);
- void (*copy_addrlist) (struct list_head *,
- struct net_device *);
- void (*dst_saddr) (union sctp_addr *saddr,
- struct dst_entry *dst,
- unsigned short port);
- int (*cmp_addr) (const union sctp_addr *addr1,
- const union sctp_addr *addr2);
- void (*addr_copy) (union sctp_addr *dst,
- union sctp_addr *src);
- void (*from_skb) (union sctp_addr *,
- struct sk_buff *skb,
- int saddr);
- void (*from_sk) (union sctp_addr *,
- struct sock *sk);
- void (*to_sk_saddr) (union sctp_addr *,
- struct sock *sk);
- void (*to_sk_daddr) (union sctp_addr *,
- struct sock *sk);
- int (*addr_valid) (union sctp_addr *,
- struct sctp_opt *);
- sctp_scope_t (*scope) (union sctp_addr *);
- void (*inaddr_any) (union sctp_addr *, unsigned short);
- int (*is_any) (const union sctp_addr *);
- int (*available) (union sctp_addr *,
- struct sctp_opt *);
- int (*skb_iif) (const struct sk_buff *sk);
- int (*is_ce) (const struct sk_buff *sk);
- void (*seq_dump_addr)(struct seq_file *seq,
- union sctp_addr *addr);
- __u16 net_header_len;
- int sockaddr_len;
- sa_family_t sa_family;
- struct list_head list;
-};
-
-struct sctp_af *sctp_get_af_specific(sa_family_t);
-int sctp_register_af(struct sctp_af *);
-
-/* Protocol family functions. */
-struct sctp_pf {
- void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
- void (*skb_msgname) (struct sk_buff *, char *, int *);
- int (*af_supported) (sa_family_t, struct sctp_opt *);
- int (*cmp_addr) (const union sctp_addr *,
- const union sctp_addr *,
- struct sctp_opt *);
- int (*bind_verify) (struct sctp_opt *, union sctp_addr *);
- int (*send_verify) (struct sctp_opt *, union sctp_addr *);
- int (*supported_addrs)(const struct sctp_opt *, __u16 *);
- struct sock *(*create_accept_sk) (struct sock *sk,
- struct sctp_association *asoc);
- void (*addr_v4map) (struct sctp_opt *, union sctp_addr *);
- struct sctp_af *af;
-};
-
/* SCTP Socket type: UDP or TCP style. */
typedef enum {
SCTP_SOCKET_UDP = 0,
@@ -488,6 +409,92 @@ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
return stream->ssn[id]++;
}
+/*
+ * Pointers to address related SCTP functions.
+ * (i.e. things that depend on the address family.)
+ */
+struct sctp_af {
+ int (*sctp_xmit) (struct sk_buff *skb,
+ struct sctp_transport *,
+ int ipfragok);
+ int (*setsockopt) (struct sock *sk,
+ int level,
+ int optname,
+ char *optval,
+ int optlen);
+ int (*getsockopt) (struct sock *sk,
+ int level,
+ int optname,
+ char *optval,
+ int *optlen);
+ struct dst_entry *(*get_dst) (struct sctp_association *asoc,
+ union sctp_addr *daddr,
+ union sctp_addr *saddr);
+ void (*get_saddr) (struct sctp_association *asoc,
+ struct dst_entry *dst,
+ union sctp_addr *daddr,
+ union sctp_addr *saddr);
+ void (*copy_addrlist) (struct list_head *,
+ struct net_device *);
+ void (*dst_saddr) (union sctp_addr *saddr,
+ struct dst_entry *dst,
+ unsigned short port);
+ int (*cmp_addr) (const union sctp_addr *addr1,
+ const union sctp_addr *addr2);
+ void (*addr_copy) (union sctp_addr *dst,
+ union sctp_addr *src);
+ void (*from_skb) (union sctp_addr *,
+ struct sk_buff *skb,
+ int saddr);
+ void (*from_sk) (union sctp_addr *,
+ struct sock *sk);
+ void (*to_sk_saddr) (union sctp_addr *,
+ struct sock *sk);
+ void (*to_sk_daddr) (union sctp_addr *,
+ struct sock *sk);
+ void (*from_addr_param) (union sctp_addr *,
+ union sctp_addr_param *,
+ __u16 port, int iif);
+ int (*to_addr_param) (const union sctp_addr *,
+ union sctp_addr_param *);
+ int (*addr_valid) (union sctp_addr *,
+ struct sctp_opt *);
+ sctp_scope_t (*scope) (union sctp_addr *);
+ void (*inaddr_any) (union sctp_addr *, unsigned short);
+ int (*is_any) (const union sctp_addr *);
+ int (*available) (union sctp_addr *,
+ struct sctp_opt *);
+ int (*skb_iif) (const struct sk_buff *sk);
+ int (*is_ce) (const struct sk_buff *sk);
+ void (*seq_dump_addr)(struct seq_file *seq,
+ union sctp_addr *addr);
+ __u16 net_header_len;
+ int sockaddr_len;
+ sa_family_t sa_family;
+ struct list_head list;
+};
+
+struct sctp_af *sctp_get_af_specific(sa_family_t);
+int sctp_register_af(struct sctp_af *);
+
+/* Protocol family functions. */
+struct sctp_pf {
+ void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
+ void (*skb_msgname) (struct sk_buff *, char *, int *);
+ int (*af_supported) (sa_family_t, struct sctp_opt *);
+ int (*cmp_addr) (const union sctp_addr *,
+ const union sctp_addr *,
+ struct sctp_opt *);
+ int (*bind_verify) (struct sctp_opt *, union sctp_addr *);
+ int (*send_verify) (struct sctp_opt *, union sctp_addr *);
+ int (*supported_addrs)(const struct sctp_opt *, __u16 *);
+ struct sock *(*create_accept_sk) (struct sock *sk,
+ struct sctp_association *asoc);
+ void (*addr_v4map) (struct sctp_opt *, union sctp_addr *);
+ struct sctp_af *af;
+};
+
+
/* Structure to track chunk fragments that have been acked, but peer
* fragments of the same message have not.
*/
@@ -1688,6 +1695,8 @@ struct sctp_transport *sctp_assoc_choose_shutdown_transport(
void sctp_assoc_update_retran_path(struct sctp_association *);
struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *,
const union sctp_addr *);
+int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
+ const union sctp_addr *laddr);
struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
const union sctp_addr *address,
const int gfp);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index da96859dba92..45f96479510f 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -551,13 +551,15 @@ struct sctp_status {
};
/*
- * 8.3, 8.5 get all peer/local addresses on a socket
- * This parameter struct is for getsockopt
+ * 8.3, 8.5 get all peer/local addresses in an association.
+ * This parameter struct is used by SCTP_GET_PEER_ADDRS and
+ * SCTP_GET_LOCAL_ADDRS socket options used internally to implement
+ * sctp_getpaddrs() and sctp_getladdrs() API.
*/
struct sctp_getaddrs {
sctp_assoc_t assoc_id;
int addr_num;
- struct sockaddr_storage *addrs;
+ struct sockaddr *addrs;
};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
diff --git a/kernel/Makefile b/kernel/Makefile
index 9bf11ae7195b..638a2f6c341c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += ksyms.o module.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_PM) += power/
-obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_IKCONFIG) += configs.o
diff --git a/kernel/futex.c b/kernel/futex.c
index 4557addfc6d6..a4feceee661a 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -5,6 +5,9 @@
* Generalized futexes, futex requeueing, misc fixes by Ingo Molnar
* (C) Copyright 2003 Red Hat Inc, All Rights Reserved
*
+ * Removed page pinning, fix privately mapped COW pages and other cleanups
+ * (C) Copyright 2003 Jamie Lokier
+ *
* Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
* enough at me, Linus for the original (flawed) idea, Matthew
* Kirkwood for proof-of-concept implementation.
@@ -33,12 +36,32 @@
#include <linux/hash.h>
#include <linux/init.h>
#include <linux/futex.h>
-#include <linux/vcache.h>
#include <linux/mount.h>
+#include <linux/pagemap.h>
#define FUTEX_HASHBITS 8
/*
+ * Futexes are matched on equal values of this key.
+ * The key type depends on whether it's a shared or private mapping.
+ */
+union futex_key {
+ struct {
+ unsigned long pgoff;
+ struct inode *inode;
+ } shared;
+ struct {
+ unsigned long uaddr;
+ struct mm_struct *mm;
+ } private;
+ struct {
+ unsigned long word;
+ void *ptr;
+ } both;
+ int offset;
+};
+
+/*
* We use this hashed waitqueue instead of a normal wait_queue_t, so
* we can wake only the relevant ones (hashed queues may be shared):
*/
@@ -46,12 +69,8 @@ struct futex_q {
struct list_head list;
wait_queue_head_t waiters;
- /* Page struct and offset within it. */
- struct page *page;
- int offset;
-
- /* the virtual => physical COW-safe cache */
- vcache_t vcache;
+ /* Key which the futex is hashed on. */
+ union futex_key key;
/* For fd, sigio sent using these. */
int fd;
@@ -66,111 +85,149 @@ static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
static struct vfsmount *futex_mnt;
/*
- * These are all locks that are necessery to look up a physical
- * mapping safely, and modify/search the futex hash, atomically:
+ * We hash on the keys returned from get_futex_key (see below).
*/
-static inline void lock_futex_mm(void)
+static inline struct list_head *hash_futex(union futex_key *key)
{
- spin_lock(&current->mm->page_table_lock);
- spin_lock(&vcache_lock);
- spin_lock(&futex_lock);
-}
-
-static inline void unlock_futex_mm(void)
-{
- spin_unlock(&futex_lock);
- spin_unlock(&vcache_lock);
- spin_unlock(&current->mm->page_table_lock);
+ return &futex_queues[hash_long(key->both.word
+ + (unsigned long) key->both.ptr
+ + key->offset, FUTEX_HASHBITS)];
}
/*
- * The physical page is shared, so we can hash on its address:
+ * Return 1 if two futex_keys are equal, 0 otherwise.
*/
-static inline struct list_head *hash_futex(struct page *page, int offset)
+static inline int match_futex(union futex_key *key1, union futex_key *key2)
{
- return &futex_queues[hash_long((unsigned long)page + offset,
- FUTEX_HASHBITS)];
+ return (key1->both.word == key2->both.word
+ && key1->both.ptr == key2->both.ptr
+ && key1->offset == key2->offset);
}
/*
- * Get kernel address of the user page and pin it.
+ * Get parameters which are the keys for a futex.
+ *
+ * For shared mappings, it's (page->index, vma->vm_file->f_dentry->d_inode,
+ * offset_within_page). For private mappings, it's (uaddr, current->mm).
+ * We can usually work out the index without swapping in the page.
*
- * Must be called with (and returns with) all futex-MM locks held.
+ * Returns: 0, or negative error code.
+ * The key words are stored in *key on success.
+ *
+ * Should be called with &current->mm->mmap_sem,
+ * but NOT &futex_lock or &current->mm->page_table_lock.
*/
-static inline struct page *__pin_page_atomic (struct page *page)
-{
- if (!PageReserved(page))
- get_page(page);
- return page;
-}
-
-static struct page *__pin_page(unsigned long addr)
+static int get_futex_key(unsigned long uaddr, union futex_key *key)
{
struct mm_struct *mm = current->mm;
- struct page *page, *tmp;
+ struct vm_area_struct *vma;
+ struct page *page;
int err;
/*
- * Do a quick atomic lookup first - this is the fastpath.
+ * The futex address must be "naturally" aligned.
+ */
+ key->offset = uaddr % PAGE_SIZE;
+ if (unlikely((key->offset % sizeof(u32)) != 0))
+ return -EINVAL;
+ uaddr -= key->offset;
+
+ /*
+ * The futex is hashed differently depending on whether
+ * it's in a shared or private mapping. So check vma first.
+ */
+ vma = find_extend_vma(mm, uaddr);
+ if (unlikely(!vma))
+ return -EFAULT;
+
+ /*
+ * Permissions.
*/
- page = follow_page(mm, addr, 0);
- if (likely(page != NULL))
- return __pin_page_atomic(page);
+ if (unlikely((vma->vm_flags & (VM_IO|VM_READ)) != VM_READ))
+ return (vma->vm_flags & VM_IO) ? -EPERM : -EACCES;
/*
- * No luck - need to fault in the page:
+ * Private mappings are handled in a simple way.
+ *
+ * NOTE: When userspace waits on a MAP_SHARED mapping, even if
+ * it's a read-only handle, it's expected that futexes attach to
+ * the object not the particular process. Therefore we use
+ * VM_MAYSHARE here, not VM_SHARED which is restricted to shared
+ * mappings of _writable_ handles.
*/
-repeat_lookup:
+ if (likely(!(vma->vm_flags & VM_MAYSHARE))) {
+ key->private.mm = mm;
+ key->private.uaddr = uaddr;
+ return 0;
+ }
- unlock_futex_mm();
+ /*
+ * Linear mappings are also simple.
+ */
+ key->shared.inode = vma->vm_file->f_dentry->d_inode;
+ if (likely(!(vma->vm_flags & VM_NONLINEAR))) {
+ key->shared.pgoff = (((uaddr - vma->vm_start) >> PAGE_SHIFT)
+ + vma->vm_pgoff);
+ return 0;
+ }
- down_read(&mm->mmap_sem);
- err = get_user_pages(current, mm, addr, 1, 0, 0, &page, NULL);
- up_read(&mm->mmap_sem);
+ /*
+ * We could walk the page table to read the non-linear
+ * pte, and get the page index without fetching the page
+ * from swap. But that's a lot of code to duplicate here
+ * for a rare case, so we simply fetch the page.
+ */
- lock_futex_mm();
+ /*
+ * Do a quick atomic lookup first - this is the fastpath.
+ */
+ spin_lock(&current->mm->page_table_lock);
+ page = follow_page(mm, uaddr, 0);
+ if (likely(page != NULL)) {
+ key->shared.pgoff =
+ page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ spin_unlock(&current->mm->page_table_lock);
+ return 0;
+ }
+ spin_unlock(&current->mm->page_table_lock);
- if (err < 0)
- return NULL;
/*
- * Since the faulting happened with locks released, we have to
- * check for races:
+ * Do it the general way.
*/
- tmp = follow_page(mm, addr, 0);
- if (tmp != page) {
+ err = get_user_pages(current, mm, uaddr, 1, 0, 0, &page, NULL);
+ if (err >= 0) {
+ key->shared.pgoff =
+ page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
put_page(page);
- goto repeat_lookup;
}
-
- return page;
+ return err;
}
+
/*
* Wake up all waiters hashed on the physical page that is mapped
* to this virtual address:
*/
-static inline int futex_wake(unsigned long uaddr, int offset, int num)
+static inline int futex_wake(unsigned long uaddr, int num)
{
struct list_head *i, *next, *head;
- struct page *page;
- int ret = 0;
+ union futex_key key;
+ int ret;
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
- return -EFAULT;
- }
+ ret = get_futex_key(uaddr, &key);
+ if (unlikely(ret != 0))
+ goto out;
- head = hash_futex(page, offset);
+ head = hash_futex(&key);
+ spin_lock(&futex_lock);
list_for_each_safe(i, next, head) {
struct futex_q *this = list_entry(i, struct futex_q, list);
- if (this->page == page && this->offset == offset) {
+ if (match_futex (&this->key, &key)) {
list_del_init(i);
- __detach_vcache(&this->vcache);
wake_up_all(&this->waiters);
if (this->filp)
send_sigio(&this->filp->f_owner, this->fd, POLL_IN);
@@ -179,113 +236,74 @@ static inline int futex_wake(unsigned long uaddr, int offset, int num)
break;
}
}
+ spin_unlock(&futex_lock);
- unlock_futex_mm();
- put_page(page);
-
+out:
+ up_read(&current->mm->mmap_sem);
return ret;
}
/*
- * This gets called by the COW code, we have to rehash any
- * futexes that were pending on the old physical page, and
- * rehash it to the new physical page. The pagetable_lock
- * and vcache_lock is already held:
- */
-static void futex_vcache_callback(vcache_t *vcache, struct page *new_page)
-{
- struct futex_q *q = container_of(vcache, struct futex_q, vcache);
- struct list_head *head = hash_futex(new_page, q->offset);
-
- spin_lock(&futex_lock);
-
- if (!list_empty(&q->list)) {
- put_page(q->page);
- q->page = new_page;
- __pin_page_atomic(new_page);
- list_del(&q->list);
- list_add_tail(&q->list, head);
- }
-
- spin_unlock(&futex_lock);
-}
-
-/*
* Requeue all waiters hashed on one physical page to another
* physical page.
*/
-static inline int futex_requeue(unsigned long uaddr1, int offset1,
- unsigned long uaddr2, int offset2, int nr_wake, int nr_requeue)
+static inline int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
+ int nr_wake, int nr_requeue)
{
struct list_head *i, *next, *head1, *head2;
- struct page *page1 = NULL, *page2 = NULL;
- int ret = 0;
+ union futex_key key1, key2;
+ int ret;
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page1 = __pin_page(uaddr1 - offset1);
- if (!page1)
+ ret = get_futex_key(uaddr1, &key1);
+ if (unlikely(ret != 0))
goto out;
- page2 = __pin_page(uaddr2 - offset2);
- if (!page2)
+ ret = get_futex_key(uaddr2, &key2);
+ if (unlikely(ret != 0))
goto out;
- head1 = hash_futex(page1, offset1);
- head2 = hash_futex(page2, offset2);
+ head1 = hash_futex(&key1);
+ head2 = hash_futex(&key2);
+ spin_lock(&futex_lock);
list_for_each_safe(i, next, head1) {
struct futex_q *this = list_entry(i, struct futex_q, list);
- if (this->page == page1 && this->offset == offset1) {
+ if (match_futex (&this->key, &key1)) {
list_del_init(i);
- __detach_vcache(&this->vcache);
if (++ret <= nr_wake) {
wake_up_all(&this->waiters);
if (this->filp)
send_sigio(&this->filp->f_owner,
this->fd, POLL_IN);
} else {
- put_page(this->page);
- __pin_page_atomic (page2);
list_add_tail(i, head2);
- __attach_vcache(&this->vcache, uaddr2,
- current->mm, futex_vcache_callback);
- this->offset = offset2;
- this->page = page2;
+ this->key = key2;
if (ret - nr_wake >= nr_requeue)
break;
}
}
}
+ spin_unlock(&futex_lock);
out:
- unlock_futex_mm();
-
- if (page1)
- put_page(page1);
- if (page2)
- put_page(page2);
-
+ up_read(&current->mm->mmap_sem);
return ret;
}
-static inline void __queue_me(struct futex_q *q, struct page *page,
- unsigned long uaddr, int offset,
- int fd, struct file *filp)
+static inline void queue_me(struct futex_q *q, union futex_key *key,
+ int fd, struct file *filp)
{
- struct list_head *head = hash_futex(page, offset);
+ struct list_head *head = hash_futex(key);
- q->offset = offset;
+ q->key = *key;
q->fd = fd;
q->filp = filp;
- q->page = page;
+ spin_lock(&futex_lock);
list_add_tail(&q->list, head);
- /*
- * We register a futex callback to this virtual address,
- * to make sure a COW properly rehashes the futex-queue.
- */
- __attach_vcache(&q->vcache, uaddr, current->mm, futex_vcache_callback);
+ spin_unlock(&futex_lock);
}
/* Return 1 if we were still queued (ie. 0 means we were woken) */
@@ -293,83 +311,107 @@ static inline int unqueue_me(struct futex_q *q)
{
int ret = 0;
- spin_lock(&vcache_lock);
spin_lock(&futex_lock);
if (!list_empty(&q->list)) {
list_del(&q->list);
- __detach_vcache(&q->vcache);
ret = 1;
}
spin_unlock(&futex_lock);
- spin_unlock(&vcache_lock);
return ret;
}
-static inline int futex_wait(unsigned long uaddr,
- int offset,
- int val,
- unsigned long time)
+static inline int futex_wait(unsigned long uaddr, int val, unsigned long time)
{
DECLARE_WAITQUEUE(wait, current);
- int ret = 0, curval;
- struct page *page;
+ int ret, curval;
+ union futex_key key;
struct futex_q q;
+ try_again:
init_waitqueue_head(&q.waiters);
- lock_futex_mm();
+ down_read(&current->mm->mmap_sem);
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
- return -EFAULT;
- }
- __queue_me(&q, page, uaddr, offset, -1, NULL);
+ ret = get_futex_key(uaddr, &key);
+ if (unlikely(ret != 0))
+ goto out_release_sem;
+
+ queue_me(&q, &key, -1, NULL);
/*
- * Page is pinned, but may no longer be in this address space.
- * It cannot schedule, so we access it with the spinlock held.
+ * Access the page after the futex is queued.
+ * We hold the mmap semaphore, so the mapping cannot have changed
+ * since we looked it up.
*/
if (get_user(curval, (int *)uaddr) != 0) {
- unlock_futex_mm();
ret = -EFAULT;
- goto out;
+ goto out_unqueue;
}
if (curval != val) {
- unlock_futex_mm();
ret = -EWOULDBLOCK;
- goto out;
+ goto out_unqueue;
}
+
+ /*
+ * Now the futex is queued and we have checked the data, we
+ * don't want to hold mmap_sem while we sleep.
+ */
+ up_read(&current->mm->mmap_sem);
+
/*
- * The get_user() above might fault and schedule so we
- * cannot just set TASK_INTERRUPTIBLE state when queueing
- * ourselves into the futex hash. This code thus has to
+ * There might have been scheduling since the queue_me(), as we
+ * cannot hold a spinlock across the get_user() in case it
+ * faults. So we cannot just set TASK_INTERRUPTIBLE state when
+ * queueing ourselves into the futex hash. This code thus has to
* rely on the futex_wake() code doing a wakeup after removing
* the waiter from the list.
*/
add_wait_queue(&q.waiters, &wait);
+ spin_lock(&futex_lock);
set_current_state(TASK_INTERRUPTIBLE);
- if (!list_empty(&q.list)) {
- unlock_futex_mm();
- time = schedule_timeout(time);
+
+ if (unlikely(list_empty(&q.list))) {
+ /*
+ * We were woken already.
+ */
+ spin_unlock(&futex_lock);
+ set_current_state(TASK_RUNNING);
+ return 0;
}
+
+ spin_unlock(&futex_lock);
+ time = schedule_timeout(time);
set_current_state(TASK_RUNNING);
+
/*
* NOTE: we don't remove ourselves from the waitqueue because
* we are the only user of it.
*/
- if (time == 0) {
- ret = -ETIMEDOUT;
- goto out;
- }
+
+ /*
+ * Were we woken or interrupted for a valid reason?
+ */
+ ret = unqueue_me(&q);
+ if (ret == 0)
+ return 0;
+ if (time == 0)
+ return -ETIMEDOUT;
if (signal_pending(current))
- ret = -EINTR;
-out:
- /* Were we woken up anyway? */
+ return -EINTR;
+
+ /*
+ * No, it was a spurious wakeup. Try again. Should never happen. :)
+ */
+ goto try_again;
+
+ out_unqueue:
+ /*
+ * Were we unqueued anyway?
+ */
if (!unqueue_me(&q))
ret = 0;
- put_page(q.page);
-
+ out_release_sem:
+ up_read(&current->mm->mmap_sem);
return ret;
}
@@ -378,7 +420,6 @@ static int futex_close(struct inode *inode, struct file *filp)
struct futex_q *q = filp->private_data;
unqueue_me(q);
- put_page(q->page);
kfree(filp->private_data);
return 0;
}
@@ -406,12 +447,12 @@ static struct file_operations futex_fops = {
/* Signal allows caller to avoid the race which would occur if they
set the sigio stuff up afterwards. */
-static int futex_fd(unsigned long uaddr, int offset, int signal)
+static int futex_fd(unsigned long uaddr, int signal)
{
- struct page *page = NULL;
struct futex_q *q;
+ union futex_key key;
struct file *filp;
- int ret;
+ int ret, err;
ret = -EINVAL;
if (signal < 0 || signal > _NSIG)
@@ -450,69 +491,47 @@ static int futex_fd(unsigned long uaddr, int offset, int signal)
goto out;
}
- lock_futex_mm();
-
- page = __pin_page(uaddr - offset);
- if (!page) {
- unlock_futex_mm();
+ down_read(&current->mm->mmap_sem);
+ err = get_futex_key(uaddr, &key);
+ up_read(&current->mm->mmap_sem);
+ if (unlikely(err != 0)) {
put_unused_fd(ret);
put_filp(filp);
kfree(q);
- return -EFAULT;
+ return err;
}
init_waitqueue_head(&q->waiters);
filp->private_data = q;
- __queue_me(q, page, uaddr, offset, ret, filp);
-
- unlock_futex_mm();
+ queue_me(q, &key, ret, filp);
/* Now we map fd to filp, so userspace can access it */
fd_install(ret, filp);
- page = NULL;
out:
- if (page)
- put_page(page);
return ret;
}
long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout,
unsigned long uaddr2, int val2)
{
- unsigned long pos_in_page;
int ret;
- pos_in_page = uaddr % PAGE_SIZE;
-
- /* Must be "naturally" aligned */
- if (pos_in_page % sizeof(u32))
- return -EINVAL;
-
switch (op) {
case FUTEX_WAIT:
- ret = futex_wait(uaddr, pos_in_page, val, timeout);
+ ret = futex_wait(uaddr, val, timeout);
break;
case FUTEX_WAKE:
- ret = futex_wake(uaddr, pos_in_page, val);
+ ret = futex_wake(uaddr, val);
break;
case FUTEX_FD:
/* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
- ret = futex_fd(uaddr, pos_in_page, val);
+ ret = futex_fd(uaddr, val);
break;
case FUTEX_REQUEUE:
- {
- unsigned long pos_in_page2 = uaddr2 % PAGE_SIZE;
-
- /* Must be "naturally" aligned */
- if (pos_in_page2 % sizeof(u32))
- return -EINVAL;
-
- ret = futex_requeue(uaddr, pos_in_page, uaddr2, pos_in_page2,
- val, val2);
+ ret = futex_requeue(uaddr, uaddr2, val, val2);
break;
- }
default:
ret = -ENOSYS;
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index e503bd8b0349..9f61a0496c2a 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -511,7 +511,6 @@ EXPORT_SYMBOL(vsnprintf);
EXPORT_SYMBOL(vsscanf);
EXPORT_SYMBOL(__bdevname);
EXPORT_SYMBOL(bdevname);
-EXPORT_SYMBOL(cdevname);
EXPORT_SYMBOL(simple_strtoull);
EXPORT_SYMBOL(simple_strtoul);
EXPORT_SYMBOL(simple_strtol);
diff --git a/mm/Makefile b/mm/Makefile
index a8de64ff3525..c66aba5886f8 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -9,6 +9,6 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \
obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
page_alloc.o page-writeback.o pdflush.o readahead.o \
- slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y)
+ slab.o swap.o truncate.o vmscan.o $(mmu-y)
obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
diff --git a/mm/fremap.c b/mm/fremap.c
index 8f96af82b4e8..b19bdde07bb6 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -144,9 +144,10 @@ long sys_remap_file_pages(unsigned long start, unsigned long size,
return err;
#endif
- down_read(&mm->mmap_sem);
-
+ /* We need down_write() to change vma->vm_flags. */
+ down_write(&mm->mmap_sem);
vma = find_vma(mm, start);
+
/*
* Make sure the vma is shared, that it supports prefaulting,
* and that the remapped range is valid and fully within
@@ -155,11 +156,27 @@ long sys_remap_file_pages(unsigned long start, unsigned long size,
if (vma && (vma->vm_flags & VM_SHARED) &&
vma->vm_ops && vma->vm_ops->populate &&
end > start && start >= vma->vm_start &&
- end <= vma->vm_end)
- err = vma->vm_ops->populate(vma, start, size, vma->vm_page_prot,
- pgoff, flags & MAP_NONBLOCK);
-
- up_read(&mm->mmap_sem);
+ end <= vma->vm_end) {
+
+ /* Must set VM_NONLINEAR before any pages are populated. */
+ if (pgoff != ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff)
+ vma->vm_flags |= VM_NONLINEAR;
+
+ /* ->populate can take a long time, so downgrade the lock. */
+ downgrade_write(&mm->mmap_sem);
+ err = vma->vm_ops->populate(vma, start, size,
+ vma->vm_page_prot,
+ pgoff, flags & MAP_NONBLOCK);
+
+ /*
+ * We can't clear VM_NONLINEAR because we'd have to do
+ * it after ->populate completes, and that would prevent
+ * downgrading the lock. (Locks can't be upgraded).
+ */
+ up_read(&mm->mmap_sem);
+ } else {
+ up_write(&mm->mmap_sem);
+ }
return err;
}
diff --git a/mm/memory.c b/mm/memory.c
index 61b782f40df9..980953dbbfb4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -43,7 +43,6 @@
#include <linux/swap.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-#include <linux/vcache.h>
#include <linux/rmap-locking.h>
#include <linux/module.h>
@@ -962,7 +961,6 @@ static inline void establish_pte(struct vm_area_struct * vma, unsigned long addr
static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address,
pte_t *page_table)
{
- invalidate_vcache(address, vma->vm_mm, new_page);
flush_cache_page(vma, address);
establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
}
diff --git a/mm/mmap.c b/mm/mmap.c
index bcc28864eab6..61c9f5ca5f82 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -136,29 +136,6 @@ out:
return retval;
}
-/* Combine the mmap "prot" and "flags" argument into one "vm_flags" used
- * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits
- * into "VM_xxx".
- */
-static inline unsigned long
-calc_vm_flags(unsigned long prot, unsigned long flags)
-{
-#define _trans(x,bit1,bit2) \
-((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
-
- unsigned long prot_bits, flag_bits;
- prot_bits =
- _trans(prot, PROT_READ, VM_READ) |
- _trans(prot, PROT_WRITE, VM_WRITE) |
- _trans(prot, PROT_EXEC, VM_EXEC);
- flag_bits =
- _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) |
- _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) |
- _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);
- return prot_bits | flag_bits;
-#undef _trans
-}
-
#ifdef DEBUG_MM_RB
static int browse_rb(struct rb_node * rb_node) {
int i = 0;
@@ -500,8 +477,8 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
* to. we assume access permissions have been handled by the open
* of the memory object, so we don't do any here.
*/
- vm_flags = calc_vm_flags(prot,flags) | mm->def_flags |
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+ vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
+ mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
if (flags & MAP_LOCKED) {
if (!capable(CAP_IPC_LOCK))
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 2c015794e3c1..699962ebd1e4 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -224,7 +224,7 @@ fail:
asmlinkage long
sys_mprotect(unsigned long start, size_t len, unsigned long prot)
{
- unsigned long nstart, end, tmp;
+ unsigned long vm_flags, nstart, end, tmp;
struct vm_area_struct * vma, * next, * prev;
int error = -EINVAL;
@@ -239,6 +239,8 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot)
if (end == start)
return 0;
+ vm_flags = calc_vm_prot_bits(prot);
+
down_write(&current->mm->mmap_sem);
vma = find_vma_prev(current->mm, start, &prev);
@@ -257,7 +259,8 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot)
goto out;
}
- newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
+ newflags = vm_flags | (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
+
if ((newflags & ~(newflags >> 4)) & 0xf) {
error = -EACCES;
goto out;
diff --git a/mm/shmem.c b/mm/shmem.c
index a106bfec7709..bb429eee7ebd 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1040,7 +1040,6 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
- inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &shmem_aops;
inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
diff --git a/mm/vcache.c b/mm/vcache.c
deleted file mode 100644
index 599e0f25490d..000000000000
--- a/mm/vcache.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * linux/mm/vcache.c
- *
- * virtual => physical page mapping cache. Users of this mechanism
- * register callbacks for a given (virt,mm,phys) page mapping, and
- * the kernel guarantees to call back when this mapping is invalidated.
- * (ie. upon COW or unmap.)
- *
- * Started by Ingo Molnar, Copyright (C) 2002
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/hash.h>
-#include <linux/vcache.h>
-
-#define VCACHE_HASHBITS 8
-#define VCACHE_HASHSIZE (1 << VCACHE_HASHBITS)
-
-spinlock_t vcache_lock = SPIN_LOCK_UNLOCKED;
-
-static struct list_head hash[VCACHE_HASHSIZE];
-
-static struct list_head *hash_vcache(unsigned long address,
- struct mm_struct *mm)
-{
- return &hash[hash_long(address + (unsigned long)mm, VCACHE_HASHBITS)];
-}
-
-void __attach_vcache(vcache_t *vcache,
- unsigned long address,
- struct mm_struct *mm,
- void (*callback)(struct vcache_s *data, struct page *new))
-{
- struct list_head *hash_head;
-
- address &= PAGE_MASK;
- vcache->address = address;
- vcache->mm = mm;
- vcache->callback = callback;
-
- hash_head = hash_vcache(address, mm);
-
- list_add_tail(&vcache->hash_entry, hash_head);
-}
-
-void __detach_vcache(vcache_t *vcache)
-{
- list_del_init(&vcache->hash_entry);
-}
-
-void invalidate_vcache(unsigned long address, struct mm_struct *mm,
- struct page *new_page)
-{
- struct list_head *l, *hash_head;
- vcache_t *vcache;
-
- address &= PAGE_MASK;
-
- hash_head = hash_vcache(address, mm);
- /*
- * This is safe, because this path is called with the pagetable
- * lock held. So while other mm's might add new entries in
- * parallel, *this* mm is locked out, so if the list is empty
- * now then we do not have to take the vcache lock to see it's
- * really empty.
- */
- if (likely(list_empty(hash_head)))
- return;
-
- spin_lock(&vcache_lock);
- list_for_each(l, hash_head) {
- vcache = list_entry(l, vcache_t, hash_entry);
- if (vcache->address != address || vcache->mm != mm)
- continue;
- vcache->callback(vcache, new_page);
- }
- spin_unlock(&vcache_lock);
-}
-
-static int __init vcache_init(void)
-{
- unsigned int i;
-
- for (i = 0; i < VCACHE_HASHSIZE; i++)
- INIT_LIST_HEAD(hash + i);
- return 0;
-}
-__initcall(vcache_init);
-
diff --git a/net/README b/net/README
deleted file mode 100644
index e509ec526c25..000000000000
--- a/net/README
+++ /dev/null
@@ -1,26 +0,0 @@
-
-Maintainers and developers for networking code sections
-
-Code Section Bug Report Contact
--------------------+-------------------------------------------
-802 [other ] alan@lxorguk.ukuu.org.uk
- [token ring ] p.norton@computer.org
-appletalk jschlst@samba.org
-ax25 g4klx@g4klx.demon.co.uk
-bridge buytenh@gnu.org
-core alan@lxorguk.ukuu.org.uk
-decnet SteveW@ACM.org
-ethernet alan@lxorguk.ukuu.org.uk
-ipv4 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipv6 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipx acme@conectiva.com.br
-spx jschlst@samba.org
-irda dagb@cs.uit.no
-lapb g4klx@g4klx.demon.co.uk
-netrom g4klx@g4klx.demon.co.uk
-rose g4klx@g4klx.demon.co.uk
-wanrouter gene@compuserve.com, jaspreet@sangoma and dm@sangoma.com
-unix alan@lxorguk.ukuu.org.uk
-x25 g4klx@g4klx.demon.co.uk
-bluetooth maxk@qualcomm.com
-8021q greearb@candelatech.com, vlan@scry.wanfear.com
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 4d5469bd8140..217244bd611d 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1888,8 +1888,6 @@ EXPORT_SYMBOL(aarp_send_ddp);
EXPORT_SYMBOL(atrtr_get_dev);
EXPORT_SYMBOL(atalk_find_dev_addr);
-static char atalk_banner[] __initdata =
- KERN_INFO "NET4: AppleTalk 0.20 for Linux NET4.0\n";
static char atalk_err_snap[] __initdata =
KERN_CRIT "Unable to register DDP with SNAP.\n";
@@ -1908,7 +1906,6 @@ static int __init atalk_init(void)
aarp_proto_init();
atalk_proc_init();
atalk_register_sysctl();
- printk(atalk_banner);
return 0;
}
module_init(atalk_init);
@@ -1939,5 +1936,5 @@ module_exit(atalk_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alan Cox <Alan.Cox@linux.org>");
-MODULE_DESCRIPTION("AppleTalk 0.20 for Linux NET4.0\n");
+MODULE_DESCRIPTION("AppleTalk 0.20\n");
MODULE_ALIAS_NETPROTO(PF_APPLETALK);
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index fa25cbdd9a80..0f9d98463a69 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -18,6 +18,7 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
#include <net/arp.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
+#include <linux/seq_file.h>
#include <linux/atmbr2684.h>
@@ -666,31 +667,57 @@ static int br2684_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
return -ENOIOCTLCMD;
}
-/* Never put more than 256 bytes in at once */
-static int br2684_proc_engine(loff_t pos, char *buf)
+#ifdef CONFIG_PROC_FS
+static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct list_head *lhd, *lhc;
- struct net_device *net_dev;
- struct br2684_dev *brdev;
- struct br2684_vcc *brvcc;
- list_for_each(lhd, &br2684_devs) {
- net_dev = list_entry_brdev(lhd);
- brdev = BRPRIV(net_dev);
- if (pos-- == 0)
- return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:"
- "%02X:%02X:%02X:%02X (%s)\n", net_dev->name,
- brdev->number,
- net_dev->dev_addr[0],
- net_dev->dev_addr[1],
- net_dev->dev_addr[2],
- net_dev->dev_addr[3],
- net_dev->dev_addr[4],
- net_dev->dev_addr[5],
- brdev->mac_was_set ? "set" : "auto");
- list_for_each(lhc, &brdev->brvccs) {
- brvcc = list_entry_brvcc(lhc);
- if (pos-- == 0)
- return sprintf(buf, " vcc %d.%d.%d: encaps=%s"
+ loff_t offs = 0;
+ struct br2684_dev *brd;
+
+ read_lock(&devs_lock);
+
+ list_for_each_entry(brd, &br2684_devs, br2684_devs) {
+ if (offs == *pos)
+ return brd;
+ ++offs;
+ }
+ return NULL;
+}
+
+static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct br2684_dev *brd = v;
+
+ ++*pos;
+
+ brd = list_entry(brd->br2684_devs.next,
+ struct br2684_dev, br2684_devs);
+ return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
+}
+
+static void br2684_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&devs_lock);
+}
+
+static int br2684_seq_show(struct seq_file *seq, void *v)
+{
+ const struct br2684_dev *brdev = v;
+ const struct net_device *net_dev = brdev->net_dev;
+ const struct br2684_vcc *brvcc;
+
+ seq_printf(seq, "dev %.16s: num=%d, mac=%02X:%02X:"
+ "%02X:%02X:%02X:%02X (%s)\n", net_dev->name,
+ brdev->number,
+ net_dev->dev_addr[0],
+ net_dev->dev_addr[1],
+ net_dev->dev_addr[2],
+ net_dev->dev_addr[3],
+ net_dev->dev_addr[4],
+ net_dev->dev_addr[5],
+ brdev->mac_was_set ? "set" : "auto");
+
+ list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
+ seq_printf(seq, " vcc %d.%d.%d: encaps=%s"
#ifndef FASTER_VERSION
", failed copies %u/%u"
#endif /* FASTER_VERSION */
@@ -711,63 +738,41 @@ static int br2684_proc_engine(loff_t pos, char *buf)
#undef bs
#undef b1
#endif /* CONFIG_ATM_BR2684_IPFILTER */
- }
}
return 0;
}
-static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count,
- loff_t *pos)
+static struct seq_operations br2684_seq_ops = {
+ .start = br2684_seq_start,
+ .next = br2684_seq_next,
+ .stop = br2684_seq_stop,
+ .show = br2684_seq_show,
+};
+
+static int br2684_proc_open(struct inode *inode, struct file *file)
{
- unsigned long page;
- int len = 0, x, left;
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
- left = PAGE_SIZE - 256;
- if (count < left)
- left = count;
- read_lock(&devs_lock);
- for (;;) {
- x = br2684_proc_engine(*pos, &((char *) page)[len]);
- if (x == 0)
- break;
- if (x > left)
- /*
- * This should only happen if the user passed in
- * a "count" too small for even one line
- */
- x = -EINVAL;
- if (x < 0) {
- len = x;
- break;
- }
- len += x;
- left -= x;
- (*pos)++;
- if (left < 256)
- break;
- }
- read_unlock(&devs_lock);
- if (len > 0 && copy_to_user(buf, (char *) page, len))
- len = -EFAULT;
- free_page(page);
- return len;
+ return seq_open(file, &br2684_seq_ops);
}
-static struct file_operations br2684_proc_operations = {
- .owner = THIS_MODULE,
- .read = br2684_proc_read,
+static struct file_operations br2684_proc_ops = {
+ .owner = THIS_MODULE,
+ .open = br2684_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
};
extern struct proc_dir_entry *atm_proc_root; /* from proc.c */
+#endif
static int __init br2684_init(void)
{
+#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p;
if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
return -ENOMEM;
- p->proc_fops = &br2684_proc_operations;
+ p->proc_fops = &br2684_proc_ops;
+#endif
br2684_ioctl_set(br2684_ioctl);
return 0;
}
@@ -779,7 +784,9 @@ static void __exit br2684_exit(void)
struct br2684_vcc *brvcc;
br2684_ioctl_set(NULL);
+#ifdef CONFIG_PROC_FS
remove_proc_entry("br2684", atm_proc_root);
+#endif
while (!list_empty(&br2684_devs)) {
net_dev = list_entry_brdev(br2684_devs.next);
diff --git a/net/atm/common.c b/net/atm/common.c
index 6fde6b018418..62c8f0a72179 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -422,26 +422,31 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
}
if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal);
if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal);
- if (error) {
- vcc_remove_socket(vcc->sk);
- return error;
- }
+ if (error)
+ goto fail;
DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal);
DPRINTK(" TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class,
vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu);
DPRINTK(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class,
vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu);
- if (!try_module_get(dev->ops->owner))
- return -ENODEV;
+ if (!try_module_get(dev->ops->owner)) {
+ error = -ENODEV;
+ goto fail;
+ }
+
if (dev->ops->open) {
- error = dev->ops->open(vcc,vpi,vci);
- if (error) {
- module_put(dev->ops->owner);
- vcc_remove_socket(vcc->sk);
- return error;
- }
+ if ((error = dev->ops->open(vcc,vpi,vci)))
+ goto put_module_fail;
}
return 0;
+
+put_module_fail:
+ module_put(dev->ops->owner);
+fail:
+ vcc_remove_socket(vcc->sk);
+ /* ensure we get dev module ref count correct */
+ vcc->dev = NULL;
+ return error;
}
@@ -1109,12 +1114,10 @@ static int __init atm_init(void)
printk(KERN_ERR "atmsvc_init() failed with %d\n", error);
goto failure;
}
-#ifdef CONFIG_PROC_FS
if ((error = atm_proc_init()) < 0) {
printk(KERN_ERR "atm_proc_init() failed with %d\n",error);
goto failure;
}
-#endif
return 0;
failure:
@@ -1125,9 +1128,7 @@ failure:
static void __exit atm_exit(void)
{
-#ifdef CONFIG_PROC_FS
atm_proc_exit();
-#endif
atmsvc_exit();
atmpvc_exit();
}
diff --git a/net/atm/common.h b/net/atm/common.h
index eb98c9357431..426f1fa8bbb1 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -33,8 +33,21 @@ int atmpvc_init(void);
void atmpvc_exit(void);
int atmsvc_init(void);
void atmsvc_exit(void);
+
+#ifdef CONFIG_PROC_FS
int atm_proc_init(void);
void atm_proc_exit(void);
+#else
+static inline int atm_proc_init(void)
+{
+ return 0;
+}
+
+static inline void atm_proc_exit(void)
+{
+ /* nothing */
+}
+#endif /* CONFIG_PROC_FS */
/* SVC */
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index cca22da87ae6..4a8f73b41edf 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -341,16 +341,13 @@ static int pppoatm_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
return -ENOIOCTLCMD;
}
-/* the following avoids some spurious warnings from the compiler */
-#define UNUSED __attribute__((unused))
-
-static int __init UNUSED pppoatm_init(void)
+static int __init pppoatm_init(void)
{
pppoatm_ioctl_set(pppoatm_ioctl);
return 0;
}
-static void __exit UNUSED pppoatm_exit(void)
+static void __exit pppoatm_exit(void)
{
pppoatm_ioctl_set(NULL);
}
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 05c41491b431..d493ab2cd420 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -593,6 +593,10 @@ int atm_proc_dev_register(struct atm_dev *dev)
int digits,num;
int error;
+ /* No proc info */
+ if (!dev->ops->proc_read)
+ return 0;
+
error = -ENOMEM;
digits = 0;
for (num = dev->number; num; num /= 10) digits++;
@@ -619,6 +623,9 @@ fail1:
void atm_proc_dev_deregister(struct atm_dev *dev)
{
+ if (!dev->ops->proc_read)
+ return;
+
remove_proc_entry(dev->proc_name, atm_proc_root);
kfree(dev->proc_name);
}
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 9dee7f22c801..c0ce4d4d20b6 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -104,6 +104,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
static struct proto_ops pvc_proto_ops = {
.family = PF_ATMPVC,
+ .owner = THIS_MODULE,
.release = vcc_release,
.bind = pvc_bind,
@@ -134,6 +135,7 @@ static int pvc_create(struct socket *sock,int protocol)
static struct net_proto_family pvc_family_ops = {
.family = PF_ATMPVC,
.create = pvc_create,
+ .owner = THIS_MODULE,
};
diff --git a/net/atm/resources.c b/net/atm/resources.c
index ae3009c6eb4f..bd32c0caabe4 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -110,20 +110,16 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
list_add_tail(&dev->dev_list, &atm_devs);
spin_unlock(&atm_dev_lock);
-#ifdef CONFIG_PROC_FS
- if (ops->proc_read) {
- if (atm_proc_dev_register(dev) < 0) {
- printk(KERN_ERR "atm_dev_register: "
- "atm_proc_dev_register failed for dev %s\n",
- type);
- spin_lock(&atm_dev_lock);
- list_del(&dev->dev_list);
- spin_unlock(&atm_dev_lock);
- __free_atm_dev(dev);
- return NULL;
- }
+ if (atm_proc_dev_register(dev) < 0) {
+ printk(KERN_ERR "atm_dev_register: "
+ "atm_proc_dev_register failed for dev %s\n",
+ type);
+ spin_lock(&atm_dev_lock);
+ list_del(&dev->dev_list);
+ spin_unlock(&atm_dev_lock);
+ __free_atm_dev(dev);
+ return NULL;
}
-#endif
return dev;
}
@@ -133,10 +129,8 @@ void atm_dev_deregister(struct atm_dev *dev)
{
unsigned long warning_time;
-#ifdef CONFIG_PROC_FS
- if (dev->ops->proc_read)
- atm_proc_dev_deregister(dev);
-#endif
+ atm_proc_dev_deregister(dev);
+
spin_lock(&atm_dev_lock);
list_del(&dev->dev_list);
spin_unlock(&atm_dev_lock);
diff --git a/net/atm/resources.h b/net/atm/resources.h
index c4ecc1be6a26..1b6bad8db9cc 100644
--- a/net/atm/resources.h
+++ b/net/atm/resources.h
@@ -24,6 +24,18 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
int atm_proc_dev_register(struct atm_dev *dev);
void atm_proc_dev_deregister(struct atm_dev *dev);
-#endif
+#else
+
+static inline int atm_proc_dev_register(struct atm_dev *dev)
+{
+ return 0;
+}
+
+static inline void atm_proc_dev_deregister(struct atm_dev *dev)
+{
+ /* nothing */
+}
+
+#endif /* CONFIG_PROC_FS */
#endif
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 07c0849b37c7..aa46d6ae96d5 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -513,6 +513,7 @@ out:
static struct proto_ops svc_proto_ops = {
.family = PF_ATMSVC,
+ .owner = THIS_MODULE,
.release = svc_release,
.bind = svc_bind,
@@ -549,6 +550,7 @@ static int svc_create(struct socket *sock,int protocol)
static struct net_proto_family svc_family_ops = {
.family = PF_ATMSVC,
.create = svc_create,
+ .owner = THIS_MODULE,
};
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 4bb3798a2638..43662ed9a619 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -2003,8 +2003,6 @@ EXPORT_SYMBOL(asc2ax);
EXPORT_SYMBOL(null_ax25_address);
EXPORT_SYMBOL(ax25_display_timer);
-static char banner[] __initdata = KERN_INFO "NET4: G4KLX/GW4PTS AX.25 for Linux. Version 0.37 for Linux NET4.0\n";
-
static int __init ax25_init(void)
{
sock_register(&ax25_family_ops);
@@ -2016,7 +2014,6 @@ static int __init ax25_init(void)
proc_net_fops_create("ax25", S_IRUGO, &ax25_info_fops);
proc_net_fops_create("ax25_calls", S_IRUGO, &ax25_uid_fops);
- printk(banner);
return 0;
}
module_init(ax25_init);
diff --git a/net/bridge/br.c b/net/bridge/br.c
index bf41aa2c61dd..3d90a9017bfc 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -32,8 +32,6 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
static int __init br_init(void)
{
- printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
-
#if defined(CONFIG_INET) && defined(CONFIG_NETFILTER)
if (br_netfilter_init())
return 1;
diff --git a/net/core/dv.c b/net/core/dv.c
index 62352d7c9bcc..e7de41f94f9c 100644
--- a/net/core/dv.c
+++ b/net/core/dv.c
@@ -40,7 +40,6 @@ const char sysctl_divert_version[32]="0.46"; /* Current version */
static int __init dv_init(void)
{
- printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version);
return 0;
}
module_init(dv_init);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4215e4a7dcd0..444f07e51e27 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -559,9 +559,6 @@ struct notifier_block rtnetlink_dev_notifier = {
void __init rtnetlink_init(void)
{
-#ifdef RTNL_DEBUG
- printk("Initializing RT netlink socket\n");
-#endif
rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv);
if (rtnl == NULL)
panic("rtnetlink_init: cannot initialize rtnetlink\n");
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8a5dbadd51f3..3879dca72b92 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1097,8 +1097,6 @@ static int __init inet_init(void)
struct inet_protosw *q;
struct list_head *r;
- printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n");
-
if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
return -EINVAL;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 3f671efed9e6..9f5a0485e0a7 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1744,7 +1744,6 @@ static struct inet_protocol pim_protocol = {
void __init ip_mr_init(void)
{
- printk(KERN_INFO "Linux IP multicast router 0.06 plus PIM-SM\n");
mrt_cachep = kmem_cache_create("ip_mrt_cache",
sizeof(struct mfc_cache),
0, SLAB_HWCACHE_ALIGN,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e55d83a6f14d..df60b4030a44 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -723,8 +723,6 @@ static int __init inet6_init(void)
#endif
#endif
- printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
-
if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "inet6_proto_init: size fault\n");
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 083155a233a6..8c9091ede27d 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1940,10 +1940,6 @@ extern void destroy_8023_client(struct datalink_proto *);
static unsigned char ipx_8022_type = 0xE0;
static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
-static char ipx_banner[] __initdata =
- KERN_INFO "NET4: Linux IPX 0.51 for NET4.0\n"
- KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \
- KERN_INFO "IPX Portions Copyright (c) 2000-2003 Conectiva, Inc.\n";
static char ipx_EII_err_msg[] __initdata =
KERN_CRIT "IPX: Unable to register with Ethernet II\n";
static char ipx_8023_err_msg[] __initdata =
@@ -1980,7 +1976,6 @@ static int __init ipx_init(void)
register_netdevice_notifier(&ipx_dev_notifier);
ipx_register_sysctl();
ipx_proc_init();
- printk(ipx_banner);
return 0;
}
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index fbb552adc243..fc71309e7e9b 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -435,11 +435,8 @@ EXPORT_SYMBOL(lapb_disconnect_request);
EXPORT_SYMBOL(lapb_data_request);
EXPORT_SYMBOL(lapb_data_received);
-static char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
-
static int __init lapb_init(void)
{
- printk(banner);
return 0;
}
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 5b011b872d94..ff2710542e4b 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -1042,15 +1042,10 @@ static struct proto_ops llc_ui_ops = {
.sendpage = sock_no_sendpage,
};
-static char llc_ui_banner[] __initdata =
- KERN_INFO "NET4.0 IEEE 802.2 BSD sockets, Jay Schulist, 2001, "
- "Arnaldo C. Melo, 2002-2003\n";
-
int __init llc_ui_init(void)
{
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
sock_register(&llc_ui_family_ops);
- printk(llc_ui_banner);
return 0;
}
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index 3ee7b0aa16ae..8f2fc4d7ec71 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -603,5 +603,5 @@ module_exit(llc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001-2003");
-MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support");
+MODULE_DESCRIPTION("LLC 2.0, IEEE 802.2 extended support");
MODULE_ALIAS_NETPROTO(PF_LLC);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 849b7a589ac0..c1323ddd5576 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines Corp.
* Copyright (c) 2001 Intel Corp.
* Copyright (c) 2001 La Monte H.P. Yarroll
*
@@ -42,6 +42,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ryan Layer <rmlayer@us.ibm.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -1155,3 +1156,23 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3,
asoc->ep->base.bind_addr.port, gfp);
}
+
+/* Lookup laddr in the bind address list of an association. */
+int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
+ const union sctp_addr *laddr)
+{
+ int found;
+
+ sctp_read_lock(&asoc->base.addr_lock);
+ if ((asoc->base.bind_addr.port == ntohs(laddr->v4.sin_port)) &&
+ sctp_bind_addr_match(&asoc->base.bind_addr, laddr,
+ sctp_sk(asoc->base.sk))) {
+ found = 1;
+ goto out;
+ }
+
+ found = 0;
+out:
+ sctp_read_unlock(&asoc->base.addr_lock);
+ return found;
+}
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 58d6a3bb7c3e..c2a288bcca39 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -1,7 +1,7 @@
/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
* Copyright (c) Cisco 1999,2000
* Copyright (c) Motorola 1999,2000,2001
- * Copyright (c) International Business Machines Corp., 2001,2002
* Copyright (c) La Monte H.P. Yarroll 2001
*
* This file is part of the SCTP kernel reference implementation.
@@ -223,6 +223,8 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
int len;
struct sctp_sockaddr_entry *addr;
struct list_head *pos;
+ struct sctp_af *af;
+
addrparms_len = 0;
len = 0;
@@ -247,7 +249,8 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
- len = sockaddr2sctp_addr(&addr->a, &rawaddr);
+ af = sctp_get_af_specific(addr->a.v4.sin_family);
+ len = af->to_addr_param(&addr->a, &rawaddr);
memcpy(addrparms.v, &rawaddr, len);
addrparms.v += len;
addrparms_len += len;
@@ -270,34 +273,31 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
union sctp_addr addr;
int retval = 0;
int len;
+ struct sctp_af *af;
/* Convert the raw address to standard address format */
while (addrs_len) {
param = (struct sctp_paramhdr *)raw_addr_list;
rawaddr = (union sctp_addr_param *)raw_addr_list;
- switch (param->type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- case SCTP_PARAM_IPV6_ADDRESS:
- sctp_param2sockaddr(&addr, rawaddr, port, 0);
- retval = sctp_add_bind_addr(bp, &addr, gfp);
- if (retval) {
- /* Can't finish building the list, clean up. */
- sctp_bind_addr_clean(bp);
- break;;
- }
- len = ntohs(param->length);
- addrs_len -= len;
- raw_addr_list += len;
- break;
- default:
- /* Corrupted raw addr list! */
+ af = sctp_get_af_specific(param_type2af(param->type));
+ if (unlikely(!af)) {
retval = -EINVAL;
sctp_bind_addr_clean(bp);
break;
}
- if (retval)
- break;
+
+ af->from_addr_param(&addr, rawaddr, port, 0);
+ retval = sctp_add_bind_addr(bp, &addr, gfp);
+ if (retval) {
+ /* Can't finish building the list, clean up. */
+ sctp_bind_addr_clean(bp);
+ break;;
+ }
+
+ len = ntohs(param->length);
+ addrs_len -= len;
+ raw_addr_list += len;
}
return retval;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 2c62c2171f6a..cc3e9314dd91 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -768,6 +768,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
union sctp_params params;
sctp_init_chunk_t *init;
struct sctp_transport *transport;
+ struct sctp_af *af;
ch = (sctp_chunkhdr_t *) skb->data;
@@ -802,11 +803,12 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
sctp_walk_params(params, init, init_hdr.params) {
/* Note: Ignoring hostname addresses. */
- if ((SCTP_PARAM_IPV4_ADDRESS != params.p->type) &&
- (SCTP_PARAM_IPV6_ADDRESS != params.p->type))
+ af = sctp_get_af_specific(param_type2af(params.p->type));
+ if (!af)
continue;
- sctp_param2sockaddr(paddr, params.addr, ntohs(sh->source), 0);
+ af->from_addr_param(paddr, params.addr, ntohs(sh->source), 0);
+
asoc = __sctp_lookup_association(laddr, paddr, &transport);
if (asoc)
return asoc;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 3bce456b895f..32ec1d5176ff 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -399,6 +399,33 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
}
}
+/* Initialize a sctp_addr from an address parameter. */
+static void sctp_v6_from_addr_param(union sctp_addr *addr,
+ union sctp_addr_param *param,
+ __u16 port, int iif)
+{
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = port;
+ addr->v6.sin6_flowinfo = 0; /* BUG */
+ ipv6_addr_copy(&addr->v6.sin6_addr, &param->v6.addr);
+ addr->v6.sin6_scope_id = iif;
+}
+
+/* Initialize an address parameter from a sctp_addr and return the length
+ * of the address parameter.
+ */
+static int sctp_v6_to_addr_param(const union sctp_addr *addr,
+ union sctp_addr_param *param)
+{
+ int length = sizeof(sctp_ipv6addr_param_t);
+
+ param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
+ param->v6.param_hdr.length = ntohs(length);
+ ipv6_addr_copy(&param->v6.addr, &addr->v6.sin6_addr);
+
+ return length;
+}
+
/* Initialize a sctp_addr from a dst_entry. */
static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
unsigned short port)
@@ -903,6 +930,8 @@ static struct sctp_af sctp_ipv6_specific = {
.from_sk = sctp_v6_from_sk,
.to_sk_saddr = sctp_v6_to_sk_saddr,
.to_sk_daddr = sctp_v6_to_sk_daddr,
+ .from_addr_param = sctp_v6_from_addr_param,
+ .to_addr_param = sctp_v6_to_addr_param,
.dst_saddr = sctp_v6_dst_saddr,
.cmp_addr = sctp_v6_cmp_addr,
.scope = sctp_v6_scope,
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index 243b1d5a8657..3a7ebfcc1fdb 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -39,6 +39,7 @@
* Narasimha Budihal <narasimha@refcode.org>
* Karl Knutson <karl@athena.chicago.il.us>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -203,3 +204,16 @@ DECLARE_PRIMITIVE(SEND);
*/
DECLARE_PRIMITIVE(REQUESTHEARTBEAT);
+
+/* ADDIP
+* 3.1.1 Address Configuration Change Chunk (ASCONF)
+*
+* This chunk is used to communicate to the remote endpoint one of the
+* configuration change requests that MUST be acknowledged. The
+* information carried in the ASCONF Chunk uses the form of a
+* Type-Length-Value (TLV), as described in "3.2.1 Optional/
+* Variable-length Parameter Format" in RFC2960 [5], forall variable
+* parameters.
+*/
+
+DECLARE_PRIMITIVE(ASCONF);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 727f237b1475..986460afaa6b 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -295,6 +295,31 @@ static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
inet_sk(sk)->daddr = addr->v4.sin_addr.s_addr;
}
+/* Initialize a sctp_addr from an address parameter. */
+static void sctp_v4_from_addr_param(union sctp_addr *addr,
+ union sctp_addr_param *param,
+ __u16 port, int iif)
+{
+ addr->v4.sin_family = AF_INET;
+ addr->v4.sin_port = port;
+ addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
+}
+
+/* Initialize an address parameter from a sctp_addr and return the length
+ * of the address parameter.
+ */
+static int sctp_v4_to_addr_param(const union sctp_addr *addr,
+ union sctp_addr_param *param)
+{
+ int length = sizeof(sctp_ipv4addr_param_t);
+
+ param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
+ param->v4.param_hdr.length = ntohs(length);
+ param->v4.addr.s_addr = addr->v4.sin_addr.s_addr;
+
+ return length;
+}
+
/* Initialize a sctp_addr from a dst_entry. */
static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst,
unsigned short port)
@@ -862,6 +887,8 @@ struct sctp_af sctp_ipv4_specific = {
.from_sk = sctp_v4_from_sk,
.to_sk_saddr = sctp_v4_to_sk_saddr,
.to_sk_daddr = sctp_v4_to_sk_daddr,
+ .from_addr_param= sctp_v4_from_addr_param,
+ .to_addr_param = sctp_v4_to_addr_param,
.dst_saddr = sctp_v4_dst_saddr,
.cmp_addr = sctp_v4_cmp_addr,
.addr_valid = sctp_v4_addr_valid,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index bf3f373d9feb..40a7a4f7116f 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1,8 +1,8 @@
/* SCTP kernel reference Implementation
+ * Copyright (C) IBM Corp. 2001, 2003
* Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2002 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
*
* This file is part of the SCTP kernel reference Implementation
*
@@ -48,6 +48,7 @@
* Sridhar Samudrala <sri@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -1213,6 +1214,7 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
struct sctp_association *asoc;
struct sk_buff *skb;
sctp_scope_t scope;
+ struct sctp_af *af;
/* Create the bare association. */
scope = sctp_scope(sctp_source(chunk));
@@ -1222,29 +1224,10 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
asoc->temp = 1;
skb = chunk->skb;
/* Create an entry for the source address of the packet. */
- /* FIXME: Use the af specific helpers. */
- switch (skb->nh.iph->version) {
- case 4:
- asoc->c.peer_addr.v4.sin_family = AF_INET;
- asoc->c.peer_addr.v4.sin_port = ntohs(chunk->sctp_hdr->source);
- asoc->c.peer_addr.v4.sin_addr.s_addr = skb->nh.iph->saddr;
- break;
-
- case 6:
- asoc->c.peer_addr.v6.sin6_family = AF_INET6;
- asoc->c.peer_addr.v6.sin6_port
- = ntohs(chunk->sctp_hdr->source);
- asoc->c.peer_addr.v6.sin6_flowinfo = 0; /* BUG BUG BUG */
- asoc->c.peer_addr.v6.sin6_addr = skb->nh.ipv6h->saddr;
- asoc->c.peer_addr.v6.sin6_scope_id =
- ((struct inet6_skb_parm *)skb->cb)->iif;
- break;
-
- default:
- /* Yikes! I never heard of this kind of address. */
+ af = sctp_get_af_specific(ipver2af(skb->nh.iph->version));
+ if (unlikely(!af))
goto fail;
- };
-
+ af->from_skb(&asoc->c.peer_addr, skb, 1);
nodata:
return asoc;
@@ -1830,11 +1813,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
* stream sequence number shall be set to 0.
*/
- /* Allocate storage for the negotiated streams. */
- asoc->ssnmap = sctp_ssnmap_new(asoc->peer.i.num_outbound_streams,
- asoc->c.sinit_num_ostreams, gfp);
- if (!asoc->ssnmap)
- goto nomem_ssnmap;
+ /* Allocate storage for the negotiated streams if it is not a temporary * association.
+ */
+ if (!asoc->temp) {
+ asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
+ asoc->c.sinit_num_ostreams, gfp);
+ if (!asoc->ssnmap)
+ goto nomem_ssnmap;
+ }
/* ADDIP Section 4.1 ASCONF Chunk Procedures
*
@@ -1882,6 +1868,7 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
int retval = 1;
sctp_scope_t scope;
time_t stale;
+ struct sctp_af *af;
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
@@ -1893,7 +1880,8 @@ int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
break;
/* Fall through. */
case SCTP_PARAM_IPV4_ADDRESS:
- sctp_param2sockaddr(&addr, param.addr, asoc->peer.port, 0);
+ af = sctp_get_af_specific(param_type2af(param.p->type));
+ af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
scope = sctp_scope(peer_addr);
if (sctp_in_scope(&addr, scope))
if (!sctp_assoc_add_peer(asoc, &addr, gfp))
@@ -2005,90 +1993,6 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
return retval;
}
-/********************************************************************
- * 4th Level Abstractions
- ********************************************************************/
-
-/* Convert from an SCTP IP parameter to a union sctp_addr. */
-void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *param,
- __u16 port, int iif)
-{
- switch(param->v4.param_hdr.type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- addr->v4.sin_family = AF_INET;
- addr->v4.sin_port = port;
- addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
- break;
-
- case SCTP_PARAM_IPV6_ADDRESS:
- addr->v6.sin6_family = AF_INET6;
- addr->v6.sin6_port = port;
- addr->v6.sin6_flowinfo = 0; /* BUG */
- addr->v6.sin6_addr = param->v6.addr;
- addr->v6.sin6_scope_id = iif;
- break;
-
- default:
- SCTP_DEBUG_PRINTK("Illegal address type %d\n",
- ntohs(param->v4.param_hdr.type));
- break;
- };
-}
-
-/* Convert an IP address in an SCTP param into a sockaddr_in. */
-/* Returns true if a valid conversion was possible. */
-int sctp_addr2sockaddr(union sctp_params p, union sctp_addr *sa)
-{
- switch (p.p->type) {
- case SCTP_PARAM_IPV4_ADDRESS:
- sa->v4.sin_addr = *((struct in_addr *)&p.v4->addr);
- sa->v4.sin_family = AF_INET;
- break;
-
- case SCTP_PARAM_IPV6_ADDRESS:
- *((struct in6_addr *)&sa->v4.sin_addr)
- = p.v6->addr;
- sa->v4.sin_family = AF_INET6;
- break;
-
- default:
- return 0;
- };
-
- return 1;
-}
-
-/* Convert a sockaddr_in to an IP address in an SCTP param.
- * Returns len if a valid conversion was possible.
- */
-int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p)
-{
- int len = 0;
-
- switch (sa->v4.sin_family) {
- case AF_INET:
- p->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
- p->v4.param_hdr.length = ntohs(sizeof(sctp_ipv4addr_param_t));
- len = sizeof(sctp_ipv4addr_param_t);
- p->v4.addr.s_addr = sa->v4.sin_addr.s_addr;
- break;
-
- case AF_INET6:
- p->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
- p->v6.param_hdr.length = ntohs(sizeof(sctp_ipv6addr_param_t));
- len = sizeof(sctp_ipv6addr_param_t);
- p->v6.addr = *(&sa->v6.sin6_addr);
- break;
-
- default:
- printk(KERN_WARNING "sockaddr2sctp_addr: Illegal family %d.\n",
- sa->v4.sin_family);
- return 0;
- };
-
- return len;
-}
-
/*
* ADDIP 3.1.1 Address Configuration Change Chunk (ASCONF)
* 0 1 2 3
@@ -2119,8 +2023,9 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
int length = sizeof(asconf) + vparam_len;
union sctp_params addrparam;
int addrlen;
+ struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
- addrlen = sockaddr2sctp_addr(addr, (union sctp_addr_param *)&addrparam);
+ addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
if (!addrlen)
return NULL;
length += addrlen;
@@ -2135,7 +2040,51 @@ struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
retval->subh.addip_hdr =
sctp_addto_chunk(retval, sizeof(asconf), &asconf);
retval->param_hdr.v =
- sctp_addto_chunk(retval, addrlen, &addr);
+ sctp_addto_chunk(retval, addrlen, &addrparam);
+
+ return retval;
+}
+
+/* ADDIP
+ * 3.2.4 Set Primary IP Address
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type =0xC004 | Length = Variable |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ASCONF-Request Correlation ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Address Parameter |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Create an ASCONF chunk with Set Primary IP address parameter.
+ */
+struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
+ union sctp_addr *addr)
+{
+ sctp_addip_param_t param;
+ struct sctp_chunk *retval;
+ int len = sizeof(param);
+ union sctp_params addrparam;
+ int addrlen;
+ struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
+
+ addrlen = af->to_addr_param(addr, (union sctp_addr_param *)&addrparam);
+ if (!addrlen)
+ return NULL;
+ len += addrlen;
+
+ /* Create the chunk and make asconf header. */
+ retval = sctp_make_asconf(asoc, addr, len);
+ if (!retval)
+ return NULL;
+
+ param.param_hdr.type = SCTP_PARAM_SET_PRIMARY;
+ param.param_hdr.length = htons(len);
+ param.crr_id = 0;
+
+ sctp_addto_chunk(retval, sizeof(param), &param);
+ sctp_addto_chunk(retval, addrlen, &addrparam);
return retval;
}
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 531ff1606429..86208c51ba36 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -929,6 +929,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
struct sctp_errhdr *errhdr;
struct sctp_endpoint *ep;
char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
+ struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
/* Build the error on the stack. We are way to malloc crazy
* throughout the code today.
@@ -937,7 +938,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
addrparm = (union sctp_addr_param *)errhdr->variable;
/* Copy into a parm format. */
- len = sockaddr2sctp_addr(ssa, addrparm);
+ len = af->to_addr_param(ssa, addrparm);
len += sizeof(sctp_errhdr_t);
errhdr->cause = SCTP_ERROR_RESTART;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 722ddbc57c09..a7db6e38441a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1,6 +1,7 @@
-/* Copyright (c) 1999-2000 Cisco, Inc.
+/* SCTP kernel reference Implementation
+ * (C) Copyright IBM Corp. 2001, 2003
+ * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001-2003 Intel Corp.
* Copyright (c) 2001-2002 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
@@ -50,6 +51,7 @@
* Ardelle Fan <ardelle.fan@intel.com>
* Ryan Layer <rmlayer@us.ibm.com>
* Anup Pemmaiah <pemmaiah@cc.usu.edu>
+ * Kevin Gao <kevin.gao@intel.com>
*
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
@@ -93,8 +95,8 @@ static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p);
static int sctp_wait_for_accept(struct sock *sk, long timeo);
static void sctp_wait_for_close(struct sock *sk, long timeo);
static inline int sctp_verify_addr(struct sock *, union sctp_addr *, int);
-static int sctp_bindx_add(struct sock *, struct sockaddr_storage *, int);
-static int sctp_bindx_rem(struct sock *, struct sockaddr_storage *, int);
+static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
+static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
static int sctp_do_bind(struct sock *, union sctp_addr *, int);
static int sctp_autobind(struct sock *sk);
static void sctp_sock_migrate(struct sock *, struct sock *,
@@ -170,10 +172,7 @@ struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
* sd - the socket descriptor returned by socket().
* addr - the address structure (struct sockaddr_in or struct
* sockaddr_in6 [RFC 2553]),
- * addrlen - the size of the address structure.
- *
- * The caller should use struct sockaddr_storage described in RFC 2553
- * to represent addr for portability reason.
+ * addr_len - the size of the address structure.
*/
int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
@@ -298,112 +297,6 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
return ret;
}
-/* API 8.1 sctp_bindx()
- *
- * The syntax of sctp_bindx() is,
- *
- * ret = sctp_bindx(int sd,
- * struct sockaddr_storage *addrs,
- * int addrcnt,
- * int flags);
- *
- * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
- * If the sd is an IPv6 socket, the addresses passed can either be IPv4
- * or IPv6 addresses.
- *
- * A single address may be specified as INADDR_ANY or IPV6_ADDR_ANY, see
- * section 3.1.2 for this usage.
- *
- * addrs is a pointer to an array of one or more socket addresses. Each
- * address is contained in a struct sockaddr_storage, so each address is
- * fixed length. The caller specifies the number of addresses in the
- * array with addrcnt.
- *
- * On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns -1,
- * and sets errno to the appropriate error code. [ Editor's note: need
- * to fill in all error code? ]
- *
- * For SCTP, the port given in each socket address must be the same, or
- * sctp_bindx() will fail, setting errno to EINVAL .
- *
- * The flags parameter is formed from the bitwise OR of zero or
- * more of the following currently defined flags:
- *
- * SCTP_BINDX_ADD_ADDR
- * SCTP_BINDX_REM_ADDR
- *
- * SCTP_BIND_ADD_ADDR directs SCTP to add the given addresses to the
- * association, and SCTP_BIND_REM_ADDR directs SCTP to remove the given
- * addresses from the association. The two flags are mutually exclusive;
- * if both are given, sctp_bindx() will fail with EINVAL. A caller may not
- * remove all addresses from an association; sctp_bindx() will reject such
- * an attempt with EINVAL.
- *
- * An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
- * additional addresses with an endpoint after calling bind(). Or use
- * sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening
- * socket is associated with so that no new association accepted will be
- * associated with those addresses.
- *
- * SCTP_BIND_ADD_ADDR is defined as 0, so that it becomes the default
- * behavior for sctp_bindx() when no flags are given.
- *
- * Adding and removing addresses from a connected association is optional
- * functionality. Implementations that do not support this functionality
- * should return EOPNOTSUPP.
- *
- * NOTE: This could be integrated into sctp_setsockopt_bindx(),
- * but keeping it this way makes it easier if sometime sys_bindx is
- * added.
- */
-
-/* Unprotected by locks. Call only with socket lock sk->sk_lock held! See
- * sctp_bindx() for a lock-protected call.
- */
-
-static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
- int addrcnt, int flags)
-{
- int retval = 0;
-
- SCTP_DEBUG_PRINTK("__sctp_bindx(sk: %p, addrs: %p, addrcnt: %d, "
- "flags: %s)\n", sk, addrs, addrcnt,
- (SCTP_BINDX_ADD_ADDR == flags) ? "ADD" :
- ((SCTP_BINDX_REM_ADDR == flags) ? "REM" : "BOGUS"));
-
- switch (flags) {
- case SCTP_BINDX_ADD_ADDR:
- retval = sctp_bindx_add(sk, addrs, addrcnt);
- break;
-
- case SCTP_BINDX_REM_ADDR:
- retval = sctp_bindx_rem(sk, addrs, addrcnt);
- break;
-
- default:
- retval = -EINVAL;
- break;
- };
-
- return retval;
-}
-
-/* BINDX with locks.
- *
- * NOTE: Currently unused at all ...
- */
-int sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt,
- int flags)
-{
- int retval;
-
- sctp_lock_sock(sk);
- retval = __sctp_bindx(sk, addrs, addrcnt, flags);
- sctp_release_sock(sk);
-
- return retval;
-}
-
/* Add a list of addresses as bind addresses to local endpoint or
* association.
*
@@ -414,41 +307,39 @@ int sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt,
* If any of them fails, then the operation will be reversed and the
* ones that were added will be removed.
*
- * Only __sctp_bindx() is supposed to call this function.
+ * Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-int sctp_bindx_add(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
+int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt)
{
int cnt;
int retval = 0;
- int addr_len;
+ void *addr_buf;
+ struct sockaddr *sa_addr;
+ struct sctp_af *af;
SCTP_DEBUG_PRINTK("sctp_bindx_add (sk: %p, addrs: %p, addrcnt: %d)\n",
sk, addrs, addrcnt);
+ addr_buf = addrs;
for (cnt = 0; cnt < addrcnt; cnt++) {
/* The list may contain either IPv4 or IPv6 address;
* determine the address length for walking thru the list.
*/
- switch (((struct sockaddr *)&addrs[cnt])->sa_family) {
- case AF_INET:
- addr_len = sizeof(struct sockaddr_in);
- break;
-
- case AF_INET6:
- addr_len = sizeof(struct sockaddr_in6);
- break;
-
- default:
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+ if (!af) {
retval = -EINVAL;
goto err_bindx_add;
- };
+ }
- retval = sctp_do_bind(sk, (union sctp_addr *)&addrs[cnt],
- addr_len);
+ retval = sctp_do_bind(sk, (union sctp_addr *)sa_addr,
+ af->sockaddr_len);
+
+ addr_buf += af->sockaddr_len;
err_bindx_add:
if (retval < 0) {
- /* Failed. Cleanup the ones that has been added */
+ /* Failed. Cleanup the ones that have been added */
if (cnt > 0)
sctp_bindx_rem(sk, addrs, cnt);
return retval;
@@ -471,9 +362,9 @@ err_bindx_add:
* At least one address has to be left; if only one address is
* available, the operation will return -EBUSY.
*
- * Only __sctp_bindx() is supposed to call this function.
+ * Only sctp_setsockopt_bindx() is supposed to call this function.
*/
-int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
+int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
{
struct sctp_opt *sp = sctp_sk(sk);
struct sctp_endpoint *ep = sp->ep;
@@ -481,50 +372,41 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
struct sctp_bind_addr *bp = &ep->base.bind_addr;
int retval = 0;
union sctp_addr saveaddr;
+ void *addr_buf;
+ struct sockaddr *sa_addr;
+ struct sctp_af *af;
SCTP_DEBUG_PRINTK("sctp_bindx_rem (sk: %p, addrs: %p, addrcnt: %d)\n",
sk, addrs, addrcnt);
+ addr_buf = addrs;
for (cnt = 0; cnt < addrcnt; cnt++) {
- /* If there is only one bind address, there is nothing more
- * to be removed (we need at least one address here).
+ /* If the bind address list is empty or if there is only one
+ * bind address, there is nothing more to be removed (we need
+ * at least one address here).
*/
- if (list_empty(&bp->address_list)) {
+ if (list_empty(&bp->address_list) ||
+ (sctp_list_single_entry(&bp->address_list))) {
retval = -EBUSY;
goto err_bindx_rem;
}
/* The list may contain either IPv4 or IPv6 address;
- * determine the address length for walking thru the list.
+ * determine the address length to copy the address to
+ * saveaddr.
*/
- switch (((struct sockaddr *)&addrs[cnt])->sa_family) {
- case AF_INET:
- saveaddr = *((union sctp_addr *)
- &addrs[cnt]);
- saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
- /* Verify the port. */
- if (saveaddr.v4.sin_port != bp->port) {
- retval = -EINVAL;
- goto err_bindx_rem;
- }
- break;
-
- case AF_INET6:
- saveaddr = *((union sctp_addr *)
- &addrs[cnt]);
- saveaddr.v6.sin6_port =
- ntohs(saveaddr.v6.sin6_port);
- /* verify the port */
- if (saveaddr.v6.sin6_port != bp->port) {
- retval = -EINVAL;
- goto err_bindx_rem;
- }
- break;
-
- default:
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+ if (!af) {
retval = -EINVAL;
goto err_bindx_rem;
- };
+ }
+ memcpy(&saveaddr, sa_addr, af->sockaddr_len);
+ saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
+ if (saveaddr.v4.sin_port != bp->port) {
+ retval = -EINVAL;
+ goto err_bindx_rem;
+ }
/* FIXME - There is probably a need to check if sk->sk_saddr and
* sk->sk_rcv_addr are currently set to one of the addresses to
@@ -541,6 +423,7 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr_storage *addrs, int addrcnt)
sctp_write_unlock(&ep->base.addr_lock);
sctp_local_bh_enable();
+ addr_buf += af->sockaddr_len;
err_bindx_rem:
if (retval < 0) {
/* Failed. Add the ones that has been removed back */
@@ -553,18 +436,62 @@ err_bindx_rem:
return retval;
}
-/* Helper for tunneling sys_bindx() requests through sctp_setsockopt()
+/* Helper for tunneling sctp_bindx() requests through sctp_setsockopt()
+ *
+ * API 8.1
+ * int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt,
+ * int flags);
+ *
+ * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+ * If the sd is an IPv6 socket, the addresses passed can either be IPv4
+ * or IPv6 addresses.
+ *
+ * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
+ * Section 3.1.2 for this usage.
+ *
+ * addrs is a pointer to an array of one or more socket addresses. Each
+ * address is contained in its appropriate structure (i.e. struct
+ * sockaddr_in or struct sockaddr_in6) the family of the address type
+ * must be used to distengish the address length (note that this
+ * representation is termed a "packed array" of addresses). The caller
+ * specifies the number of addresses in the array with addrcnt.
+ *
+ * On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns
+ * -1, and sets errno to the appropriate error code.
+ *
+ * For SCTP, the port given in each socket address must be the same, or
+ * sctp_bindx() will fail, setting errno to EINVAL.
+ *
+ * The flags parameter is formed from the bitwise OR of zero or more of
+ * the following currently defined flags:
+ *
+ * SCTP_BINDX_ADD_ADDR
+ *
+ * SCTP_BINDX_REM_ADDR
+ *
+ * SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the
+ * association, and SCTP_BINDX_REM_ADDR directs SCTP to remove the given
+ * addresses from the association. The two flags are mutually exclusive;
+ * if both are given, sctp_bindx() will fail with EINVAL. A caller may
+ * not remove all addresses from an association; sctp_bindx() will
+ * reject such an attempt with EINVAL.
+ *
+ * An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate
+ * additional addresses with an endpoint after calling bind(). Or use
+ * sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening
+ * socket is associated with so that no new association accepted will be
+ * associated with those addresses. If the endpoint supports dynamic
+ * address a SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause a
+ * endpoint to send the appropriate message to the peer to change the
+ * peers address lists.
+ *
+ * Adding and removing addresses from a connected association is
+ * optional functionality. Implementations that do not support this
+ * functionality should return EOPNOTSUPP.
*
* Basically do nothing but copying the addresses from user to kernel
- * land and invoking sctp_bindx on the sk. This is used for tunneling
- * the sctp_bindx() [sys_bindx()] request through sctp_setsockopt()
- * from userspace.
- *
- * Note I don't use move_addr_to_kernel(): the reason is we would be
- * iterating over an array of struct sockaddr_storage passing always
- * what we know is a good size (sizeof (struct sock...)), so it is
- * pointless. Instead check the whole area for read access and copy
- * it.
+ * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
+ * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace.
*
* We don't use copy_from_user() for optimization: we first do the
* sanity checks (buffer size -fast- and access check-healthy
@@ -584,38 +511,70 @@ err_bindx_rem:
*
* Returns 0 if ok, <0 errno code on error.
*/
-SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
- struct sockaddr_storage *addrs,
- int addrssize, int op)
+SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, struct sockaddr *addrs,
+ int addrs_size, int op)
{
- struct sockaddr_storage *kaddrs;
+ struct sockaddr *kaddrs;
int err;
- size_t addrcnt;
+ int addrcnt = 0;
+ int walk_size = 0;
+ struct sockaddr *sa_addr;
+ void *addr_buf;
+ struct sctp_af *af;
- SCTP_DEBUG_PRINTK("sctp_do_setsocktopt_bindx: sk %p addrs %p"
- " addrssize %d opt %d\n", sk, addrs, addrssize, op);
+ SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p"
+ " addrs_size %d opt %d\n", sk, addrs, addrs_size, op);
- /* Do we have an integer number of structs sockaddr_storage? */
- if (unlikely(addrssize <= 0 ||
- addrssize % sizeof(struct sockaddr_storage) != 0))
+ if (unlikely(addrs_size <= 0))
return -EINVAL;
/* Check the user passed a healthy pointer. */
- if (unlikely(!access_ok(VERIFY_READ, addrs, addrssize)))
+ if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
return -EFAULT;
/* Alloc space for the address array in kernel memory. */
- kaddrs = (struct sockaddr_storage *) kmalloc(addrssize, GFP_KERNEL);
+ kaddrs = (struct sockaddr *)kmalloc(addrs_size, GFP_KERNEL);
if (unlikely(!kaddrs))
return -ENOMEM;
- if (copy_from_user(kaddrs, addrs, addrssize)) {
+ if (__copy_from_user(kaddrs, addrs, addrs_size)) {
kfree(kaddrs);
return -EFAULT;
}
- addrcnt = addrssize / sizeof(struct sockaddr_storage);
- err = __sctp_bindx(sk, kaddrs, addrcnt, op); /* Do the work. */
+ /* Walk through the addrs buffer and count the number of addresses. */
+ addr_buf = kaddrs;
+ while (walk_size < addrs_size) {
+ sa_addr = (struct sockaddr *)addr_buf;
+ af = sctp_get_af_specific(sa_addr->sa_family);
+
+ /* If the address family is not supported or if this address
+ * causes the address buffer to overflow return EINVAL.
+ */
+ if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
+ kfree(kaddrs);
+ return -EINVAL;
+ }
+ addrcnt++;
+ addr_buf += af->sockaddr_len;
+ walk_size += af->sockaddr_len;
+ }
+
+ /* Do the work. */
+ switch (op) {
+ case SCTP_BINDX_ADD_ADDR:
+ err = sctp_bindx_add(sk, kaddrs, addrcnt);
+ break;
+
+ case SCTP_BINDX_REM_ADDR:
+ err = sctp_bindx_rem(sk, kaddrs, addrcnt);
+ break;
+
+ default:
+ err = -EINVAL;
+ break;
+ };
+
kfree(kaddrs);
return err;
@@ -1476,7 +1435,7 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char *optval, int optlen)
}
/*
- * 7.1.14 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
*
* Applications that wish to use the sendto() system call may wish to
* specify a default set of parameters that would normally be supplied
@@ -1522,7 +1481,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
return 0;
}
-/* 7.1.10 Set Peer Primary Address (SCTP_PRIMARY_ADDR)
+/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
*
* Requests that the local SCTP stack use the enclosed peer address as
* the association primary. The enclosed address must be one of the
@@ -1727,6 +1686,62 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char *optval, int optlen)
return 0;
}
+
+/*
+ * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR)
+ *
+ * Requests that the peer mark the enclosed address as the association
+ * primary. The enclosed address must be one of the association's
+ * locally bound addresses. The following structure is used to make a
+ * set primary request:
+ */
+static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char *optval,
+ int optlen)
+{
+ struct sctp_opt *sp;
+ struct sctp_endpoint *ep;
+ struct sctp_association *asoc = NULL;
+ struct sctp_setpeerprim prim;
+ struct sctp_chunk *chunk;
+ int err;
+
+ sp = sctp_sk(sk);
+ ep = sp->ep;
+
+ if (optlen != sizeof(struct sctp_setpeerprim))
+ return -EINVAL;
+
+ if (copy_from_user(&prim, optval, optlen))
+ return -EFAULT;
+
+ asoc = sctp_id2assoc(sk, prim.sspp_assoc_id);
+ if (!asoc)
+ return -EINVAL;
+
+ if (!sctp_state(asoc, ESTABLISHED))
+ return -ENOTCONN;
+
+ if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
+ return -EADDRNOTAVAIL;
+
+ /* Create an ASCONF chunk with SET_PRIMARY parameter */
+ chunk = sctp_make_asconf_set_prim(asoc,
+ (union sctp_addr *)&prim.sspp_addr);
+ if (!chunk)
+ return -ENOMEM;
+
+ err = sctp_primitive_ASCONF(asoc, chunk);
+ if (err) {
+ sctp_chunk_free(chunk);
+ return err;
+ }
+
+ SCTP_DEBUG_PRINTK("We set peer primary addr primitively.\n");
+
+ return 0;
+}
+
+
/* API 6.2 setsockopt(), getsockopt()
*
* Applications use setsockopt() and getsockopt() to set or retrieve
@@ -1771,16 +1786,14 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
switch (optname) {
case SCTP_SOCKOPT_BINDX_ADD:
/* 'optlen' is the size of the addresses buffer. */
- retval = sctp_setsockopt_bindx(sk, (struct sockaddr_storage *)
- optval, optlen,
- SCTP_BINDX_ADD_ADDR);
+ retval = sctp_setsockopt_bindx(sk, (struct sockaddr *)optval,
+ optlen, SCTP_BINDX_ADD_ADDR);
break;
case SCTP_SOCKOPT_BINDX_REM:
/* 'optlen' is the size of the addresses buffer. */
- retval = sctp_setsockopt_bindx(sk, (struct sockaddr_storage *)
- optval, optlen,
- SCTP_BINDX_REM_ADDR);
+ retval = sctp_setsockopt_bindx(sk, (struct sockaddr *)optval,
+ optlen, SCTP_BINDX_REM_ADDR);
break;
case SCTP_DISABLE_FRAGMENTS:
@@ -1809,6 +1822,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
case SCTP_PRIMARY_ADDR:
retval = sctp_setsockopt_primary_addr(sk, optval, optlen);
break;
+ case SCTP_SET_PEER_PRIMARY_ADDR:
+ retval = sctp_setsockopt_peer_primary_addr(sk, optval, optlen);
+ break;
case SCTP_NODELAY:
retval = sctp_setsockopt_nodelay(sk, optval, optlen);
break;
@@ -2056,9 +2072,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
return -ESOCKTNOSUPPORT;
}
- /* FIXME: The next draft (04) of the SCTP Sockets Extensions
- * should include a socket option for manipulating these
- * message parameters (and a few others).
+ /* Initialize default send parameters. These parameters can be
+ * modified with the SCTP_DEFAULT_SEND_PARAM socket option.
*/
sp->default_stream = 0;
sp->default_ppid = 0;
@@ -2077,7 +2092,6 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
/* Initialize default RTO related parameters. These parameters can
* be modified for with the SCTP_RTOINFO socket option.
- * FIXME: These are not used yet.
*/
sp->rtoinfo.srto_initial = (sctp_rto_initial / HZ) * 1000;
sp->rtoinfo.srto_max = (sctp_rto_max / HZ) * 1000;
@@ -2093,15 +2107,10 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
sp->assocparams.sasoc_cookie_life = (sctp_valid_cookie_life / HZ)
* 1000;
- /* Initialize default event subscriptions.
- * the struct sock is initialized to zero, so only
- * enable the events needed. By default, UDP-style
- * sockets enable io and association change notifications.
+ /* Initialize default event subscriptions. By default, all the
+ * options are off.
*/
- if (sctp_style(sk, UDP)) {
- sp->subscribe.sctp_data_io_event = 1;
- sp->subscribe.sctp_association_event = 1;
- }
+ memset(&sp->subscribe, 0, sizeof(struct sctp_event_subscribe));
/* Default Peer Address Parameters. These defaults can
* be modified via SCTP_PEER_ADDR_PARAMS
@@ -2552,7 +2561,7 @@ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char *optval, int *
}
static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
sctp_assoc_t id;
struct sctp_association *asoc;
@@ -2565,9 +2574,7 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
if (copy_from_user(&id, optval, sizeof(sctp_assoc_t)))
return -EFAULT;
- /*
- * For UDP-style sockets, id specifies the association to query.
- */
+ /* For UDP-style sockets, id specifies the association to query. */
asoc = sctp_id2assoc(sk, id);
if (!asoc)
return -EINVAL;
@@ -2582,16 +2589,17 @@ static int sctp_getsockopt_peer_addrs_num(struct sock *sk, int len,
}
static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
- char *optval, int *optlen)
+ char *optval, int *optlen)
{
struct sctp_association *asoc;
struct list_head *pos;
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_transport *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2600,21 +2608,21 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
return -EFAULT;
if (getaddrs.addr_num <= 0) return -EINVAL;
- /*
- * For UDP-style sockets, id specifies the association to query.
- */
+
+ /* For UDP-style sockets, id specifies the association to query. */
asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
if (!asoc)
return -EINVAL;
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &asoc->peer.transport_addr_list) {
from = list_entry(pos, struct sctp_transport, transports);
memcpy(&temp, &from->ipaddr, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
- if (copy_to_user(to, &temp, sizeof(temp)))
+ addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+ if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
- to ++;
+ to += addrlen ;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
@@ -2673,9 +2681,10 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
int cnt = 0;
struct sctp_getaddrs getaddrs;
struct sctp_sockaddr_entry *from;
- struct sockaddr_storage *to;
+ void *to;
union sctp_addr temp;
struct sctp_opt *sp = sctp_sk(sk);
+ int addrlen;
if (len != sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -2699,16 +2708,17 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
bp = &asoc->base.bind_addr;
}
- to = getaddrs.addrs;
+ to = (void *)getaddrs.addrs;
list_for_each(pos, &bp->address_list) {
from = list_entry(pos,
struct sctp_sockaddr_entry,
list);
memcpy(&temp, &from->a, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
- if (copy_to_user(to, &temp, sizeof(temp)))
+ addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+ if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
- to ++;
+ to += addrlen;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
}
@@ -2759,7 +2769,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
/*
*
- * 7.1.14 Set default send parameters (SET_DEFAULT_SEND_PARAM)
+ * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM)
*
* Applications that wish to use the sendto() system call may wish to
* specify a default set of parameters that would normally be supplied
@@ -3331,9 +3341,19 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
if (!sctp_style(sk, UDP))
return -EINVAL;
+ /* If backlog is zero, disable listening. */
+ if (!backlog) {
+ if (sctp_sstate(sk, CLOSED))
+ return 0;
+
+ sctp_unhash_endpoint(ep);
+ sk->sk_state = SCTP_SS_CLOSED;
+ }
+
+ /* Return if we are already listening. */
if (sctp_sstate(sk, LISTENING))
return 0;
-
+
/*
* If a bind() or sctp_bindx() is not called prior to a listen()
* call that allows new associations to be accepted, the system
@@ -3364,6 +3384,15 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
struct sctp_opt *sp = sctp_sk(sk);
struct sctp_endpoint *ep = sp->ep;
+ /* If backlog is zero, disable listening. */
+ if (!backlog) {
+ if (sctp_sstate(sk, CLOSED))
+ return 0;
+
+ sctp_unhash_endpoint(ep);
+ sk->sk_state = SCTP_SS_CLOSED;
+ }
+
if (sctp_sstate(sk, LISTENING))
return 0;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index cdcf6d09d24f..edffe9cc8f21 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -214,7 +214,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (olen != sizeof (int))
return -EINVAL;
}
- if (put_user((*(int *)(table->data) / HZ) * 1000,
+ if (put_user((*(int *)(table->data) * 1000) / HZ,
(int *)oldval) ||
(oldlenp && put_user(sizeof (int), oldlenp)))
return -EFAULT;
@@ -228,7 +228,7 @@ static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen,
if (get_user(new, (int *)newval))
return -EFAULT;
- *(int *)(table->data) = (new * HZ) * 1000;
+ *(int *)(table->data) = (new * HZ) / 1000;
}
return 1;
}
diff --git a/net/socket.c b/net/socket.c
index 74fd11fdd7a8..f0a1a3da7500 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1894,6 +1894,8 @@ int sock_register(struct net_proto_family *ops)
err = 0;
}
net_family_write_unlock();
+ printk(KERN_INFO "NET: Registered protocol family %d\n",
+ ops->family);
return err;
}
@@ -1911,6 +1913,8 @@ int sock_unregister(int family)
net_family_write_lock();
net_families[family]=NULL;
net_family_write_unlock();
+ printk(KERN_INFO "NET: Unregistered protocol family %d\n",
+ family);
return 0;
}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d9dd8a2f3914..61ea1a9f2a2b 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -57,7 +57,7 @@
* [TO FIX]
* ECONNREFUSED is not returned from one end of a connected() socket to the
* other the moment one end closes.
- * fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark
+ * fstat() doesn't return st_dev=0, and give the blksize as high water mark
* and a fake inode identifier (nor the BSD first socket fstat twice bug).
* [NOT TO FIX]
* accept() returns a path name even if the connecting socket has closed
@@ -111,6 +111,7 @@
#include <linux/tcp.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
@@ -1805,25 +1806,52 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
#ifdef CONFIG_PROC_FS
-static int unix_read_proc(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
+static struct sock *unix_seq_idx(int *iter, loff_t pos)
{
- off_t pos=0;
- off_t begin=0;
- int len=0;
- int i;
+ loff_t off = 0;
struct sock *s;
-
- len+= sprintf(buffer,"Num RefCount Protocol Flags Type St "
- "Inode Path\n");
+ for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
+ if (off == pos)
+ return s;
+ ++off;
+ }
+ return NULL;
+}
+
+
+static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
+{
read_lock(&unix_table_lock);
- forall_unix_sockets (i,s)
- {
+ return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
+}
+
+static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ ++*pos;
+
+ if (v == (void *)1)
+ return first_unix_socket(seq->private);
+ return next_unix_socket(seq->private, v);
+}
+
+static void unix_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock(&unix_table_lock);
+}
+
+static int unix_seq_show(struct seq_file *seq, void *v)
+{
+
+ if (v == (void *)1)
+ seq_puts(seq, "Num RefCount Protocol Flags Type St "
+ "Inode Path\n");
+ else {
+ struct sock *s = v;
struct unix_sock *u = unix_sk(s);
unix_state_rlock(s);
- len+=sprintf(buffer+len,"%p: %08X %08X %08X %04X %02X %5lu",
+ seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
s,
atomic_read(&s->sk_refcnt),
0,
@@ -1835,39 +1863,61 @@ static int unix_read_proc(char *buffer, char **start, off_t offset,
sock_i_ino(s));
if (u->addr) {
- buffer[len++] = ' ';
- memcpy(buffer+len, u->addr->name->sun_path,
- u->addr->len-sizeof(short));
- if (!UNIX_ABSTRACT(s))
- len--;
- else
- buffer[len] = '@';
- len += u->addr->len - sizeof(short);
- }
- unix_state_runlock(s);
+ int i;
+ seq_putc(seq, ' ');
+
+ for (i = 0; i < u->addr->len-sizeof(short); i++)
+ seq_putc(seq, u->addr->name->sun_path[i]);
- buffer[len++]='\n';
-
- pos = begin + len;
- if(pos<offset)
- {
- len=0;
- begin=pos;
+ if (UNIX_ABSTRACT(s))
+ seq_putc(seq, '@');
}
- if(pos>offset+length)
- goto done;
+ unix_state_runlock(s);
+ seq_putc(seq, '\n');
}
- *eof = 1;
-done:
- read_unlock(&unix_table_lock);
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- if (len < 0)
- len = 0;
- return len;
+
+ return 0;
}
+
+struct seq_operations unix_seq_ops = {
+ .start = unix_seq_start,
+ .next = unix_seq_next,
+ .stop = unix_seq_stop,
+ .show = unix_seq_show,
+};
+
+
+static int unix_seq_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int rc = -ENOMEM;
+ int *iter = kmalloc(sizeof(int), GFP_KERNEL);
+
+ if (!iter)
+ goto out;
+
+ rc = seq_open(file, &unix_seq_ops);
+ if (rc)
+ goto out_kfree;
+
+ seq = file->private_data;
+ seq->private = iter;
+ *iter = 0;
+out:
+ return rc;
+out_kfree:
+ kfree(iter);
+ goto out;
+}
+
+static struct file_operations unix_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = unix_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_private,
+};
+
#endif
struct proto_ops unix_stream_ops = {
@@ -1926,13 +1976,10 @@ static inline void unix_sysctl_register(void) {}
static inline void unix_sysctl_unregister(void) {}
#endif
-static char banner[] __initdata = KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n";
-
static int __init af_unix_init(void)
{
struct sk_buff *dummy_skb;
- printk(banner);
if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
return -1;
@@ -1947,7 +1994,7 @@ static int __init af_unix_init(void)
sock_register(&unix_family_ops);
#ifdef CONFIG_PROC_FS
- create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL);
+ proc_net_fops_create("unix", 0, &unix_seq_fops);
#endif
unix_sysctl_register();
return 0;
@@ -1957,7 +2004,7 @@ static void __exit af_unix_exit(void)
{
sock_unregister(PF_UNIX);
unix_sysctl_unregister();
- remove_proc_entry("net/unix", 0);
+ proc_net_remove("unix");
kmem_cache_destroy(unix_sk_cachep);
}