aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/filesystems/ext4.txt20
-rw-r--r--Documentation/filesystems/proc.txt39
-rw-r--r--Documentation/kbuild/kconfig-language.txt111
-rw-r--r--Documentation/mips/00-INDEX2
-rw-r--r--Documentation/mips/GT64120.README65
-rw-r--r--Makefile28
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S8
-rw-r--r--arch/alpha/lib/dec_and_lock.c3
-rw-r--r--arch/arm/kernel/vmlinux.lds.S10
-rw-r--r--arch/arm/mach-imx/Makefile3
-rw-r--r--arch/arm/mach-netx/Makefile3
-rw-r--r--arch/avr32/kernel/vmlinux.lds.S8
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S8
-rw-r--r--arch/cris/arch-v10/vmlinux.lds.S8
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile2
-rw-r--r--arch/cris/arch-v32/vmlinux.lds.S8
-rw-r--r--arch/frv/boot/Makefile8
-rw-r--r--arch/frv/kernel/gdb-stub.c2
-rw-r--r--arch/frv/kernel/vmlinux.lds.S14
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S8
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S8
-rw-r--r--arch/m32r/kernel/vmlinux.lds.S12
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds8
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds8
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/Kconfig181
-rw-r--r--arch/mips/Makefile40
-rw-r--r--arch/mips/au1000/common/au1xxx_irqmap.c21
-rw-r--r--arch/mips/au1000/common/dbdma.c2
-rw-r--r--arch/mips/au1000/db1x00/init.c11
-rw-r--r--arch/mips/au1000/mtx-1/init.c2
-rw-r--r--arch/mips/au1000/mtx-1/platform.c27
-rw-r--r--arch/mips/au1000/pb1000/init.c2
-rw-r--r--arch/mips/au1000/pb1100/init.c2
-rw-r--r--arch/mips/au1000/pb1200/init.c2
-rw-r--r--arch/mips/au1000/pb1500/init.c2
-rw-r--r--arch/mips/au1000/pb1550/init.c2
-rw-r--r--arch/mips/au1000/xxs1500/init.c2
-rw-r--r--arch/mips/basler/excite/Kconfig9
-rw-r--r--arch/mips/basler/excite/excite_iodev.c2
-rw-r--r--arch/mips/basler/excite/excite_prom.c2
-rw-r--r--arch/mips/cobalt/reset.c24
-rw-r--r--arch/mips/configs/atlas_defconfig2
-rw-r--r--arch/mips/configs/bigsur_defconfig2
-rw-r--r--arch/mips/configs/capcella_defconfig2
-rw-r--r--arch/mips/configs/cobalt_defconfig2
-rw-r--r--arch/mips/configs/db1000_defconfig2
-rw-r--r--arch/mips/configs/db1100_defconfig2
-rw-r--r--arch/mips/configs/db1200_defconfig2
-rw-r--r--arch/mips/configs/db1500_defconfig2
-rw-r--r--arch/mips/configs/db1550_defconfig2
-rw-r--r--arch/mips/configs/decstation_defconfig2
-rw-r--r--arch/mips/configs/e55_defconfig2
-rw-r--r--arch/mips/configs/emma2rh_defconfig2
-rw-r--r--arch/mips/configs/excite_defconfig2
-rw-r--r--arch/mips/configs/fulong_defconfig2
-rw-r--r--arch/mips/configs/ip22_defconfig2
-rw-r--r--arch/mips/configs/ip27_defconfig2
-rw-r--r--arch/mips/configs/ip32_defconfig2
-rw-r--r--arch/mips/configs/jazz_defconfig2
-rw-r--r--arch/mips/configs/jmr3927_defconfig17
-rw-r--r--arch/mips/configs/lasat_defconfig2
-rw-r--r--arch/mips/configs/malta_defconfig2
-rw-r--r--arch/mips/configs/mipssim_defconfig2
-rw-r--r--arch/mips/configs/mpc30x_defconfig2
-rw-r--r--arch/mips/configs/msp71xx_defconfig2
-rw-r--r--arch/mips/configs/mtx1_defconfig3
-rw-r--r--arch/mips/configs/pb1100_defconfig2
-rw-r--r--arch/mips/configs/pb1500_defconfig2
-rw-r--r--arch/mips/configs/pb1550_defconfig2
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig2
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig2
-rw-r--r--arch/mips/configs/qemu_defconfig2
-rw-r--r--arch/mips/configs/rbhma4200_defconfig17
-rw-r--r--arch/mips/configs/rbhma4500_defconfig17
-rw-r--r--arch/mips/configs/rm200_defconfig2
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig2
-rw-r--r--arch/mips/configs/sead_defconfig2
-rw-r--r--arch/mips/configs/tb0219_defconfig2
-rw-r--r--arch/mips/configs/tb0226_defconfig2
-rw-r--r--arch/mips/configs/tb0287_defconfig2
-rw-r--r--arch/mips/configs/workpad_defconfig2
-rw-r--r--arch/mips/configs/wrppmc_defconfig2
-rw-r--r--arch/mips/configs/yosemite_defconfig2
-rw-r--r--arch/mips/dec/time.c1
-rw-r--r--arch/mips/defconfig2
-rw-r--r--arch/mips/fw/arc/cmdline.c2
-rw-r--r--arch/mips/fw/arc/init.c8
-rw-r--r--arch/mips/fw/cfe/cfe_api.c184
-rw-r--r--arch/mips/fw/cfe/cfe_api_int.h186
-rw-r--r--arch/mips/fw/lib/Makefile5
-rw-r--r--arch/mips/fw/lib/call_o32.S97
-rw-r--r--arch/mips/fw/sni/Makefile5
-rw-r--r--arch/mips/fw/sni/sniprom.c151
-rw-r--r--arch/mips/gt64120/wrppmc/setup.c2
-rw-r--r--arch/mips/jazz/setup.c7
-rw-r--r--arch/mips/jmr3927/rbhma3100/init.c4
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c60
-rw-r--r--arch/mips/kernel/cpu-bugs64.c47
-rw-r--r--arch/mips/kernel/cpu-probe.c9
-rw-r--r--arch/mips/kernel/genex.S8
-rw-r--r--arch/mips/kernel/kspd.c3
-rw-r--r--arch/mips/kernel/linux32.c30
-rw-r--r--arch/mips/kernel/mips-mt.c1
-rw-r--r--arch/mips/kernel/pcspeaker.c28
-rw-r--r--arch/mips/kernel/proc.c3
-rw-r--r--arch/mips/kernel/rtlx.c1
-rw-r--r--arch/mips/kernel/setup.c7
-rw-r--r--arch/mips/kernel/smp-mt.c193
-rw-r--r--arch/mips/kernel/smp.c53
-rw-r--r--arch/mips/kernel/smtc-proc.c1
-rw-r--r--arch/mips/kernel/smtc.c1
-rw-r--r--arch/mips/kernel/time.c2
-rw-r--r--arch/mips/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/kernel/vpe.c1
-rw-r--r--arch/mips/lasat/picvue.c2
-rw-r--r--arch/mips/lasat/picvue.h3
-rw-r--r--arch/mips/lasat/picvue_proc.c18
-rw-r--r--arch/mips/lemote/lm2e/pci.c3
-rw-r--r--arch/mips/lemote/lm2e/prom.c2
-rw-r--r--arch/mips/lib/csum_partial.S275
-rw-r--r--arch/mips/lib/memcpy-inatomic.S141
-rw-r--r--arch/mips/lib/memcpy.S250
-rw-r--r--arch/mips/lib/memset.S44
-rw-r--r--arch/mips/lib/strlen_user.S6
-rw-r--r--arch/mips/lib/strncpy_user.S15
-rw-r--r--arch/mips/lib/strnlen_user.S7
-rw-r--r--arch/mips/lib/uncached.c12
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c6
-rw-r--r--arch/mips/mips-boards/generic/init.c8
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c129
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c210
-rw-r--r--arch/mips/mips-boards/malta/malta_smtc.c68
-rw-r--r--arch/mips/mips-boards/sead/sead_setup.c2
-rw-r--r--arch/mips/mipssim/Makefile2
-rw-r--r--arch/mips/mipssim/sim_setup.c16
-rw-r--r--arch/mips/mipssim/sim_smtc.c (renamed from arch/mips/mipssim/sim_smp.c)92
-rw-r--r--arch/mips/mm/c-r4k.c17
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/pg-r4k.c66
-rw-r--r--arch/mips/mm/tlbex.c252
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c2
-rw-r--r--arch/mips/pci/pci-bcm1480.c4
-rw-r--r--arch/mips/pci/pci-bcm1480ht.c4
-rw-r--r--arch/mips/philips/pnx8550/common/setup.c2
-rw-r--r--arch/mips/philips/pnx8550/common/time.c35
-rw-r--r--arch/mips/philips/pnx8550/jbs/init.c3
-rw-r--r--arch/mips/philips/pnx8550/stb810/prom_init.c2
-rw-r--r--arch/mips/pmc-sierra/yosemite/i2c-yosemite.h96
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c7
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c149
-rw-r--r--arch/mips/qemu/Makefile10
-rw-r--r--arch/mips/qemu/q-console.c26
-rw-r--r--arch/mips/qemu/q-firmware.c24
-rw-r--r--arch/mips/qemu/q-irq.c37
-rw-r--r--arch/mips/qemu/q-mem.c5
-rw-r--r--arch/mips/qemu/q-reset.c33
-rw-r--r--arch/mips/qemu/q-setup.c22
-rw-r--r--arch/mips/qemu/q-smp.c55
-rw-r--r--arch/mips/sgi-ip22/Makefile8
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c4
-rw-r--r--arch/mips/sgi-ip22/ip28-berr.c502
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-klnuma.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c109
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c101
-rw-r--r--arch/mips/sibyte/cfe/Makefile1
-rw-r--r--arch/mips/sibyte/cfe/setup.c14
-rw-r--r--arch/mips/sibyte/cfe/smp.c110
-rw-r--r--arch/mips/sibyte/sb1250/smp.c100
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/a20r.c13
-rw-r--r--arch/mips/sni/eisa.c50
-rw-r--r--arch/mips/sni/irq.c4
-rw-r--r--arch/mips/sni/pcit.c7
-rw-r--r--arch/mips/sni/rm200.c326
-rw-r--r--arch/mips/sni/setup.c143
-rw-r--r--arch/mips/sni/sniprom.c251
-rw-r--r--arch/mips/sni/time.c1
-rw-r--r--arch/mips/tx4927/common/Makefile6
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c186
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c96
-rw-r--r--arch/mips/tx4938/common/Makefile6
-rw-r--r--arch/mips/tx4938/common/setup.c45
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/Makefile4
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/prom.c1
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c31
-rw-r--r--arch/mips/vr41xx/common/init.c4
-rw-r--r--arch/mips/vr41xx/nec-cmbvr4133/setup.c4
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S8
-rw-r--r--arch/powerpc/boot/Makefile2
-rw-r--r--arch/powerpc/kernel/sysfs.c2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S10
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c6
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S8
-rw-r--r--arch/s390/kernel/vmlinux.lds.S8
-rw-r--r--arch/sh/kernel/vmlinux_32.lds.S8
-rw-r--r--arch/sh/kernel/vmlinux_64.lds.S8
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S8
-rw-r--r--arch/sparc64/kernel/unaligned.c2
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S8
-rw-r--r--arch/um/include/init.h26
-rw-r--r--arch/um/kernel/dyn.lds.S4
-rw-r--r--arch/um/kernel/uml.lds.S4
-rw-r--r--arch/v850/kernel/vmlinux.lds.S10
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S14
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S19
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S9
-rw-r--r--arch/xtensa/mm/Makefile4
-rw-r--r--arch/xtensa/platform-iss/Makefile5
-rw-r--r--drivers/base/power/Makefile8
-rw-r--r--drivers/infiniband/hw/cxgb3/Makefile3
-rw-r--r--drivers/rapidio/rio.h4
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/afs/dir.c9
-rw-r--r--fs/afs/inode.c3
-rw-r--r--fs/buffer.c44
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--fs/ext2/super.c32
-rw-r--r--fs/ext3/super.c32
-rw-r--r--fs/ext4/Makefile2
-rw-r--r--fs/ext4/balloc.c247
-rw-r--r--fs/ext4/dir.c14
-rw-r--r--fs/ext4/extents.c481
-rw-r--r--fs/ext4/file.c23
-rw-r--r--fs/ext4/group.h8
-rw-r--r--fs/ext4/ialloc.c141
-rw-r--r--fs/ext4/inode.c360
-rw-r--r--fs/ext4/ioctl.c7
-rw-r--r--fs/ext4/mballoc.c4552
-rw-r--r--fs/ext4/migrate.c560
-rw-r--r--fs/ext4/namei.c135
-rw-r--r--fs/ext4/resize.c28
-rw-r--r--fs/ext4/super.c379
-rw-r--r--fs/ext4/xattr.c4
-rw-r--r--fs/inode.c5
-rw-r--r--fs/jbd2/checkpoint.c22
-rw-r--r--fs/jbd2/commit.c255
-rw-r--r--fs/jbd2/journal.c368
-rw-r--r--fs/jbd2/recovery.c151
-rw-r--r--fs/jbd2/revoke.c6
-rw-r--r--fs/jbd2/transaction.c34
-rw-r--r--fs/ocfs2/cluster/sys.c2
-rw-r--r--fs/read_write.c1
-rw-r--r--fs/smbfs/Makefile20
-rw-r--r--include/asm-arm/bitops.h2
-rw-r--r--include/asm-avr32/setup.h2
-rw-r--r--include/asm-generic/bitops/ext2-non-atomic.h2
-rw-r--r--include/asm-generic/bitops/le.h4
-rw-r--r--include/asm-generic/vmlinux.lds.h89
-rw-r--r--include/asm-ia64/gcc_intrin.h2
-rw-r--r--include/asm-m68k/bitops.h2
-rw-r--r--include/asm-m68knommu/bitops.h2
-rw-r--r--include/asm-mips/addrspace.h2
-rw-r--r--include/asm-mips/asm.h8
-rw-r--r--include/asm-mips/bootinfo.h105
-rw-r--r--include/asm-mips/bugs.h25
-rw-r--r--include/asm-mips/cpu-info.h5
-rw-r--r--include/asm-mips/cpu.h4
-rw-r--r--include/asm-mips/delay.h23
-rw-r--r--include/asm-mips/dma.h7
-rw-r--r--include/asm-mips/fixmap.h10
-rw-r--r--include/asm-mips/fw/cfe/cfe_api.h87
-rw-r--r--include/asm-mips/fw/cfe/cfe_error.h19
-rw-r--r--include/asm-mips/mach-cobalt/cobalt.h15
-rw-r--r--include/asm-mips/mach-ip28/cpu-feature-overrides.h50
-rw-r--r--include/asm-mips/mach-ip28/ds1286.h4
-rw-r--r--include/asm-mips/mach-ip28/spaces.h22
-rw-r--r--include/asm-mips/mach-ip28/war.h (renamed from include/asm-mips/mach-qemu/war.h)8
-rw-r--r--include/asm-mips/mach-qemu/cpu-feature-overrides.h32
-rw-r--r--include/asm-mips/mips-boards/generic.h6
-rw-r--r--include/asm-mips/mipsprom.h2
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/msp_regs.h4
-rw-r--r--include/asm-mips/r4kcache.h7
-rw-r--r--include/asm-mips/sgi/ioc.h4
-rw-r--r--include/asm-mips/sibyte/board.h6
-rw-r--r--include/asm-mips/sibyte/sb1250.h2
-rw-r--r--include/asm-mips/sibyte/swarm.h18
-rw-r--r--include/asm-mips/smp-ops.h56
-rw-r--r--include/asm-mips/smp.h64
-rw-r--r--include/asm-mips/sni.h159
-rw-r--r--include/asm-mips/stackframe.h9
-rw-r--r--include/asm-mips/time.h9
-rw-r--r--include/asm-mips/topology.h16
-rw-r--r--include/asm-mips/tx4927/tx4927_pci.h1
-rw-r--r--include/asm-mips/uaccess.h13
-rw-r--r--include/asm-mips/war.h62
-rw-r--r--include/asm-powerpc/bitops.h4
-rw-r--r--include/asm-s390/bitops.h2
-rw-r--r--include/asm-sh/machvec.h2
-rw-r--r--include/asm-sh/thread_info.h2
-rw-r--r--include/asm-x86/thread_info_32.h2
-rw-r--r--include/linux/Kbuild8
-rw-r--r--include/linux/buffer_head.h2
-rw-r--r--include/linux/compiler-gcc3.h2
-rw-r--r--include/linux/compiler-gcc4.h1
-rw-r--r--include/linux/compiler.h9
-rw-r--r--include/linux/elfnote.h2
-rw-r--r--include/linux/ext4_fs.h198
-rw-r--r--include/linux/ext4_fs_extents.h25
-rw-r--r--include/linux/ext4_fs_i.h25
-rw-r--r--include/linux/ext4_fs_sb.h55
-rw-r--r--include/linux/fs.h19
-rw-r--r--include/linux/init.h130
-rw-r--r--include/linux/jbd2.h135
-rw-r--r--include/linux/module.h26
-rw-r--r--include/linux/moduleparam.h4
-rw-r--r--include/linux/pci.h2
-rw-r--r--init/Kconfig8
-rw-r--r--kernel/extable.c3
-rw-r--r--kernel/kallsyms.c11
-rw-r--r--kernel/module.c102
-rw-r--r--kernel/params.c8
-rw-r--r--lib/Kconfig.debug32
-rw-r--r--lib/find_next_bit.c43
-rw-r--r--scripts/Makefile.build26
-rw-r--r--scripts/Makefile.lib6
-rw-r--r--scripts/Makefile.modinst2
-rw-r--r--scripts/Makefile.modpost1
-rw-r--r--scripts/basic/docproc.c44
-rw-r--r--scripts/decodecode17
-rw-r--r--scripts/gcc-version.sh5
-rw-r--r--scripts/genksyms/genksyms.c10
-rw-r--r--scripts/kconfig/Makefile39
-rw-r--r--scripts/kconfig/POTFILES.in7
-rw-r--r--scripts/kconfig/conf.c69
-rw-r--r--scripts/kconfig/confdata.c24
-rw-r--r--scripts/kconfig/expr.c32
-rw-r--r--scripts/kconfig/expr.h16
-rw-r--r--scripts/kconfig/gconf.c16
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped5
-rw-r--r--scripts/kconfig/lkc.h5
-rw-r--r--scripts/kconfig/lxdialog/check-lxdialog.sh16
-rw-r--r--scripts/kconfig/lxdialog/checklist.c4
-rw-r--r--scripts/kconfig/lxdialog/dialog.h11
-rw-r--r--scripts/kconfig/lxdialog/inputbox.c4
-rw-r--r--scripts/kconfig/lxdialog/menubox.c6
-rw-r--r--scripts/kconfig/lxdialog/textbox.c2
-rw-r--r--scripts/kconfig/lxdialog/util.c32
-rw-r--r--scripts/kconfig/lxdialog/yesno.c4
-rw-r--r--scripts/kconfig/mconf.c112
-rw-r--r--scripts/kconfig/menu.c49
-rw-r--r--scripts/kconfig/qconf.cc109
-rw-r--r--scripts/kconfig/symbol.c79
-rw-r--r--scripts/kconfig/util.c23
-rw-r--r--scripts/kconfig/zconf.gperf2
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped19
-rw-r--r--scripts/kconfig/zconf.l5
-rwxr-xr-xscripts/kernel-doc85
-rw-r--r--scripts/mkmakefile10
-rw-r--r--scripts/mod/modpost.c1210
-rw-r--r--scripts/mod/modpost.h2
-rw-r--r--scripts/package/Makefile5
-rw-r--r--scripts/package/buildtar4
-rwxr-xr-xscripts/patch-kernel22
-rw-r--r--scripts/setlocalversion29
357 files changed, 13335 insertions, 5051 deletions
diff --git a/.gitignore b/.gitignore
index 8d14531846b9..8363e48cdcdc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@
17*.i 17*.i
18*.lst 18*.lst
19*.symtypes 19*.symtypes
20*.order
20 21
21# 22#
22# Top-level generic files 23# Top-level generic files
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 6a4adcae9f9a..560f88dc7090 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -86,9 +86,21 @@ Alex is working on a new set of patches right now.
86When mounting an ext4 filesystem, the following option are accepted: 86When mounting an ext4 filesystem, the following option are accepted:
87(*) == default 87(*) == default
88 88
89extents ext4 will use extents to address file data. The 89extents (*) ext4 will use extents to address file data. The
90 file system will no longer be mountable by ext3. 90 file system will no longer be mountable by ext3.
91 91
92noextents ext4 will not use extents for newly created files
93
94journal_checksum Enable checksumming of the journal transactions.
95 This will allow the recovery code in e2fsck and the
96 kernel to detect corruption in the kernel. It is a
97 compatible change and will be ignored by older kernels.
98
99journal_async_commit Commit block can be written to disk without waiting
100 for descriptor blocks. If enabled older kernels cannot
101 mount the device. This will enable 'journal_checksum'
102 internally.
103
92journal=update Update the ext4 file system's journal to the current 104journal=update Update the ext4 file system's journal to the current
93 format. 105 format.
94 106
@@ -196,6 +208,12 @@ nobh (a) cache disk block mapping information
196 "nobh" option tries to avoid associating buffer 208 "nobh" option tries to avoid associating buffer
197 heads (supported only for "writeback" mode). 209 heads (supported only for "writeback" mode).
198 210
211mballoc (*) Use the multiple block allocator for block allocation
212nomballoc disabled multiple block allocator for block allocation.
213stripe=n Number of filesystem blocks that mballoc will try
214 to use for allocation size and alignment. For RAID5/6
215 systems this should be the number of data
216 disks * RAID chunk size in file system blocks.
199 217
200Data Mode 218Data Mode
201--------- 219---------
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index dec99455321f..4413a2d4646f 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -857,6 +857,45 @@ CPUs.
857The "procs_blocked" line gives the number of processes currently blocked, 857The "procs_blocked" line gives the number of processes currently blocked,
858waiting for I/O to complete. 858waiting for I/O to complete.
859 859
8601.9 Ext4 file system parameters
861------------------------------
862Ext4 file system have one directory per partition under /proc/fs/ext4/
863# ls /proc/fs/ext4/hdc/
864group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req
865stats stream_req
866
867mb_groups:
868This file gives the details of mutiblock allocator buddy cache of free blocks
869
870mb_history:
871Multiblock allocation history.
872
873stats:
874This file indicate whether the multiblock allocator should start collecting
875statistics. The statistics are shown during unmount
876
877group_prealloc:
878The multiblock allocator normalize the block allocation request to
879group_prealloc filesystem blocks if we don't have strip value set.
880The stripe value can be specified at mount time or during mke2fs.
881
882max_to_scan:
883How long multiblock allocator can look for a best extent (in found extents)
884
885min_to_scan:
886How long multiblock allocator must look for a best extent
887
888order2_req:
889Multiblock allocator use 2^N search using buddies only for requests greater
890than or equal to order2_req. The request size is specfied in file system
891blocks. A value of 2 indicate only if the requests are greater than or equal
892to 4 blocks.
893
894stream_req:
895Files smaller than stream_req are served by the stream allocator, whose
896purpose is to pack requests as close each to other as possible to
897produce smooth I/O traffic. Avalue of 16 indicate that file smaller than 16
898filesystem block size will use group based preallocation.
860 899
861------------------------------------------------------------------------------ 900------------------------------------------------------------------------------
862Summary 901Summary
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 616043a6da99..649cb8799890 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -24,7 +24,7 @@ visible if its parent entry is also visible.
24Menu entries 24Menu entries
25------------ 25------------
26 26
27Most entries define a config option, all other entries help to organize 27Most entries define a config option; all other entries help to organize
28them. A single configuration option is defined like this: 28them. A single configuration option is defined like this:
29 29
30config MODVERSIONS 30config MODVERSIONS
@@ -50,7 +50,7 @@ applicable everywhere (see syntax).
50 50
51- type definition: "bool"/"tristate"/"string"/"hex"/"int" 51- type definition: "bool"/"tristate"/"string"/"hex"/"int"
52 Every config option must have a type. There are only two basic types: 52 Every config option must have a type. There are only two basic types:
53 tristate and string, the other types are based on these two. The type 53 tristate and string; the other types are based on these two. The type
54 definition optionally accepts an input prompt, so these two examples 54 definition optionally accepts an input prompt, so these two examples
55 are equivalent: 55 are equivalent:
56 56
@@ -108,7 +108,7 @@ applicable everywhere (see syntax).
108 equal to 'y' without visiting the dependencies. So abusing 108 equal to 'y' without visiting the dependencies. So abusing
109 select you are able to select a symbol FOO even if FOO depends 109 select you are able to select a symbol FOO even if FOO depends
110 on BAR that is not set. In general use select only for 110 on BAR that is not set. In general use select only for
111 non-visible symbols (no promts anywhere) and for symbols with 111 non-visible symbols (no prompts anywhere) and for symbols with
112 no dependencies. That will limit the usefulness but on the 112 no dependencies. That will limit the usefulness but on the
113 other hand avoid the illegal configurations all over. kconfig 113 other hand avoid the illegal configurations all over. kconfig
114 should one day warn about such things. 114 should one day warn about such things.
@@ -127,6 +127,27 @@ applicable everywhere (see syntax).
127 used to help visually separate configuration logic from help within 127 used to help visually separate configuration logic from help within
128 the file as an aid to developers. 128 the file as an aid to developers.
129 129
130- misc options: "option" <symbol>[=<value>]
131 Various less common options can be defined via this option syntax,
132 which can modify the behaviour of the menu entry and its config
133 symbol. These options are currently possible:
134
135 - "defconfig_list"
136 This declares a list of default entries which can be used when
137 looking for the default configuration (which is used when the main
138 .config doesn't exists yet.)
139
140 - "modules"
141 This declares the symbol to be used as the MODULES symbol, which
142 enables the third modular state for all config symbols.
143
144 - "env"=<value>
145 This imports the environment variable into Kconfig. It behaves like
146 a default, except that the value comes from the environment, this
147 also means that the behaviour when mixing it with normal defaults is
148 undefined at this point. The symbol is currently not exported back
149 to the build environment (if this is desired, it can be done via
150 another symbol).
130 151
131Menu dependencies 152Menu dependencies
132----------------- 153-----------------
@@ -162,9 +183,9 @@ An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
162respectively for calculations). A menu entry becomes visible when it's 183respectively for calculations). A menu entry becomes visible when it's
163expression evaluates to 'm' or 'y'. 184expression evaluates to 'm' or 'y'.
164 185
165There are two types of symbols: constant and nonconstant symbols. 186There are two types of symbols: constant and non-constant symbols.
166Nonconstant symbols are the most common ones and are defined with the 187Non-constant symbols are the most common ones and are defined with the
167'config' statement. Nonconstant symbols consist entirely of alphanumeric 188'config' statement. Non-constant symbols consist entirely of alphanumeric
168characters or underscores. 189characters or underscores.
169Constant symbols are only part of expressions. Constant symbols are 190Constant symbols are only part of expressions. Constant symbols are
170always surrounded by single or double quotes. Within the quote, any 191always surrounded by single or double quotes. Within the quote, any
@@ -301,3 +322,81 @@ mainmenu:
301 322
302This sets the config program's title bar if the config program chooses 323This sets the config program's title bar if the config program chooses
303to use it. 324to use it.
325
326
327Kconfig hints
328-------------
329This is a collection of Kconfig tips, most of which aren't obvious at
330first glance and most of which have become idioms in several Kconfig
331files.
332
333Adding common features and make the usage configurable
334~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
335It is a common idiom to implement a feature/functionality that are
336relevant for some architectures but not all.
337The recommended way to do so is to use a config variable named HAVE_*
338that is defined in a common Kconfig file and selected by the relevant
339architectures.
340An example is the generic IOMAP functionality.
341
342We would in lib/Kconfig see:
343
344# Generic IOMAP is used to ...
345config HAVE_GENERIC_IOMAP
346
347config GENERIC_IOMAP
348 depends on HAVE_GENERIC_IOMAP && FOO
349
350And in lib/Makefile we would see:
351obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
352
353For each architecture using the generic IOMAP functionality we would see:
354
355config X86
356 select ...
357 select HAVE_GENERIC_IOMAP
358 select ...
359
360Note: we use the existing config option and avoid creating a new
361config variable to select HAVE_GENERIC_IOMAP.
362
363Note: the use of the internal config variable HAVE_GENERIC_IOMAP, it is
364introduced to overcome the limitation of select which will force a
365config option to 'y' no matter the dependencies.
366The dependencies are moved to the symbol GENERIC_IOMAP and we avoid the
367situation where select forces a symbol equals to 'y'.
368
369Build as module only
370~~~~~~~~~~~~~~~~~~~~
371To restrict a component build to module-only, qualify its config symbol
372with "depends on m". E.g.:
373
374config FOO
375 depends on BAR && m
376
377limits FOO to module (=m) or disabled (=n).
378
379
380Build limited by a third config symbol which may be =y or =m
381~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
382A common idiom that we see (and sometimes have problems with) is this:
383
384When option C in B (module or subsystem) uses interfaces from A (module
385or subsystem), and both A and B are tristate (could be =y or =m if they
386were independent of each other, but they aren't), then we need to limit
387C such that it cannot be built statically if A is built as a loadable
388module. (C already depends on B, so there is no dependency issue to
389take care of here.)
390
391If A is linked statically into the kernel image, C can be built
392statically or as loadable module(s). However, if A is built as loadable
393module(s), then C must be restricted to loadable module(s) also. This
394can be expressed in kconfig language as:
395
396config C
397 depends on A = y || A = B
398
399or for real examples, use this command in a kernel tree:
400
401$ find . -name Kconfig\* | xargs grep -ns "depends on.*=.*||.*=" | grep -v orig
402
diff --git a/Documentation/mips/00-INDEX b/Documentation/mips/00-INDEX
index 3f13bf8043d2..8ae9cffc2262 100644
--- a/Documentation/mips/00-INDEX
+++ b/Documentation/mips/00-INDEX
@@ -2,5 +2,3 @@
2 - this file. 2 - this file.
3AU1xxx_IDE.README 3AU1xxx_IDE.README
4 - README for MIPS AU1XXX IDE driver. 4 - README for MIPS AU1XXX IDE driver.
5GT64120.README
6 - README for dir with info on MIPS boards using GT-64120 or GT-64120A.
diff --git a/Documentation/mips/GT64120.README b/Documentation/mips/GT64120.README
deleted file mode 100644
index 2d0eec91dc59..000000000000
--- a/Documentation/mips/GT64120.README
+++ /dev/null
@@ -1,65 +0,0 @@
1README for arch/mips/gt64120 directory and subdirectories
2
3Jun Sun, jsun@mvista.com or jsun@junsun.net
401/27, 2001
5
6MOTIVATION
7----------
8
9Many MIPS boards share the same system controller (or CPU companian chip),
10such as GT-64120. It is highly desirable to let these boards share
11the same controller code instead of duplicating them.
12
13This directory is meant to hold all MIPS boards that use GT-64120 or GT-64120A.
14
15
16HOW TO ADD A BOARD
17------------------
18
19. Create a subdirectory include/asm/gt64120/<board>.
20
21. Create a file called gt64120_dep.h under that directory.
22
23. Modify include/asm/gt64120/gt64120.h file to include the new gt64120_dep.h
24 based on config options. The board-dep section is at the end of
25 include/asm/gt64120/gt64120.h file. There you can find all required
26 definitions include/asm/gt64120/<board>/gt64120_dep.h file must supply.
27
28. Create a subdirectory arch/mips/gt64120/<board> directory to hold
29 board specific routines.
30
31. The GT-64120 common code is supplied under arch/mips/gt64120/common directory.
32 It includes:
33 1) arch/mips/gt64120/pci.c -
34 common PCI routine, include the top-level pcibios_init()
35 2) arch/mips/gt64120/irq.c -
36 common IRQ routine, include the top-level do_IRQ()
37 [This part really belongs to arch/mips/kernel. jsun]
38 3) arch/mips/gt64120/gt_irq.c -
39 common IRQ routines for GT-64120 chip. Currently it only handles
40 the timer interrupt.
41
42. Board-specific routines are supplied under arch/mips/gt64120/<board> dir.
43 1) arch/mips/gt64120/<board>/pci.c - it provides bus fixup routine
44 2) arch/mips/gt64120/<board>/irq.c - it provides enable/disable irqs
45 and board irq setup routine (irq_setup)
46 3) arch/mips/gt64120/<board>/int-handler.S -
47 The first-level interrupt dispatching routine.
48 4) a bunch of other "normal" stuff (setup, prom, dbg_io, reset, etc)
49
50. Follow other "normal" procedure to modify configuration files, etc.
51
52
53TO-DO LIST
54----------
55
56. Expand arch/mips/gt64120/gt_irq.c to handle all GT-64120 interrupts.
57 We probably need to introduce GT_IRQ_BASE in board-dep header file,
58 which is used the starting irq_nr for all GT irqs.
59
60 A function, gt64120_handle_irq(), will be added so that the first-level
61 irq dispatcher will call this function if it detects an interrupt
62 from GT-64120.
63
64. More support for GT-64120 PCI features (2nd PCI bus, perhaps)
65
diff --git a/Makefile b/Makefile
index 6d419f67939c..0f84c742ed0e 100644
--- a/Makefile
+++ b/Makefile
@@ -520,6 +520,11 @@ KBUILD_CFLAGS += -g
520KBUILD_AFLAGS += -gdwarf-2 520KBUILD_AFLAGS += -gdwarf-2
521endif 521endif
522 522
523# We trigger additional mismatches with less inlining
524ifdef CONFIG_DEBUG_SECTION_MISMATCH
525KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
526endif
527
523# Force gcc to behave correct even for buggy distributions 528# Force gcc to behave correct even for buggy distributions
524KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) 529KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
525 530
@@ -793,7 +798,7 @@ define rule_vmlinux-modpost
793endef 798endef
794 799
795# vmlinux image - including updated kernel symbols 800# vmlinux image - including updated kernel symbols
796vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE 801vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
797ifdef CONFIG_HEADERS_CHECK 802ifdef CONFIG_HEADERS_CHECK
798 $(Q)$(MAKE) -f $(srctree)/Makefile headers_check 803 $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
799endif 804endif
@@ -804,7 +809,9 @@ endif
804 $(call if_changed_rule,vmlinux__) 809 $(call if_changed_rule,vmlinux__)
805 $(Q)rm -f .old_version 810 $(Q)rm -f .old_version
806 811
807vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE 812# build vmlinux.o first to catch section mismatch errors early
813$(kallsyms.o): vmlinux.o
814vmlinux.o: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE
808 $(call if_changed_rule,vmlinux-modpost) 815 $(call if_changed_rule,vmlinux-modpost)
809 816
810# The actual objects are generated when descending, 817# The actual objects are generated when descending,
@@ -1021,9 +1028,14 @@ ifdef CONFIG_MODULES
1021all: modules 1028all: modules
1022 1029
1023# Build modules 1030# Build modules
1031#
1032# A module can be listed more than once in obj-m resulting in
1033# duplicate lines in modules.order files. Those are removed
1034# using awk while concatenating to the final file.
1024 1035
1025PHONY += modules 1036PHONY += modules
1026modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) 1037modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
1038 $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
1027 @echo ' Building modules, stage 2.'; 1039 @echo ' Building modules, stage 2.';
1028 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 1040 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
1029 1041
@@ -1051,6 +1063,7 @@ _modinst_:
1051 rm -f $(MODLIB)/build ; \ 1063 rm -f $(MODLIB)/build ; \
1052 ln -s $(objtree) $(MODLIB)/build ; \ 1064 ln -s $(objtree) $(MODLIB)/build ; \
1053 fi 1065 fi
1066 @cp -f $(objtree)/modules.order $(MODLIB)/
1054 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst 1067 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
1055 1068
1056# This depmod is only for convenience to give the initial 1069# This depmod is only for convenience to give the initial
@@ -1110,7 +1123,7 @@ clean: archclean $(clean-dirs)
1110 @find . $(RCS_FIND_IGNORE) \ 1123 @find . $(RCS_FIND_IGNORE) \
1111 \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ 1124 \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
1112 -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ 1125 -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
1113 -o -name '*.symtypes' \) \ 1126 -o -name '*.symtypes' -o -name 'modules.order' \) \
1114 -type f -print | xargs rm -f 1127 -type f -print | xargs rm -f
1115 1128
1116# mrproper - Delete all generated files, including .config 1129# mrproper - Delete all generated files, including .config
@@ -1175,7 +1188,7 @@ help:
1175 @echo ' dir/ - Build all files in dir and below' 1188 @echo ' dir/ - Build all files in dir and below'
1176 @echo ' dir/file.[ois] - Build specified target only' 1189 @echo ' dir/file.[ois] - Build specified target only'
1177 @echo ' dir/file.ko - Build module including final link' 1190 @echo ' dir/file.ko - Build module including final link'
1178 @echo ' rpm - Build a kernel as an RPM package' 1191 @echo ' prepare - Set up for building external modules'
1179 @echo ' tags/TAGS - Generate tags file for editors' 1192 @echo ' tags/TAGS - Generate tags file for editors'
1180 @echo ' cscope - Generate cscope index' 1193 @echo ' cscope - Generate cscope index'
1181 @echo ' kernelrelease - Output the release version string' 1194 @echo ' kernelrelease - Output the release version string'
@@ -1188,6 +1201,8 @@ help:
1188 @echo 'Static analysers' 1201 @echo 'Static analysers'
1189 @echo ' checkstack - Generate a list of stack hogs' 1202 @echo ' checkstack - Generate a list of stack hogs'
1190 @echo ' namespacecheck - Name space analysis on compiled kernel' 1203 @echo ' namespacecheck - Name space analysis on compiled kernel'
1204 @echo ' versioncheck - Sanity check on version.h usage'
1205 @echo ' includecheck - Check for duplicate included header files'
1191 @echo ' export_report - List the usages of all exported symbols' 1206 @echo ' export_report - List the usages of all exported symbols'
1192 @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \ 1207 @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
1193 echo ' headers_check - Sanity check on exported headers'; \ 1208 echo ' headers_check - Sanity check on exported headers'; \
@@ -1371,6 +1386,7 @@ define xtags
1371 if $1 --version 2>&1 | grep -iq exuberant; then \ 1386 if $1 --version 2>&1 | grep -iq exuberant; then \
1372 $(all-sources) | xargs $1 -a \ 1387 $(all-sources) | xargs $1 -a \
1373 -I __initdata,__exitdata,__acquires,__releases \ 1388 -I __initdata,__exitdata,__acquires,__releases \
1389 -I __read_mostly,____cacheline_aligned,____cacheline_aligned_in_smp,____cacheline_internodealigned_in_smp \
1374 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ 1390 -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
1375 --extra=+f --c-kinds=+px \ 1391 --extra=+f --c-kinds=+px \
1376 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'; \ 1392 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'; \
@@ -1428,12 +1444,12 @@ tags: FORCE
1428includecheck: 1444includecheck:
1429 find * $(RCS_FIND_IGNORE) \ 1445 find * $(RCS_FIND_IGNORE) \
1430 -name '*.[hcS]' -type f -print | sort \ 1446 -name '*.[hcS]' -type f -print | sort \
1431 | xargs $(PERL) -w scripts/checkincludes.pl 1447 | xargs $(PERL) -w $(srctree)/scripts/checkincludes.pl
1432 1448
1433versioncheck: 1449versioncheck:
1434 find * $(RCS_FIND_IGNORE) \ 1450 find * $(RCS_FIND_IGNORE) \
1435 -name '*.[hcS]' -type f -print | sort \ 1451 -name '*.[hcS]' -type f -print | sort \
1436 | xargs $(PERL) -w scripts/checkversion.pl 1452 | xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
1437 1453
1438namespacecheck: 1454namespacecheck:
1439 $(PERL) $(srctree)/scripts/namespace.pl 1455 $(PERL) $(srctree)/scripts/namespace.pl
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 55c05b511f4c..f13249be17c5 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -46,11 +46,11 @@ SECTIONS
46 __init_begin = .; 46 __init_begin = .;
47 .init.text : { 47 .init.text : {
48 _sinittext = .; 48 _sinittext = .;
49 *(.init.text) 49 INIT_TEXT
50 _einittext = .; 50 _einittext = .;
51 } 51 }
52 .init.data : { 52 .init.data : {
53 *(.init.data) 53 INIT_DATA
54 } 54 }
55 55
56 . = ALIGN(16); 56 . = ALIGN(16);
@@ -136,8 +136,8 @@ SECTIONS
136 136
137 /* Sections to be discarded */ 137 /* Sections to be discarded */
138 /DISCARD/ : { 138 /DISCARD/ : {
139 *(.exit.text) 139 EXIT_TEXT
140 *(.exit.data) 140 EXIT_DATA
141 *(.exitcall.exit) 141 *(.exitcall.exit)
142 } 142 }
143 143
diff --git a/arch/alpha/lib/dec_and_lock.c b/arch/alpha/lib/dec_and_lock.c
index 6ae2500a9d9e..0f5520d2f45f 100644
--- a/arch/alpha/lib/dec_and_lock.c
+++ b/arch/alpha/lib/dec_and_lock.c
@@ -30,8 +30,7 @@ _atomic_dec_and_lock: \n\
30 .previous \n\ 30 .previous \n\
31 .end _atomic_dec_and_lock"); 31 .end _atomic_dec_and_lock");
32 32
33static int __attribute_used__ 33static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
34atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
35{ 34{
36 /* Slow path */ 35 /* Slow path */
37 spin_lock(lock); 36 spin_lock(lock);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 30f732c7fdb5..4898bdcfe7dd 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -30,7 +30,7 @@ SECTIONS
30 } 30 }
31 31
32 .init : { /* Init code and data */ 32 .init : { /* Init code and data */
33 *(.init.text) 33 INIT_TEXT
34 _einittext = .; 34 _einittext = .;
35 __proc_info_begin = .; 35 __proc_info_begin = .;
36 *(.proc.info.init) 36 *(.proc.info.init)
@@ -70,15 +70,15 @@ SECTIONS
70 __per_cpu_end = .; 70 __per_cpu_end = .;
71#ifndef CONFIG_XIP_KERNEL 71#ifndef CONFIG_XIP_KERNEL
72 __init_begin = _stext; 72 __init_begin = _stext;
73 *(.init.data) 73 INIT_DATA
74 . = ALIGN(4096); 74 . = ALIGN(4096);
75 __init_end = .; 75 __init_end = .;
76#endif 76#endif
77 } 77 }
78 78
79 /DISCARD/ : { /* Exit code and data */ 79 /DISCARD/ : { /* Exit code and data */
80 *(.exit.text) 80 EXIT_TEXT
81 *(.exit.data) 81 EXIT_DATA
82 *(.exitcall.exit) 82 *(.exitcall.exit)
83#ifndef CONFIG_MMU 83#ifndef CONFIG_MMU
84 *(.fixup) 84 *(.fixup)
@@ -130,7 +130,7 @@ SECTIONS
130#ifdef CONFIG_XIP_KERNEL 130#ifdef CONFIG_XIP_KERNEL
131 . = ALIGN(4096); 131 . = ALIGN(4096);
132 __init_begin = .; 132 __init_begin = .;
133 *(.init.data) 133 INIT_DATA
134 . = ALIGN(4096); 134 . = ALIGN(4096);
135 __init_end = .; 135 __init_end = .;
136#endif 136#endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 02272aa36e90..88d5e61a2e13 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,9 +1,6 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7 4
8# Object file lists. 5# Object file lists.
9 6
diff --git a/arch/arm/mach-netx/Makefile b/arch/arm/mach-netx/Makefile
index 18785ff37657..7ce4ba9eb242 100644
--- a/arch/arm/mach-netx/Makefile
+++ b/arch/arm/mach-netx/Makefile
@@ -1,9 +1,6 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7 4
8# Object file lists. 5# Object file lists.
9 6
diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S
index 11f08e35a2eb..481cfd40c053 100644
--- a/arch/avr32/kernel/vmlinux.lds.S
+++ b/arch/avr32/kernel/vmlinux.lds.S
@@ -27,19 +27,19 @@ SECTIONS
27 __init_begin = .; 27 __init_begin = .;
28 _sinittext = .; 28 _sinittext = .;
29 *(.text.reset) 29 *(.text.reset)
30 *(.init.text) 30 INIT_TEXT
31 /* 31 /*
32 * .exit.text is discarded at runtime, not 32 * .exit.text is discarded at runtime, not
33 * link time, to deal with references from 33 * link time, to deal with references from
34 * __bug_table 34 * __bug_table
35 */ 35 */
36 *(.exit.text) 36 EXIT_TEXT
37 _einittext = .; 37 _einittext = .;
38 . = ALIGN(4); 38 . = ALIGN(4);
39 __tagtable_begin = .; 39 __tagtable_begin = .;
40 *(.taglist.init) 40 *(.taglist.init)
41 __tagtable_end = .; 41 __tagtable_end = .;
42 *(.init.data) 42 INIT_DATA
43 . = ALIGN(16); 43 . = ALIGN(16);
44 __setup_start = .; 44 __setup_start = .;
45 *(.init.setup) 45 *(.init.setup)
@@ -135,7 +135,7 @@ SECTIONS
135 * thrown away, as cleanup code is never called unless it's a module. 135 * thrown away, as cleanup code is never called unless it's a module.
136 */ 136 */
137 /DISCARD/ : { 137 /DISCARD/ : {
138 *(.exit.data) 138 EXIT_DATA
139 *(.exitcall.exit) 139 *(.exitcall.exit)
140 } 140 }
141 141
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 9b75bc83c71f..858722421b40 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -91,13 +91,13 @@ SECTIONS
91 { 91 {
92 . = ALIGN(PAGE_SIZE); 92 . = ALIGN(PAGE_SIZE);
93 __sinittext = .; 93 __sinittext = .;
94 *(.init.text) 94 INIT_TEXT
95 __einittext = .; 95 __einittext = .;
96 } 96 }
97 .init.data : 97 .init.data :
98 { 98 {
99 . = ALIGN(16); 99 . = ALIGN(16);
100 *(.init.data) 100 INIT_DATA
101 } 101 }
102 .init.setup : 102 .init.setup :
103 { 103 {
@@ -198,8 +198,8 @@ SECTIONS
198 198
199 /DISCARD/ : 199 /DISCARD/ :
200 { 200 {
201 *(.exit.text) 201 EXIT_TEXT
202 *(.exit.data) 202 EXIT_DATA
203 *(.exitcall.exit) 203 *(.exitcall.exit)
204 } 204 }
205} 205}
diff --git a/arch/cris/arch-v10/vmlinux.lds.S b/arch/cris/arch-v10/vmlinux.lds.S
index 97a7876ed681..93c9f0ea286b 100644
--- a/arch/cris/arch-v10/vmlinux.lds.S
+++ b/arch/cris/arch-v10/vmlinux.lds.S
@@ -57,10 +57,10 @@ SECTIONS
57 __init_begin = .; 57 __init_begin = .;
58 .init.text : { 58 .init.text : {
59 _sinittext = .; 59 _sinittext = .;
60 *(.init.text) 60 INIT_TEXT
61 _einittext = .; 61 _einittext = .;
62 } 62 }
63 .init.data : { *(.init.data) } 63 .init.data : { INIT_DATA }
64 . = ALIGN(16); 64 . = ALIGN(16);
65 __setup_start = .; 65 __setup_start = .;
66 .init.setup : { *(.init.setup) } 66 .init.setup : { *(.init.setup) }
@@ -109,8 +109,8 @@ SECTIONS
109 109
110 /* Sections to be discarded */ 110 /* Sections to be discarded */
111 /DISCARD/ : { 111 /DISCARD/ : {
112 *(.text.exit) 112 EXIT_TEXT
113 *(.data.exit) 113 EXIT_DATA
114 *(.exitcall.exit) 114 *(.exitcall.exit)
115 } 115 }
116 116
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 9f77eda914ba..609692f9d5eb 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -7,7 +7,7 @@
7target = $(target_compressed_dir) 7target = $(target_compressed_dir)
8src = $(src_compressed_dir) 8src = $(src_compressed_dir)
9 9
10CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include 10CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
11CFLAGS = -O2 11CFLAGS = -O2
12LD = gcc-cris -mlinux -march=v32 -nostdlib 12LD = gcc-cris -mlinux -march=v32 -nostdlib
13OBJCOPY = objcopy-cris 13OBJCOPY = objcopy-cris
diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S
index b076c134c0bb..fead8c59ea63 100644
--- a/arch/cris/arch-v32/vmlinux.lds.S
+++ b/arch/cris/arch-v32/vmlinux.lds.S
@@ -61,10 +61,10 @@ SECTIONS
61 __init_begin = .; 61 __init_begin = .;
62 .init.text : { 62 .init.text : {
63 _sinittext = .; 63 _sinittext = .;
64 *(.init.text) 64 INIT_TEXT
65 _einittext = .; 65 _einittext = .;
66 } 66 }
67 .init.data : { *(.init.data) } 67 .init.data : { INIT_DATA }
68 . = ALIGN(16); 68 . = ALIGN(16);
69 __setup_start = .; 69 __setup_start = .;
70 .init.setup : { *(.init.setup) } 70 .init.setup : { *(.init.setup) }
@@ -124,8 +124,8 @@ SECTIONS
124 124
125 /* Sections to be discarded */ 125 /* Sections to be discarded */
126 /DISCARD/ : { 126 /DISCARD/ : {
127 *(.text.exit) 127 EXIT_TEXT
128 *(.data.exit) 128 EXIT_DATA
129 *(.exitcall.exit) 129 *(.exitcall.exit)
130 } 130 }
131 131
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index dc6f03824423..6ae3254da019 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -10,7 +10,7 @@
10 10
11targets := Image zImage bootpImage 11targets := Image zImage bootpImage
12 12
13SYSTEM =$(TOPDIR)/$(LINUX) 13SYSTEM =$(LINUX)
14 14
15ZTEXTADDR = 0x02080000 15ZTEXTADDR = 0x02080000
16PARAMS_PHYS = 0x0207c000 16PARAMS_PHYS = 0x0207c000
@@ -45,7 +45,7 @@ zImage: $(CONFIGURE) compressed/$(LINUX)
45bootpImage: bootp/bootp 45bootpImage: bootp/bootp
46 $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ 46 $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
47 47
48compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep 48compressed/$(LINUX): $(LINUX) dep
49 @$(MAKE) -C compressed $(LINUX) 49 @$(MAKE) -C compressed $(LINUX)
50 50
51bootp/bootp: zImage initrd 51bootp/bootp: zImage initrd
@@ -59,10 +59,10 @@ initrd:
59# installation 59# installation
60# 60#
61install: $(CONFIGURE) Image 61install: $(CONFIGURE) Image
62 sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" 62 sh ./install.sh $(KERNELRELEASE) Image System.map "$(INSTALL_PATH)"
63 63
64zinstall: $(CONFIGURE) zImage 64zinstall: $(CONFIGURE) zImage
65 sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" 65 sh ./install.sh $(KERNELRELEASE) zImage System.map "$(INSTALL_PATH)"
66 66
67# 67#
68# miscellany 68# miscellany
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index e89cad1192a9..48a0393e7cee 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -87,7 +87,7 @@
87 * Example: 87 * Example:
88 * $ cd ~/linux 88 * $ cd ~/linux
89 * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging> 89 * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
90 * $ make dep; make vmlinux 90 * $ make vmlinux
91 * 91 *
92 * Step 3: 92 * Step 3:
93 * Download the kernel to the remote target and start 93 * Download the kernel to the remote target and start
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index a17a81d58bf6..f42b328b1dd0 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -28,14 +28,14 @@ SECTIONS
28 .init.text : { 28 .init.text : {
29 *(.text.head) 29 *(.text.head)
30#ifndef CONFIG_DEBUG_INFO 30#ifndef CONFIG_DEBUG_INFO
31 *(.init.text) 31 INIT_TEXT
32 *(.exit.text) 32 EXIT_TEXT
33 *(.exit.data) 33 EXIT_DATA
34 *(.exitcall.exit) 34 *(.exitcall.exit)
35#endif 35#endif
36 } 36 }
37 _einittext = .; 37 _einittext = .;
38 .init.data : { *(.init.data) } 38 .init.data : { INIT_DATA }
39 39
40 . = ALIGN(8); 40 . = ALIGN(8);
41 __setup_start = .; 41 __setup_start = .;
@@ -106,8 +106,8 @@ SECTIONS
106 LOCK_TEXT 106 LOCK_TEXT
107#ifdef CONFIG_DEBUG_INFO 107#ifdef CONFIG_DEBUG_INFO
108 *( 108 *(
109 .init.text 109 INIT_TEXT
110 .exit.text 110 EXIT_TEXT
111 .exitcall.exit 111 .exitcall.exit
112 ) 112 )
113#endif 113#endif
@@ -138,7 +138,7 @@ SECTIONS
138 .data : { /* Data */ 138 .data : { /* Data */
139 DATA_DATA 139 DATA_DATA
140 *(.data.*) 140 *(.data.*)
141 *(.exit.data) 141 EXIT_DATA
142 CONSTRUCTORS 142 CONSTRUCTORS
143 } 143 }
144 144
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index a2e72d495551..43a87b9085b6 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -110,9 +110,9 @@ SECTIONS
110 . = ALIGN(0x4) ; 110 . = ALIGN(0x4) ;
111 ___init_begin = .; 111 ___init_begin = .;
112 __sinittext = .; 112 __sinittext = .;
113 *(.init.text) 113 INIT_TEXT
114 __einittext = .; 114 __einittext = .;
115 *(.init.data) 115 INIT_DATA
116 . = ALIGN(0x4) ; 116 . = ALIGN(0x4) ;
117 ___setup_start = .; 117 ___setup_start = .;
118 *(.init.setup) 118 *(.init.setup)
@@ -124,8 +124,8 @@ SECTIONS
124 ___con_initcall_start = .; 124 ___con_initcall_start = .;
125 *(.con_initcall.init) 125 *(.con_initcall.init)
126 ___con_initcall_end = .; 126 ___con_initcall_end = .;
127 *(.exit.text) 127 EXIT_TEXT
128 *(.exit.data) 128 EXIT_DATA
129#if defined(CONFIG_BLK_DEV_INITRD) 129#if defined(CONFIG_BLK_DEV_INITRD)
130 . = ALIGN(4); 130 . = ALIGN(4);
131 ___initramfs_start = .; 131 ___initramfs_start = .;
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 757e419ebcf8..80622acc95de 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -27,8 +27,8 @@ SECTIONS
27{ 27{
28 /* Sections to be discarded */ 28 /* Sections to be discarded */
29 /DISCARD/ : { 29 /DISCARD/ : {
30 *(.exit.text) 30 EXIT_TEXT
31 *(.exit.data) 31 EXIT_DATA
32 *(.exitcall.exit) 32 *(.exitcall.exit)
33 *(.IA_64.unwind.exit.text) 33 *(.IA_64.unwind.exit.text)
34 *(.IA_64.unwind_info.exit.text) 34 *(.IA_64.unwind_info.exit.text)
@@ -119,12 +119,12 @@ SECTIONS
119 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) 119 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
120 { 120 {
121 _sinittext = .; 121 _sinittext = .;
122 *(.init.text) 122 INIT_TEXT
123 _einittext = .; 123 _einittext = .;
124 } 124 }
125 125
126 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) 126 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET)
127 { *(.init.data) } 127 { INIT_DATA }
128 128
129#ifdef CONFIG_BLK_DEV_INITRD 129#ifdef CONFIG_BLK_DEV_INITRD
130 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) 130 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET)
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 942a8c7a4417..41b07854fcc6 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -76,10 +76,10 @@ SECTIONS
76 __init_begin = .; 76 __init_begin = .;
77 .init.text : { 77 .init.text : {
78 _sinittext = .; 78 _sinittext = .;
79 *(.init.text) 79 INIT_TEXT
80 _einittext = .; 80 _einittext = .;
81 } 81 }
82 .init.data : { *(.init.data) } 82 .init.data : { INIT_DATA }
83 . = ALIGN(16); 83 . = ALIGN(16);
84 __setup_start = .; 84 __setup_start = .;
85 .init.setup : { *(.init.setup) } 85 .init.setup : { *(.init.setup) }
@@ -100,8 +100,8 @@ SECTIONS
100 .altinstr_replacement : { *(.altinstr_replacement) } 100 .altinstr_replacement : { *(.altinstr_replacement) }
101 /* .exit.text is discard at runtime, not link time, to deal with references 101 /* .exit.text is discard at runtime, not link time, to deal with references
102 from .altinstructions and .eh_frame */ 102 from .altinstructions and .eh_frame */
103 .exit.text : { *(.exit.text) } 103 .exit.text : { EXIT_TEXT }
104 .exit.data : { *(.exit.data) } 104 .exit.data : { EXIT_DATA }
105 105
106#ifdef CONFIG_BLK_DEV_INITRD 106#ifdef CONFIG_BLK_DEV_INITRD
107 . = ALIGN(4096); 107 . = ALIGN(4096);
@@ -124,8 +124,8 @@ SECTIONS
124 124
125 /* Sections to be discarded */ 125 /* Sections to be discarded */
126 /DISCARD/ : { 126 /DISCARD/ : {
127 *(.exit.text) 127 EXIT_TEXT
128 *(.exit.data) 128 EXIT_DATA
129 *(.exitcall.exit) 129 *(.exitcall.exit)
130 } 130 }
131 131
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 59fe285865ec..7537cc5e6159 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -45,10 +45,10 @@ SECTIONS
45 __init_begin = .; 45 __init_begin = .;
46 .init.text : { 46 .init.text : {
47 _sinittext = .; 47 _sinittext = .;
48 *(.init.text) 48 INIT_TEXT
49 _einittext = .; 49 _einittext = .;
50 } 50 }
51 .init.data : { *(.init.data) } 51 .init.data : { INIT_DATA }
52 . = ALIGN(16); 52 . = ALIGN(16);
53 __setup_start = .; 53 __setup_start = .;
54 .init.setup : { *(.init.setup) } 54 .init.setup : { *(.init.setup) }
@@ -82,8 +82,8 @@ SECTIONS
82 82
83 /* Sections to be discarded */ 83 /* Sections to be discarded */
84 /DISCARD/ : { 84 /DISCARD/ : {
85 *(.exit.text) 85 EXIT_TEXT
86 *(.exit.data) 86 EXIT_DATA
87 *(.exitcall.exit) 87 *(.exitcall.exit)
88 } 88 }
89 89
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 4adffefb5c48..cdc313e7c299 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -38,10 +38,10 @@ SECTIONS
38__init_begin = .; 38__init_begin = .;
39 .init.text : { 39 .init.text : {
40 _sinittext = .; 40 _sinittext = .;
41 *(.init.text) 41 INIT_TEXT
42 _einittext = .; 42 _einittext = .;
43 } 43 }
44 .init.data : { *(.init.data) } 44 .init.data : { INIT_DATA }
45 . = ALIGN(16); 45 . = ALIGN(16);
46 __setup_start = .; 46 __setup_start = .;
47 .init.setup : { *(.init.setup) } 47 .init.setup : { *(.init.setup) }
@@ -77,8 +77,8 @@ __init_begin = .;
77 77
78 /* Sections to be discarded */ 78 /* Sections to be discarded */
79 /DISCARD/ : { 79 /DISCARD/ : {
80 *(.exit.text) 80 EXIT_TEXT
81 *(.exit.data) 81 EXIT_DATA
82 *(.exitcall.exit) 82 *(.exitcall.exit)
83 } 83 }
84 84
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index 07a0055602f4..b44edb08e212 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -143,9 +143,9 @@ SECTIONS {
143 . = ALIGN(4096); 143 . = ALIGN(4096);
144 __init_begin = .; 144 __init_begin = .;
145 _sinittext = .; 145 _sinittext = .;
146 *(.init.text) 146 INIT_TEXT
147 _einittext = .; 147 _einittext = .;
148 *(.init.data) 148 INIT_DATA
149 . = ALIGN(16); 149 . = ALIGN(16);
150 __setup_start = .; 150 __setup_start = .;
151 *(.init.setup) 151 *(.init.setup)
@@ -170,8 +170,8 @@ SECTIONS {
170 } > INIT 170 } > INIT
171 171
172 /DISCARD/ : { 172 /DISCARD/ : {
173 *(.exit.text) 173 EXIT_TEXT
174 *(.exit.data) 174 EXIT_DATA
175 *(.exitcall.exit) 175 *(.exitcall.exit)
176 } 176 }
177 177
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b22c043b6ef8..6b0f85f02c79 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -37,16 +37,6 @@ config BASLER_EXCITE
37 The eXcite is a smart camera platform manufactured by 37 The eXcite is a smart camera platform manufactured by
38 Basler Vision Technologies AG. 38 Basler Vision Technologies AG.
39 39
40config BASLER_EXCITE_PROTOTYPE
41 bool "Support for pre-release units"
42 depends on BASLER_EXCITE
43 default n
44 help
45 Pre-series (prototype) units are different from later ones in
46 some ways. Select this option if you have one of these. Please
47 note that a kernel built with this option selected will not be
48 able to run on normal units.
49
50config BCM47XX 40config BCM47XX
51 bool "BCM47XX based boards" 41 bool "BCM47XX based boards"
52 select CEVT_R4K 42 select CEVT_R4K
@@ -82,7 +72,7 @@ config MIPS_COBALT
82 select SYS_HAS_CPU_NEVADA 72 select SYS_HAS_CPU_NEVADA
83 select SYS_HAS_EARLY_PRINTK 73 select SYS_HAS_EARLY_PRINTK
84 select SYS_SUPPORTS_32BIT_KERNEL 74 select SYS_SUPPORTS_32BIT_KERNEL
85 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL 75 select SYS_SUPPORTS_64BIT_KERNEL
86 select SYS_SUPPORTS_LITTLE_ENDIAN 76 select SYS_SUPPORTS_LITTLE_ENDIAN
87 select GENERIC_HARDIRQS_NO__DO_IRQ 77 select GENERIC_HARDIRQS_NO__DO_IRQ
88 78
@@ -91,6 +81,9 @@ config MACH_DECSTATION
91 select BOOT_ELF32 81 select BOOT_ELF32
92 select CEVT_R4K 82 select CEVT_R4K
93 select CSRC_R4K 83 select CSRC_R4K
84 select CPU_DADDI_WORKAROUNDS if 64BIT
85 select CPU_R4000_WORKAROUNDS if 64BIT
86 select CPU_R4400_WORKAROUNDS if 64BIT
94 select DMA_NONCOHERENT 87 select DMA_NONCOHERENT
95 select NO_IOPORT 88 select NO_IOPORT
96 select IRQ_CPU 89 select IRQ_CPU
@@ -124,12 +117,12 @@ config MACH_JAZZ
124 select ARCH_MAY_HAVE_PC_FDC 117 select ARCH_MAY_HAVE_PC_FDC
125 select CEVT_R4K 118 select CEVT_R4K
126 select CSRC_R4K 119 select CSRC_R4K
120 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
127 select GENERIC_ISA_DMA 121 select GENERIC_ISA_DMA
128 select IRQ_CPU 122 select IRQ_CPU
129 select I8253 123 select I8253
130 select I8259 124 select I8259
131 select ISA 125 select ISA
132 select PCSPEAKER
133 select SYS_HAS_CPU_R4X00 126 select SYS_HAS_CPU_R4X00
134 select SYS_SUPPORTS_32BIT_KERNEL 127 select SYS_SUPPORTS_32BIT_KERNEL
135 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL 128 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
@@ -187,6 +180,7 @@ config LEMOTE_FULONG
187config MIPS_ATLAS 180config MIPS_ATLAS
188 bool "MIPS Atlas board" 181 bool "MIPS Atlas board"
189 select BOOT_ELF32 182 select BOOT_ELF32
183 select BOOT_RAW
190 select CEVT_R4K 184 select CEVT_R4K
191 select CSRC_R4K 185 select CSRC_R4K
192 select DMA_NONCOHERENT 186 select DMA_NONCOHERENT
@@ -219,6 +213,7 @@ config MIPS_MALTA
219 bool "MIPS Malta board" 213 bool "MIPS Malta board"
220 select ARCH_MAY_HAVE_PC_FDC 214 select ARCH_MAY_HAVE_PC_FDC
221 select BOOT_ELF32 215 select BOOT_ELF32
216 select BOOT_RAW
222 select CEVT_R4K 217 select CEVT_R4K
223 select CSRC_R4K 218 select CSRC_R4K
224 select DMA_NONCOHERENT 219 select DMA_NONCOHERENT
@@ -364,35 +359,6 @@ config PMC_YOSEMITE
364 Yosemite is an evaluation board for the RM9000x2 processor 359 Yosemite is an evaluation board for the RM9000x2 processor
365 manufactured by PMC-Sierra. 360 manufactured by PMC-Sierra.
366 361
367config QEMU
368 bool "Qemu"
369 select CEVT_R4K
370 select CSRC_R4K
371 select DMA_COHERENT
372 select GENERIC_ISA_DMA
373 select HAVE_STD_PC_SERIAL_PORT
374 select I8253
375 select I8259
376 select IRQ_CPU
377 select ISA
378 select PCSPEAKER
379 select SWAP_IO_SPACE
380 select SYS_HAS_CPU_MIPS32_R1
381 select SYS_HAS_EARLY_PRINTK
382 select SYS_SUPPORTS_32BIT_KERNEL
383 select SYS_SUPPORTS_BIG_ENDIAN
384 select SYS_SUPPORTS_LITTLE_ENDIAN
385 select GENERIC_HARDIRQS_NO__DO_IRQ
386 select NR_CPUS_DEFAULT_1
387 select SYS_SUPPORTS_SMP
388 help
389 Qemu is a software emulator which among other architectures also
390 can simulate a MIPS32 4Kc system. This patch adds support for the
391 system architecture that currently is being simulated by Qemu. It
392 will eventually be removed again when Qemu has the capability to
393 simulate actual MIPS hardware platforms. More information on Qemu
394 can be found at http://www.linux-mips.org/wiki/Qemu.
395
396config SGI_IP22 362config SGI_IP22
397 bool "SGI IP22 (Indy/Indigo2)" 363 bool "SGI IP22 (Indy/Indigo2)"
398 select ARC 364 select ARC
@@ -400,6 +366,7 @@ config SGI_IP22
400 select BOOT_ELF32 366 select BOOT_ELF32
401 select CEVT_R4K 367 select CEVT_R4K
402 select CSRC_R4K 368 select CSRC_R4K
369 select DEFAULT_SGI_PARTITION
403 select DMA_NONCOHERENT 370 select DMA_NONCOHERENT
404 select HW_HAS_EISA 371 select HW_HAS_EISA
405 select I8253 372 select I8253
@@ -407,6 +374,12 @@ config SGI_IP22
407 select IP22_CPU_SCACHE 374 select IP22_CPU_SCACHE
408 select IRQ_CPU 375 select IRQ_CPU
409 select GENERIC_ISA_DMA_SUPPORT_BROKEN 376 select GENERIC_ISA_DMA_SUPPORT_BROKEN
377 select SGI_HAS_DS1286
378 select SGI_HAS_I8042
379 select SGI_HAS_INDYDOG
380 select SGI_HAS_SEEQ
381 select SGI_HAS_WD93
382 select SGI_HAS_ZILOG
410 select SWAP_IO_SPACE 383 select SWAP_IO_SPACE
411 select SYS_HAS_CPU_R4X00 384 select SYS_HAS_CPU_R4X00
412 select SYS_HAS_CPU_R5000 385 select SYS_HAS_CPU_R5000
@@ -424,6 +397,7 @@ config SGI_IP27
424 select ARC 397 select ARC
425 select ARC64 398 select ARC64
426 select BOOT_ELF64 399 select BOOT_ELF64
400 select DEFAULT_SGI_PARTITION
427 select DMA_IP27 401 select DMA_IP27
428 select SYS_HAS_EARLY_PRINTK 402 select SYS_HAS_EARLY_PRINTK
429 select HW_HAS_PCI 403 select HW_HAS_PCI
@@ -440,6 +414,36 @@ config SGI_IP27
440 workstations. To compile a Linux kernel that runs on these, say Y 414 workstations. To compile a Linux kernel that runs on these, say Y
441 here. 415 here.
442 416
417config SGI_IP28
418 bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)"
419 depends on EXPERIMENTAL
420 select ARC
421 select ARC64
422 select BOOT_ELF64
423 select CEVT_R4K
424 select CSRC_R4K
425 select DEFAULT_SGI_PARTITION
426 select DMA_NONCOHERENT
427 select GENERIC_ISA_DMA_SUPPORT_BROKEN
428 select IRQ_CPU
429 select HW_HAS_EISA
430 select I8253
431 select I8259
432 select SGI_HAS_DS1286
433 select SGI_HAS_I8042
434 select SGI_HAS_INDYDOG
435 select SGI_HAS_SEEQ
436 select SGI_HAS_WD93
437 select SGI_HAS_ZILOG
438 select SWAP_IO_SPACE
439 select SYS_HAS_CPU_R10000
440 select SYS_HAS_EARLY_PRINTK
441 select SYS_SUPPORTS_64BIT_KERNEL
442 select SYS_SUPPORTS_BIG_ENDIAN
443 help
444 This is the SGI Indigo2 with R10000 processor. To compile a Linux
445 kernel that runs on these, say Y here.
446
443config SGI_IP32 447config SGI_IP32
444 bool "SGI IP32 (O2)" 448 bool "SGI IP32 (O2)"
445 select ARC 449 select ARC
@@ -545,19 +549,6 @@ config SIBYTE_SENTOSA
545 select SYS_SUPPORTS_BIG_ENDIAN 549 select SYS_SUPPORTS_BIG_ENDIAN
546 select SYS_SUPPORTS_LITTLE_ENDIAN 550 select SYS_SUPPORTS_LITTLE_ENDIAN
547 551
548config SIBYTE_PTSWARM
549 bool "Sibyte BCM91250PT-PTSWARM"
550 depends on EXPERIMENTAL
551 select BOOT_ELF32
552 select DMA_COHERENT
553 select NR_CPUS_DEFAULT_2
554 select SIBYTE_SB1250
555 select SWAP_IO_SPACE
556 select SYS_HAS_CPU_SB1
557 select SYS_SUPPORTS_BIG_ENDIAN
558 select SYS_SUPPORTS_HIGHMEM
559 select SYS_SUPPORTS_LITTLE_ENDIAN
560
561config SIBYTE_BIGSUR 552config SIBYTE_BIGSUR
562 bool "Sibyte BCM91480B-BigSur" 553 bool "Sibyte BCM91480B-BigSur"
563 select BOOT_ELF32 554 select BOOT_ELF32
@@ -575,10 +566,12 @@ config SNI_RM
575 bool "SNI RM200/300/400" 566 bool "SNI RM200/300/400"
576 select ARC if CPU_LITTLE_ENDIAN 567 select ARC if CPU_LITTLE_ENDIAN
577 select ARC32 if CPU_LITTLE_ENDIAN 568 select ARC32 if CPU_LITTLE_ENDIAN
569 select SNIPROM if CPU_BIG_ENDIAN
578 select ARCH_MAY_HAVE_PC_FDC 570 select ARCH_MAY_HAVE_PC_FDC
579 select BOOT_ELF32 571 select BOOT_ELF32
580 select CEVT_R4K 572 select CEVT_R4K
581 select CSRC_R4K 573 select CSRC_R4K
574 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
582 select DMA_NONCOHERENT 575 select DMA_NONCOHERENT
583 select GENERIC_ISA_DMA 576 select GENERIC_ISA_DMA
584 select HW_HAS_EISA 577 select HW_HAS_EISA
@@ -587,7 +580,6 @@ config SNI_RM
587 select I8253 580 select I8253
588 select I8259 581 select I8259
589 select ISA 582 select ISA
590 select PCSPEAKER
591 select SWAP_IO_SPACE if CPU_BIG_ENDIAN 583 select SWAP_IO_SPACE if CPU_BIG_ENDIAN
592 select SYS_HAS_CPU_R4X00 584 select SYS_HAS_CPU_R4X00
593 select SYS_HAS_CPU_R5000 585 select SYS_HAS_CPU_R5000
@@ -690,6 +682,7 @@ config WR_PPMC
690endchoice 682endchoice
691 683
692source "arch/mips/au1000/Kconfig" 684source "arch/mips/au1000/Kconfig"
685source "arch/mips/basler/excite/Kconfig"
693source "arch/mips/jazz/Kconfig" 686source "arch/mips/jazz/Kconfig"
694source "arch/mips/lasat/Kconfig" 687source "arch/mips/lasat/Kconfig"
695source "arch/mips/pmc-sierra/Kconfig" 688source "arch/mips/pmc-sierra/Kconfig"
@@ -797,10 +790,6 @@ config DMA_COHERENT
797config DMA_IP27 790config DMA_IP27
798 bool 791 bool
799 792
800config DMA_IP32
801 bool
802 select DMA_NEED_PCI_MAP_STATE
803
804config DMA_NONCOHERENT 793config DMA_NONCOHERENT
805 bool 794 bool
806 select DMA_NEED_PCI_MAP_STATE 795 select DMA_NEED_PCI_MAP_STATE
@@ -956,16 +945,40 @@ config EMMA2RH
956config SERIAL_RM9000 945config SERIAL_RM9000
957 bool 946 bool
958 947
948config SGI_HAS_DS1286
949 bool
950
951config SGI_HAS_INDYDOG
952 bool
953
954config SGI_HAS_SEEQ
955 bool
956
957config SGI_HAS_WD93
958 bool
959
960config SGI_HAS_ZILOG
961 bool
962
963config SGI_HAS_I8042
964 bool
965
966config DEFAULT_SGI_PARTITION
967 bool
968
959config ARC32 969config ARC32
960 bool 970 bool
961 971
972config SNIPROM
973 bool
974
962config BOOT_ELF32 975config BOOT_ELF32
963 bool 976 bool
964 977
965config MIPS_L1_CACHE_SHIFT 978config MIPS_L1_CACHE_SHIFT
966 int 979 int
967 default "4" if MACH_DECSTATION 980 default "4" if MACH_DECSTATION
968 default "7" if SGI_IP27 || SNI_RM 981 default "7" if SGI_IP27 || SGI_IP28 || SNI_RM
969 default "4" if PMC_MSP4200_EVAL 982 default "4" if PMC_MSP4200_EVAL
970 default "5" 983 default "5"
971 984
@@ -974,7 +987,7 @@ config HAVE_STD_PC_SERIAL_PORT
974 987
975config ARC_CONSOLE 988config ARC_CONSOLE
976 bool "ARC console support" 989 bool "ARC console support"
977 depends on SGI_IP22 || (SNI_RM && CPU_LITTLE_ENDIAN) 990 depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
978 991
979config ARC_MEMORY 992config ARC_MEMORY
980 bool 993 bool
@@ -983,7 +996,7 @@ config ARC_MEMORY
983 996
984config ARC_PROMLIB 997config ARC_PROMLIB
985 bool 998 bool
986 depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP32 999 depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
987 default y 1000 default y
988 1001
989config ARC64 1002config ARC64
@@ -1443,7 +1456,9 @@ config MIPS_MT_SMP
1443 select MIPS_MT 1456 select MIPS_MT
1444 select NR_CPUS_DEFAULT_2 1457 select NR_CPUS_DEFAULT_2
1445 select SMP 1458 select SMP
1459 select SYS_SUPPORTS_SCHED_SMT if SMP
1446 select SYS_SUPPORTS_SMP 1460 select SYS_SUPPORTS_SMP
1461 select SMP_UP
1447 help 1462 help
1448 This is a kernel model which is also known a VSMP or lately 1463 This is a kernel model which is also known a VSMP or lately
1449 has been marketesed into SMVP. 1464 has been marketesed into SMVP.
@@ -1460,6 +1475,7 @@ config MIPS_MT_SMTC
1460 select NR_CPUS_DEFAULT_8 1475 select NR_CPUS_DEFAULT_8
1461 select SMP 1476 select SMP
1462 select SYS_SUPPORTS_SMP 1477 select SYS_SUPPORTS_SMP
1478 select SMP_UP
1463 help 1479 help
1464 This is a kernel model which is known a SMTC or lately has been 1480 This is a kernel model which is known a SMTC or lately has been
1465 marketesed into SMVP. 1481 marketesed into SMVP.
@@ -1469,6 +1485,19 @@ endchoice
1469config MIPS_MT 1485config MIPS_MT
1470 bool 1486 bool
1471 1487
1488config SCHED_SMT
1489 bool "SMT (multithreading) scheduler support"
1490 depends on SYS_SUPPORTS_SCHED_SMT
1491 default n
1492 help
1493 SMT scheduler support improves the CPU scheduler's decision making
1494 when dealing with MIPS MT enabled cores at a cost of slightly
1495 increased overhead in some places. If unsure say N here.
1496
1497config SYS_SUPPORTS_SCHED_SMT
1498 bool
1499
1500
1472config SYS_SUPPORTS_MULTITHREADING 1501config SYS_SUPPORTS_MULTITHREADING
1473 bool 1502 bool
1474 1503
@@ -1589,15 +1618,6 @@ config CPU_HAS_SMARTMIPS
1589config CPU_HAS_WB 1618config CPU_HAS_WB
1590 bool 1619 bool
1591 1620
1592config 64BIT_CONTEXT
1593 bool "Save 64bit integer registers"
1594 depends on 32BIT && CPU_LOONGSON2
1595 help
1596 Loongson2 CPU is 64bit , when used in 32BIT mode, its integer
1597 registers can still be accessed as 64bit, mainly for multimedia
1598 instructions. We must have all 64bit save/restored to make sure
1599 those instructions to get correct result.
1600
1601# 1621#
1602# Vectored interrupt mode is an R2 feature 1622# Vectored interrupt mode is an R2 feature
1603# 1623#
@@ -1619,6 +1639,19 @@ config GENERIC_CLOCKEVENTS_BROADCAST
1619 bool 1639 bool
1620 1640
1621# 1641#
1642# CPU non-features
1643#
1644config CPU_DADDI_WORKAROUNDS
1645 bool
1646
1647config CPU_R4000_WORKAROUNDS
1648 bool
1649 select CPU_R4400_WORKAROUNDS
1650
1651config CPU_R4400_WORKAROUNDS
1652 bool
1653
1654#
1622# Use the generic interrupt handling code in kernel/irq/: 1655# Use the generic interrupt handling code in kernel/irq/:
1623# 1656#
1624config GENERIC_HARDIRQS 1657config GENERIC_HARDIRQS
@@ -1721,6 +1754,9 @@ config SMP
1721 1754
1722 If you don't know what to do here, say N. 1755 If you don't know what to do here, say N.
1723 1756
1757config SMP_UP
1758 bool
1759
1724config SYS_SUPPORTS_SMP 1760config SYS_SUPPORTS_SMP
1725 bool 1761 bool
1726 1762
@@ -1978,9 +2014,6 @@ config MMU
1978config I8253 2014config I8253
1979 bool 2015 bool
1980 2016
1981config PCSPEAKER
1982 bool
1983
1984config ZONE_DMA32 2017config ZONE_DMA32
1985 bool 2018 bool
1986 2019
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index a1f8d8b96b03..3fb7f3065c92 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -141,6 +141,10 @@ cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
141cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ 141cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
142 -Wa,--trap 142 -Wa,--trap
143 143
144cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
145cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
146cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
147
144ifdef CONFIG_CPU_SB1 148ifdef CONFIG_CPU_SB1
145ifdef CONFIG_SB1_PASS_1_WORKAROUNDS 149ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
146MODFLAGS += -msb1-pass1-workarounds 150MODFLAGS += -msb1-pass1-workarounds
@@ -152,6 +156,8 @@ endif
152# 156#
153libs-$(CONFIG_ARC) += arch/mips/fw/arc/ 157libs-$(CONFIG_ARC) += arch/mips/fw/arc/
154libs-$(CONFIG_CFE) += arch/mips/fw/cfe/ 158libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
159libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
160libs-y += arch/mips/fw/lib/
155libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/ 161libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/
156 162
157# 163#
@@ -308,7 +314,7 @@ core-$(CONFIG_MIPS_ATLAS) += arch/mips/mips-boards/atlas/
308cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-atlas 314cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-atlas
309cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-mips 315cflags-$(CONFIG_MIPS_ATLAS) += -Iinclude/asm-mips/mach-mips
310load-$(CONFIG_MIPS_ATLAS) += 0xffffffff80100000 316load-$(CONFIG_MIPS_ATLAS) += 0xffffffff80100000
311all-$(CONFIG_MIPS_ATLAS) := vmlinux.srec 317all-$(CONFIG_MIPS_ATLAS) := vmlinux.bin
312 318
313# 319#
314# MIPS Malta board 320# MIPS Malta board
@@ -316,7 +322,7 @@ all-$(CONFIG_MIPS_ATLAS) := vmlinux.srec
316core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ 322core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/
317cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips 323cflags-$(CONFIG_MIPS_MALTA) += -Iinclude/asm-mips/mach-mips
318load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 324load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
319all-$(CONFIG_MIPS_MALTA) := vmlinux.srec 325all-$(CONFIG_MIPS_MALTA) := vmlinux.bin
320 326
321# 327#
322# MIPS SEAD board 328# MIPS SEAD board
@@ -349,14 +355,6 @@ cflags-$(CONFIG_PMC_YOSEMITE) += -Iinclude/asm-mips/mach-yosemite
349load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000 355load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000
350 356
351# 357#
352# Qemu simulating MIPS32 4Kc
353#
354core-$(CONFIG_QEMU) += arch/mips/qemu/
355cflags-$(CONFIG_QEMU) += -Iinclude/asm-mips/mach-qemu
356load-$(CONFIG_QEMU) += 0xffffffff80010000
357all-$(CONFIG_QEMU) := vmlinux.bin
358
359#
360# Basler eXcite 358# Basler eXcite
361# 359#
362core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/ 360core-$(CONFIG_BASLER_EXCITE) += arch/mips/basler/excite/
@@ -475,6 +473,20 @@ endif
475endif 473endif
476 474
477# 475#
476# SGI IP28 (Indigo2 R10k)
477#
478# Set the load address to >= 0xa800000020080000 if you want to leave space for
479# symmon, 0xa800000020004000 for production kernels ? Note that the value must
480# be 16kb aligned or the handling of the current variable will break.
481# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
482#
483#core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/ arch/mips/arc/arc_con.o
484core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/
485cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=1 -Iinclude/asm-mips/mach-ip28
486#cflags-$(CONFIG_SGI_IP28) += -Iinclude/asm-mips/mach-ip28
487load-$(CONFIG_SGI_IP28) += 0xa800000020004000
488
489#
478# SGI-IP32 (O2) 490# SGI-IP32 (O2)
479# 491#
480# Set the load address to >= 80069000 if you want to leave space for symmon, 492# Set the load address to >= 80069000 if you want to leave space for symmon,
@@ -602,9 +614,11 @@ ifdef CONFIG_64BIT
602 endif 614 endif
603 endif 615 endif
604 616
605 ifeq ($(KBUILD_SYM32), y) 617 ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy)
606 ifeq ($(call cc-option-yn,-msym32), y) 618 cflags-y += -msym32 -DKBUILD_64BIT_SYM32
607 cflags-y += -msym32 -DKBUILD_64BIT_SYM32 619 else
620 ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y)
621 $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32)
608 endif 622 endif
609 endif 623 endif
610endif 624endif
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 98a4e34b0248..37a10a01de9d 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -25,27 +25,10 @@
25 * with this program; if not, write to the Free Software Foundation, Inc., 25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28#include <linux/errno.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/irq.h> 29#include <linux/kernel.h>
31#include <linux/kernel_stat.h>
32#include <linux/module.h>
33#include <linux/signal.h>
34#include <linux/sched.h>
35#include <linux/types.h>
36#include <linux/interrupt.h>
37#include <linux/ioport.h>
38#include <linux/timex.h>
39#include <linux/slab.h>
40#include <linux/random.h>
41#include <linux/delay.h>
42#include <linux/bitops.h>
43 30
44#include <asm/bootinfo.h> 31#include <au1000.h>
45#include <asm/io.h>
46#include <asm/mipsregs.h>
47#include <asm/system.h>
48#include <asm/mach-au1x00/au1000.h>
49 32
50/* The IC0 interrupt table. This is processor, rather than 33/* The IC0 interrupt table. This is processor, rather than
51 * board dependent, so no reason to keep this info in the board 34 * board dependent, so no reason to keep this info in the board
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index edf91f41a786..428ed275a0f6 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -179,7 +179,7 @@ static dbdev_tab_t dbdev_tab[] = {
179 { 0, 0, 0, 0, 0, 0, 0 }, 179 { 0, 0, 0, 0, 0, 0, 0 },
180}; 180};
181 181
182#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) 182#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
183 183
184static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 184static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
185 185
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index 43298fd9459c..e822c123eab8 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -57,17 +57,6 @@ void __init prom_init(void)
57 prom_argv = (char **) fw_arg1; 57 prom_argv = (char **) fw_arg1;
58 prom_envp = (char **) fw_arg2; 58 prom_envp = (char **) fw_arg2;
59 59
60 /* Set the platform # */
61#if defined(CONFIG_MIPS_DB1550)
62 mips_machtype = MACH_DB1550;
63#elif defined(CONFIG_MIPS_DB1500)
64 mips_machtype = MACH_DB1500;
65#elif defined(CONFIG_MIPS_DB1100)
66 mips_machtype = MACH_DB1100;
67#else
68 mips_machtype = MACH_DB1000;
69#endif
70
71 prom_init_cmdline(); 60 prom_init_cmdline();
72 61
73 memsize_str = prom_getenv("memsize"); 62 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index cdeae3212a2d..e700fd312a24 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -54,8 +54,6 @@ void __init prom_init(void)
54 prom_argv = (char **) fw_arg1; 54 prom_argv = (char **) fw_arg1;
55 prom_envp = (char **) fw_arg2; 55 prom_envp = (char **) fw_arg2;
56 56
57 mips_machtype = MACH_MTX1; /* set the platform # */
58
59 prom_init_cmdline(); 57 prom_init_cmdline();
60 58
61 memsize_str = prom_getenv("memsize"); 59 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
index 49c0fb409fea..ce8637b3afa9 100644
--- a/arch/mips/au1000/mtx-1/platform.c
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -22,9 +22,32 @@
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/leds.h> 24#include <linux/leds.h>
25#include <linux/gpio_keys.h>
26#include <linux/input.h>
25 27
26#include <asm/gpio.h> 28#include <asm/gpio.h>
27 29
30static struct gpio_keys_button mtx1_gpio_button[] = {
31 {
32 .gpio = 207,
33 .code = BTN_0,
34 .desc = "System button",
35 }
36};
37
38static struct gpio_keys_platform_data mtx1_buttons_data = {
39 .buttons = mtx1_gpio_button,
40 .nbuttons = ARRAY_SIZE(mtx1_gpio_button),
41};
42
43static struct platform_device mtx1_button = {
44 .name = "gpio-keys",
45 .id = -1,
46 .dev = {
47 .platform_data = &mtx1_buttons_data,
48 }
49};
50
28static struct resource mtx1_wdt_res[] = { 51static struct resource mtx1_wdt_res[] = {
29 [0] = { 52 [0] = {
30 .start = 15, 53 .start = 15,
@@ -66,11 +89,13 @@ static struct platform_device mtx1_gpio_leds = {
66 89
67static struct __initdata platform_device * mtx1_devs[] = { 90static struct __initdata platform_device * mtx1_devs[] = {
68 &mtx1_gpio_leds, 91 &mtx1_gpio_leds,
69 &mtx1_wdt 92 &mtx1_wdt,
93 &mtx1_button
70}; 94};
71 95
72static int __init mtx1_register_devices(void) 96static int __init mtx1_register_devices(void)
73{ 97{
98 gpio_direction_input(207);
74 return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); 99 return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
75} 100}
76 101
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index ddccaf6997d0..2515b9fb24af 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -52,8 +52,6 @@ void __init prom_init(void)
52 prom_argv = (char **) fw_arg1; 52 prom_argv = (char **) fw_arg1;
53 prom_envp = (char **) fw_arg2; 53 prom_envp = (char **) fw_arg2;
54 54
55 mips_machtype = MACH_PB1000;
56
57 prom_init_cmdline(); 55 prom_init_cmdline();
58 memsize_str = prom_getenv("memsize"); 56 memsize_str = prom_getenv("memsize");
59 if (!memsize_str) { 57 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index c93fd39b4aba..490c3801c275 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg3; 54 prom_envp = (char **) fw_arg3;
55 55
56 mips_machtype = MACH_PB1100;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 57
60 memsize_str = prom_getenv("memsize"); 58 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index c251570749ee..069ed45f04f2 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1200;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index 507d4b204161..db558c967048 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1500;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index b03eee601e36..b716363ea564 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -53,8 +53,6 @@ void __init prom_init(void)
53 prom_argv = (char **) fw_arg1; 53 prom_argv = (char **) fw_arg1;
54 prom_envp = (char **) fw_arg2; 54 prom_envp = (char **) fw_arg2;
55 55
56 mips_machtype = MACH_PB1550;
57
58 prom_init_cmdline(); 56 prom_init_cmdline();
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
60 if (!memsize_str) { 58 if (!memsize_str) {
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 6532939f377a..7e6878c1b0a5 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -52,8 +52,6 @@ void __init prom_init(void)
52 prom_argv = (char **) fw_arg1; 52 prom_argv = (char **) fw_arg1;
53 prom_envp = (char **) fw_arg2; 53 prom_envp = (char **) fw_arg2;
54 54
55 mips_machtype = MACH_XXS1500; /* set the platform # */
56
57 prom_init_cmdline(); 55 prom_init_cmdline();
58 56
59 memsize_str = prom_getenv("memsize"); 57 memsize_str = prom_getenv("memsize");
diff --git a/arch/mips/basler/excite/Kconfig b/arch/mips/basler/excite/Kconfig
new file mode 100644
index 000000000000..ba506075608b
--- /dev/null
+++ b/arch/mips/basler/excite/Kconfig
@@ -0,0 +1,9 @@
1config BASLER_EXCITE_PROTOTYPE
2 bool "Support for pre-release units"
3 depends on BASLER_EXCITE
4 default n
5 help
6 Pre-series (prototype) units are different from later ones in
7 some ways. Select this option if you have one of these. Please
8 note that a kernel built with this option selected will not be
9 able to run on normal units.
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index 6af0b21ebc32..476d20e08d0e 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -48,7 +48,7 @@ static DECLARE_WAIT_QUEUE_HEAD(wq);
48 48
49 49
50 50
51static struct file_operations fops = 51static const struct file_operations fops =
52{ 52{
53 .owner = THIS_MODULE, 53 .owner = THIS_MODULE,
54 .open = iodev_open, 54 .open = iodev_open,
diff --git a/arch/mips/basler/excite/excite_prom.c b/arch/mips/basler/excite/excite_prom.c
index 2d752c2f6e59..68d8bc597e34 100644
--- a/arch/mips/basler/excite/excite_prom.c
+++ b/arch/mips/basler/excite/excite_prom.c
@@ -135,8 +135,6 @@ void __init prom_init(void)
135#ifdef CONFIG_64BIT 135#ifdef CONFIG_64BIT
136# error 64 bit support not implemented 136# error 64 bit support not implemented
137#endif /* CONFIG_64BIT */ 137#endif /* CONFIG_64BIT */
138
139 mips_machtype = MACH_TITAN_EXCITE;
140} 138}
141 139
142/* This is called from free_initmem(), so we need to provide it */ 140/* This is called from free_initmem(), so we need to provide it */
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 71eb4ccc4bc1..516b4428df4e 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -10,9 +10,10 @@
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/jiffies.h>
14#include <linux/leds.h> 13#include <linux/leds.h>
15 14
15#include <asm/processor.h>
16
16#include <cobalt.h> 17#include <cobalt.h>
17 18
18#define RESET_PORT ((void __iomem *)CKSEG1ADDR(0x1c000000)) 19#define RESET_PORT ((void __iomem *)CKSEG1ADDR(0x1c000000))
@@ -29,28 +30,15 @@ device_initcall(ledtrig_power_off_init);
29 30
30void cobalt_machine_halt(void) 31void cobalt_machine_halt(void)
31{ 32{
32 int state, last, diff;
33 unsigned long mark;
34
35 /* 33 /*
36 * turn on power off LED on RaQ 34 * turn on power off LED on RaQ
37 *
38 * restart if ENTER and SELECT are pressed
39 */ 35 */
40
41 last = COBALT_KEY_PORT;
42
43 led_trigger_event(power_off_led_trigger, LED_FULL); 36 led_trigger_event(power_off_led_trigger, LED_FULL);
44 37
45 for (state = 0;;) { 38 local_irq_disable();
46 diff = COBALT_KEY_PORT ^ last; 39 while (1) {
47 last ^= diff; 40 if (cpu_wait)
48 41 cpu_wait();
49 if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
50 writeb(RESET, RESET_PORT);
51
52 for (mark = jiffies; jiffies - mark < HZ;)
53 ;
54 } 42 }
55} 43}
56 44
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 62bcc887f2ca..3443f6cd57bb 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -37,7 +37,6 @@ CONFIG_MIPS_ATLAS=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MIPS_ATLAS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 3c70c9d16d01..abf70d74e9d7 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SIBYTE_BIGSUR=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index 8ecbbb226c76..a94f14b5c8fa 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 36c13039e237..b7295e988381 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS_COBALT=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS_COBALT=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 5a8b7acb7dd7..36578968d386 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1000=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1000=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index d4ed90bca269..5a90740c363a 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1100=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1100=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index a055657e6983..76f37a1159fe 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1200=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1200=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 0ad08cf446ec..508c91944f30 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1500=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1500=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 057c7d429c80..0c2c70d21db9 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_DB1550=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_DB1550=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 2fb350432669..58c2cd68c3a7 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -37,7 +37,6 @@ CONFIG_MACH_DECSTATION=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MACH_DECSTATION=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index d0d07faeb844..90d81f5dcebc 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index d73d965f7615..f9a003c2b3a1 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41CONFIG_MARKEINS=y 40CONFIG_MARKEINS=y
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MARKEINS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 17a866057fd4..15efacc75d73 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -38,7 +38,6 @@ CONFIG_BASLER_EXCITE=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_BASLER_EXCITE=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
index 4ef39a0527cc..5887a1735fba 100644
--- a/arch/mips/configs/fulong_defconfig
+++ b/arch/mips/configs/fulong_defconfig
@@ -23,7 +23,6 @@ CONFIG_LEMOTE_FULONG=y
23# CONFIG_PNX8550_STB810 is not set 23# CONFIG_PNX8550_STB810 is not set
24# CONFIG_MACH_VR41XX is not set 24# CONFIG_MACH_VR41XX is not set
25# CONFIG_PMC_YOSEMITE is not set 25# CONFIG_PMC_YOSEMITE is not set
26# CONFIG_QEMU is not set
27# CONFIG_MARKEINS is not set 26# CONFIG_MARKEINS is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
@@ -33,7 +32,6 @@ CONFIG_LEMOTE_FULONG=y
33# CONFIG_SIBYTE_SENTOSA is not set 32# CONFIG_SIBYTE_SENTOSA is not set
34# CONFIG_SIBYTE_RHONE is not set 33# CONFIG_SIBYTE_RHONE is not set
35# CONFIG_SIBYTE_CARMEL is not set 34# CONFIG_SIBYTE_CARMEL is not set
36# CONFIG_SIBYTE_PTSWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_CRHINE is not set 36# CONFIG_SIBYTE_CRHINE is not set
39# CONFIG_SIBYTE_CRHONE is not set 37# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 670039bb1a7c..4f5e56c9335e 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29CONFIG_SGI_IP22=y 28CONFIG_SGI_IP22=y
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_SGI_IP22=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 892d4c38fd0d..f40e437bd9e5 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29CONFIG_SGI_IP27=y 28CONFIG_SGI_IP27=y
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_SGI_IP27=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 47f49b60c5d6..2c5c624c5d42 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SGI_IP32=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index fa655e247ecc..56148745e8f2 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -37,7 +37,6 @@ CONFIG_MACH_JAZZ=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MACH_JAZZ=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index eb96791c33ea..a7cd67753aac 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41CONFIG_TOSHIBA_JMR3927=y 39CONFIG_TOSHIBA_JMR3927=y
@@ -464,7 +462,6 @@ CONFIG_SERIAL_TXX9_STDSERIAL=y
464CONFIG_LEGACY_PTYS=y 462CONFIG_LEGACY_PTYS=y
465CONFIG_LEGACY_PTY_COUNT=256 463CONFIG_LEGACY_PTY_COUNT=256
466# CONFIG_IPMI_HANDLER is not set 464# CONFIG_IPMI_HANDLER is not set
467# CONFIG_WATCHDOG is not set
468# CONFIG_HW_RANDOM is not set 465# CONFIG_HW_RANDOM is not set
469# CONFIG_RTC is not set 466# CONFIG_RTC is not set
470# CONFIG_R3964 is not set 467# CONFIG_R3964 is not set
@@ -482,6 +479,20 @@ CONFIG_DEVPORT=y
482# CONFIG_W1 is not set 479# CONFIG_W1 is not set
483# CONFIG_POWER_SUPPLY is not set 480# CONFIG_POWER_SUPPLY is not set
484# CONFIG_HWMON is not set 481# CONFIG_HWMON is not set
482CONFIG_WATCHDOG=y
483# CONFIG_WATCHDOG_NOWAYOUT is not set
484
485#
486# Watchdog Device Drivers
487#
488# CONFIG_SOFT_WATCHDOG is not set
489CONFIG_TXX9_WDT=y
490
491#
492# PCI-based Watchdog Cards
493#
494# CONFIG_PCIPCWATCHDOG is not set
495# CONFIG_WDTPCI is not set
485 496
486# 497#
487# Multifunction device drivers 498# Multifunction device drivers
diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig
index 2c665fcef089..e6aef999854c 100644
--- a/arch/mips/configs/lasat_defconfig
+++ b/arch/mips/configs/lasat_defconfig
@@ -25,7 +25,6 @@ CONFIG_LASAT=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29# CONFIG_SGI_IP22 is not set 28# CONFIG_SGI_IP22 is not set
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_LASAT=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 4b7e43c9f69a..3d0da952811c 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_MALTA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29# CONFIG_SGI_IP22 is not set 28# CONFIG_SGI_IP22 is not set
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_MIPS_MALTA=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 61b72f5a953e..6db0bdaefb27 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -26,7 +26,6 @@ CONFIG_MIPS_SIM=y
26# CONFIG_PNX8550_STB810 is not set 26# CONFIG_PNX8550_STB810 is not set
27# CONFIG_PMC_MSP is not set 27# CONFIG_PMC_MSP is not set
28# CONFIG_PMC_YOSEMITE is not set 28# CONFIG_PMC_YOSEMITE is not set
29# CONFIG_QEMU is not set
30# CONFIG_SGI_IP22 is not set 29# CONFIG_SGI_IP22 is not set
31# CONFIG_SGI_IP27 is not set 30# CONFIG_SGI_IP27 is not set
32# CONFIG_SGI_IP32 is not set 31# CONFIG_SGI_IP32 is not set
@@ -37,7 +36,6 @@ CONFIG_MIPS_SIM=y
37# CONFIG_SIBYTE_SWARM is not set 36# CONFIG_SIBYTE_SWARM is not set
38# CONFIG_SIBYTE_LITTLESUR is not set 37# CONFIG_SIBYTE_LITTLESUR is not set
39# CONFIG_SIBYTE_SENTOSA is not set 38# CONFIG_SIBYTE_SENTOSA is not set
40# CONFIG_SIBYTE_PTSWARM is not set
41# CONFIG_SIBYTE_BIGSUR is not set 39# CONFIG_SIBYTE_BIGSUR is not set
42# CONFIG_SNI_RM is not set 40# CONFIG_SNI_RM is not set
43# CONFIG_TOSHIBA_JMR3927 is not set 41# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 8334350d7229..27e23fc9363a 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig
index 69278999c9a2..b12b73f6d74f 100644
--- a/arch/mips/configs/msp71xx_defconfig
+++ b/arch/mips/configs/msp71xx_defconfig
@@ -38,7 +38,6 @@ CONFIG_ZONE_DMA=y
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39CONFIG_PMC_MSP=y 39CONFIG_PMC_MSP=y
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_PMC_MSP=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index b536d7c63790..fa3aa3919448 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_ALCHEMY=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_ALCHEMY=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -1617,6 +1615,7 @@ CONFIG_INPUT_EVBUG=m
1617# 1615#
1618CONFIG_INPUT_KEYBOARD=y 1616CONFIG_INPUT_KEYBOARD=y
1619CONFIG_KEYBOARD_ATKBD=y 1617CONFIG_KEYBOARD_ATKBD=y
1618CONFIG_KEYBOARD_GPIO=y
1620CONFIG_KEYBOARD_SUNKBD=m 1619CONFIG_KEYBOARD_SUNKBD=m
1621CONFIG_KEYBOARD_LKKBD=m 1620CONFIG_KEYBOARD_LKKBD=m
1622CONFIG_KEYBOARD_XTKBD=m 1621CONFIG_KEYBOARD_XTKBD=m
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 703d28db05b9..1d0157d3a5bb 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1100=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1100=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 82f0c5cee0dc..d0491a05ee58 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1500=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1500=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 147a4fc7fdd8..16d78d3cd2aa 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -38,7 +38,6 @@ CONFIG_MIPS_PB1550=y
38# CONFIG_PNX8550_STB810 is not set 38# CONFIG_PNX8550_STB810 is not set
39# CONFIG_MACH_VR41XX is not set 39# CONFIG_MACH_VR41XX is not set
40# CONFIG_PMC_YOSEMITE is not set 40# CONFIG_PMC_YOSEMITE is not set
41# CONFIG_QEMU is not set
42# CONFIG_MARKEINS is not set 41# CONFIG_MARKEINS is not set
43# CONFIG_SGI_IP22 is not set 42# CONFIG_SGI_IP22 is not set
44# CONFIG_SGI_IP27 is not set 43# CONFIG_SGI_IP27 is not set
@@ -48,7 +47,6 @@ CONFIG_MIPS_PB1550=y
48# CONFIG_SIBYTE_SENTOSA is not set 47# CONFIG_SIBYTE_SENTOSA is not set
49# CONFIG_SIBYTE_RHONE is not set 48# CONFIG_SIBYTE_RHONE is not set
50# CONFIG_SIBYTE_CARMEL is not set 49# CONFIG_SIBYTE_CARMEL is not set
51# CONFIG_SIBYTE_PTSWARM is not set
52# CONFIG_SIBYTE_LITTLESUR is not set 50# CONFIG_SIBYTE_LITTLESUR is not set
53# CONFIG_SIBYTE_CRHINE is not set 51# CONFIG_SIBYTE_CRHINE is not set
54# CONFIG_SIBYTE_CRHONE is not set 52# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index f6906b069e04..518a60892b78 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -37,7 +37,6 @@ CONFIG_PNX8550_JBS=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PNX8550_JBS=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index b741f81696fb..68351eb81bc8 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37CONFIG_PNX8550_STB810=y 37CONFIG_PNX8550_STB810=y
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PNX8550_STB810=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index b3caf5125c15..72ca147f9422 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40CONFIG_QEMU=y
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_QEMU=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/rbhma4200_defconfig b/arch/mips/configs/rbhma4200_defconfig
index 9383a598094b..470f6f4d3ea2 100644
--- a/arch/mips/configs/rbhma4200_defconfig
+++ b/arch/mips/configs/rbhma4200_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -431,7 +429,6 @@ CONFIG_UNIX98_PTYS=y
431CONFIG_LEGACY_PTYS=y 429CONFIG_LEGACY_PTYS=y
432CONFIG_LEGACY_PTY_COUNT=256 430CONFIG_LEGACY_PTY_COUNT=256
433# CONFIG_IPMI_HANDLER is not set 431# CONFIG_IPMI_HANDLER is not set
434# CONFIG_WATCHDOG is not set
435# CONFIG_HW_RANDOM is not set 432# CONFIG_HW_RANDOM is not set
436# CONFIG_RTC is not set 433# CONFIG_RTC is not set
437# CONFIG_R3964 is not set 434# CONFIG_R3964 is not set
@@ -449,6 +446,20 @@ CONFIG_DEVPORT=y
449# CONFIG_W1 is not set 446# CONFIG_W1 is not set
450# CONFIG_POWER_SUPPLY is not set 447# CONFIG_POWER_SUPPLY is not set
451# CONFIG_HWMON is not set 448# CONFIG_HWMON is not set
449CONFIG_WATCHDOG=y
450# CONFIG_WATCHDOG_NOWAYOUT is not set
451
452#
453# Watchdog Device Drivers
454#
455# CONFIG_SOFT_WATCHDOG is not set
456CONFIG_TXX9_WDT=m
457
458#
459# PCI-based Watchdog Cards
460#
461# CONFIG_PCIPCWATCHDOG is not set
462# CONFIG_WDTPCI is not set
452 463
453# 464#
454# Multifunction device drivers 465# Multifunction device drivers
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index d1b56cc0fd7c..5a39f56b175e 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -24,7 +24,6 @@ CONFIG_MIPS=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MIPS=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
@@ -450,7 +448,6 @@ CONFIG_UNIX98_PTYS=y
450CONFIG_LEGACY_PTYS=y 448CONFIG_LEGACY_PTYS=y
451CONFIG_LEGACY_PTY_COUNT=256 449CONFIG_LEGACY_PTY_COUNT=256
452# CONFIG_IPMI_HANDLER is not set 450# CONFIG_IPMI_HANDLER is not set
453# CONFIG_WATCHDOG is not set
454# CONFIG_HW_RANDOM is not set 451# CONFIG_HW_RANDOM is not set
455# CONFIG_RTC is not set 452# CONFIG_RTC is not set
456# CONFIG_R3964 is not set 453# CONFIG_R3964 is not set
@@ -479,6 +476,20 @@ CONFIG_SPI_AT25=y
479# CONFIG_W1 is not set 476# CONFIG_W1 is not set
480# CONFIG_POWER_SUPPLY is not set 477# CONFIG_POWER_SUPPLY is not set
481# CONFIG_HWMON is not set 478# CONFIG_HWMON is not set
479CONFIG_WATCHDOG=y
480# CONFIG_WATCHDOG_NOWAYOUT is not set
481
482#
483# Watchdog Device Drivers
484#
485# CONFIG_SOFT_WATCHDOG is not set
486CONFIG_TXX9_WDT=m
487
488#
489# PCI-based Watchdog Cards
490#
491# CONFIG_PCIPCWATCHDOG is not set
492# CONFIG_WDTPCI is not set
482 493
483# 494#
484# Multifunction device drivers 495# Multifunction device drivers
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index fc388118b114..56371b860eb0 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_ZONE_DMA=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index c2798229cbfb..117470b60e34 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_SIBYTE_SWARM=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 2b6282d132a8..3ee75b15c0b0 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -37,7 +37,6 @@ CONFIG_MIPS_SEAD=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_MIPS_SEAD=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig
index 326aa7aa40ea..af82e1a1823c 100644
--- a/arch/mips/configs/tb0219_defconfig
+++ b/arch/mips/configs/tb0219_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index 9fd0faeacf53..a95385b24546 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index 499b6bd7ee68..40d4a40a970e 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index b52256ca0b53..edf90b321fe6 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -24,7 +24,6 @@ CONFIG_MACH_VR41XX=y
24# CONFIG_PNX8550_STB810 is not set 24# CONFIG_PNX8550_STB810 is not set
25# CONFIG_PMC_MSP is not set 25# CONFIG_PMC_MSP is not set
26# CONFIG_PMC_YOSEMITE is not set 26# CONFIG_PMC_YOSEMITE is not set
27# CONFIG_QEMU is not set
28# CONFIG_SGI_IP22 is not set 27# CONFIG_SGI_IP22 is not set
29# CONFIG_SGI_IP27 is not set 28# CONFIG_SGI_IP27 is not set
30# CONFIG_SGI_IP32 is not set 29# CONFIG_SGI_IP32 is not set
@@ -35,7 +34,6 @@ CONFIG_MACH_VR41XX=y
35# CONFIG_SIBYTE_SWARM is not set 34# CONFIG_SIBYTE_SWARM is not set
36# CONFIG_SIBYTE_LITTLESUR is not set 35# CONFIG_SIBYTE_LITTLESUR is not set
37# CONFIG_SIBYTE_SENTOSA is not set 36# CONFIG_SIBYTE_SENTOSA is not set
38# CONFIG_SIBYTE_PTSWARM is not set
39# CONFIG_SIBYTE_BIGSUR is not set 37# CONFIG_SIBYTE_BIGSUR is not set
40# CONFIG_SNI_RM is not set 38# CONFIG_SNI_RM is not set
41# CONFIG_TOSHIBA_JMR3927 is not set 39# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 7e410e10fed7..2e3c683b2052 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -37,7 +37,6 @@ CONFIG_WR_PPMC=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39# CONFIG_PMC_YOSEMITE is not set 39# CONFIG_PMC_YOSEMITE is not set
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_WR_PPMC=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index acaf0e21bb00..b6178ffbc523 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -37,7 +37,6 @@ CONFIG_ZONE_DMA=y
37# CONFIG_PNX8550_STB810 is not set 37# CONFIG_PNX8550_STB810 is not set
38# CONFIG_MACH_VR41XX is not set 38# CONFIG_MACH_VR41XX is not set
39CONFIG_PMC_YOSEMITE=y 39CONFIG_PMC_YOSEMITE=y
40# CONFIG_QEMU is not set
41# CONFIG_MARKEINS is not set 40# CONFIG_MARKEINS is not set
42# CONFIG_SGI_IP22 is not set 41# CONFIG_SGI_IP22 is not set
43# CONFIG_SGI_IP27 is not set 42# CONFIG_SGI_IP27 is not set
@@ -47,7 +46,6 @@ CONFIG_PMC_YOSEMITE=y
47# CONFIG_SIBYTE_SENTOSA is not set 46# CONFIG_SIBYTE_SENTOSA is not set
48# CONFIG_SIBYTE_RHONE is not set 47# CONFIG_SIBYTE_RHONE is not set
49# CONFIG_SIBYTE_CARMEL is not set 48# CONFIG_SIBYTE_CARMEL is not set
50# CONFIG_SIBYTE_PTSWARM is not set
51# CONFIG_SIBYTE_LITTLESUR is not set 49# CONFIG_SIBYTE_LITTLESUR is not set
52# CONFIG_SIBYTE_CRHINE is not set 50# CONFIG_SIBYTE_CRHINE is not set
53# CONFIG_SIBYTE_CRHONE is not set 51# CONFIG_SIBYTE_CRHONE is not set
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 820e5331205f..60349062595a 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -161,7 +161,6 @@ static cycle_t dec_ioasic_hpt_read(void)
161 161
162void __init plat_time_init(void) 162void __init plat_time_init(void)
163{ 163{
164 mips_timer_state = dec_timer_state;
165 mips_timer_ack = dec_timer_ack; 164 mips_timer_ack = dec_timer_ack;
166 165
167 if (!cpu_has_counter && IOASIC) 166 if (!cpu_has_counter && IOASIC)
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 670039bb1a7c..4f5e56c9335e 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -25,7 +25,6 @@ CONFIG_ZONE_DMA=y
25# CONFIG_PNX8550_STB810 is not set 25# CONFIG_PNX8550_STB810 is not set
26# CONFIG_PMC_MSP is not set 26# CONFIG_PMC_MSP is not set
27# CONFIG_PMC_YOSEMITE is not set 27# CONFIG_PMC_YOSEMITE is not set
28# CONFIG_QEMU is not set
29CONFIG_SGI_IP22=y 28CONFIG_SGI_IP22=y
30# CONFIG_SGI_IP27 is not set 29# CONFIG_SGI_IP27 is not set
31# CONFIG_SGI_IP32 is not set 30# CONFIG_SGI_IP32 is not set
@@ -36,7 +35,6 @@ CONFIG_SGI_IP22=y
36# CONFIG_SIBYTE_SWARM is not set 35# CONFIG_SIBYTE_SWARM is not set
37# CONFIG_SIBYTE_LITTLESUR is not set 36# CONFIG_SIBYTE_LITTLESUR is not set
38# CONFIG_SIBYTE_SENTOSA is not set 37# CONFIG_SIBYTE_SENTOSA is not set
39# CONFIG_SIBYTE_PTSWARM is not set
40# CONFIG_SIBYTE_BIGSUR is not set 38# CONFIG_SIBYTE_BIGSUR is not set
41# CONFIG_SNI_RM is not set 39# CONFIG_SNI_RM is not set
42# CONFIG_TOSHIBA_JMR3927 is not set 40# CONFIG_TOSHIBA_JMR3927 is not set
diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c
index fd604ef28823..4ca4eef934a5 100644
--- a/arch/mips/fw/arc/cmdline.c
+++ b/arch/mips/fw/arc/cmdline.c
@@ -52,7 +52,7 @@ static char * __init move_firmware_args(char* cp)
52 strcat(cp, used_arc[i][1]); 52 strcat(cp, used_arc[i][1]);
53 cp += strlen(used_arc[i][1]); 53 cp += strlen(used_arc[i][1]);
54 /* ... and now the argument */ 54 /* ... and now the argument */
55 s = strstr(prom_argv(actr), "="); 55 s = strchr(prom_argv(actr), '=');
56 if (s) { 56 if (s) {
57 s++; 57 s++;
58 strcpy(cp, s); 58 strcpy(cp, s);
diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c
index e2f75b13312f..3ad8788b6eaa 100644
--- a/arch/mips/fw/arc/init.c
+++ b/arch/mips/fw/arc/init.c
@@ -12,6 +12,7 @@
12 12
13#include <asm/bootinfo.h> 13#include <asm/bootinfo.h>
14#include <asm/sgialib.h> 14#include <asm/sgialib.h>
15#include <asm/smp-ops.h>
15 16
16#undef DEBUG_PROM_INIT 17#undef DEBUG_PROM_INIT
17 18
@@ -48,4 +49,11 @@ void __init prom_init(void)
48 ArcRead(0, &c, 1, &cnt); 49 ArcRead(0, &c, 1, &cnt);
49 ArcEnterInteractiveMode(); 50 ArcEnterInteractiveMode();
50#endif 51#endif
52#ifdef CONFIG_SGI_IP27
53 {
54 extern struct plat_smp_ops ip27_smp_ops;
55
56 register_smp_ops(&ip27_smp_ops);
57 }
58#endif
51} 59}
diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c
index a9f69e4e40ac..717db74f7c6e 100644
--- a/arch/mips/fw/cfe/cfe_api.c
+++ b/arch/mips/fw/cfe/cfe_api.c
@@ -16,19 +16,16 @@
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18 18
19/* ********************************************************************* 19/*
20 * 20 *
21 * Broadcom Common Firmware Environment (CFE) 21 * Broadcom Common Firmware Environment (CFE)
22 * 22 *
23 * Device Function stubs File: cfe_api.c 23 * This module contains device function stubs (small routines to
24 * 24 * call the standard "iocb" interface entry point to CFE).
25 * This module contains device function stubs (small routines to 25 * There should be one routine here per iocb function call.
26 * call the standard "iocb" interface entry point to CFE). 26 *
27 * There should be one routine here per iocb function call. 27 * Authors: Mitch Lichtenberg, Chris Demetriou
28 * 28 */
29 * Authors: Mitch Lichtenberg, Chris Demetriou
30 *
31 ********************************************************************* */
32 29
33#include <asm/fw/cfe/cfe_api.h> 30#include <asm/fw/cfe/cfe_api.h>
34#include "cfe_api_int.h" 31#include "cfe_api_int.h"
@@ -37,12 +34,8 @@
37#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) 34#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n))
38#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) 35#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x))
39 36
40#ifdef CFE_API_IMPL_NAMESPACE 37int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
41#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a)
42#endif
43int cfe_iocb_dispatch(cfe_xiocb_t * xiocb);
44 38
45#if defined(CFE_API_common) || defined(CFE_API_ALL)
46/* 39/*
47 * Declare the dispatch function with args of "intptr_t". 40 * Declare the dispatch function with args of "intptr_t".
48 * This makes sure whatever model we're compiling in 41 * This makes sure whatever model we're compiling in
@@ -53,27 +46,25 @@ int cfe_iocb_dispatch(cfe_xiocb_t * xiocb);
53 */ 46 */
54 47
55static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; 48static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0;
56static cfe_xuint_t cfe_handle = 0; 49static u64 cfe_handle = 0;
57 50
58int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) 51int cfe_init(u64 handle, u64 ept)
59{ 52{
60 cfe_dispfunc = NATIVE_FROM_XPTR(ept); 53 cfe_dispfunc = NATIVE_FROM_XPTR(ept);
61 cfe_handle = handle; 54 cfe_handle = handle;
62 return 0; 55 return 0;
63} 56}
64 57
65int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) 58int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
66{ 59{
67 if (!cfe_dispfunc) 60 if (!cfe_dispfunc)
68 return -1; 61 return -1;
69 return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); 62 return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
70} 63}
71#endif /* CFE_API_common || CFE_API_ALL */
72 64
73#if defined(CFE_API_close) || defined(CFE_API_ALL)
74int cfe_close(int handle) 65int cfe_close(int handle)
75{ 66{
76 cfe_xiocb_t xiocb; 67 struct cfe_xiocb xiocb;
77 68
78 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; 69 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
79 xiocb.xiocb_status = 0; 70 xiocb.xiocb_status = 0;
@@ -86,18 +77,16 @@ int cfe_close(int handle)
86 return xiocb.xiocb_status; 77 return xiocb.xiocb_status;
87 78
88} 79}
89#endif /* CFE_API_close || CFE_API_ALL */
90 80
91#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL)
92int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) 81int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
93{ 82{
94 cfe_xiocb_t xiocb; 83 struct cfe_xiocb xiocb;
95 84
96 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 85 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
97 xiocb.xiocb_status = 0; 86 xiocb.xiocb_status = 0;
98 xiocb.xiocb_handle = 0; 87 xiocb.xiocb_handle = 0;
99 xiocb.xiocb_flags = 0; 88 xiocb.xiocb_flags = 0;
100 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 89 xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
101 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 90 xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
102 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; 91 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
103 xiocb.plist.xiocb_cpuctl.gp_val = gp; 92 xiocb.plist.xiocb_cpuctl.gp_val = gp;
@@ -109,18 +98,16 @@ int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
109 98
110 return xiocb.xiocb_status; 99 return xiocb.xiocb_status;
111} 100}
112#endif /* CFE_API_cpu_start || CFE_API_ALL */
113 101
114#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL)
115int cfe_cpu_stop(int cpu) 102int cfe_cpu_stop(int cpu)
116{ 103{
117 cfe_xiocb_t xiocb; 104 struct cfe_xiocb xiocb;
118 105
119 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 106 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
120 xiocb.xiocb_status = 0; 107 xiocb.xiocb_status = 0;
121 xiocb.xiocb_handle = 0; 108 xiocb.xiocb_handle = 0;
122 xiocb.xiocb_flags = 0; 109 xiocb.xiocb_flags = 0;
123 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 110 xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
124 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 111 xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
125 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; 112 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
126 113
@@ -128,18 +115,16 @@ int cfe_cpu_stop(int cpu)
128 115
129 return xiocb.xiocb_status; 116 return xiocb.xiocb_status;
130} 117}
131#endif /* CFE_API_cpu_stop || CFE_API_ALL */
132 118
133#if defined(CFE_API_enumenv) || defined(CFE_API_ALL)
134int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) 119int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
135{ 120{
136 cfe_xiocb_t xiocb; 121 struct cfe_xiocb xiocb;
137 122
138 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 123 xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
139 xiocb.xiocb_status = 0; 124 xiocb.xiocb_status = 0;
140 xiocb.xiocb_handle = 0; 125 xiocb.xiocb_handle = 0;
141 xiocb.xiocb_flags = 0; 126 xiocb.xiocb_flags = 0;
142 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 127 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
143 xiocb.plist.xiocb_envbuf.enum_idx = idx; 128 xiocb.plist.xiocb_envbuf.enum_idx = idx;
144 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 129 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
145 xiocb.plist.xiocb_envbuf.name_length = namelen; 130 xiocb.plist.xiocb_envbuf.name_length = namelen;
@@ -150,20 +135,17 @@ int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
150 135
151 return xiocb.xiocb_status; 136 return xiocb.xiocb_status;
152} 137}
153#endif /* CFE_API_enumenv || CFE_API_ALL */
154 138
155#if defined(CFE_API_enummem) || defined(CFE_API_ALL)
156int 139int
157cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, 140cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
158 cfe_xuint_t * type)
159{ 141{
160 cfe_xiocb_t xiocb; 142 struct cfe_xiocb xiocb;
161 143
162 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; 144 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
163 xiocb.xiocb_status = 0; 145 xiocb.xiocb_status = 0;
164 xiocb.xiocb_handle = 0; 146 xiocb.xiocb_handle = 0;
165 xiocb.xiocb_flags = flags; 147 xiocb.xiocb_flags = flags;
166 xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); 148 xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
167 xiocb.plist.xiocb_meminfo.mi_idx = idx; 149 xiocb.plist.xiocb_meminfo.mi_idx = idx;
168 150
169 cfe_iocb_dispatch(&xiocb); 151 cfe_iocb_dispatch(&xiocb);
@@ -177,30 +159,26 @@ cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length,
177 159
178 return 0; 160 return 0;
179} 161}
180#endif /* CFE_API_enummem || CFE_API_ALL */
181 162
182#if defined(CFE_API_exit) || defined(CFE_API_ALL)
183int cfe_exit(int warm, int status) 163int cfe_exit(int warm, int status)
184{ 164{
185 cfe_xiocb_t xiocb; 165 struct cfe_xiocb xiocb;
186 166
187 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; 167 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
188 xiocb.xiocb_status = 0; 168 xiocb.xiocb_status = 0;
189 xiocb.xiocb_handle = 0; 169 xiocb.xiocb_handle = 0;
190 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; 170 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
191 xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); 171 xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
192 xiocb.plist.xiocb_exitstat.status = status; 172 xiocb.plist.xiocb_exitstat.status = status;
193 173
194 cfe_iocb_dispatch(&xiocb); 174 cfe_iocb_dispatch(&xiocb);
195 175
196 return xiocb.xiocb_status; 176 return xiocb.xiocb_status;
197} 177}
198#endif /* CFE_API_exit || CFE_API_ALL */
199 178
200#if defined(CFE_API_flushcache) || defined(CFE_API_ALL)
201int cfe_flushcache(int flg) 179int cfe_flushcache(int flg)
202{ 180{
203 cfe_xiocb_t xiocb; 181 struct cfe_xiocb xiocb;
204 182
205 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; 183 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
206 xiocb.xiocb_status = 0; 184 xiocb.xiocb_status = 0;
@@ -212,34 +190,30 @@ int cfe_flushcache(int flg)
212 190
213 return xiocb.xiocb_status; 191 return xiocb.xiocb_status;
214} 192}
215#endif /* CFE_API_flushcache || CFE_API_ALL */
216 193
217#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL)
218int cfe_getdevinfo(char *name) 194int cfe_getdevinfo(char *name)
219{ 195{
220 cfe_xiocb_t xiocb; 196 struct cfe_xiocb xiocb;
221 197
222 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; 198 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
223 xiocb.xiocb_status = 0; 199 xiocb.xiocb_status = 0;
224 xiocb.xiocb_handle = 0; 200 xiocb.xiocb_handle = 0;
225 xiocb.xiocb_flags = 0; 201 xiocb.xiocb_flags = 0;
226 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 202 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
227 xiocb.plist.xiocb_buffer.buf_offset = 0; 203 xiocb.plist.xiocb_buffer.buf_offset = 0;
228 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 204 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
229 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 205 xiocb.plist.xiocb_buffer.buf_length = strlen(name);
230 206
231 cfe_iocb_dispatch(&xiocb); 207 cfe_iocb_dispatch(&xiocb);
232 208
233 if (xiocb.xiocb_status < 0) 209 if (xiocb.xiocb_status < 0)
234 return xiocb.xiocb_status; 210 return xiocb.xiocb_status;
235 return xiocb.plist.xiocb_buffer.buf_devflags; 211 return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
236} 212}
237#endif /* CFE_API_getdevinfo || CFE_API_ALL */
238 213
239#if defined(CFE_API_getenv) || defined(CFE_API_ALL)
240int cfe_getenv(char *name, char *dest, int destlen) 214int cfe_getenv(char *name, char *dest, int destlen)
241{ 215{
242 cfe_xiocb_t xiocb; 216 struct cfe_xiocb xiocb;
243 217
244 *dest = 0; 218 *dest = 0;
245 219
@@ -247,10 +221,10 @@ int cfe_getenv(char *name, char *dest, int destlen)
247 xiocb.xiocb_status = 0; 221 xiocb.xiocb_status = 0;
248 xiocb.xiocb_handle = 0; 222 xiocb.xiocb_handle = 0;
249 xiocb.xiocb_flags = 0; 223 xiocb.xiocb_flags = 0;
250 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 224 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
251 xiocb.plist.xiocb_envbuf.enum_idx = 0; 225 xiocb.plist.xiocb_envbuf.enum_idx = 0;
252 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 226 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
253 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 227 xiocb.plist.xiocb_envbuf.name_length = strlen(name);
254 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); 228 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
255 xiocb.plist.xiocb_envbuf.val_length = destlen; 229 xiocb.plist.xiocb_envbuf.val_length = destlen;
256 230
@@ -258,18 +232,16 @@ int cfe_getenv(char *name, char *dest, int destlen)
258 232
259 return xiocb.xiocb_status; 233 return xiocb.xiocb_status;
260} 234}
261#endif /* CFE_API_getenv || CFE_API_ALL */
262 235
263#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL)
264int cfe_getfwinfo(cfe_fwinfo_t * info) 236int cfe_getfwinfo(cfe_fwinfo_t * info)
265{ 237{
266 cfe_xiocb_t xiocb; 238 struct cfe_xiocb xiocb;
267 239
268 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; 240 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
269 xiocb.xiocb_status = 0; 241 xiocb.xiocb_status = 0;
270 xiocb.xiocb_handle = 0; 242 xiocb.xiocb_handle = 0;
271 xiocb.xiocb_flags = 0; 243 xiocb.xiocb_flags = 0;
272 xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); 244 xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
273 245
274 cfe_iocb_dispatch(&xiocb); 246 cfe_iocb_dispatch(&xiocb);
275 247
@@ -292,12 +264,10 @@ int cfe_getfwinfo(cfe_fwinfo_t * info)
292 264
293 return 0; 265 return 0;
294} 266}
295#endif /* CFE_API_getfwinfo || CFE_API_ALL */
296 267
297#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL)
298int cfe_getstdhandle(int flg) 268int cfe_getstdhandle(int flg)
299{ 269{
300 cfe_xiocb_t xiocb; 270 struct cfe_xiocb xiocb;
301 271
302 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; 272 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
303 xiocb.xiocb_status = 0; 273 xiocb.xiocb_status = 0;
@@ -311,23 +281,17 @@ int cfe_getstdhandle(int flg)
311 return xiocb.xiocb_status; 281 return xiocb.xiocb_status;
312 return xiocb.xiocb_handle; 282 return xiocb.xiocb_handle;
313} 283}
314#endif /* CFE_API_getstdhandle || CFE_API_ALL */
315 284
316#if defined(CFE_API_getticks) || defined(CFE_API_ALL)
317int64_t 285int64_t
318#ifdef CFE_API_IMPL_NAMESPACE
319__cfe_getticks(void)
320#else
321cfe_getticks(void) 286cfe_getticks(void)
322#endif
323{ 287{
324 cfe_xiocb_t xiocb; 288 struct cfe_xiocb xiocb;
325 289
326 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; 290 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
327 xiocb.xiocb_status = 0; 291 xiocb.xiocb_status = 0;
328 xiocb.xiocb_handle = 0; 292 xiocb.xiocb_handle = 0;
329 xiocb.xiocb_flags = 0; 293 xiocb.xiocb_flags = 0;
330 xiocb.xiocb_psize = sizeof(xiocb_time_t); 294 xiocb.xiocb_psize = sizeof(struct xiocb_time);
331 xiocb.plist.xiocb_time.ticks = 0; 295 xiocb.plist.xiocb_time.ticks = 0;
332 296
333 cfe_iocb_dispatch(&xiocb); 297 cfe_iocb_dispatch(&xiocb);
@@ -335,18 +299,16 @@ cfe_getticks(void)
335 return xiocb.plist.xiocb_time.ticks; 299 return xiocb.plist.xiocb_time.ticks;
336 300
337} 301}
338#endif /* CFE_API_getticks || CFE_API_ALL */
339 302
340#if defined(CFE_API_inpstat) || defined(CFE_API_ALL)
341int cfe_inpstat(int handle) 303int cfe_inpstat(int handle)
342{ 304{
343 cfe_xiocb_t xiocb; 305 struct cfe_xiocb xiocb;
344 306
345 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; 307 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
346 xiocb.xiocb_status = 0; 308 xiocb.xiocb_status = 0;
347 xiocb.xiocb_handle = handle; 309 xiocb.xiocb_handle = handle;
348 xiocb.xiocb_flags = 0; 310 xiocb.xiocb_flags = 0;
349 xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); 311 xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
350 xiocb.plist.xiocb_inpstat.inp_status = 0; 312 xiocb.plist.xiocb_inpstat.inp_status = 0;
351 313
352 cfe_iocb_dispatch(&xiocb); 314 cfe_iocb_dispatch(&xiocb);
@@ -355,20 +317,18 @@ int cfe_inpstat(int handle)
355 return xiocb.xiocb_status; 317 return xiocb.xiocb_status;
356 return xiocb.plist.xiocb_inpstat.inp_status; 318 return xiocb.plist.xiocb_inpstat.inp_status;
357} 319}
358#endif /* CFE_API_inpstat || CFE_API_ALL */
359 320
360#if defined(CFE_API_ioctl) || defined(CFE_API_ALL)
361int 321int
362cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, 322cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
363 int length, int *retlen, cfe_xuint_t offset) 323 int length, int *retlen, u64 offset)
364{ 324{
365 cfe_xiocb_t xiocb; 325 struct cfe_xiocb xiocb;
366 326
367 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; 327 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
368 xiocb.xiocb_status = 0; 328 xiocb.xiocb_status = 0;
369 xiocb.xiocb_handle = handle; 329 xiocb.xiocb_handle = handle;
370 xiocb.xiocb_flags = 0; 330 xiocb.xiocb_flags = 0;
371 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 331 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
372 xiocb.plist.xiocb_buffer.buf_offset = offset; 332 xiocb.plist.xiocb_buffer.buf_offset = offset;
373 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; 333 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
374 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 334 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
@@ -380,21 +340,19 @@ cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
380 *retlen = xiocb.plist.xiocb_buffer.buf_retlen; 340 *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
381 return xiocb.xiocb_status; 341 return xiocb.xiocb_status;
382} 342}
383#endif /* CFE_API_ioctl || CFE_API_ALL */
384 343
385#if defined(CFE_API_open) || defined(CFE_API_ALL)
386int cfe_open(char *name) 344int cfe_open(char *name)
387{ 345{
388 cfe_xiocb_t xiocb; 346 struct cfe_xiocb xiocb;
389 347
390 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; 348 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
391 xiocb.xiocb_status = 0; 349 xiocb.xiocb_status = 0;
392 xiocb.xiocb_handle = 0; 350 xiocb.xiocb_handle = 0;
393 xiocb.xiocb_flags = 0; 351 xiocb.xiocb_flags = 0;
394 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 352 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
395 xiocb.plist.xiocb_buffer.buf_offset = 0; 353 xiocb.plist.xiocb_buffer.buf_offset = 0;
396 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 354 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
397 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 355 xiocb.plist.xiocb_buffer.buf_length = strlen(name);
398 356
399 cfe_iocb_dispatch(&xiocb); 357 cfe_iocb_dispatch(&xiocb);
400 358
@@ -402,27 +360,21 @@ int cfe_open(char *name)
402 return xiocb.xiocb_status; 360 return xiocb.xiocb_status;
403 return xiocb.xiocb_handle; 361 return xiocb.xiocb_handle;
404} 362}
405#endif /* CFE_API_open || CFE_API_ALL */
406 363
407#if defined(CFE_API_read) || defined(CFE_API_ALL)
408int cfe_read(int handle, unsigned char *buffer, int length) 364int cfe_read(int handle, unsigned char *buffer, int length)
409{ 365{
410 return cfe_readblk(handle, 0, buffer, length); 366 return cfe_readblk(handle, 0, buffer, length);
411} 367}
412#endif /* CFE_API_read || CFE_API_ALL */
413 368
414#if defined(CFE_API_readblk) || defined(CFE_API_ALL) 369int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
415int
416cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer,
417 int length)
418{ 370{
419 cfe_xiocb_t xiocb; 371 struct cfe_xiocb xiocb;
420 372
421 xiocb.xiocb_fcode = CFE_CMD_DEV_READ; 373 xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
422 xiocb.xiocb_status = 0; 374 xiocb.xiocb_status = 0;
423 xiocb.xiocb_handle = handle; 375 xiocb.xiocb_handle = handle;
424 xiocb.xiocb_flags = 0; 376 xiocb.xiocb_flags = 0;
425 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 377 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
426 xiocb.plist.xiocb_buffer.buf_offset = offset; 378 xiocb.plist.xiocb_buffer.buf_offset = offset;
427 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 379 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
428 xiocb.plist.xiocb_buffer.buf_length = length; 380 xiocb.plist.xiocb_buffer.buf_length = length;
@@ -433,62 +385,41 @@ cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer,
433 return xiocb.xiocb_status; 385 return xiocb.xiocb_status;
434 return xiocb.plist.xiocb_buffer.buf_retlen; 386 return xiocb.plist.xiocb_buffer.buf_retlen;
435} 387}
436#endif /* CFE_API_readblk || CFE_API_ALL */
437 388
438#if defined(CFE_API_setenv) || defined(CFE_API_ALL)
439int cfe_setenv(char *name, char *val) 389int cfe_setenv(char *name, char *val)
440{ 390{
441 cfe_xiocb_t xiocb; 391 struct cfe_xiocb xiocb;
442 392
443 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 393 xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
444 xiocb.xiocb_status = 0; 394 xiocb.xiocb_status = 0;
445 xiocb.xiocb_handle = 0; 395 xiocb.xiocb_handle = 0;
446 xiocb.xiocb_flags = 0; 396 xiocb.xiocb_flags = 0;
447 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 397 xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
448 xiocb.plist.xiocb_envbuf.enum_idx = 0; 398 xiocb.plist.xiocb_envbuf.enum_idx = 0;
449 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 399 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
450 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 400 xiocb.plist.xiocb_envbuf.name_length = strlen(name);
451 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 401 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
452 xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); 402 xiocb.plist.xiocb_envbuf.val_length = strlen(val);
453 403
454 cfe_iocb_dispatch(&xiocb); 404 cfe_iocb_dispatch(&xiocb);
455 405
456 return xiocb.xiocb_status; 406 return xiocb.xiocb_status;
457} 407}
458#endif /* CFE_API_setenv || CFE_API_ALL */
459
460#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \
461 && !defined(CFE_API_STRLEN_CUSTOM)
462int cfe_strlen(char *name)
463{
464 int count = 0;
465
466 while (*name++)
467 count++;
468 408
469 return count;
470}
471#endif /* CFE_API_strlen || CFE_API_ALL */
472
473#if defined(CFE_API_write) || defined(CFE_API_ALL)
474int cfe_write(int handle, unsigned char *buffer, int length) 409int cfe_write(int handle, unsigned char *buffer, int length)
475{ 410{
476 return cfe_writeblk(handle, 0, buffer, length); 411 return cfe_writeblk(handle, 0, buffer, length);
477} 412}
478#endif /* CFE_API_write || CFE_API_ALL */
479 413
480#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) 414int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
481int
482cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer,
483 int length)
484{ 415{
485 cfe_xiocb_t xiocb; 416 struct cfe_xiocb xiocb;
486 417
487 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; 418 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
488 xiocb.xiocb_status = 0; 419 xiocb.xiocb_status = 0;
489 xiocb.xiocb_handle = handle; 420 xiocb.xiocb_handle = handle;
490 xiocb.xiocb_flags = 0; 421 xiocb.xiocb_flags = 0;
491 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 422 xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
492 xiocb.plist.xiocb_buffer.buf_offset = offset; 423 xiocb.plist.xiocb_buffer.buf_offset = offset;
493 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 424 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
494 xiocb.plist.xiocb_buffer.buf_length = length; 425 xiocb.plist.xiocb_buffer.buf_length = length;
@@ -499,4 +430,3 @@ cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer,
499 return xiocb.xiocb_status; 430 return xiocb.xiocb_status;
500 return xiocb.plist.xiocb_buffer.buf_retlen; 431 return xiocb.plist.xiocb_buffer.buf_retlen;
501} 432}
502#endif /* CFE_API_writeblk || CFE_API_ALL */
diff --git a/arch/mips/fw/cfe/cfe_api_int.h b/arch/mips/fw/cfe/cfe_api_int.h
index f7e5a64b55f3..d9759e646956 100644
--- a/arch/mips/fw/cfe/cfe_api_int.h
+++ b/arch/mips/fw/cfe/cfe_api_int.h
@@ -15,28 +15,12 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18
19/* *********************************************************************
20 *
21 * Broadcom Common Firmware Environment (CFE)
22 *
23 * Device function prototypes File: cfe_api_int.h
24 *
25 * This header defines all internal types and macros for the
26 * library. This is stuff that's not exported to an app
27 * using the library.
28 *
29 * Authors: Mitch Lichtenberg, Chris Demetriou
30 *
31 ********************************************************************* */
32
33#ifndef CFE_API_INT_H 18#ifndef CFE_API_INT_H
34#define CFE_API_INT_H 19#define CFE_API_INT_H
35 20
36/* ********************************************************************* 21/*
37 * Constants 22 * Constants.
38 ********************************************************************* */ 23 */
39
40#define CFE_CMD_FW_GETINFO 0 24#define CFE_CMD_FW_GETINFO 0
41#define CFE_CMD_FW_RESTART 1 25#define CFE_CMD_FW_RESTART 1
42#define CFE_CMD_FW_BOOT 2 26#define CFE_CMD_FW_BOOT 2
@@ -64,89 +48,101 @@
64 48
65#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */ 49#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
66 50
67/* ********************************************************************* 51/*
68 * Structures 52 * Structures.
69 ********************************************************************* */ 53 */
70 54
71typedef uint64_t cfe_xuint_t; 55/* eeek, signed "pointers" */
72typedef int64_t cfe_xint_t; 56typedef s64 cfe_xptr_t;
73typedef int64_t cfe_xptr_t;
74 57
75typedef struct xiocb_buffer_s { 58struct xiocb_buffer {
76 cfe_xuint_t buf_offset; /* offset on device (bytes) */ 59 u64 buf_offset; /* offset on device (bytes) */
77 cfe_xptr_t buf_ptr; /* pointer to a buffer */ 60 cfe_xptr_t buf_ptr; /* pointer to a buffer */
78 cfe_xuint_t buf_length; /* length of this buffer */ 61 u64 buf_length; /* length of this buffer */
79 cfe_xuint_t buf_retlen; /* returned length (for read ops) */ 62 u64 buf_retlen; /* returned length (for read ops) */
80 cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ 63 u64 buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */
81} xiocb_buffer_t; 64};
82
83#define buf_devflags buf_ioctlcmd /* returned device info flags */
84 65
85typedef struct xiocb_inpstat_s { 66struct xiocb_inpstat {
86 cfe_xuint_t inp_status; /* 1 means input available */ 67 u64 inp_status; /* 1 means input available */
87} xiocb_inpstat_t; 68};
88 69
89typedef struct xiocb_envbuf_s { 70struct xiocb_envbuf {
90 cfe_xint_t enum_idx; /* 0-based enumeration index */ 71 s64 enum_idx; /* 0-based enumeration index */
91 cfe_xptr_t name_ptr; /* name string buffer */ 72 cfe_xptr_t name_ptr; /* name string buffer */
92 cfe_xint_t name_length; /* size of name buffer */ 73 s64 name_length; /* size of name buffer */
93 cfe_xptr_t val_ptr; /* value string buffer */ 74 cfe_xptr_t val_ptr; /* value string buffer */
94 cfe_xint_t val_length; /* size of value string buffer */ 75 s64 val_length; /* size of value string buffer */
95} xiocb_envbuf_t; 76};
96 77
97typedef struct xiocb_cpuctl_s { 78struct xiocb_cpuctl {
98 cfe_xuint_t cpu_number; /* cpu number to control */ 79 u64 cpu_number; /* cpu number to control */
99 cfe_xuint_t cpu_command; /* command to issue to CPU */ 80 u64 cpu_command; /* command to issue to CPU */
100 cfe_xuint_t start_addr; /* CPU start address */ 81 u64 start_addr; /* CPU start address */
101 cfe_xuint_t gp_val; /* starting GP value */ 82 u64 gp_val; /* starting GP value */
102 cfe_xuint_t sp_val; /* starting SP value */ 83 u64 sp_val; /* starting SP value */
103 cfe_xuint_t a1_val; /* starting A1 value */ 84 u64 a1_val; /* starting A1 value */
104} xiocb_cpuctl_t; 85};
105 86
106typedef struct xiocb_time_s { 87struct xiocb_time {
107 cfe_xint_t ticks; /* current time in ticks */ 88 s64 ticks; /* current time in ticks */
108} xiocb_time_t; 89};
109 90
110typedef struct xiocb_exitstat_s { 91struct xiocb_exitstat{
111 cfe_xint_t status; 92 s64 status;
112} xiocb_exitstat_t; 93};
113 94
114typedef struct xiocb_meminfo_s { 95struct xiocb_meminfo {
115 cfe_xint_t mi_idx; /* 0-based enumeration index */ 96 s64 mi_idx; /* 0-based enumeration index */
116 cfe_xint_t mi_type; /* type of memory block */ 97 s64 mi_type; /* type of memory block */
117 cfe_xuint_t mi_addr; /* physical start address */ 98 u64 mi_addr; /* physical start address */
118 cfe_xuint_t mi_size; /* block size */ 99 u64 mi_size; /* block size */
119} xiocb_meminfo_t; 100};
120 101
121typedef struct xiocb_fwinfo_s { 102struct xiocb_fwinfo {
122 cfe_xint_t fwi_version; /* major, minor, eco version */ 103 s64 fwi_version; /* major, minor, eco version */
123 cfe_xint_t fwi_totalmem; /* total installed mem */ 104 s64 fwi_totalmem; /* total installed mem */
124 cfe_xint_t fwi_flags; /* various flags */ 105 s64 fwi_flags; /* various flags */
125 cfe_xint_t fwi_boardid; /* board ID */ 106 s64 fwi_boardid; /* board ID */
126 cfe_xint_t fwi_bootarea_va; /* VA of boot area */ 107 s64 fwi_bootarea_va; /* VA of boot area */
127 cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ 108 s64 fwi_bootarea_pa; /* PA of boot area */
128 cfe_xint_t fwi_bootarea_size; /* size of boot area */ 109 s64 fwi_bootarea_size; /* size of boot area */
129 cfe_xint_t fwi_reserved1; 110 s64 fwi_reserved1;
130 cfe_xint_t fwi_reserved2; 111 s64 fwi_reserved2;
131 cfe_xint_t fwi_reserved3; 112 s64 fwi_reserved3;
132} xiocb_fwinfo_t; 113};
133 114
134typedef struct cfe_xiocb_s { 115struct cfe_xiocb {
135 cfe_xuint_t xiocb_fcode; /* IOCB function code */ 116 u64 xiocb_fcode; /* IOCB function code */
136 cfe_xint_t xiocb_status; /* return status */ 117 s64 xiocb_status; /* return status */
137 cfe_xint_t xiocb_handle; /* file/device handle */ 118 s64 xiocb_handle; /* file/device handle */
138 cfe_xuint_t xiocb_flags; /* flags for this IOCB */ 119 u64 xiocb_flags; /* flags for this IOCB */
139 cfe_xuint_t xiocb_psize; /* size of parameter list */ 120 u64 xiocb_psize; /* size of parameter list */
140 union { 121 union {
141 xiocb_buffer_t xiocb_buffer; /* buffer parameters */ 122 /* buffer parameters */
142 xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ 123 struct xiocb_buffer xiocb_buffer;
143 xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ 124
144 xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ 125 /* input status parameters */
145 xiocb_time_t xiocb_time; /* timer parameters */ 126 struct xiocb_inpstat xiocb_inpstat;
146 xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ 127
147 xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ 128 /* environment function parameters */
148 xiocb_exitstat_t xiocb_exitstat; /* Exit Status */ 129 struct xiocb_envbuf xiocb_envbuf;
130
131 /* CPU control parameters */
132 struct xiocb_cpuctl xiocb_cpuctl;
133
134 /* timer parameters */
135 struct xiocb_time xiocb_time;
136
137 /* memory arena info parameters */
138 struct xiocb_meminfo xiocb_meminfo;
139
140 /* firmware information */
141 struct xiocb_fwinfo xiocb_fwinfo;
142
143 /* Exit Status */
144 struct xiocb_exitstat xiocb_exitstat;
149 } plist; 145 } plist;
150} cfe_xiocb_t; 146};
151 147
152#endif /* CFE_API_INT_H */ 148#endif /* CFE_API_INT_H */
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile
new file mode 100644
index 000000000000..84befc968fc4
--- /dev/null
+++ b/arch/mips/fw/lib/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for generic prom monitor library routines under Linux.
3#
4
5lib-$(CONFIG_64BIT) += call_o32.o
diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S
new file mode 100644
index 000000000000..bdf7d1d4081a
--- /dev/null
+++ b/arch/mips/fw/lib/call_o32.S
@@ -0,0 +1,97 @@
1/*
2 * arch/mips/dec/prom/call_o32.S
3 *
4 * O32 interface for the 64 (or N32) ABI.
5 *
6 * Copyright (C) 2002 Maciej W. Rozycki
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <asm/asm.h>
15#include <asm/regdef.h>
16
17/* Maximum number of arguments supported. Must be even! */
18#define O32_ARGC 32
19/* Number of static registers we save. */
20#define O32_STATC 11
21/* Frame size for static register */
22#define O32_FRAMESZ (SZREG * O32_STATC)
23/* Frame size on new stack */
24#define O32_FRAMESZ_NEW (SZREG + 4 * O32_ARGC)
25
26 .text
27
28/*
29 * O32 function call dispatcher, for interfacing 32-bit ROM routines.
30 *
31 * The standard 64 (N32) calling sequence is supported, with a0
32 * holding a function pointer, a1 a new stack pointer, a2-a7 -- its
33 * first six arguments and the stack -- remaining ones (up to O32_ARGC,
34 * including a2-a7). Static registers, gp and fp are preserved, v0 holds
35 * a result. This code relies on the called o32 function for sp and ra
36 * restoration and this dispatcher has to be placed in a KSEGx (or KUSEG)
37 * address space. Any pointers passed have to point to addresses within
38 * one of these spaces as well.
39 */
40NESTED(call_o32, O32_FRAMESZ, ra)
41 REG_SUBU sp,O32_FRAMESZ
42
43 REG_S ra,O32_FRAMESZ-1*SZREG(sp)
44 REG_S fp,O32_FRAMESZ-2*SZREG(sp)
45 REG_S gp,O32_FRAMESZ-3*SZREG(sp)
46 REG_S s7,O32_FRAMESZ-4*SZREG(sp)
47 REG_S s6,O32_FRAMESZ-5*SZREG(sp)
48 REG_S s5,O32_FRAMESZ-6*SZREG(sp)
49 REG_S s4,O32_FRAMESZ-7*SZREG(sp)
50 REG_S s3,O32_FRAMESZ-8*SZREG(sp)
51 REG_S s2,O32_FRAMESZ-9*SZREG(sp)
52 REG_S s1,O32_FRAMESZ-10*SZREG(sp)
53 REG_S s0,O32_FRAMESZ-11*SZREG(sp)
54
55 move jp,a0
56 REG_SUBU s0,a1,O32_FRAMESZ_NEW
57 REG_S sp,O32_FRAMESZ_NEW-1*SZREG(s0)
58
59 sll a0,a2,zero
60 sll a1,a3,zero
61 sll a2,a4,zero
62 sll a3,a5,zero
63 sw a6,0x10(s0)
64 sw a7,0x14(s0)
65
66 PTR_LA t0,O32_FRAMESZ(sp)
67 PTR_LA t1,0x18(s0)
68 li t2,O32_ARGC-6
691:
70 lw t3,(t0)
71 REG_ADDU t0,SZREG
72 sw t3,(t1)
73 REG_SUBU t2,1
74 REG_ADDU t1,4
75 bnez t2,1b
76
77 move sp,s0
78
79 jalr jp
80
81 REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp)
82
83 REG_L s0,O32_FRAMESZ-11*SZREG(sp)
84 REG_L s1,O32_FRAMESZ-10*SZREG(sp)
85 REG_L s2,O32_FRAMESZ-9*SZREG(sp)
86 REG_L s3,O32_FRAMESZ-8*SZREG(sp)
87 REG_L s4,O32_FRAMESZ-7*SZREG(sp)
88 REG_L s5,O32_FRAMESZ-6*SZREG(sp)
89 REG_L s6,O32_FRAMESZ-5*SZREG(sp)
90 REG_L s7,O32_FRAMESZ-4*SZREG(sp)
91 REG_L gp,O32_FRAMESZ-3*SZREG(sp)
92 REG_L fp,O32_FRAMESZ-2*SZREG(sp)
93 REG_L ra,O32_FRAMESZ-1*SZREG(sp)
94
95 REG_ADDU sp,O32_FRAMESZ
96 jr ra
97END(call_o32)
diff --git a/arch/mips/fw/sni/Makefile b/arch/mips/fw/sni/Makefile
new file mode 100644
index 000000000000..d9740a3788e2
--- /dev/null
+++ b/arch/mips/fw/sni/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the SNI prom monitor routines under Linux.
3#
4
5lib-$(CONFIG_SNIPROM) += sniprom.o
diff --git a/arch/mips/fw/sni/sniprom.c b/arch/mips/fw/sni/sniprom.c
new file mode 100644
index 000000000000..96ba99202758
--- /dev/null
+++ b/arch/mips/fw/sni/sniprom.c
@@ -0,0 +1,151 @@
1/*
2 * Big Endian PROM code for SNI RM machines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/console.h>
16
17#include <asm/addrspace.h>
18#include <asm/sni.h>
19#include <asm/mipsprom.h>
20#include <asm/mipsregs.h>
21#include <asm/bootinfo.h>
22
23/* special SNI prom calls */
24/*
25 * This does not exist in all proms - SINIX compares
26 * the prom env variable "version" against "2.0008"
27 * or greater. If lesser it tries to probe interesting
28 * registers
29 */
30#define PROM_GET_MEMCONF 58
31#define PROM_GET_HWCONF 61
32
33#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
34#define PROM_ENTRY(x) (PROM_VEC + (x))
35
36#define ___prom_putchar ((int *(*)(int))PROM_ENTRY(PROM_PUTCHAR))
37#define ___prom_getenv ((char *(*)(char *))PROM_ENTRY(PROM_GETENV))
38#define ___prom_get_memconf ((void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF))
39#define ___prom_get_hwconf ((u32 (*)(void))PROM_ENTRY(PROM_GET_HWCONF))
40
41#ifdef CONFIG_64BIT
42
43static u8 o32_stk[16384];
44#define O32_STK &o32_stk[sizeof(o32_stk)]
45
46#define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
47 __asm__(#fun " = call_o32")
48
49int __PROM_O32(__prom_putchar, (int *(*)(int), void *, int));
50char *__PROM_O32(__prom_getenv, (char *(*)(char *), void *, char *));
51void __PROM_O32(__prom_get_memconf, (void (*)(void *), void *, void *));
52u32 __PROM_O32(__prom_get_hwconf, (u32 (*)(void), void *));
53
54#define _prom_putchar(x) __prom_putchar(___prom_putchar, O32_STK, x)
55#define _prom_getenv(x) __prom_getenv(___prom_getenv, O32_STK, x)
56#define _prom_get_memconf(x) __prom_get_memconf(___prom_get_memconf, O32_STK, x)
57#define _prom_get_hwconf() __prom_get_hwconf(___prom_get_hwconf, O32_STK)
58
59#else
60#define _prom_putchar(x) ___prom_putchar(x)
61#define _prom_getenv(x) ___prom_getenv(x)
62#define _prom_get_memconf(x) ___prom_get_memconf(x)
63#define _prom_get_hwconf(x) ___prom_get_hwconf(x)
64#endif
65
66void prom_putchar(char c)
67{
68 _prom_putchar(c);
69}
70
71
72char *prom_getenv(char *s)
73{
74 return _prom_getenv(s);
75}
76
77void *prom_get_hwconf(void)
78{
79 u32 hwconf = _prom_get_hwconf();
80
81 if (hwconf == 0xffffffff)
82 return NULL;
83
84 return (void *)CKSEG1ADDR(hwconf);
85}
86
87void __init prom_free_prom_memory(void)
88{
89}
90
91/*
92 * /proc/cpuinfo system type
93 *
94 */
95char *system_type = "Unknown";
96const char *get_system_type(void)
97{
98 return system_type;
99}
100
101static void __init sni_mem_init(void)
102{
103 int i, memsize;
104 struct membank {
105 u32 size;
106 u32 base;
107 u32 size2;
108 u32 pad1;
109 u32 pad2;
110 } memconf[8];
111 int brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
112
113
114 /* MemSIZE from prom in 16MByte chunks */
115 memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
116
117 pr_debug("IDProm memsize: %u MByte\n", memsize);
118
119 /* get memory bank layout from prom */
120 _prom_get_memconf(&memconf);
121
122 pr_debug("prom_get_mem_conf memory configuration:\n");
123 for (i = 0; i < 8 && memconf[i].size; i++) {
124 if (brd_type == SNI_BRD_PCI_TOWER ||
125 brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
126 if (memconf[i].base >= 0x20000000 &&
127 memconf[i].base < 0x30000000)
128 memconf[i].base -= 0x20000000;
129 }
130 pr_debug("Bank%d: %08x @ %08x\n", i,
131 memconf[i].size, memconf[i].base);
132 add_memory_region(memconf[i].base, memconf[i].size,
133 BOOT_MEM_RAM);
134 }
135}
136
137void __init prom_init(void)
138{
139 int argc = fw_arg0;
140 u32 *argv = (u32 *)CKSEG0ADDR(fw_arg1);
141 int i;
142
143 sni_mem_init();
144
145 /* copy prom cmdline parameters to kernel cmdline */
146 for (i = 1; i < argc; i++) {
147 strcat(arcs_cmdline, (char *)CKSEG0ADDR(argv[i]));
148 if (i < (argc - 1))
149 strcat(arcs_cmdline, " ");
150 }
151}
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c
index 51f6b7862460..728ef6a80edd 100644
--- a/arch/mips/gt64120/wrppmc/setup.c
+++ b/arch/mips/gt64120/wrppmc/setup.c
@@ -121,8 +121,6 @@ const char *get_system_type(void)
121 */ 121 */
122void __init prom_init(void) 122void __init prom_init(void)
123{ 123{
124 mips_machtype = MACH_WRPPMC;
125
126 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); 124 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
127 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); 125 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
128 126
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index a7857973ca03..a7947199c99b 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -200,12 +200,19 @@ static struct platform_device jazz_cmos_pdev = {
200 .resource = jazz_cmos_rsrc 200 .resource = jazz_cmos_rsrc
201}; 201};
202 202
203static struct platform_device pcspeaker_pdev = {
204 .name = "pcspkr",
205 .id = -1,
206};
207
203static int __init jazz_setup_devinit(void) 208static int __init jazz_setup_devinit(void)
204{ 209{
205 platform_device_register(&jazz_serial8250_device); 210 platform_device_register(&jazz_serial8250_device);
206 platform_device_register(&jazz_esp_pdev); 211 platform_device_register(&jazz_esp_pdev);
207 platform_device_register(&jazz_sonic_pdev); 212 platform_device_register(&jazz_sonic_pdev);
208 platform_device_register(&jazz_cmos_pdev); 213 platform_device_register(&jazz_cmos_pdev);
214 platform_device_register(&pcspeaker_pdev);
215
209 return 0; 216 return 0;
210} 217}
211 218
diff --git a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c
index b643f75ec9a5..700b9cf8eb9d 100644
--- a/arch/mips/jmr3927/rbhma3100/init.c
+++ b/arch/mips/jmr3927/rbhma3100/init.c
@@ -52,10 +52,6 @@ void __init prom_init(void)
52 puts("Warning: TX3927 TLB off\n"); 52 puts("Warning: TX3927 TLB off\n");
53#endif 53#endif
54 54
55#ifdef CONFIG_TOSHIBA_JMR3927
56 mips_machtype = MACH_TOSHIBA_JMR3927;
57#endif
58
59 prom_init_cmdline(); 55 prom_init_cmdline();
60 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); 56 add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
61} 57}
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 06e01c8f4e3a..c886d804d303 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -29,21 +29,17 @@
29 29
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/kdev_t.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/ide.h>
36#include <linux/ioport.h> 34#include <linux/ioport.h>
37#include <linux/delay.h> 35#include <linux/delay.h>
38#include <linux/pm.h> 36#include <linux/pm.h>
39#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/clk.h>
40#ifdef CONFIG_SERIAL_TXX9 39#ifdef CONFIG_SERIAL_TXX9
41#include <linux/tty.h>
42#include <linux/serial.h>
43#include <linux/serial_core.h> 40#include <linux/serial_core.h>
44#endif 41#endif
45 42
46#include <asm/addrspace.h>
47#include <asm/txx9tmr.h> 43#include <asm/txx9tmr.h>
48#include <asm/reboot.h> 44#include <asm/reboot.h>
49#include <asm/jmr3927/jmr3927.h> 45#include <asm/jmr3927/jmr3927.h>
@@ -238,6 +234,8 @@ static void __init tx3927_setup(void)
238 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; 234 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
239 /* Disable PCI snoop */ 235 /* Disable PCI snoop */
240 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; 236 tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
237 /* do reset on watchdog */
238 tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
241 239
242#ifdef DO_WRITE_THROUGH 240#ifdef DO_WRITE_THROUGH
243 /* Enable PCI SNOOP - with write through only */ 241 /* Enable PCI SNOOP - with write through only */
@@ -388,3 +386,55 @@ static int __init jmr3927_rtc_init(void)
388 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 386 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
389} 387}
390device_initcall(jmr3927_rtc_init); 388device_initcall(jmr3927_rtc_init);
389
390/* Watchdog support */
391
392static int __init txx9_wdt_init(unsigned long base)
393{
394 struct resource res = {
395 .start = base,
396 .end = base + 0x100 - 1,
397 .flags = IORESOURCE_MEM,
398 };
399 struct platform_device *dev =
400 platform_device_register_simple("txx9wdt", -1, &res, 1);
401 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
402}
403
404static int __init jmr3927_wdt_init(void)
405{
406 return txx9_wdt_init(TX3927_TMR_REG(2));
407}
408device_initcall(jmr3927_wdt_init);
409
410/* Minimum CLK support */
411
412struct clk *clk_get(struct device *dev, const char *id)
413{
414 if (!strcmp(id, "imbus_clk"))
415 return (struct clk *)JMR3927_IMCLK;
416 return ERR_PTR(-ENOENT);
417}
418EXPORT_SYMBOL(clk_get);
419
420int clk_enable(struct clk *clk)
421{
422 return 0;
423}
424EXPORT_SYMBOL(clk_enable);
425
426void clk_disable(struct clk *clk)
427{
428}
429EXPORT_SYMBOL(clk_disable);
430
431unsigned long clk_get_rate(struct clk *clk)
432{
433 return (unsigned long)clk;
434}
435EXPORT_SYMBOL(clk_get_rate);
436
437void clk_put(struct clk *clk)
438{
439}
440EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index af78456d4138..417bb3e336ac 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -18,6 +18,15 @@
18#include <asm/mipsregs.h> 18#include <asm/mipsregs.h>
19#include <asm/system.h> 19#include <asm/system.h>
20 20
21static char bug64hit[] __initdata =
22 "reliable operation impossible!\n%s";
23static char nowar[] __initdata =
24 "Please report to <linux-mips@linux-mips.org>.";
25static char r4kwar[] __initdata =
26 "Enable CPU_R4000_WORKAROUNDS to rectify.";
27static char daddiwar[] __initdata =
28 "Enable CPU_DADDI_WORKAROUNDS to rectify.";
29
21static inline void align_mod(const int align, const int mod) 30static inline void align_mod(const int align, const int mod)
22{ 31{
23 asm volatile( 32 asm volatile(
@@ -155,13 +164,7 @@ static inline void check_mult_sh(void)
155 } 164 }
156 165
157 printk("no.\n"); 166 printk("no.\n");
158 panic("Reliable operation impossible!\n" 167 panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
159#ifndef CONFIG_CPU_R4000
160 "Configure for R4000 to enable the workaround."
161#else
162 "Please report to <linux-mips@linux-mips.org>."
163#endif
164 );
165} 168}
166 169
167static volatile int daddi_ov __initdata = 0; 170static volatile int daddi_ov __initdata = 0;
@@ -233,15 +236,11 @@ static inline void check_daddi(void)
233 } 236 }
234 237
235 printk("no.\n"); 238 printk("no.\n");
236 panic("Reliable operation impossible!\n" 239 panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
237#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
238 "Configure for R4000 or R4400 to enable the workaround."
239#else
240 "Please report to <linux-mips@linux-mips.org>."
241#endif
242 );
243} 240}
244 241
242int daddiu_bug __initdata = -1;
243
245static inline void check_daddiu(void) 244static inline void check_daddiu(void)
246{ 245{
247 long v, w, tmp; 246 long v, w, tmp;
@@ -281,7 +280,9 @@ static inline void check_daddiu(void)
281 : "=&r" (v), "=&r" (w), "=&r" (tmp) 280 : "=&r" (v), "=&r" (w), "=&r" (tmp)
282 : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); 281 : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
283 282
284 if (v == w) { 283 daddiu_bug = v != w;
284
285 if (!daddiu_bug) {
285 printk("no.\n"); 286 printk("no.\n");
286 return; 287 return;
287 } 288 }
@@ -303,18 +304,16 @@ static inline void check_daddiu(void)
303 } 304 }
304 305
305 printk("no.\n"); 306 printk("no.\n");
306 panic("Reliable operation impossible!\n" 307 panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
307#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400)
308 "Configure for R4000 or R4400 to enable the workaround."
309#else
310 "Please report to <linux-mips@linux-mips.org>."
311#endif
312 );
313} 308}
314 309
315void __init check_bugs64(void) 310void __init check_bugs64_early(void)
316{ 311{
317 check_mult_sh(); 312 check_mult_sh();
318 check_daddi();
319 check_daddiu(); 313 check_daddiu();
320} 314}
315
316void __init check_bugs64(void)
317{
318 check_daddi();
319}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 5c2794391bf5..5861a432a52f 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -188,6 +188,8 @@ static inline void check_wait(void)
188 case CPU_AU1500: 188 case CPU_AU1500:
189 case CPU_AU1550: 189 case CPU_AU1550:
190 case CPU_AU1200: 190 case CPU_AU1200:
191 case CPU_AU1210:
192 case CPU_AU1250:
191 if (allow_au1k_wait) 193 if (allow_au1k_wait)
192 cpu_wait = au1k_wait; 194 cpu_wait = au1k_wait;
193 break; 195 break;
@@ -733,6 +735,11 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
733 break; 735 break;
734 case 4: 736 case 4:
735 c->cputype = CPU_AU1200; 737 c->cputype = CPU_AU1200;
738 if (2 == (c->processor_id & 0xff))
739 c->cputype = CPU_AU1250;
740 break;
741 case 5:
742 c->cputype = CPU_AU1210;
736 break; 743 break;
737 default: 744 default:
738 panic("Unknown Au Core!"); 745 panic("Unknown Au Core!");
@@ -858,6 +865,8 @@ static __init const char *cpu_to_name(struct cpuinfo_mips *c)
858 case CPU_AU1100: name = "Au1100"; break; 865 case CPU_AU1100: name = "Au1100"; break;
859 case CPU_AU1550: name = "Au1550"; break; 866 case CPU_AU1550: name = "Au1550"; break;
860 case CPU_AU1200: name = "Au1200"; break; 867 case CPU_AU1200: name = "Au1200"; break;
868 case CPU_AU1210: name = "Au1210"; break;
869 case CPU_AU1250: name = "Au1250"; break;
861 case CPU_4KEC: name = "MIPS 4KEc"; break; 870 case CPU_4KEC: name = "MIPS 4KEc"; break;
862 case CPU_4KSC: name = "MIPS 4KSc"; break; 871 case CPU_4KSC: name = "MIPS 4KSc"; break;
863 case CPU_VR41XX: name = "NEC Vr41xx"; break; 872 case CPU_VR41XX: name = "NEC Vr41xx"; break;
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index e76a76bf0b3d..c6ada98ee042 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -6,7 +6,7 @@
6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc. 8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 * Copyright (C) 2002 Maciej W. Rozycki 9 * Copyright (C) 2002, 2007 Maciej W. Rozycki
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12 12
@@ -471,7 +471,13 @@ NESTED(nmi_handler, PT_SIZE, sp)
471 jr k0 471 jr k0
472 rfe 472 rfe
473#else 473#else
474#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
474 LONG_ADDIU k0, 4 /* stall on $k0 */ 475 LONG_ADDIU k0, 4 /* stall on $k0 */
476#else
477 .set at=v1
478 LONG_ADDIU k0, 4
479 .set noat
480#endif
475 MTC0 k0, CP0_EPC 481 MTC0 k0, CP0_EPC
476 /* I hope three instructions between MTC0 and ERET are enough... */ 482 /* I hope three instructions between MTC0 and ERET are enough... */
477 ori k1, _THREAD_MASK 483 ori k1, _THREAD_MASK
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index d2c2e00e5864..f6704ab16306 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -161,8 +161,7 @@ static unsigned int translate_open_flags(int flags)
161 int i; 161 int i;
162 unsigned int ret = 0; 162 unsigned int ret = 0;
163 163
164 for (i = 0; i < (sizeof(open_flags_table) / sizeof(struct apsp_table)); 164 for (i = 0; i < ARRAY_SIZE(open_flags_table); i++) {
165 i++) {
166 if( (flags & open_flags_table[i].sp) ) { 165 if( (flags & open_flags_table[i].sp) ) {
167 ret |= open_flags_table[i].ap; 166 ret |= open_flags_table[i].ap;
168 } 167 }
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 2b8ec1102e86..65af3cc90abb 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -174,36 +174,16 @@ struct rlimit32 {
174 int rlim_max; 174 int rlim_max;
175}; 175};
176 176
177#ifdef __MIPSEB__ 177asmlinkage long sys32_truncate64(const char __user * path,
178asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy, 178 unsigned long __dummy, int a2, int a3)
179 int length_hi, int length_lo)
180#endif
181#ifdef __MIPSEL__
182asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
183 int length_lo, int length_hi)
184#endif
185{ 179{
186 loff_t length; 180 return sys_truncate(path, merge_64(a2, a3));
187
188 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
189
190 return sys_truncate(path, length);
191} 181}
192 182
193#ifdef __MIPSEB__
194asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, 183asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
195 int length_hi, int length_lo) 184 int a2, int a3)
196#endif
197#ifdef __MIPSEL__
198asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
199 int length_lo, int length_hi)
200#endif
201{ 185{
202 loff_t length; 186 return sys_ftruncate(fd, merge_64(a2, a3));
203
204 length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
205
206 return sys_ftruncate(fd, length);
207} 187}
208 188
209static inline long 189static inline long
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index 3d6b1ec1f328..640fb0cc6e39 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -17,7 +17,6 @@
17#include <asm/system.h> 17#include <asm/system.h>
18#include <asm/hardirq.h> 18#include <asm/hardirq.h>
19#include <asm/mmu_context.h> 19#include <asm/mmu_context.h>
20#include <asm/smp.h>
21#include <asm/mipsmtregs.h> 20#include <asm/mipsmtregs.h>
22#include <asm/r4kcache.h> 21#include <asm/r4kcache.h>
23#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
diff --git a/arch/mips/kernel/pcspeaker.c b/arch/mips/kernel/pcspeaker.c
deleted file mode 100644
index 475df6904219..000000000000
--- a/arch/mips/kernel/pcspeaker.c
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (C) 2006 IBM Corporation
3 *
4 * Implements device information for i8253 timer chip
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation
9 */
10
11#include <linux/platform_device.h>
12
13static __init int add_pcspkr(void)
14{
15 struct platform_device *pd;
16 int ret;
17
18 pd = platform_device_alloc("pcspkr", -1);
19 if (!pd)
20 return -ENOMEM;
21
22 ret = platform_device_add(pd);
23 if (ret)
24 platform_device_put(pd);
25
26 return ret;
27}
28device_initcall(add_pcspkr);
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 6e6e947cce1e..36f065398243 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -62,6 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
62 ); 62 );
63 seq_printf(m, "shadow register sets\t: %d\n", 63 seq_printf(m, "shadow register sets\t: %d\n",
64 cpu_data[n].srsets); 64 cpu_data[n].srsets);
65 seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
65 66
66 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 67 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
67 cpu_has_vce ? "%u" : "not available"); 68 cpu_has_vce ? "%u" : "not available");
@@ -89,7 +90,7 @@ static void c_stop(struct seq_file *m, void *v)
89{ 90{
90} 91}
91 92
92struct seq_operations cpuinfo_op = { 93const struct seq_operations cpuinfo_op = {
93 .start = c_start, 94 .start = c_start,
94 .next = c_next, 95 .next = c_next,
95 .stop = c_stop, 96 .stop = c_stop,
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 1ba00c15505b..0233798f7155 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -40,7 +40,6 @@
40#include <asm/atomic.h> 40#include <asm/atomic.h>
41#include <asm/cpu.h> 41#include <asm/cpu.h>
42#include <asm/processor.h> 42#include <asm/processor.h>
43#include <asm/mips_mt.h>
44#include <asm/system.h> 43#include <asm/system.h>
45#include <asm/vpe.h> 44#include <asm/vpe.h>
46#include <asm/rtlx.h> 45#include <asm/rtlx.h>
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f8a535afce39..269c252d956f 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -8,7 +8,7 @@
8 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle 8 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle
9 * Copyright (C) 1996 Stoned Elipot 9 * Copyright (C) 1996 Stoned Elipot
10 * Copyright (C) 1999 Silicon Graphics, Inc. 10 * Copyright (C) 1999 Silicon Graphics, Inc.
11 * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki 11 * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki
12 */ 12 */
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/ioport.h> 14#include <linux/ioport.h>
@@ -24,10 +24,12 @@
24 24
25#include <asm/addrspace.h> 25#include <asm/addrspace.h>
26#include <asm/bootinfo.h> 26#include <asm/bootinfo.h>
27#include <asm/bugs.h>
27#include <asm/cache.h> 28#include <asm/cache.h>
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/sections.h> 30#include <asm/sections.h>
30#include <asm/setup.h> 31#include <asm/setup.h>
32#include <asm/smp-ops.h>
31#include <asm/system.h> 33#include <asm/system.h>
32 34
33struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; 35struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
@@ -561,6 +563,7 @@ void __init setup_arch(char **cmdline_p)
561 } 563 }
562#endif 564#endif
563 cpu_report(); 565 cpu_report();
566 check_bugs_early();
564 567
565#if defined(CONFIG_VT) 568#if defined(CONFIG_VT)
566#if defined(CONFIG_VGA_CONSOLE) 569#if defined(CONFIG_VGA_CONSOLE)
@@ -573,9 +576,7 @@ void __init setup_arch(char **cmdline_p)
573 arch_mem_init(cmdline_p); 576 arch_mem_init(cmdline_p);
574 577
575 resource_init(); 578 resource_init();
576#ifdef CONFIG_SMP
577 plat_smp_setup(); 579 plat_smp_setup();
578#endif
579} 580}
580 581
581static int __init fpu_disable(char *s) 582static int __init fpu_disable(char *s)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 94e210cc6cb6..89e6f6aa5166 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -22,6 +22,7 @@
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25#include <linux/smp.h>
25 26
26#include <asm/atomic.h> 27#include <asm/atomic.h>
27#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
@@ -30,7 +31,6 @@
30#include <asm/system.h> 31#include <asm/system.h>
31#include <asm/hardirq.h> 32#include <asm/hardirq.h>
32#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
33#include <asm/smp.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
36#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
@@ -215,68 +215,67 @@ static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0)
215 write_tc_c0_tchalt(TCHALT_H); 215 write_tc_c0_tchalt(TCHALT_H);
216} 216}
217 217
218/* 218static void vsmp_send_ipi_single(int cpu, unsigned int action)
219 * Common setup before any secondaries are started
220 * Make sure all CPU's are in a sensible state before we boot any of the
221 * secondarys
222 */
223void __init plat_smp_setup(void)
224{ 219{
225 unsigned int mvpconf0, ntc, tc, ncpu = 0; 220 int i;
226 221 unsigned long flags;
227#ifdef CONFIG_MIPS_MT_FPAFF 222 int vpflags;
228 /* If we have an FPU, enroll ourselves in the FPU-full mask */
229 if (cpu_has_fpu)
230 cpu_set(0, mt_fpu_cpumask);
231#endif /* CONFIG_MIPS_MT_FPAFF */
232 if (!cpu_has_mipsmt)
233 return;
234
235 /* disable MT so we can configure */
236 dvpe();
237 dmt();
238 223
239 /* Put MVPE's into 'configuration state' */ 224 local_irq_save(flags);
240 set_c0_mvpcontrol(MVPCONTROL_VPC);
241 225
242 mvpconf0 = read_c0_mvpconf0(); 226 vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */
243 ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
244 227
245 /* we'll always have more TC's than VPE's, so loop setting everything 228 switch (action) {
246 to a sensible state */ 229 case SMP_CALL_FUNCTION:
247 for (tc = 0; tc <= ntc; tc++) { 230 i = C_SW1;
248 settc(tc); 231 break;
249 232
250 smp_tc_init(tc, mvpconf0); 233 case SMP_RESCHEDULE_YOURSELF:
251 ncpu = smp_vpe_init(tc, mvpconf0, ncpu); 234 default:
235 i = C_SW0;
236 break;
252 } 237 }
253 238
254 /* Release config state */ 239 /* 1:1 mapping of vpe and tc... */
255 clear_c0_mvpcontrol(MVPCONTROL_VPC); 240 settc(cpu);
241 write_vpe_c0_cause(read_vpe_c0_cause() | i);
242 evpe(vpflags);
256 243
257 /* We'll wait until starting the secondaries before starting MVPE */ 244 local_irq_restore(flags);
245}
258 246
259 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); 247static void vsmp_send_ipi_mask(cpumask_t mask, unsigned int action)
248{
249 unsigned int i;
250
251 for_each_cpu_mask(i, mask)
252 vsmp_send_ipi_single(i, action);
260} 253}
261 254
262void __init plat_prepare_cpus(unsigned int max_cpus) 255static void __cpuinit vsmp_init_secondary(void)
263{ 256{
264 mips_mt_set_cpuoptions(); 257 /* Enable per-cpu interrupts */
265 258
266 /* set up ipi interrupts */ 259 /* This is Malta specific: IPI,performance and timer inetrrupts */
267 if (cpu_has_vint) { 260 write_c0_status((read_c0_status() & ~ST0_IM ) |
268 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); 261 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
269 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); 262}
270 }
271 263
272 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 264static void __cpuinit vsmp_smp_finish(void)
273 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ; 265{
266 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
274 267
275 setup_irq(cpu_ipi_resched_irq, &irq_resched); 268#ifdef CONFIG_MIPS_MT_FPAFF
276 setup_irq(cpu_ipi_call_irq, &irq_call); 269 /* If we have an FPU, enroll ourselves in the FPU-full mask */
270 if (cpu_has_fpu)
271 cpu_set(smp_processor_id(), mt_fpu_cpumask);
272#endif /* CONFIG_MIPS_MT_FPAFF */
277 273
278 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); 274 local_irq_enable();
279 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); 275}
276
277static void vsmp_cpus_done(void)
278{
280} 279}
281 280
282/* 281/*
@@ -287,7 +286,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
287 * (unsigned long)idle->thread_info the gp 286 * (unsigned long)idle->thread_info the gp
288 * assumes a 1:1 mapping of TC => VPE 287 * assumes a 1:1 mapping of TC => VPE
289 */ 288 */
290void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) 289static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
291{ 290{
292 struct thread_info *gp = task_thread_info(idle); 291 struct thread_info *gp = task_thread_info(idle);
293 dvpe(); 292 dvpe();
@@ -321,57 +320,81 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
321 evpe(EVPE_ENABLE); 320 evpe(EVPE_ENABLE);
322} 321}
323 322
324void __cpuinit prom_init_secondary(void) 323/*
325{ 324 * Common setup before any secondaries are started
326 /* Enable per-cpu interrupts */ 325 * Make sure all CPU's are in a sensible state before we boot any of the
327 326 * secondarys
328 /* This is Malta specific: IPI,performance and timer inetrrupts */ 327 */
329 write_c0_status((read_c0_status() & ~ST0_IM ) | 328static void __init vsmp_smp_setup(void)
330 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
331}
332
333void __cpuinit prom_smp_finish(void)
334{ 329{
335 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 330 unsigned int mvpconf0, ntc, tc, ncpu = 0;
331 unsigned int nvpe;
336 332
337#ifdef CONFIG_MIPS_MT_FPAFF 333#ifdef CONFIG_MIPS_MT_FPAFF
338 /* If we have an FPU, enroll ourselves in the FPU-full mask */ 334 /* If we have an FPU, enroll ourselves in the FPU-full mask */
339 if (cpu_has_fpu) 335 if (cpu_has_fpu)
340 cpu_set(smp_processor_id(), mt_fpu_cpumask); 336 cpu_set(0, mt_fpu_cpumask);
341#endif /* CONFIG_MIPS_MT_FPAFF */ 337#endif /* CONFIG_MIPS_MT_FPAFF */
338 if (!cpu_has_mipsmt)
339 return;
342 340
343 local_irq_enable(); 341 /* disable MT so we can configure */
344} 342 dvpe();
343 dmt();
345 344
346void prom_cpus_done(void) 345 /* Put MVPE's into 'configuration state' */
347{ 346 set_c0_mvpcontrol(MVPCONTROL_VPC);
348}
349 347
350void core_send_ipi(int cpu, unsigned int action) 348 mvpconf0 = read_c0_mvpconf0();
351{ 349 ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
352 int i;
353 unsigned long flags;
354 int vpflags;
355 350
356 local_irq_save(flags); 351 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
352 smp_num_siblings = nvpe;
357 353
358 vpflags = dvpe(); /* cant access the other CPU's registers whilst MVPE enabled */ 354 /* we'll always have more TC's than VPE's, so loop setting everything
355 to a sensible state */
356 for (tc = 0; tc <= ntc; tc++) {
357 settc(tc);
359 358
360 switch (action) { 359 smp_tc_init(tc, mvpconf0);
361 case SMP_CALL_FUNCTION: 360 ncpu = smp_vpe_init(tc, mvpconf0, ncpu);
362 i = C_SW1; 361 }
363 break;
364 362
365 case SMP_RESCHEDULE_YOURSELF: 363 /* Release config state */
366 default: 364 clear_c0_mvpcontrol(MVPCONTROL_VPC);
367 i = C_SW0; 365
368 break; 366 /* We'll wait until starting the secondaries before starting MVPE */
367
368 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
369}
370
371static void __init vsmp_prepare_cpus(unsigned int max_cpus)
372{
373 mips_mt_set_cpuoptions();
374
375 /* set up ipi interrupts */
376 if (cpu_has_vint) {
377 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
378 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
369 } 379 }
370 380
371 /* 1:1 mapping of vpe and tc... */ 381 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
372 settc(cpu); 382 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
373 write_vpe_c0_cause(read_vpe_c0_cause() | i);
374 evpe(vpflags);
375 383
376 local_irq_restore(flags); 384 setup_irq(cpu_ipi_resched_irq, &irq_resched);
385 setup_irq(cpu_ipi_call_irq, &irq_call);
386
387 set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq);
388 set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq);
377} 389}
390
391struct plat_smp_ops vsmp_smp_ops = {
392 .send_ipi_single = vsmp_send_ipi_single,
393 .send_ipi_mask = vsmp_send_ipi_mask,
394 .init_secondary = vsmp_init_secondary,
395 .smp_finish = vsmp_smp_finish,
396 .cpus_done = vsmp_cpus_done,
397 .boot_secondary = vsmp_boot_secondary,
398 .smp_setup = vsmp_smp_setup,
399 .prepare_cpus = vsmp_prepare_cpus,
400};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 63989e9df4f9..1e5dfc28294a 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -37,7 +37,6 @@
37#include <asm/processor.h> 37#include <asm/processor.h>
38#include <asm/system.h> 38#include <asm/system.h>
39#include <asm/mmu_context.h> 39#include <asm/mmu_context.h>
40#include <asm/smp.h>
41#include <asm/time.h> 40#include <asm/time.h>
42 41
43#ifdef CONFIG_MIPS_MT_SMTC 42#ifdef CONFIG_MIPS_MT_SMTC
@@ -56,6 +55,44 @@ EXPORT_SYMBOL(cpu_online_map);
56extern void __init calibrate_delay(void); 55extern void __init calibrate_delay(void);
57extern void cpu_idle(void); 56extern void cpu_idle(void);
58 57
58/* Number of TCs (or siblings in Intel speak) per CPU core */
59int smp_num_siblings = 1;
60EXPORT_SYMBOL(smp_num_siblings);
61
62/* representing the TCs (or siblings in Intel speak) of each logical CPU */
63cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
64EXPORT_SYMBOL(cpu_sibling_map);
65
66/* representing cpus for which sibling maps can be computed */
67static cpumask_t cpu_sibling_setup_map;
68
69static inline void set_cpu_sibling_map(int cpu)
70{
71 int i;
72
73 cpu_set(cpu, cpu_sibling_setup_map);
74
75 if (smp_num_siblings > 1) {
76 for_each_cpu_mask(i, cpu_sibling_setup_map) {
77 if (cpu_data[cpu].core == cpu_data[i].core) {
78 cpu_set(i, cpu_sibling_map[cpu]);
79 cpu_set(cpu, cpu_sibling_map[i]);
80 }
81 }
82 } else
83 cpu_set(cpu, cpu_sibling_map[cpu]);
84}
85
86struct plat_smp_ops *mp_ops;
87
88__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
89{
90 if (ops)
91 printk(KERN_WARNING "Overriding previous set SMP ops\n");
92
93 mp_ops = ops;
94}
95
59/* 96/*
60 * First C code run on the secondary CPUs after being started up by 97 * First C code run on the secondary CPUs after being started up by
61 * the master. 98 * the master.
@@ -72,7 +109,7 @@ asmlinkage __cpuinit void start_secondary(void)
72 cpu_report(); 109 cpu_report();
73 per_cpu_trap_init(); 110 per_cpu_trap_init();
74 mips_clockevent_init(); 111 mips_clockevent_init();
75 prom_init_secondary(); 112 mp_ops->init_secondary();
76 113
77 /* 114 /*
78 * XXX parity protection should be folded in here when it's converted 115 * XXX parity protection should be folded in here when it's converted
@@ -84,7 +121,8 @@ asmlinkage __cpuinit void start_secondary(void)
84 cpu = smp_processor_id(); 121 cpu = smp_processor_id();
85 cpu_data[cpu].udelay_val = loops_per_jiffy; 122 cpu_data[cpu].udelay_val = loops_per_jiffy;
86 123
87 prom_smp_finish(); 124 mp_ops->smp_finish();
125 set_cpu_sibling_map(cpu);
88 126
89 cpu_set(cpu, cpu_callin_map); 127 cpu_set(cpu, cpu_callin_map);
90 128
@@ -155,7 +193,7 @@ int smp_call_function_mask(cpumask_t mask, void (*func) (void *info),
155 smp_mb(); 193 smp_mb();
156 194
157 /* Send a message to all other CPUs and wait for them to respond */ 195 /* Send a message to all other CPUs and wait for them to respond */
158 core_send_ipi_mask(mask, SMP_CALL_FUNCTION); 196 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
159 197
160 /* Wait for response */ 198 /* Wait for response */
161 /* FIXME: lock-up detection, backtrace on lock-up */ 199 /* FIXME: lock-up detection, backtrace on lock-up */
@@ -249,7 +287,7 @@ void smp_send_stop(void)
249 287
250void __init smp_cpus_done(unsigned int max_cpus) 288void __init smp_cpus_done(unsigned int max_cpus)
251{ 289{
252 prom_cpus_done(); 290 mp_ops->cpus_done();
253} 291}
254 292
255/* called from main before smp_init() */ 293/* called from main before smp_init() */
@@ -257,7 +295,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
257{ 295{
258 init_new_context(current, &init_mm); 296 init_new_context(current, &init_mm);
259 current_thread_info()->cpu = 0; 297 current_thread_info()->cpu = 0;
260 plat_prepare_cpus(max_cpus); 298 mp_ops->prepare_cpus(max_cpus);
299 set_cpu_sibling_map(0);
261#ifndef CONFIG_HOTPLUG_CPU 300#ifndef CONFIG_HOTPLUG_CPU
262 cpu_present_map = cpu_possible_map; 301 cpu_present_map = cpu_possible_map;
263#endif 302#endif
@@ -295,7 +334,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
295 if (IS_ERR(idle)) 334 if (IS_ERR(idle))
296 panic(KERN_ERR "Fork failed for CPU %d", cpu); 335 panic(KERN_ERR "Fork failed for CPU %d", cpu);
297 336
298 prom_boot_secondary(cpu, idle); 337 mp_ops->boot_secondary(cpu, idle);
299 338
300 /* 339 /*
301 * Trust is futile. We should really have timeouts ... 340 * Trust is futile. We should really have timeouts ...
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
index 6f3709996172..fe256559c997 100644
--- a/arch/mips/kernel/smtc-proc.c
+++ b/arch/mips/kernel/smtc-proc.c
@@ -14,7 +14,6 @@
14#include <asm/system.h> 14#include <asm/system.h>
15#include <asm/hardirq.h> 15#include <asm/hardirq.h>
16#include <asm/mmu_context.h> 16#include <asm/mmu_context.h>
17#include <asm/smp.h>
18#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
19#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 9c92d42996cb..85f700e58131 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -16,7 +16,6 @@
16#include <asm/hazards.h> 16#include <asm/hazards.h>
17#include <asm/irq.h> 17#include <asm/irq.h>
18#include <asm/mmu_context.h> 18#include <asm/mmu_context.h>
19#include <asm/smp.h>
20#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
21#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
22#include <asm/time.h> 21#include <asm/time.h>
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 2995be1ab3ca..9f85d4cecc5b 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -50,8 +50,6 @@ int update_persistent_clock(struct timespec now)
50 return rtc_mips_set_mmss(now.tv_sec); 50 return rtc_mips_set_mmss(now.tv_sec);
51} 51}
52 52
53int (*mips_timer_state)(void);
54
55int null_perf_irq(void) 53int null_perf_irq(void)
56{ 54{
57 return 0; 55 return 0;
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 5fc2398bdb76..b5470ceb418b 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -114,11 +114,11 @@ SECTIONS
114 __init_begin = .; 114 __init_begin = .;
115 .init.text : { 115 .init.text : {
116 _sinittext = .; 116 _sinittext = .;
117 *(.init.text) 117 INIT_TEXT
118 _einittext = .; 118 _einittext = .;
119 } 119 }
120 .init.data : { 120 .init.data : {
121 *(.init.data) 121 INIT_DATA
122 } 122 }
123 . = ALIGN(16); 123 . = ALIGN(16);
124 .init.setup : { 124 .init.setup : {
@@ -144,10 +144,10 @@ SECTIONS
144 * references from .rodata 144 * references from .rodata
145 */ 145 */
146 .exit.text : { 146 .exit.text : {
147 *(.exit.text) 147 EXIT_TEXT
148 } 148 }
149 .exit.data : { 149 .exit.data : {
150 *(.exit.data) 150 EXIT_DATA
151 } 151 }
152#if defined(CONFIG_BLK_DEV_INITRD) 152#if defined(CONFIG_BLK_DEV_INITRD)
153 . = ALIGN(_PAGE_SIZE); 153 . = ALIGN(_PAGE_SIZE);
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index c06eb812a95e..eed2dc4273e0 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -53,7 +53,6 @@
53#include <asm/system.h> 53#include <asm/system.h>
54#include <asm/vpe.h> 54#include <asm/vpe.h>
55#include <asm/kspd.h> 55#include <asm/kspd.h>
56#include <asm/mips_mt.h>
57 56
58typedef void *vpe_handle; 57typedef void *vpe_handle;
59 58
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
index 6471d0663fd8..d3d04c392e25 100644
--- a/arch/mips/lasat/picvue.c
+++ b/arch/mips/lasat/picvue.c
@@ -22,8 +22,6 @@
22 22
23struct pvc_defs *picvue; 23struct pvc_defs *picvue;
24 24
25DECLARE_MUTEX(pvc_sem);
26
27static void pvc_reg_write(u32 val) 25static void pvc_reg_write(u32 val)
28{ 26{
29 *picvue->reg = val; 27 *picvue->reg = val;
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
index 2a96bf971897..91df55371127 100644
--- a/arch/mips/lasat/picvue.h
+++ b/arch/mips/lasat/picvue.h
@@ -4,8 +4,6 @@
4 * Brian Murphy <brian.murphy@eicon.com> 4 * Brian Murphy <brian.murphy@eicon.com>
5 * 5 *
6 */ 6 */
7#include <asm/semaphore.h>
8
9struct pvc_defs { 7struct pvc_defs {
10 volatile u32 *reg; 8 volatile u32 *reg;
11 u32 data_shift; 9 u32 data_shift;
@@ -45,4 +43,3 @@ void pvc_move(u8 cmd);
45void pvc_clear(void); 43void pvc_clear(void);
46void pvc_home(void); 44void pvc_home(void);
47 45
48extern struct semaphore pvc_sem;
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
index 9947c1525822..0bb6037afba3 100644
--- a/arch/mips/lasat/picvue_proc.c
+++ b/arch/mips/lasat/picvue_proc.c
@@ -13,9 +13,11 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14 14
15#include <linux/timer.h> 15#include <linux/timer.h>
16#include <linux/mutex.h>
16 17
17#include "picvue.h" 18#include "picvue.h"
18 19
20static DEFINE_MUTEX(pvc_mutex);
19static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; 21static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
20static int pvc_linedata[PVC_NLINES]; 22static int pvc_linedata[PVC_NLINES];
21static struct proc_dir_entry *pvc_display_dir; 23static struct proc_dir_entry *pvc_display_dir;
@@ -48,9 +50,9 @@ static int pvc_proc_read_line(char *page, char **start,
48 return 0; 50 return 0;
49 } 51 }
50 52
51 down(&pvc_sem); 53 mutex_lock(&pvc_mutex);
52 page += sprintf(page, "%s\n", pvc_lines[lineno]); 54 page += sprintf(page, "%s\n", pvc_lines[lineno]);
53 up(&pvc_sem); 55 mutex_unlock(&pvc_mutex);
54 56
55 return page - origpage; 57 return page - origpage;
56} 58}
@@ -73,10 +75,10 @@ static int pvc_proc_write_line(struct file *file, const char *buffer,
73 if (buffer[count-1] == '\n') 75 if (buffer[count-1] == '\n')
74 count--; 76 count--;
75 77
76 down(&pvc_sem); 78 mutex_lock(&pvc_mutex);
77 strncpy(pvc_lines[lineno], buffer, count); 79 strncpy(pvc_lines[lineno], buffer, count);
78 pvc_lines[lineno][count] = '\0'; 80 pvc_lines[lineno][count] = '\0';
79 up(&pvc_sem); 81 mutex_unlock(&pvc_mutex);
80 82
81 tasklet_schedule(&pvc_display_tasklet); 83 tasklet_schedule(&pvc_display_tasklet);
82 84
@@ -89,7 +91,7 @@ static int pvc_proc_write_scroll(struct file *file, const char *buffer,
89 int origcount = count; 91 int origcount = count;
90 int cmd = simple_strtol(buffer, NULL, 10); 92 int cmd = simple_strtol(buffer, NULL, 10);
91 93
92 down(&pvc_sem); 94 mutex_lock(&pvc_mutex);
93 if (scroll_interval != 0) 95 if (scroll_interval != 0)
94 del_timer(&timer); 96 del_timer(&timer);
95 97
@@ -106,7 +108,7 @@ static int pvc_proc_write_scroll(struct file *file, const char *buffer,
106 } 108 }
107 add_timer(&timer); 109 add_timer(&timer);
108 } 110 }
109 up(&pvc_sem); 111 mutex_unlock(&pvc_mutex);
110 112
111 return origcount; 113 return origcount;
112} 114}
@@ -117,9 +119,9 @@ static int pvc_proc_read_scroll(char *page, char **start,
117{ 119{
118 char *origpage = page; 120 char *origpage = page;
119 121
120 down(&pvc_sem); 122 mutex_lock(&pvc_mutex);
121 page += sprintf(page, "%d\n", scroll_dir * scroll_interval); 123 page += sprintf(page, "%d\n", scroll_dir * scroll_interval);
122 up(&pvc_sem); 124 mutex_unlock(&pvc_mutex);
123 125
124 return page - origpage; 126 return page - origpage;
125} 127}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
index 1ade1cef3899..c1e41f15cc7e 100644
--- a/arch/mips/lemote/lm2e/pci.c
+++ b/arch/mips/lemote/lm2e/pci.c
@@ -81,9 +81,6 @@ static void __init ict_pcimap(void)
81 81
82static int __init pcibios_init(void) 82static int __init pcibios_init(void)
83{ 83{
84 extern int pci_probe_only;
85 pci_probe_only = 0;
86
87 ict_pcimap(); 84 ict_pcimap();
88 register_pci_controller(&loongson2e_pci_controller); 85 register_pci_controller(&loongson2e_pci_controller);
89 86
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
index 824336812198..7edc15dfed6c 100644
--- a/arch/mips/lemote/lm2e/prom.c
+++ b/arch/mips/lemote/lm2e/prom.c
@@ -57,8 +57,6 @@ void __init prom_init(void)
57 arg = (int *)fw_arg1; 57 arg = (int *)fw_arg1;
58 env = (int *)fw_arg2; 58 env = (int *)fw_arg2;
59 59
60 mips_machtype = MACH_LEMOTE_FULONG;
61
62 prom_init_cmdline(); 60 prom_init_cmdline();
63 61
64 if ((strstr(arcs_cmdline, "console=")) == NULL) 62 if ((strstr(arcs_cmdline, "console=")) == NULL)
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
index c0a77fe038be..8d7784122c14 100644
--- a/arch/mips/lib/csum_partial.S
+++ b/arch/mips/lib/csum_partial.S
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright (C) 1998, 1999 Ralf Baechle 8 * Copyright (C) 1998, 1999 Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc. 9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 * Copyright (C) 2007 Maciej W. Rozycki
10 */ 11 */
11#include <linux/errno.h> 12#include <linux/errno.h>
12#include <asm/asm.h> 13#include <asm/asm.h>
@@ -52,9 +53,12 @@
52#define UNIT(unit) ((unit)*NBYTES) 53#define UNIT(unit) ((unit)*NBYTES)
53 54
54#define ADDC(sum,reg) \ 55#define ADDC(sum,reg) \
56 .set push; \
57 .set noat; \
55 ADD sum, reg; \ 58 ADD sum, reg; \
56 sltu v1, sum, reg; \ 59 sltu v1, sum, reg; \
57 ADD sum, v1 60 ADD sum, v1; \
61 .set pop
58 62
59#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ 63#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
60 LOAD _t0, (offset + UNIT(0))(src); \ 64 LOAD _t0, (offset + UNIT(0))(src); \
@@ -92,13 +96,13 @@ LEAF(csum_partial)
92 move t7, zero 96 move t7, zero
93 97
94 sltiu t8, a1, 0x8 98 sltiu t8, a1, 0x8
95 bnez t8, small_csumcpy /* < 8 bytes to copy */ 99 bnez t8, .Lsmall_csumcpy /* < 8 bytes to copy */
96 move t2, a1 100 move t2, a1
97 101
98 andi t7, src, 0x1 /* odd buffer? */ 102 andi t7, src, 0x1 /* odd buffer? */
99 103
100hword_align: 104.Lhword_align:
101 beqz t7, word_align 105 beqz t7, .Lword_align
102 andi t8, src, 0x2 106 andi t8, src, 0x2
103 107
104 lbu t0, (src) 108 lbu t0, (src)
@@ -110,8 +114,8 @@ hword_align:
110 PTR_ADDU src, src, 0x1 114 PTR_ADDU src, src, 0x1
111 andi t8, src, 0x2 115 andi t8, src, 0x2
112 116
113word_align: 117.Lword_align:
114 beqz t8, dword_align 118 beqz t8, .Ldword_align
115 sltiu t8, a1, 56 119 sltiu t8, a1, 56
116 120
117 lhu t0, (src) 121 lhu t0, (src)
@@ -120,12 +124,12 @@ word_align:
120 sltiu t8, a1, 56 124 sltiu t8, a1, 56
121 PTR_ADDU src, src, 0x2 125 PTR_ADDU src, src, 0x2
122 126
123dword_align: 127.Ldword_align:
124 bnez t8, do_end_words 128 bnez t8, .Ldo_end_words
125 move t8, a1 129 move t8, a1
126 130
127 andi t8, src, 0x4 131 andi t8, src, 0x4
128 beqz t8, qword_align 132 beqz t8, .Lqword_align
129 andi t8, src, 0x8 133 andi t8, src, 0x8
130 134
131 lw t0, 0x00(src) 135 lw t0, 0x00(src)
@@ -134,8 +138,8 @@ dword_align:
134 PTR_ADDU src, src, 0x4 138 PTR_ADDU src, src, 0x4
135 andi t8, src, 0x8 139 andi t8, src, 0x8
136 140
137qword_align: 141.Lqword_align:
138 beqz t8, oword_align 142 beqz t8, .Loword_align
139 andi t8, src, 0x10 143 andi t8, src, 0x10
140 144
141#ifdef USE_DOUBLE 145#ifdef USE_DOUBLE
@@ -152,8 +156,8 @@ qword_align:
152 PTR_ADDU src, src, 0x8 156 PTR_ADDU src, src, 0x8
153 andi t8, src, 0x10 157 andi t8, src, 0x10
154 158
155oword_align: 159.Loword_align:
156 beqz t8, begin_movement 160 beqz t8, .Lbegin_movement
157 LONG_SRL t8, a1, 0x7 161 LONG_SRL t8, a1, 0x7
158 162
159#ifdef USE_DOUBLE 163#ifdef USE_DOUBLE
@@ -168,51 +172,55 @@ oword_align:
168 PTR_ADDU src, src, 0x10 172 PTR_ADDU src, src, 0x10
169 LONG_SRL t8, a1, 0x7 173 LONG_SRL t8, a1, 0x7
170 174
171begin_movement: 175.Lbegin_movement:
172 beqz t8, 1f 176 beqz t8, 1f
173 andi t2, a1, 0x40 177 andi t2, a1, 0x40
174 178
175move_128bytes: 179.Lmove_128bytes:
176 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 180 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
177 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) 181 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
178 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4) 182 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
179 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4) 183 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
180 LONG_SUBU t8, t8, 0x01 184 LONG_SUBU t8, t8, 0x01
181 bnez t8, move_128bytes 185 .set reorder /* DADDI_WAR */
182 PTR_ADDU src, src, 0x80 186 PTR_ADDU src, src, 0x80
187 bnez t8, .Lmove_128bytes
188 .set noreorder
183 189
1841: 1901:
185 beqz t2, 1f 191 beqz t2, 1f
186 andi t2, a1, 0x20 192 andi t2, a1, 0x20
187 193
188move_64bytes: 194.Lmove_64bytes:
189 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 195 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
190 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) 196 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
191 PTR_ADDU src, src, 0x40 197 PTR_ADDU src, src, 0x40
192 198
1931: 1991:
194 beqz t2, do_end_words 200 beqz t2, .Ldo_end_words
195 andi t8, a1, 0x1c 201 andi t8, a1, 0x1c
196 202
197move_32bytes: 203.Lmove_32bytes:
198 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) 204 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
199 andi t8, a1, 0x1c 205 andi t8, a1, 0x1c
200 PTR_ADDU src, src, 0x20 206 PTR_ADDU src, src, 0x20
201 207
202do_end_words: 208.Ldo_end_words:
203 beqz t8, small_csumcpy 209 beqz t8, .Lsmall_csumcpy
204 andi t2, a1, 0x3 210 andi t2, a1, 0x3
205 LONG_SRL t8, t8, 0x2 211 LONG_SRL t8, t8, 0x2
206 212
207end_words: 213.Lend_words:
208 lw t0, (src) 214 lw t0, (src)
209 LONG_SUBU t8, t8, 0x1 215 LONG_SUBU t8, t8, 0x1
210 ADDC(sum, t0) 216 ADDC(sum, t0)
211 bnez t8, end_words 217 .set reorder /* DADDI_WAR */
212 PTR_ADDU src, src, 0x4 218 PTR_ADDU src, src, 0x4
219 bnez t8, .Lend_words
220 .set noreorder
213 221
214/* unknown src alignment and < 8 bytes to go */ 222/* unknown src alignment and < 8 bytes to go */
215small_csumcpy: 223.Lsmall_csumcpy:
216 move a1, t2 224 move a1, t2
217 225
218 andi t0, a1, 4 226 andi t0, a1, 4
@@ -246,6 +254,8 @@ small_csumcpy:
2461: ADDC(sum, t1) 2541: ADDC(sum, t1)
247 255
248 /* fold checksum */ 256 /* fold checksum */
257 .set push
258 .set noat
249#ifdef USE_DOUBLE 259#ifdef USE_DOUBLE
250 dsll32 v1, sum, 0 260 dsll32 v1, sum, 0
251 daddu sum, v1 261 daddu sum, v1
@@ -266,6 +276,7 @@ small_csumcpy:
266 srl sum, sum, 8 276 srl sum, sum, 8
267 or sum, v1 277 or sum, v1
268 andi sum, 0xffff 278 andi sum, 0xffff
279 .set pop
2691: 2801:
270 .set reorder 281 .set reorder
271 /* Add the passed partial csum. */ 282 /* Add the passed partial csum. */
@@ -373,7 +384,11 @@ small_csumcpy:
373 384
374#define ADDRMASK (NBYTES-1) 385#define ADDRMASK (NBYTES-1)
375 386
387#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
376 .set noat 388 .set noat
389#else
390 .set at=v1
391#endif
377 392
378LEAF(__csum_partial_copy_user) 393LEAF(__csum_partial_copy_user)
379 PTR_ADDU AT, src, len /* See (1) above. */ 394 PTR_ADDU AT, src, len /* See (1) above. */
@@ -398,95 +413,101 @@ FEXPORT(csum_partial_copy_nocheck)
398 */ 413 */
399 sltu t2, len, NBYTES 414 sltu t2, len, NBYTES
400 and t1, dst, ADDRMASK 415 and t1, dst, ADDRMASK
401 bnez t2, copy_bytes_checklen 416 bnez t2, .Lcopy_bytes_checklen
402 and t0, src, ADDRMASK 417 and t0, src, ADDRMASK
403 andi odd, dst, 0x1 /* odd buffer? */ 418 andi odd, dst, 0x1 /* odd buffer? */
404 bnez t1, dst_unaligned 419 bnez t1, .Ldst_unaligned
405 nop 420 nop
406 bnez t0, src_unaligned_dst_aligned 421 bnez t0, .Lsrc_unaligned_dst_aligned
407 /* 422 /*
408 * use delay slot for fall-through 423 * use delay slot for fall-through
409 * src and dst are aligned; need to compute rem 424 * src and dst are aligned; need to compute rem
410 */ 425 */
411both_aligned: 426.Lboth_aligned:
412 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 427 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
413 beqz t0, cleanup_both_aligned # len < 8*NBYTES 428 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
414 nop 429 nop
415 SUB len, 8*NBYTES # subtract here for bgez loop 430 SUB len, 8*NBYTES # subtract here for bgez loop
416 .align 4 431 .align 4
4171: 4321:
418EXC( LOAD t0, UNIT(0)(src), l_exc) 433EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
419EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 434EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
420EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 435EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
421EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 436EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
422EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 437EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
423EXC( LOAD t5, UNIT(5)(src), l_exc_copy) 438EXC( LOAD t5, UNIT(5)(src), .Ll_exc_copy)
424EXC( LOAD t6, UNIT(6)(src), l_exc_copy) 439EXC( LOAD t6, UNIT(6)(src), .Ll_exc_copy)
425EXC( LOAD t7, UNIT(7)(src), l_exc_copy) 440EXC( LOAD t7, UNIT(7)(src), .Ll_exc_copy)
426 SUB len, len, 8*NBYTES 441 SUB len, len, 8*NBYTES
427 ADD src, src, 8*NBYTES 442 ADD src, src, 8*NBYTES
428EXC( STORE t0, UNIT(0)(dst), s_exc) 443EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
429 ADDC(sum, t0) 444 ADDC(sum, t0)
430EXC( STORE t1, UNIT(1)(dst), s_exc) 445EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
431 ADDC(sum, t1) 446 ADDC(sum, t1)
432EXC( STORE t2, UNIT(2)(dst), s_exc) 447EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
433 ADDC(sum, t2) 448 ADDC(sum, t2)
434EXC( STORE t3, UNIT(3)(dst), s_exc) 449EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
435 ADDC(sum, t3) 450 ADDC(sum, t3)
436EXC( STORE t4, UNIT(4)(dst), s_exc) 451EXC( STORE t4, UNIT(4)(dst), .Ls_exc)
437 ADDC(sum, t4) 452 ADDC(sum, t4)
438EXC( STORE t5, UNIT(5)(dst), s_exc) 453EXC( STORE t5, UNIT(5)(dst), .Ls_exc)
439 ADDC(sum, t5) 454 ADDC(sum, t5)
440EXC( STORE t6, UNIT(6)(dst), s_exc) 455EXC( STORE t6, UNIT(6)(dst), .Ls_exc)
441 ADDC(sum, t6) 456 ADDC(sum, t6)
442EXC( STORE t7, UNIT(7)(dst), s_exc) 457EXC( STORE t7, UNIT(7)(dst), .Ls_exc)
443 ADDC(sum, t7) 458 ADDC(sum, t7)
459 .set reorder /* DADDI_WAR */
460 ADD dst, dst, 8*NBYTES
444 bgez len, 1b 461 bgez len, 1b
445 ADD dst, dst, 8*NBYTES 462 .set noreorder
446 ADD len, 8*NBYTES # revert len (see above) 463 ADD len, 8*NBYTES # revert len (see above)
447 464
448 /* 465 /*
449 * len == the number of bytes left to copy < 8*NBYTES 466 * len == the number of bytes left to copy < 8*NBYTES
450 */ 467 */
451cleanup_both_aligned: 468.Lcleanup_both_aligned:
452#define rem t7 469#define rem t7
453 beqz len, done 470 beqz len, .Ldone
454 sltu t0, len, 4*NBYTES 471 sltu t0, len, 4*NBYTES
455 bnez t0, less_than_4units 472 bnez t0, .Lless_than_4units
456 and rem, len, (NBYTES-1) # rem = len % NBYTES 473 and rem, len, (NBYTES-1) # rem = len % NBYTES
457 /* 474 /*
458 * len >= 4*NBYTES 475 * len >= 4*NBYTES
459 */ 476 */
460EXC( LOAD t0, UNIT(0)(src), l_exc) 477EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
461EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 478EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
462EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 479EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
463EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 480EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
464 SUB len, len, 4*NBYTES 481 SUB len, len, 4*NBYTES
465 ADD src, src, 4*NBYTES 482 ADD src, src, 4*NBYTES
466EXC( STORE t0, UNIT(0)(dst), s_exc) 483EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
467 ADDC(sum, t0) 484 ADDC(sum, t0)
468EXC( STORE t1, UNIT(1)(dst), s_exc) 485EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
469 ADDC(sum, t1) 486 ADDC(sum, t1)
470EXC( STORE t2, UNIT(2)(dst), s_exc) 487EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
471 ADDC(sum, t2) 488 ADDC(sum, t2)
472EXC( STORE t3, UNIT(3)(dst), s_exc) 489EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
473 ADDC(sum, t3) 490 ADDC(sum, t3)
474 beqz len, done 491 .set reorder /* DADDI_WAR */
475 ADD dst, dst, 4*NBYTES 492 ADD dst, dst, 4*NBYTES
476less_than_4units: 493 beqz len, .Ldone
494 .set noreorder
495.Lless_than_4units:
477 /* 496 /*
478 * rem = len % NBYTES 497 * rem = len % NBYTES
479 */ 498 */
480 beq rem, len, copy_bytes 499 beq rem, len, .Lcopy_bytes
481 nop 500 nop
4821: 5011:
483EXC( LOAD t0, 0(src), l_exc) 502EXC( LOAD t0, 0(src), .Ll_exc)
484 ADD src, src, NBYTES 503 ADD src, src, NBYTES
485 SUB len, len, NBYTES 504 SUB len, len, NBYTES
486EXC( STORE t0, 0(dst), s_exc) 505EXC( STORE t0, 0(dst), .Ls_exc)
487 ADDC(sum, t0) 506 ADDC(sum, t0)
507 .set reorder /* DADDI_WAR */
508 ADD dst, dst, NBYTES
488 bne rem, len, 1b 509 bne rem, len, 1b
489 ADD dst, dst, NBYTES 510 .set noreorder
490 511
491 /* 512 /*
492 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 513 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -500,20 +521,20 @@ EXC( STORE t0, 0(dst), s_exc)
500 * more instruction-level parallelism. 521 * more instruction-level parallelism.
501 */ 522 */
502#define bits t2 523#define bits t2
503 beqz len, done 524 beqz len, .Ldone
504 ADD t1, dst, len # t1 is just past last byte of dst 525 ADD t1, dst, len # t1 is just past last byte of dst
505 li bits, 8*NBYTES 526 li bits, 8*NBYTES
506 SLL rem, len, 3 # rem = number of bits to keep 527 SLL rem, len, 3 # rem = number of bits to keep
507EXC( LOAD t0, 0(src), l_exc) 528EXC( LOAD t0, 0(src), .Ll_exc)
508 SUB bits, bits, rem # bits = number of bits to discard 529 SUB bits, bits, rem # bits = number of bits to discard
509 SHIFT_DISCARD t0, t0, bits 530 SHIFT_DISCARD t0, t0, bits
510EXC( STREST t0, -1(t1), s_exc) 531EXC( STREST t0, -1(t1), .Ls_exc)
511 SHIFT_DISCARD_REVERT t0, t0, bits 532 SHIFT_DISCARD_REVERT t0, t0, bits
512 .set reorder 533 .set reorder
513 ADDC(sum, t0) 534 ADDC(sum, t0)
514 b done 535 b .Ldone
515 .set noreorder 536 .set noreorder
516dst_unaligned: 537.Ldst_unaligned:
517 /* 538 /*
518 * dst is unaligned 539 * dst is unaligned
519 * t0 = src & ADDRMASK 540 * t0 = src & ADDRMASK
@@ -524,25 +545,25 @@ dst_unaligned:
524 * Set match = (src and dst have same alignment) 545 * Set match = (src and dst have same alignment)
525 */ 546 */
526#define match rem 547#define match rem
527EXC( LDFIRST t3, FIRST(0)(src), l_exc) 548EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
528 ADD t2, zero, NBYTES 549 ADD t2, zero, NBYTES
529EXC( LDREST t3, REST(0)(src), l_exc_copy) 550EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
530 SUB t2, t2, t1 # t2 = number of bytes copied 551 SUB t2, t2, t1 # t2 = number of bytes copied
531 xor match, t0, t1 552 xor match, t0, t1
532EXC( STFIRST t3, FIRST(0)(dst), s_exc) 553EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
533 SLL t4, t1, 3 # t4 = number of bits to discard 554 SLL t4, t1, 3 # t4 = number of bits to discard
534 SHIFT_DISCARD t3, t3, t4 555 SHIFT_DISCARD t3, t3, t4
535 /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */ 556 /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */
536 ADDC(sum, t3) 557 ADDC(sum, t3)
537 beq len, t2, done 558 beq len, t2, .Ldone
538 SUB len, len, t2 559 SUB len, len, t2
539 ADD dst, dst, t2 560 ADD dst, dst, t2
540 beqz match, both_aligned 561 beqz match, .Lboth_aligned
541 ADD src, src, t2 562 ADD src, src, t2
542 563
543src_unaligned_dst_aligned: 564.Lsrc_unaligned_dst_aligned:
544 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 565 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
545 beqz t0, cleanup_src_unaligned 566 beqz t0, .Lcleanup_src_unaligned
546 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 567 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
5471: 5681:
548/* 569/*
@@ -551,49 +572,53 @@ src_unaligned_dst_aligned:
551 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 572 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
552 * are to the same unit (unless src is aligned, but it's not). 573 * are to the same unit (unless src is aligned, but it's not).
553 */ 574 */
554EXC( LDFIRST t0, FIRST(0)(src), l_exc) 575EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
555EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 576EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
556 SUB len, len, 4*NBYTES 577 SUB len, len, 4*NBYTES
557EXC( LDREST t0, REST(0)(src), l_exc_copy) 578EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
558EXC( LDREST t1, REST(1)(src), l_exc_copy) 579EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
559EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 580EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
560EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 581EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
561EXC( LDREST t2, REST(2)(src), l_exc_copy) 582EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
562EXC( LDREST t3, REST(3)(src), l_exc_copy) 583EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
563 ADD src, src, 4*NBYTES 584 ADD src, src, 4*NBYTES
564#ifdef CONFIG_CPU_SB1 585#ifdef CONFIG_CPU_SB1
565 nop # improves slotting 586 nop # improves slotting
566#endif 587#endif
567EXC( STORE t0, UNIT(0)(dst), s_exc) 588EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
568 ADDC(sum, t0) 589 ADDC(sum, t0)
569EXC( STORE t1, UNIT(1)(dst), s_exc) 590EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
570 ADDC(sum, t1) 591 ADDC(sum, t1)
571EXC( STORE t2, UNIT(2)(dst), s_exc) 592EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
572 ADDC(sum, t2) 593 ADDC(sum, t2)
573EXC( STORE t3, UNIT(3)(dst), s_exc) 594EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
574 ADDC(sum, t3) 595 ADDC(sum, t3)
596 .set reorder /* DADDI_WAR */
597 ADD dst, dst, 4*NBYTES
575 bne len, rem, 1b 598 bne len, rem, 1b
576 ADD dst, dst, 4*NBYTES 599 .set noreorder
577 600
578cleanup_src_unaligned: 601.Lcleanup_src_unaligned:
579 beqz len, done 602 beqz len, .Ldone
580 and rem, len, NBYTES-1 # rem = len % NBYTES 603 and rem, len, NBYTES-1 # rem = len % NBYTES
581 beq rem, len, copy_bytes 604 beq rem, len, .Lcopy_bytes
582 nop 605 nop
5831: 6061:
584EXC( LDFIRST t0, FIRST(0)(src), l_exc) 607EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
585EXC( LDREST t0, REST(0)(src), l_exc_copy) 608EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
586 ADD src, src, NBYTES 609 ADD src, src, NBYTES
587 SUB len, len, NBYTES 610 SUB len, len, NBYTES
588EXC( STORE t0, 0(dst), s_exc) 611EXC( STORE t0, 0(dst), .Ls_exc)
589 ADDC(sum, t0) 612 ADDC(sum, t0)
613 .set reorder /* DADDI_WAR */
614 ADD dst, dst, NBYTES
590 bne len, rem, 1b 615 bne len, rem, 1b
591 ADD dst, dst, NBYTES 616 .set noreorder
592 617
593copy_bytes_checklen: 618.Lcopy_bytes_checklen:
594 beqz len, done 619 beqz len, .Ldone
595 nop 620 nop
596copy_bytes: 621.Lcopy_bytes:
597 /* 0 < len < NBYTES */ 622 /* 0 < len < NBYTES */
598#ifdef CONFIG_CPU_LITTLE_ENDIAN 623#ifdef CONFIG_CPU_LITTLE_ENDIAN
599#define SHIFT_START 0 624#define SHIFT_START 0
@@ -604,14 +629,14 @@ copy_bytes:
604#endif 629#endif
605 move t2, zero # partial word 630 move t2, zero # partial word
606 li t3, SHIFT_START # shift 631 li t3, SHIFT_START # shift
607/* use l_exc_copy here to return correct sum on fault */ 632/* use .Ll_exc_copy here to return correct sum on fault */
608#define COPY_BYTE(N) \ 633#define COPY_BYTE(N) \
609EXC( lbu t0, N(src), l_exc_copy); \ 634EXC( lbu t0, N(src), .Ll_exc_copy); \
610 SUB len, len, 1; \ 635 SUB len, len, 1; \
611EXC( sb t0, N(dst), s_exc); \ 636EXC( sb t0, N(dst), .Ls_exc); \
612 SLLV t0, t0, t3; \ 637 SLLV t0, t0, t3; \
613 addu t3, SHIFT_INC; \ 638 addu t3, SHIFT_INC; \
614 beqz len, copy_bytes_done; \ 639 beqz len, .Lcopy_bytes_done; \
615 or t2, t0 640 or t2, t0
616 641
617 COPY_BYTE(0) 642 COPY_BYTE(0)
@@ -622,15 +647,17 @@ EXC( sb t0, N(dst), s_exc); \
622 COPY_BYTE(4) 647 COPY_BYTE(4)
623 COPY_BYTE(5) 648 COPY_BYTE(5)
624#endif 649#endif
625EXC( lbu t0, NBYTES-2(src), l_exc_copy) 650EXC( lbu t0, NBYTES-2(src), .Ll_exc_copy)
626 SUB len, len, 1 651 SUB len, len, 1
627EXC( sb t0, NBYTES-2(dst), s_exc) 652EXC( sb t0, NBYTES-2(dst), .Ls_exc)
628 SLLV t0, t0, t3 653 SLLV t0, t0, t3
629 or t2, t0 654 or t2, t0
630copy_bytes_done: 655.Lcopy_bytes_done:
631 ADDC(sum, t2) 656 ADDC(sum, t2)
632done: 657.Ldone:
633 /* fold checksum */ 658 /* fold checksum */
659 .set push
660 .set noat
634#ifdef USE_DOUBLE 661#ifdef USE_DOUBLE
635 dsll32 v1, sum, 0 662 dsll32 v1, sum, 0
636 daddu sum, v1 663 daddu sum, v1
@@ -651,13 +678,14 @@ done:
651 srl sum, sum, 8 678 srl sum, sum, 8
652 or sum, v1 679 or sum, v1
653 andi sum, 0xffff 680 andi sum, 0xffff
681 .set pop
6541: 6821:
655 .set reorder 683 .set reorder
656 ADDC(sum, psum) 684 ADDC(sum, psum)
657 jr ra 685 jr ra
658 .set noreorder 686 .set noreorder
659 687
660l_exc_copy: 688.Ll_exc_copy:
661 /* 689 /*
662 * Copy bytes from src until faulting load address (or until a 690 * Copy bytes from src until faulting load address (or until a
663 * lb faults) 691 * lb faults)
@@ -672,15 +700,17 @@ l_exc_copy:
672 li t2, SHIFT_START 700 li t2, SHIFT_START
673 LOAD t0, THREAD_BUADDR(t0) 701 LOAD t0, THREAD_BUADDR(t0)
6741: 7021:
675EXC( lbu t1, 0(src), l_exc) 703EXC( lbu t1, 0(src), .Ll_exc)
676 ADD src, src, 1 704 ADD src, src, 1
677 sb t1, 0(dst) # can't fault -- we're copy_from_user 705 sb t1, 0(dst) # can't fault -- we're copy_from_user
678 SLLV t1, t1, t2 706 SLLV t1, t1, t2
679 addu t2, SHIFT_INC 707 addu t2, SHIFT_INC
680 ADDC(sum, t1) 708 ADDC(sum, t1)
709 .set reorder /* DADDI_WAR */
710 ADD dst, dst, 1
681 bne src, t0, 1b 711 bne src, t0, 1b
682 ADD dst, dst, 1 712 .set noreorder
683l_exc: 713.Ll_exc:
684 LOAD t0, TI_TASK($28) 714 LOAD t0, TI_TASK($28)
685 nop 715 nop
686 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 716 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -697,19 +727,30 @@ l_exc:
697 * Clear len bytes starting at dst. Can't call __bzero because it 727 * Clear len bytes starting at dst. Can't call __bzero because it
698 * might modify len. An inefficient loop for these rare times... 728 * might modify len. An inefficient loop for these rare times...
699 */ 729 */
700 beqz len, done 730 .set reorder /* DADDI_WAR */
701 SUB src, len, 1 731 SUB src, len, 1
732 beqz len, .Ldone
733 .set noreorder
7021: sb zero, 0(dst) 7341: sb zero, 0(dst)
703 ADD dst, dst, 1 735 ADD dst, dst, 1
736 .set push
737 .set noat
738#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
704 bnez src, 1b 739 bnez src, 1b
705 SUB src, src, 1 740 SUB src, src, 1
741#else
742 li v1, 1
743 bnez src, 1b
744 SUB src, src, v1
745#endif
706 li v1, -EFAULT 746 li v1, -EFAULT
707 b done 747 b .Ldone
708 sw v1, (errptr) 748 sw v1, (errptr)
709 749
710s_exc: 750.Ls_exc:
711 li v0, -1 /* invalid checksum */ 751 li v0, -1 /* invalid checksum */
712 li v1, -EFAULT 752 li v1, -EFAULT
713 jr ra 753 jr ra
714 sw v1, (errptr) 754 sw v1, (errptr)
755 .set pop
715 END(__csum_partial_copy_user) 756 END(__csum_partial_copy_user)
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
index 3a534b2baa0f..736d0fb56a94 100644
--- a/arch/mips/lib/memcpy-inatomic.S
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -9,6 +9,7 @@
9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. 9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
10 * Copyright (C) 2002 Broadcom, Inc. 10 * Copyright (C) 2002 Broadcom, Inc.
11 * memcpy/copy_user author: Mark Vandevoorde 11 * memcpy/copy_user author: Mark Vandevoorde
12 * Copyright (C) 2007 Maciej W. Rozycki
12 * 13 *
13 * Mnemonic names for arguments to memcpy/__copy_user 14 * Mnemonic names for arguments to memcpy/__copy_user
14 */ 15 */
@@ -175,7 +176,11 @@
175 176
176 .text 177 .text
177 .set noreorder 178 .set noreorder
179#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
178 .set noat 180 .set noat
181#else
182 .set at=v1
183#endif
179 184
180/* 185/*
181 * A combined memcpy/__copy_user 186 * A combined memcpy/__copy_user
@@ -204,36 +209,36 @@ LEAF(__copy_user_inatomic)
204 and t1, dst, ADDRMASK 209 and t1, dst, ADDRMASK
205 PREF( 0, 1*32(src) ) 210 PREF( 0, 1*32(src) )
206 PREF( 1, 1*32(dst) ) 211 PREF( 1, 1*32(dst) )
207 bnez t2, copy_bytes_checklen 212 bnez t2, .Lcopy_bytes_checklen
208 and t0, src, ADDRMASK 213 and t0, src, ADDRMASK
209 PREF( 0, 2*32(src) ) 214 PREF( 0, 2*32(src) )
210 PREF( 1, 2*32(dst) ) 215 PREF( 1, 2*32(dst) )
211 bnez t1, dst_unaligned 216 bnez t1, .Ldst_unaligned
212 nop 217 nop
213 bnez t0, src_unaligned_dst_aligned 218 bnez t0, .Lsrc_unaligned_dst_aligned
214 /* 219 /*
215 * use delay slot for fall-through 220 * use delay slot for fall-through
216 * src and dst are aligned; need to compute rem 221 * src and dst are aligned; need to compute rem
217 */ 222 */
218both_aligned: 223.Lboth_aligned:
219 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 224 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
220 beqz t0, cleanup_both_aligned # len < 8*NBYTES 225 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
221 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) 226 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
222 PREF( 0, 3*32(src) ) 227 PREF( 0, 3*32(src) )
223 PREF( 1, 3*32(dst) ) 228 PREF( 1, 3*32(dst) )
224 .align 4 229 .align 4
2251: 2301:
226EXC( LOAD t0, UNIT(0)(src), l_exc) 231EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
227EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 232EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
228EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 233EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
229EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 234EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
230 SUB len, len, 8*NBYTES 235 SUB len, len, 8*NBYTES
231EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 236EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
232EXC( LOAD t7, UNIT(5)(src), l_exc_copy) 237EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
233 STORE t0, UNIT(0)(dst) 238 STORE t0, UNIT(0)(dst)
234 STORE t1, UNIT(1)(dst) 239 STORE t1, UNIT(1)(dst)
235EXC( LOAD t0, UNIT(6)(src), l_exc_copy) 240EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
236EXC( LOAD t1, UNIT(7)(src), l_exc_copy) 241EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
237 ADD src, src, 8*NBYTES 242 ADD src, src, 8*NBYTES
238 ADD dst, dst, 8*NBYTES 243 ADD dst, dst, 8*NBYTES
239 STORE t2, UNIT(-6)(dst) 244 STORE t2, UNIT(-6)(dst)
@@ -250,39 +255,43 @@ EXC( LOAD t1, UNIT(7)(src), l_exc_copy)
250 /* 255 /*
251 * len == rem == the number of bytes left to copy < 8*NBYTES 256 * len == rem == the number of bytes left to copy < 8*NBYTES
252 */ 257 */
253cleanup_both_aligned: 258.Lcleanup_both_aligned:
254 beqz len, done 259 beqz len, .Ldone
255 sltu t0, len, 4*NBYTES 260 sltu t0, len, 4*NBYTES
256 bnez t0, less_than_4units 261 bnez t0, .Lless_than_4units
257 and rem, len, (NBYTES-1) # rem = len % NBYTES 262 and rem, len, (NBYTES-1) # rem = len % NBYTES
258 /* 263 /*
259 * len >= 4*NBYTES 264 * len >= 4*NBYTES
260 */ 265 */
261EXC( LOAD t0, UNIT(0)(src), l_exc) 266EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
262EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 267EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
263EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 268EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
264EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 269EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
265 SUB len, len, 4*NBYTES 270 SUB len, len, 4*NBYTES
266 ADD src, src, 4*NBYTES 271 ADD src, src, 4*NBYTES
267 STORE t0, UNIT(0)(dst) 272 STORE t0, UNIT(0)(dst)
268 STORE t1, UNIT(1)(dst) 273 STORE t1, UNIT(1)(dst)
269 STORE t2, UNIT(2)(dst) 274 STORE t2, UNIT(2)(dst)
270 STORE t3, UNIT(3)(dst) 275 STORE t3, UNIT(3)(dst)
271 beqz len, done 276 .set reorder /* DADDI_WAR */
272 ADD dst, dst, 4*NBYTES 277 ADD dst, dst, 4*NBYTES
273less_than_4units: 278 beqz len, .Ldone
279 .set noreorder
280.Lless_than_4units:
274 /* 281 /*
275 * rem = len % NBYTES 282 * rem = len % NBYTES
276 */ 283 */
277 beq rem, len, copy_bytes 284 beq rem, len, .Lcopy_bytes
278 nop 285 nop
2791: 2861:
280EXC( LOAD t0, 0(src), l_exc) 287EXC( LOAD t0, 0(src), .Ll_exc)
281 ADD src, src, NBYTES 288 ADD src, src, NBYTES
282 SUB len, len, NBYTES 289 SUB len, len, NBYTES
283 STORE t0, 0(dst) 290 STORE t0, 0(dst)
291 .set reorder /* DADDI_WAR */
292 ADD dst, dst, NBYTES
284 bne rem, len, 1b 293 bne rem, len, 1b
285 ADD dst, dst, NBYTES 294 .set noreorder
286 295
287 /* 296 /*
288 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 297 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -296,17 +305,17 @@ EXC( LOAD t0, 0(src), l_exc)
296 * more instruction-level parallelism. 305 * more instruction-level parallelism.
297 */ 306 */
298#define bits t2 307#define bits t2
299 beqz len, done 308 beqz len, .Ldone
300 ADD t1, dst, len # t1 is just past last byte of dst 309 ADD t1, dst, len # t1 is just past last byte of dst
301 li bits, 8*NBYTES 310 li bits, 8*NBYTES
302 SLL rem, len, 3 # rem = number of bits to keep 311 SLL rem, len, 3 # rem = number of bits to keep
303EXC( LOAD t0, 0(src), l_exc) 312EXC( LOAD t0, 0(src), .Ll_exc)
304 SUB bits, bits, rem # bits = number of bits to discard 313 SUB bits, bits, rem # bits = number of bits to discard
305 SHIFT_DISCARD t0, t0, bits 314 SHIFT_DISCARD t0, t0, bits
306 STREST t0, -1(t1) 315 STREST t0, -1(t1)
307 jr ra 316 jr ra
308 move len, zero 317 move len, zero
309dst_unaligned: 318.Ldst_unaligned:
310 /* 319 /*
311 * dst is unaligned 320 * dst is unaligned
312 * t0 = src & ADDRMASK 321 * t0 = src & ADDRMASK
@@ -317,22 +326,22 @@ dst_unaligned:
317 * Set match = (src and dst have same alignment) 326 * Set match = (src and dst have same alignment)
318 */ 327 */
319#define match rem 328#define match rem
320EXC( LDFIRST t3, FIRST(0)(src), l_exc) 329EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
321 ADD t2, zero, NBYTES 330 ADD t2, zero, NBYTES
322EXC( LDREST t3, REST(0)(src), l_exc_copy) 331EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
323 SUB t2, t2, t1 # t2 = number of bytes copied 332 SUB t2, t2, t1 # t2 = number of bytes copied
324 xor match, t0, t1 333 xor match, t0, t1
325 STFIRST t3, FIRST(0)(dst) 334 STFIRST t3, FIRST(0)(dst)
326 beq len, t2, done 335 beq len, t2, .Ldone
327 SUB len, len, t2 336 SUB len, len, t2
328 ADD dst, dst, t2 337 ADD dst, dst, t2
329 beqz match, both_aligned 338 beqz match, .Lboth_aligned
330 ADD src, src, t2 339 ADD src, src, t2
331 340
332src_unaligned_dst_aligned: 341.Lsrc_unaligned_dst_aligned:
333 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 342 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
334 PREF( 0, 3*32(src) ) 343 PREF( 0, 3*32(src) )
335 beqz t0, cleanup_src_unaligned 344 beqz t0, .Lcleanup_src_unaligned
336 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 345 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
337 PREF( 1, 3*32(dst) ) 346 PREF( 1, 3*32(dst) )
3381: 3471:
@@ -342,15 +351,15 @@ src_unaligned_dst_aligned:
342 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 351 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
343 * are to the same unit (unless src is aligned, but it's not). 352 * are to the same unit (unless src is aligned, but it's not).
344 */ 353 */
345EXC( LDFIRST t0, FIRST(0)(src), l_exc) 354EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
346EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 355EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
347 SUB len, len, 4*NBYTES 356 SUB len, len, 4*NBYTES
348EXC( LDREST t0, REST(0)(src), l_exc_copy) 357EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
349EXC( LDREST t1, REST(1)(src), l_exc_copy) 358EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
350EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 359EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
351EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 360EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
352EXC( LDREST t2, REST(2)(src), l_exc_copy) 361EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
353EXC( LDREST t3, REST(3)(src), l_exc_copy) 362EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
354 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) 363 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
355 ADD src, src, 4*NBYTES 364 ADD src, src, 4*NBYTES
356#ifdef CONFIG_CPU_SB1 365#ifdef CONFIG_CPU_SB1
@@ -361,32 +370,36 @@ EXC( LDREST t3, REST(3)(src), l_exc_copy)
361 STORE t2, UNIT(2)(dst) 370 STORE t2, UNIT(2)(dst)
362 STORE t3, UNIT(3)(dst) 371 STORE t3, UNIT(3)(dst)
363 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) 372 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
373 .set reorder /* DADDI_WAR */
374 ADD dst, dst, 4*NBYTES
364 bne len, rem, 1b 375 bne len, rem, 1b
365 ADD dst, dst, 4*NBYTES 376 .set noreorder
366 377
367cleanup_src_unaligned: 378.Lcleanup_src_unaligned:
368 beqz len, done 379 beqz len, .Ldone
369 and rem, len, NBYTES-1 # rem = len % NBYTES 380 and rem, len, NBYTES-1 # rem = len % NBYTES
370 beq rem, len, copy_bytes 381 beq rem, len, .Lcopy_bytes
371 nop 382 nop
3721: 3831:
373EXC( LDFIRST t0, FIRST(0)(src), l_exc) 384EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
374EXC( LDREST t0, REST(0)(src), l_exc_copy) 385EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
375 ADD src, src, NBYTES 386 ADD src, src, NBYTES
376 SUB len, len, NBYTES 387 SUB len, len, NBYTES
377 STORE t0, 0(dst) 388 STORE t0, 0(dst)
389 .set reorder /* DADDI_WAR */
390 ADD dst, dst, NBYTES
378 bne len, rem, 1b 391 bne len, rem, 1b
379 ADD dst, dst, NBYTES 392 .set noreorder
380 393
381copy_bytes_checklen: 394.Lcopy_bytes_checklen:
382 beqz len, done 395 beqz len, .Ldone
383 nop 396 nop
384copy_bytes: 397.Lcopy_bytes:
385 /* 0 < len < NBYTES */ 398 /* 0 < len < NBYTES */
386#define COPY_BYTE(N) \ 399#define COPY_BYTE(N) \
387EXC( lb t0, N(src), l_exc); \ 400EXC( lb t0, N(src), .Ll_exc); \
388 SUB len, len, 1; \ 401 SUB len, len, 1; \
389 beqz len, done; \ 402 beqz len, .Ldone; \
390 sb t0, N(dst) 403 sb t0, N(dst)
391 404
392 COPY_BYTE(0) 405 COPY_BYTE(0)
@@ -397,16 +410,16 @@ EXC( lb t0, N(src), l_exc); \
397 COPY_BYTE(4) 410 COPY_BYTE(4)
398 COPY_BYTE(5) 411 COPY_BYTE(5)
399#endif 412#endif
400EXC( lb t0, NBYTES-2(src), l_exc) 413EXC( lb t0, NBYTES-2(src), .Ll_exc)
401 SUB len, len, 1 414 SUB len, len, 1
402 jr ra 415 jr ra
403 sb t0, NBYTES-2(dst) 416 sb t0, NBYTES-2(dst)
404done: 417.Ldone:
405 jr ra 418 jr ra
406 nop 419 nop
407 END(__copy_user_inatomic) 420 END(__copy_user_inatomic)
408 421
409l_exc_copy: 422.Ll_exc_copy:
410 /* 423 /*
411 * Copy bytes from src until faulting load address (or until a 424 * Copy bytes from src until faulting load address (or until a
412 * lb faults) 425 * lb faults)
@@ -421,12 +434,14 @@ l_exc_copy:
421 nop 434 nop
422 LOAD t0, THREAD_BUADDR(t0) 435 LOAD t0, THREAD_BUADDR(t0)
4231: 4361:
424EXC( lb t1, 0(src), l_exc) 437EXC( lb t1, 0(src), .Ll_exc)
425 ADD src, src, 1 438 ADD src, src, 1
426 sb t1, 0(dst) # can't fault -- we're copy_from_user 439 sb t1, 0(dst) # can't fault -- we're copy_from_user
440 .set reorder /* DADDI_WAR */
441 ADD dst, dst, 1
427 bne src, t0, 1b 442 bne src, t0, 1b
428 ADD dst, dst, 1 443 .set noreorder
429l_exc: 444.Ll_exc:
430 LOAD t0, TI_TASK($28) 445 LOAD t0, TI_TASK($28)
431 nop 446 nop
432 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 447 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a526c62cb76a..c06cccf60bec 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -9,6 +9,7 @@
9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. 9 * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
10 * Copyright (C) 2002 Broadcom, Inc. 10 * Copyright (C) 2002 Broadcom, Inc.
11 * memcpy/copy_user author: Mark Vandevoorde 11 * memcpy/copy_user author: Mark Vandevoorde
12 * Copyright (C) 2007 Maciej W. Rozycki
12 * 13 *
13 * Mnemonic names for arguments to memcpy/__copy_user 14 * Mnemonic names for arguments to memcpy/__copy_user
14 */ 15 */
@@ -175,7 +176,11 @@
175 176
176 .text 177 .text
177 .set noreorder 178 .set noreorder
179#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
178 .set noat 180 .set noat
181#else
182 .set at=v1
183#endif
179 184
180/* 185/*
181 * A combined memcpy/__copy_user 186 * A combined memcpy/__copy_user
@@ -186,7 +191,7 @@
186 .align 5 191 .align 5
187LEAF(memcpy) /* a0=dst a1=src a2=len */ 192LEAF(memcpy) /* a0=dst a1=src a2=len */
188 move v0, dst /* return value */ 193 move v0, dst /* return value */
189__memcpy: 194.L__memcpy:
190FEXPORT(__copy_user) 195FEXPORT(__copy_user)
191 /* 196 /*
192 * Note: dst & src may be unaligned, len may be 0 197 * Note: dst & src may be unaligned, len may be 0
@@ -194,6 +199,7 @@ FEXPORT(__copy_user)
194 */ 199 */
195#define rem t8 200#define rem t8
196 201
202 R10KCBARRIER(0(ra))
197 /* 203 /*
198 * The "issue break"s below are very approximate. 204 * The "issue break"s below are very approximate.
199 * Issue delays for dcache fills will perturb the schedule, as will 205 * Issue delays for dcache fills will perturb the schedule, as will
@@ -207,44 +213,45 @@ FEXPORT(__copy_user)
207 and t1, dst, ADDRMASK 213 and t1, dst, ADDRMASK
208 PREF( 0, 1*32(src) ) 214 PREF( 0, 1*32(src) )
209 PREF( 1, 1*32(dst) ) 215 PREF( 1, 1*32(dst) )
210 bnez t2, copy_bytes_checklen 216 bnez t2, .Lcopy_bytes_checklen
211 and t0, src, ADDRMASK 217 and t0, src, ADDRMASK
212 PREF( 0, 2*32(src) ) 218 PREF( 0, 2*32(src) )
213 PREF( 1, 2*32(dst) ) 219 PREF( 1, 2*32(dst) )
214 bnez t1, dst_unaligned 220 bnez t1, .Ldst_unaligned
215 nop 221 nop
216 bnez t0, src_unaligned_dst_aligned 222 bnez t0, .Lsrc_unaligned_dst_aligned
217 /* 223 /*
218 * use delay slot for fall-through 224 * use delay slot for fall-through
219 * src and dst are aligned; need to compute rem 225 * src and dst are aligned; need to compute rem
220 */ 226 */
221both_aligned: 227.Lboth_aligned:
222 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter 228 SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
223 beqz t0, cleanup_both_aligned # len < 8*NBYTES 229 beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
224 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) 230 and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
225 PREF( 0, 3*32(src) ) 231 PREF( 0, 3*32(src) )
226 PREF( 1, 3*32(dst) ) 232 PREF( 1, 3*32(dst) )
227 .align 4 233 .align 4
2281: 2341:
229EXC( LOAD t0, UNIT(0)(src), l_exc) 235 R10KCBARRIER(0(ra))
230EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 236EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
231EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 237EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
232EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 238EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
239EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
233 SUB len, len, 8*NBYTES 240 SUB len, len, 8*NBYTES
234EXC( LOAD t4, UNIT(4)(src), l_exc_copy) 241EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
235EXC( LOAD t7, UNIT(5)(src), l_exc_copy) 242EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
236EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) 243EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p8u)
237EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) 244EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p7u)
238EXC( LOAD t0, UNIT(6)(src), l_exc_copy) 245EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
239EXC( LOAD t1, UNIT(7)(src), l_exc_copy) 246EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
240 ADD src, src, 8*NBYTES 247 ADD src, src, 8*NBYTES
241 ADD dst, dst, 8*NBYTES 248 ADD dst, dst, 8*NBYTES
242EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) 249EXC( STORE t2, UNIT(-6)(dst), .Ls_exc_p6u)
243EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) 250EXC( STORE t3, UNIT(-5)(dst), .Ls_exc_p5u)
244EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) 251EXC( STORE t4, UNIT(-4)(dst), .Ls_exc_p4u)
245EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) 252EXC( STORE t7, UNIT(-3)(dst), .Ls_exc_p3u)
246EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) 253EXC( STORE t0, UNIT(-2)(dst), .Ls_exc_p2u)
247EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) 254EXC( STORE t1, UNIT(-1)(dst), .Ls_exc_p1u)
248 PREF( 0, 8*32(src) ) 255 PREF( 0, 8*32(src) )
249 PREF( 1, 8*32(dst) ) 256 PREF( 1, 8*32(dst) )
250 bne len, rem, 1b 257 bne len, rem, 1b
@@ -253,39 +260,45 @@ EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u)
253 /* 260 /*
254 * len == rem == the number of bytes left to copy < 8*NBYTES 261 * len == rem == the number of bytes left to copy < 8*NBYTES
255 */ 262 */
256cleanup_both_aligned: 263.Lcleanup_both_aligned:
257 beqz len, done 264 beqz len, .Ldone
258 sltu t0, len, 4*NBYTES 265 sltu t0, len, 4*NBYTES
259 bnez t0, less_than_4units 266 bnez t0, .Lless_than_4units
260 and rem, len, (NBYTES-1) # rem = len % NBYTES 267 and rem, len, (NBYTES-1) # rem = len % NBYTES
261 /* 268 /*
262 * len >= 4*NBYTES 269 * len >= 4*NBYTES
263 */ 270 */
264EXC( LOAD t0, UNIT(0)(src), l_exc) 271EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
265EXC( LOAD t1, UNIT(1)(src), l_exc_copy) 272EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
266EXC( LOAD t2, UNIT(2)(src), l_exc_copy) 273EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
267EXC( LOAD t3, UNIT(3)(src), l_exc_copy) 274EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
268 SUB len, len, 4*NBYTES 275 SUB len, len, 4*NBYTES
269 ADD src, src, 4*NBYTES 276 ADD src, src, 4*NBYTES
270EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) 277 R10KCBARRIER(0(ra))
271EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) 278EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
272EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) 279EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
273EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) 280EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
274 beqz len, done 281EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
275 ADD dst, dst, 4*NBYTES 282 .set reorder /* DADDI_WAR */
276less_than_4units: 283 ADD dst, dst, 4*NBYTES
284 beqz len, .Ldone
285 .set noreorder
286.Lless_than_4units:
277 /* 287 /*
278 * rem = len % NBYTES 288 * rem = len % NBYTES
279 */ 289 */
280 beq rem, len, copy_bytes 290 beq rem, len, .Lcopy_bytes
281 nop 291 nop
2821: 2921:
283EXC( LOAD t0, 0(src), l_exc) 293 R10KCBARRIER(0(ra))
294EXC( LOAD t0, 0(src), .Ll_exc)
284 ADD src, src, NBYTES 295 ADD src, src, NBYTES
285 SUB len, len, NBYTES 296 SUB len, len, NBYTES
286EXC( STORE t0, 0(dst), s_exc_p1u) 297EXC( STORE t0, 0(dst), .Ls_exc_p1u)
298 .set reorder /* DADDI_WAR */
299 ADD dst, dst, NBYTES
287 bne rem, len, 1b 300 bne rem, len, 1b
288 ADD dst, dst, NBYTES 301 .set noreorder
289 302
290 /* 303 /*
291 * src and dst are aligned, need to copy rem bytes (rem < NBYTES) 304 * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
@@ -299,17 +312,17 @@ EXC( STORE t0, 0(dst), s_exc_p1u)
299 * more instruction-level parallelism. 312 * more instruction-level parallelism.
300 */ 313 */
301#define bits t2 314#define bits t2
302 beqz len, done 315 beqz len, .Ldone
303 ADD t1, dst, len # t1 is just past last byte of dst 316 ADD t1, dst, len # t1 is just past last byte of dst
304 li bits, 8*NBYTES 317 li bits, 8*NBYTES
305 SLL rem, len, 3 # rem = number of bits to keep 318 SLL rem, len, 3 # rem = number of bits to keep
306EXC( LOAD t0, 0(src), l_exc) 319EXC( LOAD t0, 0(src), .Ll_exc)
307 SUB bits, bits, rem # bits = number of bits to discard 320 SUB bits, bits, rem # bits = number of bits to discard
308 SHIFT_DISCARD t0, t0, bits 321 SHIFT_DISCARD t0, t0, bits
309EXC( STREST t0, -1(t1), s_exc) 322EXC( STREST t0, -1(t1), .Ls_exc)
310 jr ra 323 jr ra
311 move len, zero 324 move len, zero
312dst_unaligned: 325.Ldst_unaligned:
313 /* 326 /*
314 * dst is unaligned 327 * dst is unaligned
315 * t0 = src & ADDRMASK 328 * t0 = src & ADDRMASK
@@ -320,22 +333,23 @@ dst_unaligned:
320 * Set match = (src and dst have same alignment) 333 * Set match = (src and dst have same alignment)
321 */ 334 */
322#define match rem 335#define match rem
323EXC( LDFIRST t3, FIRST(0)(src), l_exc) 336EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
324 ADD t2, zero, NBYTES 337 ADD t2, zero, NBYTES
325EXC( LDREST t3, REST(0)(src), l_exc_copy) 338EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
326 SUB t2, t2, t1 # t2 = number of bytes copied 339 SUB t2, t2, t1 # t2 = number of bytes copied
327 xor match, t0, t1 340 xor match, t0, t1
328EXC( STFIRST t3, FIRST(0)(dst), s_exc) 341 R10KCBARRIER(0(ra))
329 beq len, t2, done 342EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
343 beq len, t2, .Ldone
330 SUB len, len, t2 344 SUB len, len, t2
331 ADD dst, dst, t2 345 ADD dst, dst, t2
332 beqz match, both_aligned 346 beqz match, .Lboth_aligned
333 ADD src, src, t2 347 ADD src, src, t2
334 348
335src_unaligned_dst_aligned: 349.Lsrc_unaligned_dst_aligned:
336 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter 350 SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
337 PREF( 0, 3*32(src) ) 351 PREF( 0, 3*32(src) )
338 beqz t0, cleanup_src_unaligned 352 beqz t0, .Lcleanup_src_unaligned
339 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES 353 and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
340 PREF( 1, 3*32(dst) ) 354 PREF( 1, 3*32(dst) )
3411: 3551:
@@ -345,52 +359,59 @@ src_unaligned_dst_aligned:
345 * It's OK to load FIRST(N+1) before REST(N) because the two addresses 359 * It's OK to load FIRST(N+1) before REST(N) because the two addresses
346 * are to the same unit (unless src is aligned, but it's not). 360 * are to the same unit (unless src is aligned, but it's not).
347 */ 361 */
348EXC( LDFIRST t0, FIRST(0)(src), l_exc) 362 R10KCBARRIER(0(ra))
349EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) 363EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
364EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
350 SUB len, len, 4*NBYTES 365 SUB len, len, 4*NBYTES
351EXC( LDREST t0, REST(0)(src), l_exc_copy) 366EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
352EXC( LDREST t1, REST(1)(src), l_exc_copy) 367EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
353EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) 368EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
354EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) 369EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
355EXC( LDREST t2, REST(2)(src), l_exc_copy) 370EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
356EXC( LDREST t3, REST(3)(src), l_exc_copy) 371EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
357 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) 372 PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
358 ADD src, src, 4*NBYTES 373 ADD src, src, 4*NBYTES
359#ifdef CONFIG_CPU_SB1 374#ifdef CONFIG_CPU_SB1
360 nop # improves slotting 375 nop # improves slotting
361#endif 376#endif
362EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) 377EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
363EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) 378EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
364EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) 379EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
365EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) 380EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
366 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) 381 PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
382 .set reorder /* DADDI_WAR */
383 ADD dst, dst, 4*NBYTES
367 bne len, rem, 1b 384 bne len, rem, 1b
368 ADD dst, dst, 4*NBYTES 385 .set noreorder
369 386
370cleanup_src_unaligned: 387.Lcleanup_src_unaligned:
371 beqz len, done 388 beqz len, .Ldone
372 and rem, len, NBYTES-1 # rem = len % NBYTES 389 and rem, len, NBYTES-1 # rem = len % NBYTES
373 beq rem, len, copy_bytes 390 beq rem, len, .Lcopy_bytes
374 nop 391 nop
3751: 3921:
376EXC( LDFIRST t0, FIRST(0)(src), l_exc) 393 R10KCBARRIER(0(ra))
377EXC( LDREST t0, REST(0)(src), l_exc_copy) 394EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
395EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
378 ADD src, src, NBYTES 396 ADD src, src, NBYTES
379 SUB len, len, NBYTES 397 SUB len, len, NBYTES
380EXC( STORE t0, 0(dst), s_exc_p1u) 398EXC( STORE t0, 0(dst), .Ls_exc_p1u)
399 .set reorder /* DADDI_WAR */
400 ADD dst, dst, NBYTES
381 bne len, rem, 1b 401 bne len, rem, 1b
382 ADD dst, dst, NBYTES 402 .set noreorder
383 403
384copy_bytes_checklen: 404.Lcopy_bytes_checklen:
385 beqz len, done 405 beqz len, .Ldone
386 nop 406 nop
387copy_bytes: 407.Lcopy_bytes:
388 /* 0 < len < NBYTES */ 408 /* 0 < len < NBYTES */
409 R10KCBARRIER(0(ra))
389#define COPY_BYTE(N) \ 410#define COPY_BYTE(N) \
390EXC( lb t0, N(src), l_exc); \ 411EXC( lb t0, N(src), .Ll_exc); \
391 SUB len, len, 1; \ 412 SUB len, len, 1; \
392 beqz len, done; \ 413 beqz len, .Ldone; \
393EXC( sb t0, N(dst), s_exc_p1) 414EXC( sb t0, N(dst), .Ls_exc_p1)
394 415
395 COPY_BYTE(0) 416 COPY_BYTE(0)
396 COPY_BYTE(1) 417 COPY_BYTE(1)
@@ -400,16 +421,16 @@ EXC( sb t0, N(dst), s_exc_p1)
400 COPY_BYTE(4) 421 COPY_BYTE(4)
401 COPY_BYTE(5) 422 COPY_BYTE(5)
402#endif 423#endif
403EXC( lb t0, NBYTES-2(src), l_exc) 424EXC( lb t0, NBYTES-2(src), .Ll_exc)
404 SUB len, len, 1 425 SUB len, len, 1
405 jr ra 426 jr ra
406EXC( sb t0, NBYTES-2(dst), s_exc_p1) 427EXC( sb t0, NBYTES-2(dst), .Ls_exc_p1)
407done: 428.Ldone:
408 jr ra 429 jr ra
409 nop 430 nop
410 END(memcpy) 431 END(memcpy)
411 432
412l_exc_copy: 433.Ll_exc_copy:
413 /* 434 /*
414 * Copy bytes from src until faulting load address (or until a 435 * Copy bytes from src until faulting load address (or until a
415 * lb faults) 436 * lb faults)
@@ -424,12 +445,14 @@ l_exc_copy:
424 nop 445 nop
425 LOAD t0, THREAD_BUADDR(t0) 446 LOAD t0, THREAD_BUADDR(t0)
4261: 4471:
427EXC( lb t1, 0(src), l_exc) 448EXC( lb t1, 0(src), .Ll_exc)
428 ADD src, src, 1 449 ADD src, src, 1
429 sb t1, 0(dst) # can't fault -- we're copy_from_user 450 sb t1, 0(dst) # can't fault -- we're copy_from_user
451 .set reorder /* DADDI_WAR */
452 ADD dst, dst, 1
430 bne src, t0, 1b 453 bne src, t0, 1b
431 ADD dst, dst, 1 454 .set noreorder
432l_exc: 455.Ll_exc:
433 LOAD t0, TI_TASK($28) 456 LOAD t0, TI_TASK($28)
434 nop 457 nop
435 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address 458 LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
@@ -446,20 +469,33 @@ l_exc:
446 * Clear len bytes starting at dst. Can't call __bzero because it 469 * Clear len bytes starting at dst. Can't call __bzero because it
447 * might modify len. An inefficient loop for these rare times... 470 * might modify len. An inefficient loop for these rare times...
448 */ 471 */
449 beqz len, done 472 .set reorder /* DADDI_WAR */
450 SUB src, len, 1 473 SUB src, len, 1
474 beqz len, .Ldone
475 .set noreorder
4511: sb zero, 0(dst) 4761: sb zero, 0(dst)
452 ADD dst, dst, 1 477 ADD dst, dst, 1
478#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
453 bnez src, 1b 479 bnez src, 1b
454 SUB src, src, 1 480 SUB src, src, 1
481#else
482 .set push
483 .set noat
484 li v1, 1
485 bnez src, 1b
486 SUB src, src, v1
487 .set pop
488#endif
455 jr ra 489 jr ra
456 nop 490 nop
457 491
458 492
459#define SEXC(n) \ 493#define SEXC(n) \
460s_exc_p ## n ## u: \ 494 .set reorder; /* DADDI_WAR */ \
461 jr ra; \ 495.Ls_exc_p ## n ## u: \
462 ADD len, len, n*NBYTES 496 ADD len, len, n*NBYTES; \
497 jr ra; \
498 .set noreorder
463 499
464SEXC(8) 500SEXC(8)
465SEXC(7) 501SEXC(7)
@@ -470,10 +506,12 @@ SEXC(3)
470SEXC(2) 506SEXC(2)
471SEXC(1) 507SEXC(1)
472 508
473s_exc_p1: 509.Ls_exc_p1:
510 .set reorder /* DADDI_WAR */
511 ADD len, len, 1
474 jr ra 512 jr ra
475 ADD len, len, 1 513 .set noreorder
476s_exc: 514.Ls_exc:
477 jr ra 515 jr ra
478 nop 516 nop
479 517
@@ -484,38 +522,44 @@ LEAF(memmove)
484 sltu t0, a1, t0 # dst + len <= src -> memcpy 522 sltu t0, a1, t0 # dst + len <= src -> memcpy
485 sltu t1, a0, t1 # dst >= src + len -> memcpy 523 sltu t1, a0, t1 # dst >= src + len -> memcpy
486 and t0, t1 524 and t0, t1
487 beqz t0, __memcpy 525 beqz t0, .L__memcpy
488 move v0, a0 /* return value */ 526 move v0, a0 /* return value */
489 beqz a2, r_out 527 beqz a2, .Lr_out
490 END(memmove) 528 END(memmove)
491 529
492 /* fall through to __rmemcpy */ 530 /* fall through to __rmemcpy */
493LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ 531LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
494 sltu t0, a1, a0 532 sltu t0, a1, a0
495 beqz t0, r_end_bytes_up # src >= dst 533 beqz t0, .Lr_end_bytes_up # src >= dst
496 nop 534 nop
497 ADD a0, a2 # dst = dst + len 535 ADD a0, a2 # dst = dst + len
498 ADD a1, a2 # src = src + len 536 ADD a1, a2 # src = src + len
499 537
500r_end_bytes: 538.Lr_end_bytes:
539 R10KCBARRIER(0(ra))
501 lb t0, -1(a1) 540 lb t0, -1(a1)
502 SUB a2, a2, 0x1 541 SUB a2, a2, 0x1
503 sb t0, -1(a0) 542 sb t0, -1(a0)
504 SUB a1, a1, 0x1 543 SUB a1, a1, 0x1
505 bnez a2, r_end_bytes 544 .set reorder /* DADDI_WAR */
506 SUB a0, a0, 0x1 545 SUB a0, a0, 0x1
546 bnez a2, .Lr_end_bytes
547 .set noreorder
507 548
508r_out: 549.Lr_out:
509 jr ra 550 jr ra
510 move a2, zero 551 move a2, zero
511 552
512r_end_bytes_up: 553.Lr_end_bytes_up:
554 R10KCBARRIER(0(ra))
513 lb t0, (a1) 555 lb t0, (a1)
514 SUB a2, a2, 0x1 556 SUB a2, a2, 0x1
515 sb t0, (a0) 557 sb t0, (a0)
516 ADD a1, a1, 0x1 558 ADD a1, a1, 0x1
517 bnez a2, r_end_bytes_up 559 .set reorder /* DADDI_WAR */
518 ADD a0, a0, 0x1 560 ADD a0, a0, 0x1
561 bnez a2, .Lr_end_bytes_up
562 .set noreorder
519 563
520 jr ra 564 jr ra
521 move a2, zero 565 move a2, zero
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 3f8b8b3d0b23..77dc3b20110a 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -5,6 +5,7 @@
5 * 5 *
6 * Copyright (C) 1998, 1999, 2000 by Ralf Baechle 6 * Copyright (C) 1998, 1999, 2000 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2007 Maciej W. Rozycki
8 */ 9 */
9#include <asm/asm.h> 10#include <asm/asm.h>
10#include <asm/asm-offsets.h> 11#include <asm/asm-offsets.h>
@@ -71,34 +72,45 @@ LEAF(memset)
71 72
72FEXPORT(__bzero) 73FEXPORT(__bzero)
73 sltiu t0, a2, LONGSIZE /* very small region? */ 74 sltiu t0, a2, LONGSIZE /* very small region? */
74 bnez t0, small_memset 75 bnez t0, .Lsmall_memset
75 andi t0, a0, LONGMASK /* aligned? */ 76 andi t0, a0, LONGMASK /* aligned? */
76 77
78#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
77 beqz t0, 1f 79 beqz t0, 1f
78 PTR_SUBU t0, LONGSIZE /* alignment in bytes */ 80 PTR_SUBU t0, LONGSIZE /* alignment in bytes */
81#else
82 .set noat
83 li AT, LONGSIZE
84 beqz t0, 1f
85 PTR_SUBU t0, AT /* alignment in bytes */
86 .set at
87#endif
79 88
89 R10KCBARRIER(0(ra))
80#ifdef __MIPSEB__ 90#ifdef __MIPSEB__
81 EX(LONG_S_L, a1, (a0), first_fixup) /* make word/dword aligned */ 91 EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
82#endif 92#endif
83#ifdef __MIPSEL__ 93#ifdef __MIPSEL__
84 EX(LONG_S_R, a1, (a0), first_fixup) /* make word/dword aligned */ 94 EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
85#endif 95#endif
86 PTR_SUBU a0, t0 /* long align ptr */ 96 PTR_SUBU a0, t0 /* long align ptr */
87 PTR_ADDU a2, t0 /* correct size */ 97 PTR_ADDU a2, t0 /* correct size */
88 98
891: ori t1, a2, 0x3f /* # of full blocks */ 991: ori t1, a2, 0x3f /* # of full blocks */
90 xori t1, 0x3f 100 xori t1, 0x3f
91 beqz t1, memset_partial /* no block to fill */ 101 beqz t1, .Lmemset_partial /* no block to fill */
92 andi t0, a2, 0x40-LONGSIZE 102 andi t0, a2, 0x40-LONGSIZE
93 103
94 PTR_ADDU t1, a0 /* end address */ 104 PTR_ADDU t1, a0 /* end address */
95 .set reorder 105 .set reorder
961: PTR_ADDIU a0, 64 1061: PTR_ADDIU a0, 64
97 f_fill64 a0, -64, a1, fwd_fixup 107 R10KCBARRIER(0(ra))
108 f_fill64 a0, -64, a1, .Lfwd_fixup
98 bne t1, a0, 1b 109 bne t1, a0, 1b
99 .set noreorder 110 .set noreorder
100 111
101memset_partial: 112.Lmemset_partial:
113 R10KCBARRIER(0(ra))
102 PTR_LA t1, 2f /* where to start */ 114 PTR_LA t1, 2f /* where to start */
103#if LONGSIZE == 4 115#if LONGSIZE == 4
104 PTR_SUBU t1, t0 116 PTR_SUBU t1, t0
@@ -106,7 +118,7 @@ memset_partial:
106 .set noat 118 .set noat
107 LONG_SRL AT, t0, 1 119 LONG_SRL AT, t0, 1
108 PTR_SUBU t1, AT 120 PTR_SUBU t1, AT
109 .set noat 121 .set at
110#endif 122#endif
111 jr t1 123 jr t1
112 PTR_ADDU a0, t0 /* dest ptr */ 124 PTR_ADDU a0, t0 /* dest ptr */
@@ -114,26 +126,28 @@ memset_partial:
114 .set push 126 .set push
115 .set noreorder 127 .set noreorder
116 .set nomacro 128 .set nomacro
117 f_fill64 a0, -64, a1, partial_fixup /* ... but first do longs ... */ 129 f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */
1182: .set pop 1302: .set pop
119 andi a2, LONGMASK /* At most one long to go */ 131 andi a2, LONGMASK /* At most one long to go */
120 132
121 beqz a2, 1f 133 beqz a2, 1f
122 PTR_ADDU a0, a2 /* What's left */ 134 PTR_ADDU a0, a2 /* What's left */
135 R10KCBARRIER(0(ra))
123#ifdef __MIPSEB__ 136#ifdef __MIPSEB__
124 EX(LONG_S_R, a1, -1(a0), last_fixup) 137 EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
125#endif 138#endif
126#ifdef __MIPSEL__ 139#ifdef __MIPSEL__
127 EX(LONG_S_L, a1, -1(a0), last_fixup) 140 EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
128#endif 141#endif
1291: jr ra 1421: jr ra
130 move a2, zero 143 move a2, zero
131 144
132small_memset: 145.Lsmall_memset:
133 beqz a2, 2f 146 beqz a2, 2f
134 PTR_ADDU t1, a0, a2 147 PTR_ADDU t1, a0, a2
135 148
1361: PTR_ADDIU a0, 1 /* fill bytewise */ 1491: PTR_ADDIU a0, 1 /* fill bytewise */
150 R10KCBARRIER(0(ra))
137 bne t1, a0, 1b 151 bne t1, a0, 1b
138 sb a1, -1(a0) 152 sb a1, -1(a0)
139 153
@@ -141,11 +155,11 @@ small_memset:
141 move a2, zero 155 move a2, zero
142 END(memset) 156 END(memset)
143 157
144first_fixup: 158.Lfirst_fixup:
145 jr ra 159 jr ra
146 nop 160 nop
147 161
148fwd_fixup: 162.Lfwd_fixup:
149 PTR_L t0, TI_TASK($28) 163 PTR_L t0, TI_TASK($28)
150 LONG_L t0, THREAD_BUADDR(t0) 164 LONG_L t0, THREAD_BUADDR(t0)
151 andi a2, 0x3f 165 andi a2, 0x3f
@@ -153,7 +167,7 @@ fwd_fixup:
153 jr ra 167 jr ra
154 LONG_SUBU a2, t0 168 LONG_SUBU a2, t0
155 169
156partial_fixup: 170.Lpartial_fixup:
157 PTR_L t0, TI_TASK($28) 171 PTR_L t0, TI_TASK($28)
158 LONG_L t0, THREAD_BUADDR(t0) 172 LONG_L t0, THREAD_BUADDR(t0)
159 andi a2, LONGMASK 173 andi a2, LONGMASK
@@ -161,6 +175,6 @@ partial_fixup:
161 jr ra 175 jr ra
162 LONG_SUBU a2, t0 176 LONG_SUBU a2, t0
163 177
164last_fixup: 178.Llast_fixup:
165 jr ra 179 jr ra
166 andi v1, a2, LONGMASK 180 andi v1, a2, LONGMASK
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index eca558d83a37..fdbb970f670d 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -24,16 +24,16 @@
24LEAF(__strlen_user_asm) 24LEAF(__strlen_user_asm)
25 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 25 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
26 and v0, a0 26 and v0, a0
27 bnez v0, fault 27 bnez v0, .Lfault
28 28
29FEXPORT(__strlen_user_nocheck_asm) 29FEXPORT(__strlen_user_nocheck_asm)
30 move v0, a0 30 move v0, a0
311: EX(lb, t0, (v0), fault) 311: EX(lb, t0, (v0), .Lfault)
32 PTR_ADDIU v0, 1 32 PTR_ADDIU v0, 1
33 bnez t0, 1b 33 bnez t0, 1b
34 PTR_SUBU v0, a0 34 PTR_SUBU v0, a0
35 jr ra 35 jr ra
36 END(__strlen_user_asm) 36 END(__strlen_user_asm)
37 37
38fault: move v0, zero 38.Lfault: move v0, zero
39 jr ra 39 jr ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
index d16c76fbfac7..7201b2ff08c8 100644
--- a/arch/mips/lib/strncpy_user.S
+++ b/arch/mips/lib/strncpy_user.S
@@ -30,29 +30,30 @@
30LEAF(__strncpy_from_user_asm) 30LEAF(__strncpy_from_user_asm)
31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
32 and v0, a1 32 and v0, a1
33 bnez v0, fault 33 bnez v0, .Lfault
34 34
35FEXPORT(__strncpy_from_user_nocheck_asm) 35FEXPORT(__strncpy_from_user_nocheck_asm)
36 move v0, zero 36 move v0, zero
37 move v1, a1 37 move v1, a1
38 .set noreorder 38 .set noreorder
391: EX(lbu, t0, (v1), fault) 391: EX(lbu, t0, (v1), .Lfault)
40 PTR_ADDIU v1, 1 40 PTR_ADDIU v1, 1
41 R10KCBARRIER(0(ra))
41 beqz t0, 2f 42 beqz t0, 2f
42 sb t0, (a0) 43 sb t0, (a0)
43 PTR_ADDIU v0, 1 44 PTR_ADDIU v0, 1
44 bne v0, a2, 1b
45 PTR_ADDIU a0, 1
46 .set reorder 45 .set reorder
46 PTR_ADDIU a0, 1
47 bne v0, a2, 1b
472: PTR_ADDU t0, a1, v0 482: PTR_ADDU t0, a1, v0
48 xor t0, a1 49 xor t0, a1
49 bltz t0, fault 50 bltz t0, .Lfault
50 jr ra # return n 51 jr ra # return n
51 END(__strncpy_from_user_asm) 52 END(__strncpy_from_user_asm)
52 53
53fault: li v0, -EFAULT 54.Lfault: li v0, -EFAULT
54 jr ra 55 jr ra
55 56
56 .section __ex_table,"a" 57 .section __ex_table,"a"
57 PTR 1b, fault 58 PTR 1b, .Lfault
58 .previous 59 .previous
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
index c0ea15194a0e..c768e3000616 100644
--- a/arch/mips/lib/strnlen_user.S
+++ b/arch/mips/lib/strnlen_user.S
@@ -28,18 +28,19 @@
28LEAF(__strnlen_user_asm) 28LEAF(__strnlen_user_asm)
29 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok? 29 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
30 and v0, a0 30 and v0, a0
31 bnez v0, fault 31 bnez v0, .Lfault
32 32
33FEXPORT(__strnlen_user_nocheck_asm) 33FEXPORT(__strnlen_user_nocheck_asm)
34 move v0, a0 34 move v0, a0
35 PTR_ADDU a1, a0 # stop pointer 35 PTR_ADDU a1, a0 # stop pointer
361: beq v0, a1, 1f # limit reached? 361: beq v0, a1, 1f # limit reached?
37 EX(lb, t0, (v0), fault) 37 EX(lb, t0, (v0), .Lfault)
38 PTR_ADDU v0, 1 38 PTR_ADDU v0, 1
39 bnez t0, 1b 39 bnez t0, 1b
401: PTR_SUBU v0, a0 401: PTR_SUBU v0, a0
41 jr ra 41 jr ra
42 END(__strnlen_user_asm) 42 END(__strnlen_user_asm)
43 43
44fault: move v0, zero 44.Lfault:
45 move v0, zero
45 jr ra 46 jr ra
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
index 58d14f4d9349..27b012d4341c 100644
--- a/arch/mips/lib/uncached.c
+++ b/arch/mips/lib/uncached.c
@@ -46,9 +46,9 @@ unsigned long __init run_uncached(void *func)
46 if (sp >= (long)CKSEG0 && sp < (long)CKSEG2) 46 if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
47 usp = CKSEG1ADDR(sp); 47 usp = CKSEG1ADDR(sp);
48#ifdef CONFIG_64BIT 48#ifdef CONFIG_64BIT
49 else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0LL, 0) && 49 else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0, 0) &&
50 (long long)sp < (long long)PHYS_TO_XKPHYS(8LL, 0)) 50 (long long)sp < (long long)PHYS_TO_XKPHYS(8, 0))
51 usp = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, 51 usp = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
52 XKPHYS_TO_PHYS((long long)sp)); 52 XKPHYS_TO_PHYS((long long)sp));
53#endif 53#endif
54 else { 54 else {
@@ -58,9 +58,9 @@ unsigned long __init run_uncached(void *func)
58 if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2) 58 if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
59 ufunc = CKSEG1ADDR(lfunc); 59 ufunc = CKSEG1ADDR(lfunc);
60#ifdef CONFIG_64BIT 60#ifdef CONFIG_64BIT
61 else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0LL, 0) && 61 else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0, 0) &&
62 (long long)lfunc < (long long)PHYS_TO_XKPHYS(8LL, 0)) 62 (long long)lfunc < (long long)PHYS_TO_XKPHYS(8, 0))
63 ufunc = PHYS_TO_XKPHYS((long long)K_CALG_UNCACHED, 63 ufunc = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
64 XKPHYS_TO_PHYS((long long)lfunc)); 64 XKPHYS_TO_PHYS((long long)lfunc));
65#endif 65#endif
66 else { 66 else {
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index e405d112a067..5c500802271e 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -34,12 +34,6 @@
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/traps.h> 35#include <asm/traps.h>
36 36
37extern void mips_reboot_setup(void);
38
39#ifdef CONFIG_KGDB
40extern void kgdb_config(void);
41#endif
42
43static void __init serial_init(void); 37static void __init serial_init(void);
44 38
45const char *get_system_type(void) 39const char *get_system_type(void)
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 30f1f54cb68b..1695dca5506b 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -250,6 +250,8 @@ void __init mips_ejtag_setup(void)
250 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); 250 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
251} 251}
252 252
253extern struct plat_smp_ops msmtc_smp_ops;
254
253void __init prom_init(void) 255void __init prom_init(void)
254{ 256{
255 prom_argc = fw_arg0; 257 prom_argc = fw_arg0;
@@ -416,4 +418,10 @@ void __init prom_init(void)
416#ifdef CONFIG_SERIAL_8250_CONSOLE 418#ifdef CONFIG_SERIAL_8250_CONSOLE
417 console_config(); 419 console_config();
418#endif 420#endif
421#ifdef CONFIG_MIPS_MT_SMP
422 register_smp_ops(&vsmp_smp_ops);
423#endif
424#ifdef CONFIG_MIPS_MT_SMTC
425 register_smp_ops(&msmtc_smp_ops);
426#endif
419} 427}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index f010261b75d8..dbe60eb55e29 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -26,13 +26,13 @@
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/io.h>
29#include <linux/kernel_stat.h> 30#include <linux/kernel_stat.h>
30#include <linux/kernel.h> 31#include <linux/kernel.h>
31#include <linux/random.h> 32#include <linux/random.h>
32 33
33#include <asm/i8259.h> 34#include <asm/i8259.h>
34#include <asm/irq_cpu.h> 35#include <asm/irq_cpu.h>
35#include <asm/io.h>
36#include <asm/irq_regs.h> 36#include <asm/irq_regs.h>
37#include <asm/mips-boards/malta.h> 37#include <asm/mips-boards/malta.h>
38#include <asm/mips-boards/maltaint.h> 38#include <asm/mips-boards/maltaint.h>
@@ -47,7 +47,7 @@ static DEFINE_SPINLOCK(mips_irq_lock);
47static inline int mips_pcibios_iack(void) 47static inline int mips_pcibios_iack(void)
48{ 48{
49 int irq; 49 int irq;
50 u32 dummy; 50 u32 dummy;
51 51
52 /* 52 /*
53 * Determine highest priority pending interrupt by performing 53 * Determine highest priority pending interrupt by performing
@@ -58,7 +58,7 @@ static inline int mips_pcibios_iack(void)
58 case MIPS_REVISION_SCON_ROCIT: 58 case MIPS_REVISION_SCON_ROCIT:
59 case MIPS_REVISION_SCON_SOCITSC: 59 case MIPS_REVISION_SCON_SOCITSC:
60 case MIPS_REVISION_SCON_SOCITSCP: 60 case MIPS_REVISION_SCON_SOCITSCP:
61 MSC_READ(MSC01_PCI_IACK, irq); 61 MSC_READ(MSC01_PCI_IACK, irq);
62 irq &= 0xff; 62 irq &= 0xff;
63 break; 63 break;
64 case MIPS_REVISION_SCON_GT64120: 64 case MIPS_REVISION_SCON_GT64120:
@@ -83,7 +83,7 @@ static inline int mips_pcibios_iack(void)
83 BONITO_PCIMAP_CFG = 0; 83 BONITO_PCIMAP_CFG = 0;
84 break; 84 break;
85 default: 85 default:
86 printk("Unknown system controller.\n"); 86 printk(KERN_WARNING "Unknown system controller.\n");
87 return -1; 87 return -1;
88 } 88 }
89 return irq; 89 return irq;
@@ -114,7 +114,8 @@ static void malta_hw0_irqdispatch(void)
114 114
115 irq = get_int(); 115 irq = get_int();
116 if (irq < 0) { 116 if (irq < 0) {
117 return; /* interrupt has already been cleared */ 117 /* interrupt has already been cleared */
118 return;
118 } 119 }
119 120
120 do_IRQ(MALTA_INT_BASE + irq); 121 do_IRQ(MALTA_INT_BASE + irq);
@@ -123,15 +124,15 @@ static void malta_hw0_irqdispatch(void)
123static void corehi_irqdispatch(void) 124static void corehi_irqdispatch(void)
124{ 125{
125 unsigned int intedge, intsteer, pcicmd, pcibadaddr; 126 unsigned int intedge, intsteer, pcicmd, pcibadaddr;
126 unsigned int pcimstat, intisr, inten, intpol; 127 unsigned int pcimstat, intisr, inten, intpol;
127 unsigned int intrcause, datalo, datahi; 128 unsigned int intrcause, datalo, datahi;
128 struct pt_regs *regs = get_irq_regs(); 129 struct pt_regs *regs = get_irq_regs();
129 130
130 printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); 131 printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n");
131 printk("epc : %08lx\nStatus: %08lx\n" 132 printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n"
132 "Cause : %08lx\nbadVaddr : %08lx\n", 133 "Cause : %08lx\nbadVaddr : %08lx\n",
133 regs->cp0_epc, regs->cp0_status, 134 regs->cp0_epc, regs->cp0_status,
134 regs->cp0_cause, regs->cp0_badvaddr); 135 regs->cp0_cause, regs->cp0_badvaddr);
135 136
136 /* Read all the registers and then print them as there is a 137 /* Read all the registers and then print them as there is a
137 problem with interspersed printk's upsetting the Bonito controller. 138 problem with interspersed printk's upsetting the Bonito controller.
@@ -139,41 +140,41 @@ static void corehi_irqdispatch(void)
139 */ 140 */
140 141
141 switch (mips_revision_sconid) { 142 switch (mips_revision_sconid) {
142 case MIPS_REVISION_SCON_SOCIT: 143 case MIPS_REVISION_SCON_SOCIT:
143 case MIPS_REVISION_SCON_ROCIT: 144 case MIPS_REVISION_SCON_ROCIT:
144 case MIPS_REVISION_SCON_SOCITSC: 145 case MIPS_REVISION_SCON_SOCITSC:
145 case MIPS_REVISION_SCON_SOCITSCP: 146 case MIPS_REVISION_SCON_SOCITSCP:
146 ll_msc_irq(); 147 ll_msc_irq();
147 break; 148 break;
148 case MIPS_REVISION_SCON_GT64120: 149 case MIPS_REVISION_SCON_GT64120:
149 intrcause = GT_READ(GT_INTRCAUSE_OFS); 150 intrcause = GT_READ(GT_INTRCAUSE_OFS);
150 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS); 151 datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
151 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); 152 datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
152 printk("GT_INTRCAUSE = %08x\n", intrcause); 153 printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause);
153 printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, datalo); 154 printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n",
154 break; 155 datahi, datalo);
155 case MIPS_REVISION_SCON_BONITO: 156 break;
156 pcibadaddr = BONITO_PCIBADADDR; 157 case MIPS_REVISION_SCON_BONITO:
157 pcimstat = BONITO_PCIMSTAT; 158 pcibadaddr = BONITO_PCIBADADDR;
158 intisr = BONITO_INTISR; 159 pcimstat = BONITO_PCIMSTAT;
159 inten = BONITO_INTEN; 160 intisr = BONITO_INTISR;
160 intpol = BONITO_INTPOL; 161 inten = BONITO_INTEN;
161 intedge = BONITO_INTEDGE; 162 intpol = BONITO_INTPOL;
162 intsteer = BONITO_INTSTEER; 163 intedge = BONITO_INTEDGE;
163 pcicmd = BONITO_PCICMD; 164 intsteer = BONITO_INTSTEER;
164 printk("BONITO_INTISR = %08x\n", intisr); 165 pcicmd = BONITO_PCICMD;
165 printk("BONITO_INTEN = %08x\n", inten); 166 printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr);
166 printk("BONITO_INTPOL = %08x\n", intpol); 167 printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten);
167 printk("BONITO_INTEDGE = %08x\n", intedge); 168 printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol);
168 printk("BONITO_INTSTEER = %08x\n", intsteer); 169 printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge);
169 printk("BONITO_PCICMD = %08x\n", pcicmd); 170 printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer);
170 printk("BONITO_PCIBADADDR = %08x\n", pcibadaddr); 171 printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd);
171 printk("BONITO_PCIMSTAT = %08x\n", pcimstat); 172 printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr);
172 break; 173 printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat);
173 } 174 break;
174 175 }
175 /* We die here*/ 176
176 die("CoreHi interrupt", regs); 177 die("CoreHi interrupt", regs);
177} 178}
178 179
179static inline int clz(unsigned long x) 180static inline int clz(unsigned long x)
@@ -214,9 +215,9 @@ static inline unsigned int irq_ffs(unsigned int pending)
214 215
215 t0 = pending & 0x8000; 216 t0 = pending & 0x8000;
216 t0 = t0 < 1; 217 t0 = t0 < 1;
217 //t0 = t0 << 2; 218 /* t0 = t0 << 2; */
218 a0 = a0 - t0; 219 a0 = a0 - t0;
219 //pending = pending << t0; 220 /* pending = pending << t0; */
220 221
221 return a0; 222 return a0;
222#endif 223#endif
@@ -299,21 +300,29 @@ void __init arch_init_irq(void)
299 if (!cpu_has_veic) 300 if (!cpu_has_veic)
300 mips_cpu_irq_init(); 301 mips_cpu_irq_init();
301 302
302 switch(mips_revision_sconid) { 303 switch (mips_revision_sconid) {
303 case MIPS_REVISION_SCON_SOCIT: 304 case MIPS_REVISION_SCON_SOCIT:
304 case MIPS_REVISION_SCON_ROCIT: 305 case MIPS_REVISION_SCON_ROCIT:
305 if (cpu_has_veic) 306 if (cpu_has_veic)
306 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); 307 init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
308 MSC01E_INT_BASE, msc_eicirqmap,
309 msc_nr_eicirqs);
307 else 310 else
308 init_msc_irqs(MIPS_MSC01_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); 311 init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
312 MSC01C_INT_BASE, msc_irqmap,
313 msc_nr_irqs);
309 break; 314 break;
310 315
311 case MIPS_REVISION_SCON_SOCITSC: 316 case MIPS_REVISION_SCON_SOCITSC:
312 case MIPS_REVISION_SCON_SOCITSCP: 317 case MIPS_REVISION_SCON_SOCITSCP:
313 if (cpu_has_veic) 318 if (cpu_has_veic)
314 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs); 319 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
320 MSC01E_INT_BASE, msc_eicirqmap,
321 msc_nr_eicirqs);
315 else 322 else
316 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs); 323 init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
324 MSC01C_INT_BASE, msc_irqmap,
325 msc_nr_irqs);
317 } 326 }
318 327
319 if (cpu_has_veic) { 328 if (cpu_has_veic) {
@@ -321,8 +330,7 @@ void __init arch_init_irq(void)
321 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); 330 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
322 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); 331 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
323 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); 332 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
324 } 333 } else if (cpu_has_vint) {
325 else if (cpu_has_vint) {
326 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); 334 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
327 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); 335 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
328#ifdef CONFIG_MIPS_MT_SMTC 336#ifdef CONFIG_MIPS_MT_SMTC
@@ -344,11 +352,12 @@ void __init arch_init_irq(void)
344 } 352 }
345#else /* Not SMTC */ 353#else /* Not SMTC */
346 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 354 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
347 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 355 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
356 &corehi_irqaction);
348#endif /* CONFIG_MIPS_MT_SMTC */ 357#endif /* CONFIG_MIPS_MT_SMTC */
349 } 358 } else {
350 else {
351 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); 359 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
352 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 360 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
361 &corehi_irqaction);
353 } 362 }
354} 363}
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index bc43a5c2224d..2cd8f5734b36 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Carsten Langgaard, carstenl@mips.com 2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 3 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
4 * Copyright (C) Dmitri Vorobiev
4 * 5 *
5 * This program is free software; you can distribute it and/or modify it 6 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as 7 * under the terms of the GNU General Public License (Version 2) as
@@ -15,39 +16,57 @@
15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 17 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 */ 18 */
19#include <linux/cpu.h>
18#include <linux/init.h> 20#include <linux/init.h>
19#include <linux/sched.h> 21#include <linux/sched.h>
20#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/irq.h>
21#include <linux/pci.h> 24#include <linux/pci.h>
22#include <linux/screen_info.h> 25#include <linux/screen_info.h>
26#include <linux/time.h>
23 27
24#include <asm/cpu.h>
25#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
26#include <asm/irq.h>
27#include <asm/mips-boards/generic.h> 29#include <asm/mips-boards/generic.h>
28#include <asm/mips-boards/prom.h> 30#include <asm/mips-boards/prom.h>
29#include <asm/mips-boards/malta.h> 31#include <asm/mips-boards/malta.h>
30#include <asm/mips-boards/maltaint.h> 32#include <asm/mips-boards/maltaint.h>
31#include <asm/dma.h> 33#include <asm/dma.h>
32#include <asm/time.h>
33#include <asm/traps.h> 34#include <asm/traps.h>
34#ifdef CONFIG_VT 35#ifdef CONFIG_VT
35#include <linux/console.h> 36#include <linux/console.h>
36#endif 37#endif
37 38
38extern void mips_reboot_setup(void);
39extern unsigned long mips_rtc_get_time(void);
40
41#ifdef CONFIG_KGDB
42extern void kgdb_config(void);
43#endif
44
45struct resource standard_io_resources[] = { 39struct resource standard_io_resources[] = {
46 { .name = "dma1", .start = 0x00, .end = 0x1f, .flags = IORESOURCE_BUSY }, 40 {
47 { .name = "timer", .start = 0x40, .end = 0x5f, .flags = IORESOURCE_BUSY }, 41 .name = "dma1",
48 { .name = "keyboard", .start = 0x60, .end = 0x6f, .flags = IORESOURCE_BUSY }, 42 .start = 0x00,
49 { .name = "dma page reg", .start = 0x80, .end = 0x8f, .flags = IORESOURCE_BUSY }, 43 .end = 0x1f,
50 { .name = "dma2", .start = 0xc0, .end = 0xdf, .flags = IORESOURCE_BUSY }, 44 .flags = IORESOURCE_BUSY
45 },
46 {
47 .name = "timer",
48 .start = 0x40,
49 .end = 0x5f,
50 .flags = IORESOURCE_BUSY
51 },
52 {
53 .name = "keyboard",
54 .start = 0x60,
55 .end = 0x6f,
56 .flags = IORESOURCE_BUSY
57 },
58 {
59 .name = "dma page reg",
60 .start = 0x80,
61 .end = 0x8f,
62 .flags = IORESOURCE_BUSY
63 },
64 {
65 .name = "dma2",
66 .start = 0xc0,
67 .end = 0xdf,
68 .flags = IORESOURCE_BUSY
69 },
51}; 70};
52 71
53const char *get_system_type(void) 72const char *get_system_type(void)
@@ -62,7 +81,7 @@ const char display_string[] = " LINUX ON MALTA ";
62#endif /* CONFIG_MIPS_MT_SMTC */ 81#endif /* CONFIG_MIPS_MT_SMTC */
63 82
64#ifdef CONFIG_BLK_DEV_FD 83#ifdef CONFIG_BLK_DEV_FD
65void __init fd_activate(void) 84static void __init fd_activate(void)
66{ 85{
67 /* 86 /*
68 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O 87 * Activate Floppy Controller in the SMSC FDC37M817 Super I/O
@@ -83,6 +102,85 @@ void __init fd_activate(void)
83} 102}
84#endif 103#endif
85 104
105#ifdef CONFIG_BLK_DEV_IDE
106static void __init pci_clock_check(void)
107{
108 unsigned int __iomem *jmpr_p =
109 (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));
110 int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07;
111 static const int pciclocks[] __initdata = {
112 33, 20, 25, 30, 12, 16, 37, 10
113 };
114 int pciclock = pciclocks[jmpr];
115 char *argptr = prom_getcmdline();
116
117 if (pciclock != 33 && !strstr(argptr, "idebus=")) {
118 printk(KERN_WARNING "WARNING: PCI clock is %dMHz, "
119 "setting idebus\n", pciclock);
120 argptr += strlen(argptr);
121 sprintf(argptr, " idebus=%d", pciclock);
122 if (pciclock < 20 || pciclock > 66)
123 printk(KERN_WARNING "WARNING: IDE timing "
124 "calculations will be incorrect\n");
125 }
126}
127#endif
128
129#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
130static void __init screen_info_setup(void)
131{
132 screen_info = (struct screen_info) {
133 .orig_x = 0,
134 .orig_y = 25,
135 .ext_mem_k = 0,
136 .orig_video_page = 0,
137 .orig_video_mode = 0,
138 .orig_video_cols = 80,
139 .unused2 = 0,
140 .orig_video_ega_bx = 0,
141 .unused3 = 0,
142 .orig_video_lines = 25,
143 .orig_video_isVGA = VIDEO_TYPE_VGAC,
144 .orig_video_points = 16
145 };
146}
147#endif
148
149static void __init bonito_quirks_setup(void)
150{
151 char *argptr;
152
153 argptr = prom_getcmdline();
154 if (strstr(argptr, "debug")) {
155 BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
156 printk(KERN_INFO "Enabled Bonito debug mode\n");
157 } else
158 BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
159
160#ifdef CONFIG_DMA_COHERENT
161 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
162 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
163 printk(KERN_INFO "Enabled Bonito CPU coherency\n");
164
165 argptr = prom_getcmdline();
166 if (strstr(argptr, "iobcuncached")) {
167 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
168 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
169 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
170 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
171 printk(KERN_INFO "Disabled Bonito IOBC coherency\n");
172 } else {
173 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
174 BONITO_PCIMEMBASECFG |=
175 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
176 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
177 printk(KERN_INFO "Enabled Bonito IOBC coherency\n");
178 }
179 } else
180 panic("Hardware DMA cache coherency not supported");
181#endif
182}
183
86void __init plat_mem_setup(void) 184void __init plat_mem_setup(void)
87{ 185{
88 unsigned int i; 186 unsigned int i;
@@ -102,86 +200,24 @@ void __init plat_mem_setup(void)
102 kgdb_config(); 200 kgdb_config();
103#endif 201#endif
104 202
105 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO) {
106 char *argptr;
107
108 argptr = prom_getcmdline();
109 if (strstr(argptr, "debug")) {
110 BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
111 printk("Enabled Bonito debug mode\n");
112 }
113 else
114 BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
115
116#ifdef CONFIG_DMA_COHERENT
117 if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
118 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
119 printk("Enabled Bonito CPU coherency\n");
120
121 argptr = prom_getcmdline();
122 if (strstr(argptr, "iobcuncached")) {
123 BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
124 BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
125 ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
126 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
127 printk("Disabled Bonito IOBC coherency\n");
128 }
129 else {
130 BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
131 BONITO_PCIMEMBASECFG |=
132 (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
133 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
134 printk("Enabled Bonito IOBC coherency\n");
135 }
136 }
137 else
138 panic("Hardware DMA cache coherency not supported");
139
140#endif
141 }
142#ifdef CONFIG_DMA_COHERENT 203#ifdef CONFIG_DMA_COHERENT
143 else { 204 if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO)
144 panic("Hardware DMA cache coherency not supported"); 205 panic("Hardware DMA cache coherency not supported");
145 }
146#endif 206#endif
147 207
208 if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO)
209 bonito_quirks_setup();
210
148#ifdef CONFIG_BLK_DEV_IDE 211#ifdef CONFIG_BLK_DEV_IDE
149 /* Check PCI clock */ 212 pci_clock_check();
150 {
151 unsigned int __iomem *jmpr_p = (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));
152 int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07;
153 static const int pciclocks[] __initdata = {
154 33, 20, 25, 30, 12, 16, 37, 10
155 };
156 int pciclock = pciclocks[jmpr];
157 char *argptr = prom_getcmdline();
158
159 if (pciclock != 33 && !strstr (argptr, "idebus=")) {
160 printk("WARNING: PCI clock is %dMHz, setting idebus\n", pciclock);
161 argptr += strlen(argptr);
162 sprintf(argptr, " idebus=%d", pciclock);
163 if (pciclock < 20 || pciclock > 66)
164 printk("WARNING: IDE timing calculations will be incorrect\n");
165 }
166 }
167#endif 213#endif
214
168#ifdef CONFIG_BLK_DEV_FD 215#ifdef CONFIG_BLK_DEV_FD
169 fd_activate(); 216 fd_activate();
170#endif 217#endif
171#ifdef CONFIG_VT 218
172#if defined(CONFIG_VGA_CONSOLE) 219#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
173 screen_info = (struct screen_info) { 220 screen_info_setup();
174 0, 25, /* orig-x, orig-y */
175 0, /* unused */
176 0, /* orig-video-page */
177 0, /* orig-video-mode */
178 80, /* orig-video-cols */
179 0, 0, 0, /* ega_ax, ega_bx, ega_cx */
180 25, /* orig-video-lines */
181 VIDEO_TYPE_VGAC, /* orig-video-isVGA */
182 16 /* orig-video-points */
183 };
184#endif
185#endif 221#endif
186 mips_reboot_setup(); 222 mips_reboot_setup();
187} 223}
diff --git a/arch/mips/mips-boards/malta/malta_smtc.c b/arch/mips/mips-boards/malta/malta_smtc.c
index 5c980f4a48fe..5ea705e49454 100644
--- a/arch/mips/mips-boards/malta/malta_smtc.c
+++ b/arch/mips/mips-boards/malta/malta_smtc.c
@@ -15,28 +15,26 @@
15 * Cause the specified action to be performed on a targeted "CPU" 15 * Cause the specified action to be performed on a targeted "CPU"
16 */ 16 */
17 17
18void core_send_ipi(int cpu, unsigned int action) 18static void msmtc_send_ipi_single(int cpu, unsigned int action)
19{ 19{
20 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ 20 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
21 smtc_send_ipi(cpu, LINUX_SMP_IPI, action); 21 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
22} 22}
23 23
24/* 24static void msmtc_send_ipi_mask(cpumask_t mask, unsigned int action)
25 * Platform "CPU" startup hook
26 */
27
28void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
29{ 25{
30 smtc_boot_secondary(cpu, idle); 26 unsigned int i;
27
28 for_each_cpu_mask(i, mask)
29 msmtc_send_ipi_single(i, action);
31} 30}
32 31
33/* 32/*
34 * Post-config but pre-boot cleanup entry point 33 * Post-config but pre-boot cleanup entry point
35 */ 34 */
36 35static void __cpuinit msmtc_init_secondary(void)
37void __cpuinit prom_init_secondary(void)
38{ 36{
39 void smtc_init_secondary(void); 37 void smtc_init_secondary(void);
40 int myvpe; 38 int myvpe;
41 39
42 /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ 40 /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
@@ -50,45 +48,61 @@ void __cpuinit prom_init_secondary(void)
50 set_c0_status(0x100 << cp0_perfcount_irq); 48 set_c0_status(0x100 << cp0_perfcount_irq);
51 } 49 }
52 50
53 smtc_init_secondary(); 51 smtc_init_secondary();
54} 52}
55 53
56/* 54/*
57 * Platform SMP pre-initialization 55 * Platform "CPU" startup hook
58 *
59 * As noted above, we can assume a single CPU for now
60 * but it may be multithreaded.
61 */ 56 */
62 57static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle)
63void __cpuinit plat_smp_setup(void)
64{ 58{
65 if (read_c0_config3() & (1<<2)) 59 smtc_boot_secondary(cpu, idle);
66 mipsmt_build_cpu_map(0);
67} 60}
68 61
69void __init plat_prepare_cpus(unsigned int max_cpus) 62/*
63 * SMP initialization finalization entry point
64 */
65static void __cpuinit msmtc_smp_finish(void)
70{ 66{
71 if (read_c0_config3() & (1<<2)) 67 smtc_smp_finish();
72 mipsmt_prepare_cpus();
73} 68}
74 69
75/* 70/*
76 * SMP initialization finalization entry point 71 * Hook for after all CPUs are online
77 */ 72 */
78 73
79void __cpuinit prom_smp_finish(void) 74static void msmtc_cpus_done(void)
80{ 75{
81 smtc_smp_finish();
82} 76}
83 77
84/* 78/*
85 * Hook for after all CPUs are online 79 * Platform SMP pre-initialization
80 *
81 * As noted above, we can assume a single CPU for now
82 * but it may be multithreaded.
86 */ 83 */
87 84
88void prom_cpus_done(void) 85static void __init msmtc_smp_setup(void)
89{ 86{
87 mipsmt_build_cpu_map(0);
90} 88}
91 89
90static void __init msmtc_prepare_cpus(unsigned int max_cpus)
91{
92 mipsmt_prepare_cpus();
93}
94
95struct plat_smp_ops msmtc_smp_ops = {
96 .send_ipi_single = msmtc_send_ipi_single,
97 .send_ipi_mask = msmtc_send_ipi_mask,
98 .init_secondary = msmtc_init_secondary,
99 .smp_finish = msmtc_smp_finish,
100 .cpus_done = msmtc_cpus_done,
101 .boot_secondary = msmtc_boot_secondary,
102 .smp_setup = msmtc_smp_setup,
103 .prepare_cpus = msmtc_prepare_cpus,
104};
105
92#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF 106#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
93/* 107/*
94 * IRQ affinity hook 108 * IRQ affinity hook
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c
index 1fb61b852304..8aa8e5b7b074 100644
--- a/arch/mips/mips-boards/sead/sead_setup.c
+++ b/arch/mips/mips-boards/sead/sead_setup.c
@@ -34,8 +34,6 @@
34#include <asm/mips-boards/seadint.h> 34#include <asm/mips-boards/seadint.h>
35#include <asm/time.h> 35#include <asm/time.h>
36 36
37extern void mips_reboot_setup(void);
38
39static void __init serial_init(void); 37static void __init serial_init(void);
40 38
41const char *get_system_type(void) 39const char *get_system_type(void)
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
index 75568b584df4..57f43c1c7882 100644
--- a/arch/mips/mipssim/Makefile
+++ b/arch/mips/mipssim/Makefile
@@ -21,6 +21,6 @@ obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o \
21 sim_cmdline.o 21 sim_cmdline.o
22 22
23obj-$(CONFIG_EARLY_PRINTK) += sim_console.o 23obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
24obj-$(CONFIG_SMP) += sim_smp.o 24obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
25 25
26EXTRA_CFLAGS += -Werror 26EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index 452c129d02c1..d49fe73426b7 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -60,6 +60,8 @@ void __init plat_mem_setup(void)
60#endif 60#endif
61} 61}
62 62
63extern struct plat_smp_ops ssmtc_smp_ops;
64
63void __init prom_init(void) 65void __init prom_init(void)
64{ 66{
65 set_io_port_base(0xbfd00000); 67 set_io_port_base(0xbfd00000);
@@ -67,8 +69,20 @@ void __init prom_init(void)
67 pr_info("\nLINUX started...\n"); 69 pr_info("\nLINUX started...\n");
68 prom_init_cmdline(); 70 prom_init_cmdline();
69 prom_meminit(); 71 prom_meminit();
70}
71 72
73#ifdef CONFIG_MIPS_MT_SMP
74 if (cpu_has_mipsmt)
75 register_smp_ops(&vsmp_smp_ops);
76 else
77 register_smp_ops(&up_smp_ops);
78#endif
79#ifdef CONFIG_MIPS_MT_SMTC
80 if (cpu_has_mipsmt)
81 register_smp_ops(&ssmtc_smp_ops);
82 else
83 register_smp_ops(&up_smp_ops);
84#endif
85}
72 86
73static void __init serial_init(void) 87static void __init serial_init(void)
74{ 88{
diff --git a/arch/mips/mipssim/sim_smp.c b/arch/mips/mipssim/sim_smtc.c
index ccbbccac23ef..d6e4f656ad14 100644
--- a/arch/mips/mipssim/sim_smp.c
+++ b/arch/mips/mipssim/sim_smtc.c
@@ -16,7 +16,7 @@
16 * 16 *
17 */ 17 */
18/* 18/*
19 * Simulator Platform-specific hooks for SMP operation 19 * Simulator Platform-specific hooks for SMTC operation
20 */ 20 */
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
@@ -29,65 +29,72 @@
29#include <asm/processor.h> 29#include <asm/processor.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
32#ifdef CONFIG_MIPS_MT_SMTC
33#include <asm/smtc_ipi.h> 32#include <asm/smtc_ipi.h>
34#endif /* CONFIG_MIPS_MT_SMTC */
35 33
36/* VPE/SMP Prototype implements platform interfaces directly */ 34/* VPE/SMP Prototype implements platform interfaces directly */
37#if !defined(CONFIG_MIPS_MT_SMP)
38 35
39/* 36/*
40 * Cause the specified action to be performed on a targeted "CPU" 37 * Cause the specified action to be performed on a targeted "CPU"
41 */ 38 */
42 39
43void core_send_ipi(int cpu, unsigned int action) 40static void ssmtc_send_ipi_single(int cpu, unsigned int action)
44{ 41{
45#ifdef CONFIG_MIPS_MT_SMTC
46 smtc_send_ipi(cpu, LINUX_SMP_IPI, action); 42 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
47#endif /* CONFIG_MIPS_MT_SMTC */ 43 /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
48/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ 44}
45
46static inline void ssmtc_send_ipi_mask(cpumask_t mask, unsigned int action)
47{
48 unsigned int i;
49 49
50 for_each_cpu_mask(i, mask)
51 ssmtc_send_ipi_single(i, action);
50} 52}
51 53
52/* 54/*
53 * Platform "CPU" startup hook 55 * Post-config but pre-boot cleanup entry point
54 */ 56 */
55 57static void __cpuinit ssmtc_init_secondary(void)
56void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
57{ 58{
58#ifdef CONFIG_MIPS_MT_SMTC 59 void smtc_init_secondary(void);
59 smtc_boot_secondary(cpu, idle); 60
60#endif /* CONFIG_MIPS_MT_SMTC */ 61 smtc_init_secondary();
61} 62}
62 63
63/* 64/*
64 * Post-config but pre-boot cleanup entry point 65 * SMP initialization finalization entry point
65 */ 66 */
67static void __cpuinit ssmtc_smp_finish(void)
68{
69 smtc_smp_finish();
70}
66 71
67void __cpuinit prom_init_secondary(void) 72/*
73 * Hook for after all CPUs are online
74 */
75static void ssmtc_cpus_done(void)
68{ 76{
69#ifdef CONFIG_MIPS_MT_SMTC 77}
70 void smtc_init_secondary(void);
71 78
72 smtc_init_secondary(); 79/*
73#endif /* CONFIG_MIPS_MT_SMTC */ 80 * Platform "CPU" startup hook
81 */
82static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)
83{
84 smtc_boot_secondary(cpu, idle);
74} 85}
75 86
76void plat_smp_setup(void) 87static void __init ssmtc_smp_setup(void)
77{ 88{
78#ifdef CONFIG_MIPS_MT_SMTC
79 if (read_c0_config3() & (1 << 2)) 89 if (read_c0_config3() & (1 << 2))
80 mipsmt_build_cpu_map(0); 90 mipsmt_build_cpu_map(0);
81#endif /* CONFIG_MIPS_MT_SMTC */
82} 91}
83 92
84/* 93/*
85 * Platform SMP pre-initialization 94 * Platform SMP pre-initialization
86 */ 95 */
87 96static void ssmtc_prepare_cpus(unsigned int max_cpus)
88void plat_prepare_cpus(unsigned int max_cpus)
89{ 97{
90#ifdef CONFIG_MIPS_MT_SMTC
91 /* 98 /*
92 * As noted above, we can assume a single CPU for now 99 * As noted above, we can assume a single CPU for now
93 * but it may be multithreaded. 100 * but it may be multithreaded.
@@ -96,28 +103,15 @@ void plat_prepare_cpus(unsigned int max_cpus)
96 if (read_c0_config3() & (1 << 2)) { 103 if (read_c0_config3() & (1 << 2)) {
97 mipsmt_prepare_cpus(); 104 mipsmt_prepare_cpus();
98 } 105 }
99#endif /* CONFIG_MIPS_MT_SMTC */
100} 106}
101 107
102/* 108struct plat_smp_ops ssmtc_smp_ops = {
103 * SMP initialization finalization entry point 109 .send_ipi_single = ssmtc_send_ipi_single,
104 */ 110 .send_ipi_mask = ssmtc_send_ipi_mask,
105 111 .init_secondary = ssmtc_init_secondary,
106void __cpuinit prom_smp_finish(void) 112 .smp_finish = ssmtc_smp_finish,
107{ 113 .cpus_done = ssmtc_cpus_done,
108#ifdef CONFIG_MIPS_MT_SMTC 114 .boot_secondary = ssmtc_boot_secondary,
109 smtc_smp_finish(); 115 .smp_setup = ssmtc_smp_setup,
110#endif /* CONFIG_MIPS_MT_SMTC */ 116 .prepare_cpus = ssmtc_prepare_cpus,
111} 117};
112
113/*
114 * Hook for after all CPUs are online
115 */
116
117void prom_cpus_done(void)
118{
119#ifdef CONFIG_MIPS_MT_SMTC
120
121#endif /* CONFIG_MIPS_MT_SMTC */
122}
123#endif /* CONFIG_MIPS32R2_MT_SMP */
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 9355f1c9325f..02bd180f0e02 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -449,7 +449,7 @@ static inline void local_r4k_flush_cache_page(void *args)
449 * If the page isn't marked valid, the page cannot possibly be 449 * If the page isn't marked valid, the page cannot possibly be
450 * in the cache. 450 * in the cache.
451 */ 451 */
452 if (!(pte_val(*ptep) & _PAGE_PRESENT)) 452 if (!(pte_present(*ptep)))
453 return; 453 return;
454 454
455 if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) 455 if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
@@ -468,8 +468,6 @@ static inline void local_r4k_flush_cache_page(void *args)
468 468
469 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { 469 if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
470 r4k_blast_dcache_page(addr); 470 r4k_blast_dcache_page(addr);
471 if (exec && !cpu_icache_snoops_remote_store)
472 r4k_blast_scache_page(addr);
473 } 471 }
474 if (exec) { 472 if (exec) {
475 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { 473 if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
@@ -533,13 +531,6 @@ static inline void local_r4k_flush_icache_range(void *args)
533 R4600_HIT_CACHEOP_WAR_IMPL; 531 R4600_HIT_CACHEOP_WAR_IMPL;
534 protected_blast_dcache_range(start, end); 532 protected_blast_dcache_range(start, end);
535 } 533 }
536
537 if (!cpu_icache_snoops_remote_store && scache_size) {
538 if (end - start > scache_size)
539 r4k_blast_scache();
540 else
541 protected_blast_scache_range(start, end);
542 }
543 } 534 }
544 535
545 if (end - start > icache_size) 536 if (end - start > icache_size)
@@ -598,7 +589,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
598 if (size >= scache_size) 589 if (size >= scache_size)
599 r4k_blast_scache(); 590 r4k_blast_scache();
600 else 591 else
601 blast_scache_range(addr, addr + size); 592 blast_inv_scache_range(addr, addr + size);
602 return; 593 return;
603 } 594 }
604 595
@@ -606,7 +597,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
606 r4k_blast_dcache(); 597 r4k_blast_dcache();
607 } else { 598 } else {
608 R4600_HIT_CACHEOP_WAR_IMPL; 599 R4600_HIT_CACHEOP_WAR_IMPL;
609 blast_dcache_range(addr, addr + size); 600 blast_inv_dcache_range(addr, addr + size);
610 } 601 }
611 602
612 bc_inv(addr, size); 603 bc_inv(addr, size);
@@ -989,6 +980,8 @@ static void __init probe_pcache(void)
989 case CPU_AU1100: 980 case CPU_AU1100:
990 case CPU_AU1550: 981 case CPU_AU1550:
991 case CPU_AU1200: 982 case CPU_AU1200:
983 case CPU_AU1210:
984 case CPU_AU1250:
992 c->icache.flags |= MIPS_CACHE_IC_F_DC; 985 c->icache.flags |= MIPS_CACHE_IC_F_DC;
993 break; 986 break;
994 } 987 }
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 810535dd091b..ae39dd88b9aa 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -383,7 +383,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
383 BUG_ON(direction == DMA_NONE); 383 BUG_ON(direction == DMA_NONE);
384 384
385 if (!plat_device_is_coherent(dev)) 385 if (!plat_device_is_coherent(dev))
386 dma_cache_wback_inv((unsigned long)vaddr, size); 386 __dma_sync((unsigned long)vaddr, size, direction);
387} 387}
388 388
389EXPORT_SYMBOL(dma_cache_sync); 389EXPORT_SYMBOL(dma_cache_sync);
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index 4f770ac885ce..9185fbf37c0d 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -4,6 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) 6 * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2007 Maciej W. Rozycki
7 */ 8 */
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -12,6 +13,7 @@
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/proc_fs.h> 14#include <linux/proc_fs.h>
14 15
16#include <asm/bugs.h>
15#include <asm/cacheops.h> 17#include <asm/cacheops.h>
16#include <asm/inst.h> 18#include <asm/inst.h>
17#include <asm/io.h> 19#include <asm/io.h>
@@ -255,64 +257,58 @@ static inline void build_store_reg(int reg)
255 __build_store_reg(reg); 257 __build_store_reg(reg);
256} 258}
257 259
258static inline void build_addiu_a2_a0(unsigned long offset) 260static inline void build_addiu_rt_rs(unsigned int rt, unsigned int rs,
261 unsigned long offset)
259{ 262{
260 union mips_instruction mi; 263 union mips_instruction mi;
261 264
262 BUG_ON(offset > 0x7fff); 265 BUG_ON(offset > 0x7fff);
263 266
264 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; 267 if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
265 mi.i_format.rs = 4; /* $a0 */ 268 mi.i_format.opcode = addiu_op;
266 mi.i_format.rt = 6; /* $a2 */ 269 mi.i_format.rs = 0; /* $zero */
267 mi.i_format.simmediate = offset; 270 mi.i_format.rt = 25; /* $t9 */
271 mi.i_format.simmediate = offset;
272 emit_instruction(mi);
268 273
274 mi.r_format.opcode = spec_op;
275 mi.r_format.rs = rs;
276 mi.r_format.rt = 25; /* $t9 */
277 mi.r_format.rd = rt;
278 mi.r_format.re = 0;
279 mi.r_format.func = daddu_op;
280 } else {
281 mi.i_format.opcode = cpu_has_64bit_gp_regs ?
282 daddiu_op : addiu_op;
283 mi.i_format.rs = rs;
284 mi.i_format.rt = rt;
285 mi.i_format.simmediate = offset;
286 }
269 emit_instruction(mi); 287 emit_instruction(mi);
270} 288}
271 289
272static inline void build_addiu_a2(unsigned long offset) 290static inline void build_addiu_a2_a0(unsigned long offset)
273{ 291{
274 union mips_instruction mi; 292 build_addiu_rt_rs(6, 4, offset); /* $a2, $a0, offset */
275 293}
276 BUG_ON(offset > 0x7fff);
277
278 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
279 mi.i_format.rs = 6; /* $a2 */
280 mi.i_format.rt = 6; /* $a2 */
281 mi.i_format.simmediate = offset;
282 294
283 emit_instruction(mi); 295static inline void build_addiu_a2(unsigned long offset)
296{
297 build_addiu_rt_rs(6, 6, offset); /* $a2, $a2, offset */
284} 298}
285 299
286static inline void build_addiu_a1(unsigned long offset) 300static inline void build_addiu_a1(unsigned long offset)
287{ 301{
288 union mips_instruction mi; 302 build_addiu_rt_rs(5, 5, offset); /* $a1, $a1, offset */
289
290 BUG_ON(offset > 0x7fff);
291
292 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
293 mi.i_format.rs = 5; /* $a1 */
294 mi.i_format.rt = 5; /* $a1 */
295 mi.i_format.simmediate = offset;
296 303
297 load_offset -= offset; 304 load_offset -= offset;
298
299 emit_instruction(mi);
300} 305}
301 306
302static inline void build_addiu_a0(unsigned long offset) 307static inline void build_addiu_a0(unsigned long offset)
303{ 308{
304 union mips_instruction mi; 309 build_addiu_rt_rs(4, 4, offset); /* $a0, $a0, offset */
305
306 BUG_ON(offset > 0x7fff);
307
308 mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
309 mi.i_format.rs = 4; /* $a0 */
310 mi.i_format.rt = 4; /* $a0 */
311 mi.i_format.simmediate = offset;
312 310
313 store_offset -= offset; 311 store_offset -= offset;
314
315 emit_instruction(mi);
316} 312}
317 313
318static inline void build_bne(unsigned int *dest) 314static inline void build_bne(unsigned int *dest)
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index a61246d3533d..d026302e0ecc 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,7 +6,7 @@
6 * Synthesize TLB refill handlers at runtime. 6 * Synthesize TLB refill handlers at runtime.
7 * 7 *
8 * Copyright (C) 2004,2005,2006 by Thiemo Seufer 8 * Copyright (C) 2004,2005,2006 by Thiemo Seufer
9 * Copyright (C) 2005 Maciej W. Rozycki 9 * Copyright (C) 2005, 2007 Maciej W. Rozycki
10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) 10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
11 * 11 *
12 * ... and the days got worse and worse and now you see 12 * ... and the days got worse and worse and now you see
@@ -19,20 +19,15 @@
19 * (Condolences to Napoleon XIV) 19 * (Condolences to Napoleon XIV)
20 */ 20 */
21 21
22#include <stdarg.h>
23
24#include <linux/mm.h>
25#include <linux/kernel.h> 22#include <linux/kernel.h>
26#include <linux/types.h> 23#include <linux/types.h>
27#include <linux/string.h> 24#include <linux/string.h>
28#include <linux/init.h> 25#include <linux/init.h>
29 26
30#include <asm/pgtable.h> 27#include <asm/bugs.h>
31#include <asm/cacheflush.h>
32#include <asm/mmu_context.h> 28#include <asm/mmu_context.h>
33#include <asm/inst.h> 29#include <asm/inst.h>
34#include <asm/elf.h> 30#include <asm/elf.h>
35#include <asm/smp.h>
36#include <asm/war.h> 31#include <asm/war.h>
37 32
38static inline int r45k_bvahwbug(void) 33static inline int r45k_bvahwbug(void)
@@ -66,7 +61,7 @@ static inline int __maybe_unused r10000_llsc_war(void)
66 * why; it's not an issue caused by the core RTL. 61 * why; it's not an issue caused by the core RTL.
67 * 62 *
68 */ 63 */
69static __init int __attribute__((unused)) m4kc_tlbp_war(void) 64static int __init m4kc_tlbp_war(void)
70{ 65{
71 return (current_cpu_data.processor_id & 0xffff00) == 66 return (current_cpu_data.processor_id & 0xffff00) ==
72 (PRID_COMP_MIPS | PRID_IMP_4KC); 67 (PRID_COMP_MIPS | PRID_IMP_4KC);
@@ -140,7 +135,7 @@ struct insn {
140 | (e) << RE_SH \ 135 | (e) << RE_SH \
141 | (f) << FUNC_SH) 136 | (f) << FUNC_SH)
142 137
143static __initdata struct insn insn_table[] = { 138static struct insn insn_table[] __initdata = {
144 { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 139 { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
145 { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, 140 { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
146 { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, 141 { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
@@ -193,7 +188,7 @@ static __initdata struct insn insn_table[] = {
193 188
194#undef M 189#undef M
195 190
196static __init u32 build_rs(u32 arg) 191static u32 __init build_rs(u32 arg)
197{ 192{
198 if (arg & ~RS_MASK) 193 if (arg & ~RS_MASK)
199 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 194 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -201,7 +196,7 @@ static __init u32 build_rs(u32 arg)
201 return (arg & RS_MASK) << RS_SH; 196 return (arg & RS_MASK) << RS_SH;
202} 197}
203 198
204static __init u32 build_rt(u32 arg) 199static u32 __init build_rt(u32 arg)
205{ 200{
206 if (arg & ~RT_MASK) 201 if (arg & ~RT_MASK)
207 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 202 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -209,7 +204,7 @@ static __init u32 build_rt(u32 arg)
209 return (arg & RT_MASK) << RT_SH; 204 return (arg & RT_MASK) << RT_SH;
210} 205}
211 206
212static __init u32 build_rd(u32 arg) 207static u32 __init build_rd(u32 arg)
213{ 208{
214 if (arg & ~RD_MASK) 209 if (arg & ~RD_MASK)
215 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 210 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -217,7 +212,7 @@ static __init u32 build_rd(u32 arg)
217 return (arg & RD_MASK) << RD_SH; 212 return (arg & RD_MASK) << RD_SH;
218} 213}
219 214
220static __init u32 build_re(u32 arg) 215static u32 __init build_re(u32 arg)
221{ 216{
222 if (arg & ~RE_MASK) 217 if (arg & ~RE_MASK)
223 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 218 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -225,7 +220,7 @@ static __init u32 build_re(u32 arg)
225 return (arg & RE_MASK) << RE_SH; 220 return (arg & RE_MASK) << RE_SH;
226} 221}
227 222
228static __init u32 build_simm(s32 arg) 223static u32 __init build_simm(s32 arg)
229{ 224{
230 if (arg > 0x7fff || arg < -0x8000) 225 if (arg > 0x7fff || arg < -0x8000)
231 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 226 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -233,7 +228,7 @@ static __init u32 build_simm(s32 arg)
233 return arg & 0xffff; 228 return arg & 0xffff;
234} 229}
235 230
236static __init u32 build_uimm(u32 arg) 231static u32 __init build_uimm(u32 arg)
237{ 232{
238 if (arg & ~IMM_MASK) 233 if (arg & ~IMM_MASK)
239 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 234 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -241,7 +236,7 @@ static __init u32 build_uimm(u32 arg)
241 return arg & IMM_MASK; 236 return arg & IMM_MASK;
242} 237}
243 238
244static __init u32 build_bimm(s32 arg) 239static u32 __init build_bimm(s32 arg)
245{ 240{
246 if (arg > 0x1ffff || arg < -0x20000) 241 if (arg > 0x1ffff || arg < -0x20000)
247 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 242 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -252,7 +247,7 @@ static __init u32 build_bimm(s32 arg)
252 return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); 247 return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
253} 248}
254 249
255static __init u32 build_jimm(u32 arg) 250static u32 __init build_jimm(u32 arg)
256{ 251{
257 if (arg & ~((JIMM_MASK) << 2)) 252 if (arg & ~((JIMM_MASK) << 2))
258 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 253 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -260,7 +255,7 @@ static __init u32 build_jimm(u32 arg)
260 return (arg >> 2) & JIMM_MASK; 255 return (arg >> 2) & JIMM_MASK;
261} 256}
262 257
263static __init u32 build_func(u32 arg) 258static u32 __init build_func(u32 arg)
264{ 259{
265 if (arg & ~FUNC_MASK) 260 if (arg & ~FUNC_MASK)
266 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 261 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -268,7 +263,7 @@ static __init u32 build_func(u32 arg)
268 return arg & FUNC_MASK; 263 return arg & FUNC_MASK;
269} 264}
270 265
271static __init u32 build_set(u32 arg) 266static u32 __init build_set(u32 arg)
272{ 267{
273 if (arg & ~SET_MASK) 268 if (arg & ~SET_MASK)
274 printk(KERN_WARNING "TLB synthesizer field overflow\n"); 269 printk(KERN_WARNING "TLB synthesizer field overflow\n");
@@ -293,7 +288,7 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...)
293 break; 288 break;
294 } 289 }
295 290
296 if (!ip) 291 if (!ip || (opc == insn_daddiu && r4k_daddiu_bug()))
297 panic("Unsupported TLB synthesizer instruction %d", opc); 292 panic("Unsupported TLB synthesizer instruction %d", opc);
298 293
299 op = ip->match; 294 op = ip->match;
@@ -315,69 +310,69 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...)
315} 310}
316 311
317#define I_u1u2u3(op) \ 312#define I_u1u2u3(op) \
318 static inline void __init i##op(u32 **buf, unsigned int a, \ 313 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
319 unsigned int b, unsigned int c) \ 314 unsigned int b, unsigned int c) \
320 { \ 315 { \
321 build_insn(buf, insn##op, a, b, c); \ 316 build_insn(buf, insn##op, a, b, c); \
322 } 317 }
323 318
324#define I_u2u1u3(op) \ 319#define I_u2u1u3(op) \
325 static inline void __init i##op(u32 **buf, unsigned int a, \ 320 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
326 unsigned int b, unsigned int c) \ 321 unsigned int b, unsigned int c) \
327 { \ 322 { \
328 build_insn(buf, insn##op, b, a, c); \ 323 build_insn(buf, insn##op, b, a, c); \
329 } 324 }
330 325
331#define I_u3u1u2(op) \ 326#define I_u3u1u2(op) \
332 static inline void __init i##op(u32 **buf, unsigned int a, \ 327 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
333 unsigned int b, unsigned int c) \ 328 unsigned int b, unsigned int c) \
334 { \ 329 { \
335 build_insn(buf, insn##op, b, c, a); \ 330 build_insn(buf, insn##op, b, c, a); \
336 } 331 }
337 332
338#define I_u1u2s3(op) \ 333#define I_u1u2s3(op) \
339 static inline void __init i##op(u32 **buf, unsigned int a, \ 334 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
340 unsigned int b, signed int c) \ 335 unsigned int b, signed int c) \
341 { \ 336 { \
342 build_insn(buf, insn##op, a, b, c); \ 337 build_insn(buf, insn##op, a, b, c); \
343 } 338 }
344 339
345#define I_u2s3u1(op) \ 340#define I_u2s3u1(op) \
346 static inline void __init i##op(u32 **buf, unsigned int a, \ 341 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
347 signed int b, unsigned int c) \ 342 signed int b, unsigned int c) \
348 { \ 343 { \
349 build_insn(buf, insn##op, c, a, b); \ 344 build_insn(buf, insn##op, c, a, b); \
350 } 345 }
351 346
352#define I_u2u1s3(op) \ 347#define I_u2u1s3(op) \
353 static inline void __init i##op(u32 **buf, unsigned int a, \ 348 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
354 unsigned int b, signed int c) \ 349 unsigned int b, signed int c) \
355 { \ 350 { \
356 build_insn(buf, insn##op, b, a, c); \ 351 build_insn(buf, insn##op, b, a, c); \
357 } 352 }
358 353
359#define I_u1u2(op) \ 354#define I_u1u2(op) \
360 static inline void __init i##op(u32 **buf, unsigned int a, \ 355 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
361 unsigned int b) \ 356 unsigned int b) \
362 { \ 357 { \
363 build_insn(buf, insn##op, a, b); \ 358 build_insn(buf, insn##op, a, b); \
364 } 359 }
365 360
366#define I_u1s2(op) \ 361#define I_u1s2(op) \
367 static inline void __init i##op(u32 **buf, unsigned int a, \ 362 static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
368 signed int b) \ 363 signed int b) \
369 { \ 364 { \
370 build_insn(buf, insn##op, a, b); \ 365 build_insn(buf, insn##op, a, b); \
371 } 366 }
372 367
373#define I_u1(op) \ 368#define I_u1(op) \
374 static inline void __init i##op(u32 **buf, unsigned int a) \ 369 static void __init __maybe_unused i##op(u32 **buf, unsigned int a) \
375 { \ 370 { \
376 build_insn(buf, insn##op, a); \ 371 build_insn(buf, insn##op, a); \
377 } 372 }
378 373
379#define I_0(op) \ 374#define I_0(op) \
380 static inline void __init i##op(u32 **buf) \ 375 static void __init __maybe_unused i##op(u32 **buf) \
381 { \ 376 { \
382 build_insn(buf, insn##op); \ 377 build_insn(buf, insn##op); \
383 } 378 }
@@ -457,7 +452,7 @@ struct label {
457 enum label_id lab; 452 enum label_id lab;
458}; 453};
459 454
460static __init void build_label(struct label **lab, u32 *addr, 455static void __init build_label(struct label **lab, u32 *addr,
461 enum label_id l) 456 enum label_id l)
462{ 457{
463 (*lab)->addr = addr; 458 (*lab)->addr = addr;
@@ -466,7 +461,7 @@ static __init void build_label(struct label **lab, u32 *addr,
466} 461}
467 462
468#define L_LA(lb) \ 463#define L_LA(lb) \
469 static inline void l##lb(struct label **lab, u32 *addr) \ 464 static inline void __init l##lb(struct label **lab, u32 *addr) \
470 { \ 465 { \
471 build_label(lab, addr, label##lb); \ 466 build_label(lab, addr, label##lb); \
472 } 467 }
@@ -525,37 +520,46 @@ L_LA(_r3000_write_probe_fail)
525#define i_ssnop(buf) i_sll(buf, 0, 0, 1) 520#define i_ssnop(buf) i_sll(buf, 0, 0, 1)
526#define i_ehb(buf) i_sll(buf, 0, 0, 3) 521#define i_ehb(buf) i_sll(buf, 0, 0, 3)
527 522
528#ifdef CONFIG_64BIT 523static int __init __maybe_unused in_compat_space_p(long addr)
529static __init int __maybe_unused in_compat_space_p(long addr)
530{ 524{
531 /* Is this address in 32bit compat space? */ 525 /* Is this address in 32bit compat space? */
526#ifdef CONFIG_64BIT
532 return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L); 527 return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
528#else
529 return 1;
530#endif
533} 531}
534 532
535static __init int __maybe_unused rel_highest(long val) 533static int __init __maybe_unused rel_highest(long val)
536{ 534{
535#ifdef CONFIG_64BIT
537 return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; 536 return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
537#else
538 return 0;
539#endif
538} 540}
539 541
540static __init int __maybe_unused rel_higher(long val) 542static int __init __maybe_unused rel_higher(long val)
541{ 543{
544#ifdef CONFIG_64BIT
542 return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; 545 return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
543} 546#else
547 return 0;
544#endif 548#endif
549}
545 550
546static __init int rel_hi(long val) 551static int __init rel_hi(long val)
547{ 552{
548 return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; 553 return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
549} 554}
550 555
551static __init int rel_lo(long val) 556static int __init rel_lo(long val)
552{ 557{
553 return ((val & 0xffff) ^ 0x8000) - 0x8000; 558 return ((val & 0xffff) ^ 0x8000) - 0x8000;
554} 559}
555 560
556static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr) 561static void __init i_LA_mostly(u32 **buf, unsigned int rs, long addr)
557{ 562{
558#ifdef CONFIG_64BIT
559 if (!in_compat_space_p(addr)) { 563 if (!in_compat_space_p(addr)) {
560 i_lui(buf, rs, rel_highest(addr)); 564 i_lui(buf, rs, rel_highest(addr));
561 if (rel_higher(addr)) 565 if (rel_higher(addr))
@@ -567,16 +571,18 @@ static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr)
567 } else 571 } else
568 i_dsll32(buf, rs, rs, 0); 572 i_dsll32(buf, rs, rs, 0);
569 } else 573 } else
570#endif
571 i_lui(buf, rs, rel_hi(addr)); 574 i_lui(buf, rs, rel_hi(addr));
572} 575}
573 576
574static __init void __maybe_unused i_LA(u32 **buf, unsigned int rs, 577static void __init __maybe_unused i_LA(u32 **buf, unsigned int rs, long addr)
575 long addr)
576{ 578{
577 i_LA_mostly(buf, rs, addr); 579 i_LA_mostly(buf, rs, addr);
578 if (rel_lo(addr)) 580 if (rel_lo(addr)) {
579 i_ADDIU(buf, rs, rs, rel_lo(addr)); 581 if (!in_compat_space_p(addr))
582 i_daddiu(buf, rs, rs, rel_lo(addr));
583 else
584 i_addiu(buf, rs, rs, rel_lo(addr));
585 }
580} 586}
581 587
582/* 588/*
@@ -589,7 +595,7 @@ struct reloc {
589 enum label_id lab; 595 enum label_id lab;
590}; 596};
591 597
592static __init void r_mips_pc16(struct reloc **rel, u32 *addr, 598static void __init r_mips_pc16(struct reloc **rel, u32 *addr,
593 enum label_id l) 599 enum label_id l)
594{ 600{
595 (*rel)->addr = addr; 601 (*rel)->addr = addr;
@@ -614,7 +620,7 @@ static inline void __resolve_relocs(struct reloc *rel, struct label *lab)
614 } 620 }
615} 621}
616 622
617static __init void resolve_relocs(struct reloc *rel, struct label *lab) 623static void __init resolve_relocs(struct reloc *rel, struct label *lab)
618{ 624{
619 struct label *l; 625 struct label *l;
620 626
@@ -624,7 +630,7 @@ static __init void resolve_relocs(struct reloc *rel, struct label *lab)
624 __resolve_relocs(rel, l); 630 __resolve_relocs(rel, l);
625} 631}
626 632
627static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, 633static void __init move_relocs(struct reloc *rel, u32 *first, u32 *end,
628 long off) 634 long off)
629{ 635{
630 for (; rel->lab != label_invalid; rel++) 636 for (; rel->lab != label_invalid; rel++)
@@ -632,7 +638,7 @@ static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
632 rel->addr += off; 638 rel->addr += off;
633} 639}
634 640
635static __init void move_labels(struct label *lab, u32 *first, u32 *end, 641static void __init move_labels(struct label *lab, u32 *first, u32 *end,
636 long off) 642 long off)
637{ 643{
638 for (; lab->lab != label_invalid; lab++) 644 for (; lab->lab != label_invalid; lab++)
@@ -640,7 +646,7 @@ static __init void move_labels(struct label *lab, u32 *first, u32 *end,
640 lab->addr += off; 646 lab->addr += off;
641} 647}
642 648
643static __init void copy_handler(struct reloc *rel, struct label *lab, 649static void __init copy_handler(struct reloc *rel, struct label *lab,
644 u32 *first, u32 *end, u32 *target) 650 u32 *first, u32 *end, u32 *target)
645{ 651{
646 long off = (long)(target - first); 652 long off = (long)(target - first);
@@ -651,7 +657,7 @@ static __init void copy_handler(struct reloc *rel, struct label *lab,
651 move_labels(lab, first, end, off); 657 move_labels(lab, first, end, off);
652} 658}
653 659
654static __init int __maybe_unused insn_has_bdelay(struct reloc *rel, 660static int __init __maybe_unused insn_has_bdelay(struct reloc *rel,
655 u32 *addr) 661 u32 *addr)
656{ 662{
657 for (; rel->lab != label_invalid; rel++) { 663 for (; rel->lab != label_invalid; rel++) {
@@ -714,6 +720,22 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
714 i_bgez(p, reg, 0); 720 i_bgez(p, reg, 0);
715} 721}
716 722
723/*
724 * For debug purposes.
725 */
726static inline void dump_handler(const u32 *handler, int count)
727{
728 int i;
729
730 pr_debug("\t.set push\n");
731 pr_debug("\t.set noreorder\n");
732
733 for (i = 0; i < count; i++)
734 pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]);
735
736 pr_debug("\t.set pop\n");
737}
738
717/* The only general purpose registers allowed in TLB handlers. */ 739/* The only general purpose registers allowed in TLB handlers. */
718#define K0 26 740#define K0 26
719#define K1 27 741#define K1 27
@@ -743,11 +765,11 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
743 * We deliberately chose a buffer size of 128, so we won't scribble 765 * We deliberately chose a buffer size of 128, so we won't scribble
744 * over anything important on overflow before we panic. 766 * over anything important on overflow before we panic.
745 */ 767 */
746static __initdata u32 tlb_handler[128]; 768static u32 tlb_handler[128] __initdata;
747 769
748/* simply assume worst case size for labels and relocs */ 770/* simply assume worst case size for labels and relocs */
749static __initdata struct label labels[128]; 771static struct label labels[128] __initdata;
750static __initdata struct reloc relocs[128]; 772static struct reloc relocs[128] __initdata;
751 773
752/* 774/*
753 * The R3000 TLB handler is simple. 775 * The R3000 TLB handler is simple.
@@ -756,7 +778,6 @@ static void __init build_r3000_tlb_refill_handler(void)
756{ 778{
757 long pgdc = (long)pgd_current; 779 long pgdc = (long)pgd_current;
758 u32 *p; 780 u32 *p;
759 int i;
760 781
761 memset(tlb_handler, 0, sizeof(tlb_handler)); 782 memset(tlb_handler, 0, sizeof(tlb_handler));
762 p = tlb_handler; 783 p = tlb_handler;
@@ -785,13 +806,9 @@ static void __init build_r3000_tlb_refill_handler(void)
785 pr_info("Synthesized TLB refill handler (%u instructions).\n", 806 pr_info("Synthesized TLB refill handler (%u instructions).\n",
786 (unsigned int)(p - tlb_handler)); 807 (unsigned int)(p - tlb_handler));
787 808
788 pr_debug("\t.set push\n");
789 pr_debug("\t.set noreorder\n");
790 for (i = 0; i < (p - tlb_handler); i++)
791 pr_debug("\t.word 0x%08x\n", tlb_handler[i]);
792 pr_debug("\t.set pop\n");
793
794 memcpy((void *)ebase, tlb_handler, 0x80); 809 memcpy((void *)ebase, tlb_handler, 0x80);
810
811 dump_handler((u32 *)ebase, 32);
795} 812}
796 813
797/* 814/*
@@ -801,7 +818,7 @@ static void __init build_r3000_tlb_refill_handler(void)
801 * other one.To keep things simple, we first assume linear space, 818 * other one.To keep things simple, we first assume linear space,
802 * then we relocate it to the final handler layout as needed. 819 * then we relocate it to the final handler layout as needed.
803 */ 820 */
804static __initdata u32 final_handler[64]; 821static u32 final_handler[64] __initdata;
805 822
806/* 823/*
807 * Hazards 824 * Hazards
@@ -825,7 +842,7 @@ static __initdata u32 final_handler[64];
825 * 842 *
826 * As if we MIPS hackers wouldn't know how to nop pipelines happy ... 843 * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
827 */ 844 */
828static __init void __maybe_unused build_tlb_probe_entry(u32 **p) 845static void __init __maybe_unused build_tlb_probe_entry(u32 **p)
829{ 846{
830 switch (current_cpu_type()) { 847 switch (current_cpu_type()) {
831 /* Found by experiment: R4600 v2.0 needs this, too. */ 848 /* Found by experiment: R4600 v2.0 needs this, too. */
@@ -849,7 +866,7 @@ static __init void __maybe_unused build_tlb_probe_entry(u32 **p)
849 */ 866 */
850enum tlb_write_entry { tlb_random, tlb_indexed }; 867enum tlb_write_entry { tlb_random, tlb_indexed };
851 868
852static __init void build_tlb_write_entry(u32 **p, struct label **l, 869static void __init build_tlb_write_entry(u32 **p, struct label **l,
853 struct reloc **r, 870 struct reloc **r,
854 enum tlb_write_entry wmode) 871 enum tlb_write_entry wmode)
855{ 872{
@@ -860,6 +877,12 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
860 case tlb_indexed: tlbw = i_tlbwi; break; 877 case tlb_indexed: tlbw = i_tlbwi; break;
861 } 878 }
862 879
880 if (cpu_has_mips_r2) {
881 i_ehb(p);
882 tlbw(p);
883 return;
884 }
885
863 switch (current_cpu_type()) { 886 switch (current_cpu_type()) {
864 case CPU_R4000PC: 887 case CPU_R4000PC:
865 case CPU_R4000SC: 888 case CPU_R4000SC:
@@ -894,6 +917,8 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
894 case CPU_AU1500: 917 case CPU_AU1500:
895 case CPU_AU1550: 918 case CPU_AU1550:
896 case CPU_AU1200: 919 case CPU_AU1200:
920 case CPU_AU1210:
921 case CPU_AU1250:
897 case CPU_PR4450: 922 case CPU_PR4450:
898 i_nop(p); 923 i_nop(p);
899 tlbw(p); 924 tlbw(p);
@@ -935,14 +960,6 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
935 tlbw(p); 960 tlbw(p);
936 break; 961 break;
937 962
938 case CPU_4KEC:
939 case CPU_24K:
940 case CPU_34K:
941 case CPU_74K:
942 i_ehb(p);
943 tlbw(p);
944 break;
945
946 case CPU_RM9000: 963 case CPU_RM9000:
947 /* 964 /*
948 * When the JTLB is updated by tlbwi or tlbwr, a subsequent 965 * When the JTLB is updated by tlbwi or tlbwr, a subsequent
@@ -993,7 +1010,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
993 * TMP and PTR are scratch. 1010 * TMP and PTR are scratch.
994 * TMP will be clobbered, PTR will hold the pmd entry. 1011 * TMP will be clobbered, PTR will hold the pmd entry.
995 */ 1012 */
996static __init void 1013static void __init
997build_get_pmde64(u32 **p, struct label **l, struct reloc **r, 1014build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
998 unsigned int tmp, unsigned int ptr) 1015 unsigned int tmp, unsigned int ptr)
999{ 1016{
@@ -1054,7 +1071,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
1054 * BVADDR is the faulting address, PTR is scratch. 1071 * BVADDR is the faulting address, PTR is scratch.
1055 * PTR will hold the pgd for vmalloc. 1072 * PTR will hold the pgd for vmalloc.
1056 */ 1073 */
1057static __init void 1074static void __init
1058build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, 1075build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1059 unsigned int bvaddr, unsigned int ptr) 1076 unsigned int bvaddr, unsigned int ptr)
1060{ 1077{
@@ -1087,7 +1104,10 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1087 } else { 1104 } else {
1088 i_LA_mostly(p, ptr, modd); 1105 i_LA_mostly(p, ptr, modd);
1089 il_b(p, r, label_vmalloc_done); 1106 il_b(p, r, label_vmalloc_done);
1090 i_daddiu(p, ptr, ptr, rel_lo(modd)); 1107 if (in_compat_space_p(modd))
1108 i_addiu(p, ptr, ptr, rel_lo(modd));
1109 else
1110 i_daddiu(p, ptr, ptr, rel_lo(modd));
1091 } 1111 }
1092 1112
1093 l_vmalloc(l, *p); 1113 l_vmalloc(l, *p);
@@ -1108,7 +1128,10 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1108 } else { 1128 } else {
1109 i_LA_mostly(p, ptr, swpd); 1129 i_LA_mostly(p, ptr, swpd);
1110 il_b(p, r, label_vmalloc_done); 1130 il_b(p, r, label_vmalloc_done);
1111 i_daddiu(p, ptr, ptr, rel_lo(swpd)); 1131 if (in_compat_space_p(swpd))
1132 i_addiu(p, ptr, ptr, rel_lo(swpd));
1133 else
1134 i_daddiu(p, ptr, ptr, rel_lo(swpd));
1112 } 1135 }
1113} 1136}
1114 1137
@@ -1118,7 +1141,7 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
1118 * TMP and PTR are scratch. 1141 * TMP and PTR are scratch.
1119 * TMP will be clobbered, PTR will hold the pgd entry. 1142 * TMP will be clobbered, PTR will hold the pgd entry.
1120 */ 1143 */
1121static __init void __maybe_unused 1144static void __init __maybe_unused
1122build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) 1145build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1123{ 1146{
1124 long pgdc = (long)pgd_current; 1147 long pgdc = (long)pgd_current;
@@ -1153,7 +1176,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1153 1176
1154#endif /* !CONFIG_64BIT */ 1177#endif /* !CONFIG_64BIT */
1155 1178
1156static __init void build_adjust_context(u32 **p, unsigned int ctx) 1179static void __init build_adjust_context(u32 **p, unsigned int ctx)
1157{ 1180{
1158 unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; 1181 unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
1159 unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); 1182 unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
@@ -1179,7 +1202,7 @@ static __init void build_adjust_context(u32 **p, unsigned int ctx)
1179 i_andi(p, ctx, ctx, mask); 1202 i_andi(p, ctx, ctx, mask);
1180} 1203}
1181 1204
1182static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) 1205static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
1183{ 1206{
1184 /* 1207 /*
1185 * Bug workaround for the Nevada. It seems as if under certain 1208 * Bug workaround for the Nevada. It seems as if under certain
@@ -1204,7 +1227,7 @@ static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
1204 i_ADDU(p, ptr, ptr, tmp); /* add in offset */ 1227 i_ADDU(p, ptr, ptr, tmp); /* add in offset */
1205} 1228}
1206 1229
1207static __init void build_update_entries(u32 **p, unsigned int tmp, 1230static void __init build_update_entries(u32 **p, unsigned int tmp,
1208 unsigned int ptep) 1231 unsigned int ptep)
1209{ 1232{
1210 /* 1233 /*
@@ -1254,7 +1277,6 @@ static void __init build_r4000_tlb_refill_handler(void)
1254 struct reloc *r = relocs; 1277 struct reloc *r = relocs;
1255 u32 *f; 1278 u32 *f;
1256 unsigned int final_len; 1279 unsigned int final_len;
1257 int i;
1258 1280
1259 memset(tlb_handler, 0, sizeof(tlb_handler)); 1281 memset(tlb_handler, 0, sizeof(tlb_handler));
1260 memset(labels, 0, sizeof(labels)); 1282 memset(labels, 0, sizeof(labels));
@@ -1356,20 +1378,9 @@ static void __init build_r4000_tlb_refill_handler(void)
1356 pr_info("Synthesized TLB refill handler (%u instructions).\n", 1378 pr_info("Synthesized TLB refill handler (%u instructions).\n",
1357 final_len); 1379 final_len);
1358 1380
1359 f = final_handler;
1360#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
1361 if (final_len > 32)
1362 final_len = 64;
1363 else
1364 f = final_handler + 32;
1365#endif /* CONFIG_64BIT */
1366 pr_debug("\t.set push\n");
1367 pr_debug("\t.set noreorder\n");
1368 for (i = 0; i < final_len; i++)
1369 pr_debug("\t.word 0x%08x\n", f[i]);
1370 pr_debug("\t.set pop\n");
1371
1372 memcpy((void *)ebase, final_handler, 0x100); 1381 memcpy((void *)ebase, final_handler, 0x100);
1382
1383 dump_handler((u32 *)ebase, 64);
1373} 1384}
1374 1385
1375/* 1386/*
@@ -1381,18 +1392,15 @@ static void __init build_r4000_tlb_refill_handler(void)
1381extern void tlb_do_page_fault_0(void); 1392extern void tlb_do_page_fault_0(void);
1382extern void tlb_do_page_fault_1(void); 1393extern void tlb_do_page_fault_1(void);
1383 1394
1384#define __tlb_handler_align \
1385 __attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
1386
1387/* 1395/*
1388 * 128 instructions for the fastpath handler is generous and should 1396 * 128 instructions for the fastpath handler is generous and should
1389 * never be exceeded. 1397 * never be exceeded.
1390 */ 1398 */
1391#define FASTPATH_SIZE 128 1399#define FASTPATH_SIZE 128
1392 1400
1393u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE]; 1401u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
1394u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE]; 1402u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
1395u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; 1403u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
1396 1404
1397static void __init 1405static void __init
1398iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr) 1406iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
@@ -1600,7 +1608,6 @@ static void __init build_r3000_tlb_load_handler(void)
1600 u32 *p = handle_tlbl; 1608 u32 *p = handle_tlbl;
1601 struct label *l = labels; 1609 struct label *l = labels;
1602 struct reloc *r = relocs; 1610 struct reloc *r = relocs;
1603 int i;
1604 1611
1605 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1612 memset(handle_tlbl, 0, sizeof(handle_tlbl));
1606 memset(labels, 0, sizeof(labels)); 1613 memset(labels, 0, sizeof(labels));
@@ -1623,11 +1630,7 @@ static void __init build_r3000_tlb_load_handler(void)
1623 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n", 1630 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
1624 (unsigned int)(p - handle_tlbl)); 1631 (unsigned int)(p - handle_tlbl));
1625 1632
1626 pr_debug("\t.set push\n"); 1633 dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
1627 pr_debug("\t.set noreorder\n");
1628 for (i = 0; i < (p - handle_tlbl); i++)
1629 pr_debug("\t.word 0x%08x\n", handle_tlbl[i]);
1630 pr_debug("\t.set pop\n");
1631} 1634}
1632 1635
1633static void __init build_r3000_tlb_store_handler(void) 1636static void __init build_r3000_tlb_store_handler(void)
@@ -1635,7 +1638,6 @@ static void __init build_r3000_tlb_store_handler(void)
1635 u32 *p = handle_tlbs; 1638 u32 *p = handle_tlbs;
1636 struct label *l = labels; 1639 struct label *l = labels;
1637 struct reloc *r = relocs; 1640 struct reloc *r = relocs;
1638 int i;
1639 1641
1640 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 1642 memset(handle_tlbs, 0, sizeof(handle_tlbs));
1641 memset(labels, 0, sizeof(labels)); 1643 memset(labels, 0, sizeof(labels));
@@ -1658,11 +1660,7 @@ static void __init build_r3000_tlb_store_handler(void)
1658 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n", 1660 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
1659 (unsigned int)(p - handle_tlbs)); 1661 (unsigned int)(p - handle_tlbs));
1660 1662
1661 pr_debug("\t.set push\n"); 1663 dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
1662 pr_debug("\t.set noreorder\n");
1663 for (i = 0; i < (p - handle_tlbs); i++)
1664 pr_debug("\t.word 0x%08x\n", handle_tlbs[i]);
1665 pr_debug("\t.set pop\n");
1666} 1664}
1667 1665
1668static void __init build_r3000_tlb_modify_handler(void) 1666static void __init build_r3000_tlb_modify_handler(void)
@@ -1670,7 +1668,6 @@ static void __init build_r3000_tlb_modify_handler(void)
1670 u32 *p = handle_tlbm; 1668 u32 *p = handle_tlbm;
1671 struct label *l = labels; 1669 struct label *l = labels;
1672 struct reloc *r = relocs; 1670 struct reloc *r = relocs;
1673 int i;
1674 1671
1675 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 1672 memset(handle_tlbm, 0, sizeof(handle_tlbm));
1676 memset(labels, 0, sizeof(labels)); 1673 memset(labels, 0, sizeof(labels));
@@ -1693,11 +1690,7 @@ static void __init build_r3000_tlb_modify_handler(void)
1693 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n", 1690 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
1694 (unsigned int)(p - handle_tlbm)); 1691 (unsigned int)(p - handle_tlbm));
1695 1692
1696 pr_debug("\t.set push\n"); 1693 dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
1697 pr_debug("\t.set noreorder\n");
1698 for (i = 0; i < (p - handle_tlbm); i++)
1699 pr_debug("\t.word 0x%08x\n", handle_tlbm[i]);
1700 pr_debug("\t.set pop\n");
1701} 1694}
1702 1695
1703/* 1696/*
@@ -1750,7 +1743,6 @@ static void __init build_r4000_tlb_load_handler(void)
1750 u32 *p = handle_tlbl; 1743 u32 *p = handle_tlbl;
1751 struct label *l = labels; 1744 struct label *l = labels;
1752 struct reloc *r = relocs; 1745 struct reloc *r = relocs;
1753 int i;
1754 1746
1755 memset(handle_tlbl, 0, sizeof(handle_tlbl)); 1747 memset(handle_tlbl, 0, sizeof(handle_tlbl));
1756 memset(labels, 0, sizeof(labels)); 1748 memset(labels, 0, sizeof(labels));
@@ -1783,11 +1775,7 @@ static void __init build_r4000_tlb_load_handler(void)
1783 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n", 1775 pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
1784 (unsigned int)(p - handle_tlbl)); 1776 (unsigned int)(p - handle_tlbl));
1785 1777
1786 pr_debug("\t.set push\n"); 1778 dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
1787 pr_debug("\t.set noreorder\n");
1788 for (i = 0; i < (p - handle_tlbl); i++)
1789 pr_debug("\t.word 0x%08x\n", handle_tlbl[i]);
1790 pr_debug("\t.set pop\n");
1791} 1779}
1792 1780
1793static void __init build_r4000_tlb_store_handler(void) 1781static void __init build_r4000_tlb_store_handler(void)
@@ -1795,7 +1783,6 @@ static void __init build_r4000_tlb_store_handler(void)
1795 u32 *p = handle_tlbs; 1783 u32 *p = handle_tlbs;
1796 struct label *l = labels; 1784 struct label *l = labels;
1797 struct reloc *r = relocs; 1785 struct reloc *r = relocs;
1798 int i;
1799 1786
1800 memset(handle_tlbs, 0, sizeof(handle_tlbs)); 1787 memset(handle_tlbs, 0, sizeof(handle_tlbs));
1801 memset(labels, 0, sizeof(labels)); 1788 memset(labels, 0, sizeof(labels));
@@ -1819,11 +1806,7 @@ static void __init build_r4000_tlb_store_handler(void)
1819 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n", 1806 pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
1820 (unsigned int)(p - handle_tlbs)); 1807 (unsigned int)(p - handle_tlbs));
1821 1808
1822 pr_debug("\t.set push\n"); 1809 dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
1823 pr_debug("\t.set noreorder\n");
1824 for (i = 0; i < (p - handle_tlbs); i++)
1825 pr_debug("\t.word 0x%08x\n", handle_tlbs[i]);
1826 pr_debug("\t.set pop\n");
1827} 1810}
1828 1811
1829static void __init build_r4000_tlb_modify_handler(void) 1812static void __init build_r4000_tlb_modify_handler(void)
@@ -1831,7 +1814,6 @@ static void __init build_r4000_tlb_modify_handler(void)
1831 u32 *p = handle_tlbm; 1814 u32 *p = handle_tlbm;
1832 struct label *l = labels; 1815 struct label *l = labels;
1833 struct reloc *r = relocs; 1816 struct reloc *r = relocs;
1834 int i;
1835 1817
1836 memset(handle_tlbm, 0, sizeof(handle_tlbm)); 1818 memset(handle_tlbm, 0, sizeof(handle_tlbm));
1837 memset(labels, 0, sizeof(labels)); 1819 memset(labels, 0, sizeof(labels));
@@ -1856,11 +1838,7 @@ static void __init build_r4000_tlb_modify_handler(void)
1856 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n", 1838 pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
1857 (unsigned int)(p - handle_tlbm)); 1839 (unsigned int)(p - handle_tlbm));
1858 1840
1859 pr_debug("\t.set push\n"); 1841 dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
1860 pr_debug("\t.set noreorder\n");
1861 for (i = 0; i < (p - handle_tlbm); i++)
1862 pr_debug("\t.word 0x%08x\n", handle_tlbm[i]);
1863 pr_debug("\t.set pop\n");
1864} 1842}
1865 1843
1866void __init build_tlb_refill_handler(void) 1844void __init build_tlb_refill_handler(void)
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index bdfa07aecd97..ccbea229a0e6 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -19,7 +19,7 @@
19#define M_PERFCTL_SUPERVISOR (1UL << 2) 19#define M_PERFCTL_SUPERVISOR (1UL << 2)
20#define M_PERFCTL_USER (1UL << 3) 20#define M_PERFCTL_USER (1UL << 3)
21#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) 21#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
22#define M_PERFCTL_EVENT(event) (((event) & 0x3f) << 5) 22#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
23#define M_PERFCTL_VPEID(vpe) ((vpe) << 16) 23#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
24#define M_PERFCTL_MT_EN(filter) ((filter) << 20) 24#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
25#define M_TC_EN_ALL M_PERFCTL_MT_EN(0) 25#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index 47f316c86ab1..30ed36125bcd 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -178,8 +178,8 @@ struct pci_ops bcm1480_pci_ops = {
178 178
179static struct resource bcm1480_mem_resource = { 179static struct resource bcm1480_mem_resource = {
180 .name = "BCM1480 PCI MEM", 180 .name = "BCM1480 PCI MEM",
181 .start = 0x30000000UL, 181 .start = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES,
182 .end = 0x3fffffffUL, 182 .end = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES + 0xfffffffUL,
183 .flags = IORESOURCE_MEM, 183 .flags = IORESOURCE_MEM,
184}; 184};
185 185
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
index a63e3bd6b0ac..005e7fecab08 100644
--- a/arch/mips/pci/pci-bcm1480ht.c
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -173,8 +173,8 @@ struct pci_ops bcm1480ht_pci_ops = {
173 173
174static struct resource bcm1480ht_mem_resource = { 174static struct resource bcm1480ht_mem_resource = {
175 .name = "BCM1480 HT MEM", 175 .name = "BCM1480 HT MEM",
176 .start = 0x40000000UL, 176 .start = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES,
177 .end = 0x5fffffffUL, 177 .end = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES + 0x1fffffffUL,
178 .flags = IORESOURCE_MEM, 178 .flags = IORESOURCE_MEM,
179}; 179};
180 180
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c
index 2ce298f4d19a..92d764c97701 100644
--- a/arch/mips/philips/pnx8550/common/setup.c
+++ b/arch/mips/philips/pnx8550/common/setup.c
@@ -74,7 +74,7 @@ struct resource standard_io_resources[] = {
74 }, 74 },
75}; 75};
76 76
77#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) 77#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
78 78
79extern struct resource pci_io_resource; 79extern struct resource pci_io_resource;
80extern struct resource pci_mem_resource; 80extern struct resource pci_mem_resource;
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
index 6d494e0de3d9..62f495b57f93 100644
--- a/arch/mips/philips/pnx8550/common/time.c
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -47,11 +47,6 @@ static struct clocksource pnx_clocksource = {
47 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 47 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
48}; 48};
49 49
50static void timer_ack(void)
51{
52 write_c0_compare(cpj);
53}
54
55static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id) 50static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
56{ 51{
57 struct clock_event_device *c = dev_id; 52 struct clock_event_device *c = dev_id;
@@ -94,30 +89,22 @@ static struct clock_event_device pnx8xxx_clockevent = {
94 .set_next_event = pnx8xxx_set_next_event, 89 .set_next_event = pnx8xxx_set_next_event,
95}; 90};
96 91
97/* 92static inline void timer_ack(void)
98 * plat_time_init() - it does the following things: 93{
99 * 94 write_c0_compare(cpj);
100 * 1) plat_time_init() - 95}
101 * a) (optional) set up RTC routines,
102 * b) (optional) calibrate and set the mips_hpt_frequency
103 * (only needed if you intended to use cpu counter as timer interrupt
104 * source)
105 */
106 96
107__init void plat_time_init(void) 97__init void plat_time_init(void)
108{ 98{
109 unsigned int configPR; 99 unsigned int configPR;
110 unsigned int n; 100 unsigned int n;
111 unsigned int m; 101 unsigned int m;
112 unsigned int p; 102 unsigned int p;
113 unsigned int pow2p; 103 unsigned int pow2p;
114 104
115 clockevents_register_device(&pnx8xxx_clockevent); 105 clockevents_register_device(&pnx8xxx_clockevent);
116 clocksource_register(&pnx_clocksource); 106 clocksource_register(&pnx_clocksource);
117 107
118 setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq);
119 setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
120
121 /* Timer 1 start */ 108 /* Timer 1 start */
122 configPR = read_c0_config7(); 109 configPR = read_c0_config7();
123 configPR &= ~0x00000008; 110 configPR &= ~0x00000008;
@@ -158,6 +145,6 @@ __init void plat_time_init(void)
158 write_c0_count2(0); 145 write_c0_count2(0);
159 write_c0_compare2(0xffffffff); 146 write_c0_compare2(0xffffffff);
160 147
148 setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq);
149 setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
161} 150}
162
163
diff --git a/arch/mips/philips/pnx8550/jbs/init.c b/arch/mips/philips/pnx8550/jbs/init.c
index cfd90fa3d799..90b4d35f3ece 100644
--- a/arch/mips/philips/pnx8550/jbs/init.c
+++ b/arch/mips/philips/pnx8550/jbs/init.c
@@ -45,11 +45,8 @@ const char *get_system_type(void)
45 45
46void __init prom_init(void) 46void __init prom_init(void)
47{ 47{
48
49 unsigned long memsize; 48 unsigned long memsize;
50 49
51 mips_machtype = MACH_PHILIPS_JBS;
52
53 //memsize = 0x02800000; /* Trimedia uses memory above */ 50 //memsize = 0x02800000; /* Trimedia uses memory above */
54 memsize = 0x08000000; /* Trimedia uses memory above */ 51 memsize = 0x08000000; /* Trimedia uses memory above */
55 add_memory_region(0, memsize, BOOT_MEM_RAM); 52 add_memory_region(0, memsize, BOOT_MEM_RAM);
diff --git a/arch/mips/philips/pnx8550/stb810/prom_init.c b/arch/mips/philips/pnx8550/stb810/prom_init.c
index fdb33ed089b9..832dd60b0a7a 100644
--- a/arch/mips/philips/pnx8550/stb810/prom_init.c
+++ b/arch/mips/philips/pnx8550/stb810/prom_init.c
@@ -41,8 +41,6 @@ void __init prom_init(void)
41 41
42 prom_init_cmdline(); 42 prom_init_cmdline();
43 43
44 mips_machtype = MACH_PHILIPS_STB810;
45
46 memsize = 0x08000000; /* Trimedia uses memory above */ 44 memsize = 0x08000000; /* Trimedia uses memory above */
47 add_memory_region(0, memsize, BOOT_MEM_RAM); 45 add_memory_region(0, memsize, BOOT_MEM_RAM);
48} 46}
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
deleted file mode 100644
index 31c5523276fa..000000000000
--- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
3 *
4 * Copyright (C) 2003 PMC-Sierra Inc.
5 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef __I2C_YOSEMITE_H
29#define __I2C_YOSEMITE_H
30
31/* Read and Write operations to the chip */
32
33#define TITAN_I2C_BASE 0xbb000000 /* XXX Needs to change */
34
35#define TITAN_I2C_WRITE(offset, data) \
36 *(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data
37
38#define TITAN_I2C_READ(offset) *(volatile unsigned long *)(TITAN_I2C_BASE + offset)
39
40
41/* Local constansts*/
42#define TITAN_I2C_MAX_FILTER 15
43#define TITAN_I2C_MAX_CLK 1023
44#define TITAN_I2C_MAX_ARBF 15
45#define TITAN_I2C_MAX_NAK 15
46#define TITAN_I2C_MAX_MASTERCODE 7
47#define TITAN_I2C_MAX_WORDS_PER_RW 4
48#define TITAN_I2C_MAX_POLL 100
49
50/* Registers used for I2C work */
51#define TITAN_I2C_SCMB_CONTROL 0x0180 /* SCMB Control */
52#define TITAN_I2C_SCMB_CLOCK_A 0x0184 /* SCMB Clock A */
53#define TITAN_I2C_SCMB_CLOCK_B 0x0188 /* SCMB Clock B */
54#define TITAN_I2C_CONFIG 0x01A0 /* I2C Config */
55#define TITAN_I2C_COMMAND 0x01A4 /* I2C Command */
56#define TITAN_I2C_SLAVE_ADDRESS 0x01A8 /* I2C Slave Address */
57#define TITAN_I2C_DATA 0x01AC /* I2C Data [15:0] */
58#define TITAN_I2C_INTERRUPTS 0x01BC /* I2C Interrupts */
59
60/* Error */
61#define TITAN_I2C_ERR_ARB_LOST (-9220)
62#define TITAN_I2C_ERR_NO_RESP (-9221)
63#define TITAN_I2C_ERR_DATA_COLLISION (-9222)
64#define TITAN_I2C_ERR_TIMEOUT (-9223)
65#define TITAN_I2C_ERR_OK 0
66
67/* I2C Command Type */
68typedef enum {
69 TITAN_I2C_CMD_WRITE = 0,
70 TITAN_I2C_CMD_READ = 1,
71 TITAN_I2C_CMD_READ_WRITE = 2
72} titan_i2c_cmd_type;
73
74/* I2C structures */
75typedef struct {
76 int filtera; /* Register 0x0184, bits 15 - 12 */
77 int clka; /* Register 0x0184, bits 9 - 0 */
78 int filterb; /* Register 0x0188, bits 15 - 12 */
79 int clkb; /* Register 0x0188, bits 9 - 0 */
80} titan_i2c_config;
81
82/* I2C command type */
83typedef struct {
84 titan_i2c_cmd_type type; /* Type of command */
85 int num_arb; /* Register 0x01a0, bits 15 - 12 */
86 int num_nak; /* Register 0x01a0, bits 11 - 8 */
87 int addr_size; /* Register 0x01a0, bit 7 */
88 int mst_code; /* Register 0x01a0, bits 6 - 4 */
89 int arb_en; /* Register 0x01a0, bit 1 */
90 int speed; /* Register 0x01a0, bit 0 */
91 int slave_addr; /* Register 0x01a8 */
92 int write_size; /* Register 0x01a4, bits 10 - 8 */
93 unsigned int *data; /* Register 0x01ac */
94} titan_i2c_command;
95
96#endif /* __I2C_YOSEMITE_H */
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
index 9b9936de6589..35dc435846a6 100644
--- a/arch/mips/pmc-sierra/yosemite/prom.c
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -19,6 +19,7 @@
19#include <asm/pgtable.h> 19#include <asm/pgtable.h>
20#include <asm/processor.h> 20#include <asm/processor.h>
21#include <asm/reboot.h> 21#include <asm/reboot.h>
22#include <asm/smp-ops.h>
22#include <asm/system.h> 23#include <asm/system.h>
23#include <asm/bootinfo.h> 24#include <asm/bootinfo.h>
24#include <asm/pmon.h> 25#include <asm/pmon.h>
@@ -78,6 +79,8 @@ static void prom_halt(void)
78 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); 79 __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
79} 80}
80 81
82extern struct plat_smp_ops yos_smp_ops;
83
81/* 84/*
82 * Init routine which accepts the variables from PMON 85 * Init routine which accepts the variables from PMON
83 */ 86 */
@@ -126,9 +129,9 @@ void __init prom_init(void)
126 env++; 129 env++;
127 } 130 }
128 131
129 mips_machtype = MACH_TITAN_YOSEMITE;
130
131 prom_grab_secondary(); 132 prom_grab_secondary();
133
134 register_smp_ops(&yos_smp_ops);
132} 135}
133 136
134void __init prom_free_prom_memory(void) 137void __init prom_free_prom_memory(void)
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index b0f12cd2968a..653f3ec61cab 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -42,70 +42,6 @@ void __init prom_grab_secondary(void)
42 launchstack + LAUNCHSTACK_SIZE, 0); 42 launchstack + LAUNCHSTACK_SIZE, 0);
43} 43}
44 44
45/*
46 * Detect available CPUs, populate phys_cpu_present_map before smp_init
47 *
48 * We don't want to start the secondary CPU yet nor do we have a nice probing
49 * feature in PMON so we just assume presence of the secondary core.
50 */
51void __init plat_smp_setup(void)
52{
53 int i;
54
55 cpus_clear(phys_cpu_present_map);
56
57 for (i = 0; i < 2; i++) {
58 cpu_set(i, phys_cpu_present_map);
59 __cpu_number_map[i] = i;
60 __cpu_logical_map[i] = i;
61 }
62}
63
64void __init plat_prepare_cpus(unsigned int max_cpus)
65{
66 /*
67 * Be paranoid. Enable the IPI only if we're really about to go SMP.
68 */
69 if (cpus_weight(cpu_possible_map))
70 set_c0_status(STATUSF_IP5);
71}
72
73/*
74 * Firmware CPU startup hook
75 * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
76 * It launches the next * available CPU and copies some information on the
77 * stack so the first thing we do is throw away that stuff and load useful
78 * values into the registers ...
79 */
80void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
81{
82 unsigned long gp = (unsigned long) task_thread_info(idle);
83 unsigned long sp = __KSTK_TOS(idle);
84
85 secondary_sp = sp;
86 secondary_gp = gp;
87
88 spin_unlock(&launch_lock);
89}
90
91/* Hook for after all CPUs are online */
92void prom_cpus_done(void)
93{
94}
95
96/*
97 * After we've done initial boot, this function is called to allow the
98 * board code to clean up state, if needed
99 */
100void __cpuinit prom_init_secondary(void)
101{
102 set_c0_status(ST0_CO | ST0_IE | ST0_IM);
103}
104
105void __cpuinit prom_smp_finish(void)
106{
107}
108
109void titan_mailbox_irq(void) 45void titan_mailbox_irq(void)
110{ 46{
111 int cpu = smp_processor_id(); 47 int cpu = smp_processor_id();
@@ -133,7 +69,7 @@ void titan_mailbox_irq(void)
133/* 69/*
134 * Send inter-processor interrupt 70 * Send inter-processor interrupt
135 */ 71 */
136void core_send_ipi(int cpu, unsigned int action) 72static void yos_send_ipi_single(int cpu, unsigned int action)
137{ 73{
138 /* 74 /*
139 * Generate an INTMSG so that it can be sent over to the 75 * Generate an INTMSG so that it can be sent over to the
@@ -159,3 +95,86 @@ void core_send_ipi(int cpu, unsigned int action)
159 break; 95 break;
160 } 96 }
161} 97}
98
99static void yos_send_ipi_mask(cpumask_t mask, unsigned int action)
100{
101 unsigned int i;
102
103 for_each_cpu_mask(i, mask)
104 yos_send_ipi_single(i, action);
105}
106
107/*
108 * After we've done initial boot, this function is called to allow the
109 * board code to clean up state, if needed
110 */
111static void __cpuinit yos_init_secondary(void)
112{
113 set_c0_status(ST0_CO | ST0_IE | ST0_IM);
114}
115
116static void __cpuinit yos_smp_finish(void)
117{
118}
119
120/* Hook for after all CPUs are online */
121static void yos_cpus_done(void)
122{
123}
124
125/*
126 * Firmware CPU startup hook
127 * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
128 * It launches the next * available CPU and copies some information on the
129 * stack so the first thing we do is throw away that stuff and load useful
130 * values into the registers ...
131 */
132static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)
133{
134 unsigned long gp = (unsigned long) task_thread_info(idle);
135 unsigned long sp = __KSTK_TOS(idle);
136
137 secondary_sp = sp;
138 secondary_gp = gp;
139
140 spin_unlock(&launch_lock);
141}
142
143/*
144 * Detect available CPUs, populate phys_cpu_present_map before smp_init
145 *
146 * We don't want to start the secondary CPU yet nor do we have a nice probing
147 * feature in PMON so we just assume presence of the secondary core.
148 */
149static void __init yos_smp_setup(void)
150{
151 int i;
152
153 cpus_clear(phys_cpu_present_map);
154
155 for (i = 0; i < 2; i++) {
156 cpu_set(i, phys_cpu_present_map);
157 __cpu_number_map[i] = i;
158 __cpu_logical_map[i] = i;
159 }
160}
161
162static void __init yos_prepare_cpus(unsigned int max_cpus)
163{
164 /*
165 * Be paranoid. Enable the IPI only if we're really about to go SMP.
166 */
167 if (cpus_weight(cpu_possible_map))
168 set_c0_status(STATUSF_IP5);
169}
170
171struct plat_smp_ops yos_smp_ops = {
172 .send_ipi_single = yos_send_ipi_single,
173 .send_ipi_mask = yos_send_ipi_mask,
174 .init_secondary = yos_init_secondary,
175 .smp_finish = yos_smp_finish,
176 .cpus_done = yos_cpus_done,
177 .boot_secondary = yos_boot_secondary,
178 .smp_setup = yos_smp_setup,
179 .prepare_cpus = yos_prepare_cpus,
180};
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
deleted file mode 100644
index 2ba4ef34b4a7..000000000000
--- a/arch/mips/qemu/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Makefile for Qemu specific kernel interface routines under Linux.
3#
4
5obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
6
7obj-$(CONFIG_EARLY_PRINTK) += q-console.o
8obj-$(CONFIG_SMP) += q-smp.o
9
10EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/qemu/q-console.c b/arch/mips/qemu/q-console.c
deleted file mode 100644
index 81101ae5017a..000000000000
--- a/arch/mips/qemu/q-console.c
+++ /dev/null
@@ -1,26 +0,0 @@
1#include <linux/console.h>
2#include <linux/init.h>
3#include <linux/serial_reg.h>
4#include <asm/io.h>
5
6#define PORT(offset) (0x3f8 + (offset))
7
8static inline unsigned int serial_in(int offset)
9{
10 return inb(PORT(offset));
11}
12
13static inline void serial_out(int offset, int value)
14{
15 outb(value, PORT(offset));
16}
17
18int prom_putchar(char c)
19{
20 while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
21 ;
22
23 serial_out(UART_TX, c);
24
25 return 1;
26}
diff --git a/arch/mips/qemu/q-firmware.c b/arch/mips/qemu/q-firmware.c
deleted file mode 100644
index 3ed43f416cd1..000000000000
--- a/arch/mips/qemu/q-firmware.c
+++ /dev/null
@@ -1,24 +0,0 @@
1#include <linux/init.h>
2#include <linux/string.h>
3#include <asm/addrspace.h>
4#include <asm/bootinfo.h>
5#include <asm/io.h>
6
7#define QEMU_PORT_BASE 0xb4000000
8
9void __init prom_init(void)
10{
11 int *cmdline;
12
13 cmdline = (int *) (CKSEG0 + (0x10 << 20) - 260);
14 if (*cmdline == 0x12345678) {
15 if (*(char *)(cmdline + 1))
16 strcpy(arcs_cmdline, (char *)(cmdline + 1));
17 add_memory_region(0x0<<20, cmdline[-1], BOOT_MEM_RAM);
18 } else {
19 add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
20 }
21
22
23 set_io_port_base(QEMU_PORT_BASE);
24}
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c
deleted file mode 100644
index 7df36dbe65c7..000000000000
--- a/arch/mips/qemu/q-irq.c
+++ /dev/null
@@ -1,37 +0,0 @@
1#include <linux/init.h>
2#include <linux/interrupt.h>
3#include <linux/linkage.h>
4
5#include <asm/i8259.h>
6#include <asm/irq_cpu.h>
7#include <asm/mipsregs.h>
8#include <asm/qemu.h>
9#include <asm/system.h>
10#include <asm/time.h>
11
12asmlinkage void plat_irq_dispatch(void)
13{
14 unsigned int pending = read_c0_status() & read_c0_cause();
15
16 if (pending & 0x8000) {
17 do_IRQ(Q_COUNT_COMPARE_IRQ);
18 return;
19 }
20 if (pending & 0x0400) {
21 int irq = i8259_irq();
22
23 if (likely(irq >= 0))
24 do_IRQ(irq);
25
26 return;
27 }
28}
29
30void __init arch_init_irq(void)
31{
32 mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
33
34 mips_cpu_irq_init();
35 init_i8259_irqs();
36 set_c0_status(0x400);
37}
diff --git a/arch/mips/qemu/q-mem.c b/arch/mips/qemu/q-mem.c
deleted file mode 100644
index dae39b59de15..000000000000
--- a/arch/mips/qemu/q-mem.c
+++ /dev/null
@@ -1,5 +0,0 @@
1#include <linux/init.h>
2
3void __init prom_free_prom_memory(void)
4{
5}
diff --git a/arch/mips/qemu/q-reset.c b/arch/mips/qemu/q-reset.c
deleted file mode 100644
index dbbe44ad7e89..000000000000
--- a/arch/mips/qemu/q-reset.c
+++ /dev/null
@@ -1,33 +0,0 @@
1
2#include <asm/io.h>
3#include <asm/reboot.h>
4#include <asm/cacheflush.h>
5#include <asm/qemu.h>
6
7static void qemu_machine_restart(char *command)
8{
9 volatile unsigned int *reg = (unsigned int *)QEMU_RESTART_REG;
10
11 set_c0_status(ST0_BEV | ST0_ERL);
12 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
13 flush_cache_all();
14 write_c0_wired(0);
15 *reg = 42;
16 while (1)
17 cpu_wait();
18}
19
20static void qemu_machine_halt(void)
21{
22 volatile unsigned int *reg = (unsigned int *)QEMU_HALT_REG;
23
24 *reg = 42;
25 while (1)
26 cpu_wait();
27}
28
29void qemu_reboot_setup(void)
30{
31 _machine_restart = qemu_machine_restart;
32 _machine_halt = qemu_machine_halt;
33}
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
deleted file mode 100644
index 969cedc8d8b9..000000000000
--- a/arch/mips/qemu/q-setup.c
+++ /dev/null
@@ -1,22 +0,0 @@
1#include <linux/init.h>
2
3#include <asm/i8253.h>
4#include <asm/io.h>
5#include <asm/time.h>
6
7extern void qemu_reboot_setup(void);
8
9const char *get_system_type(void)
10{
11 return "Qemu";
12}
13
14void __init plat_time_init(void)
15{
16 setup_pit_timer();
17}
18
19void __init plat_mem_setup(void)
20{
21 qemu_reboot_setup();
22}
diff --git a/arch/mips/qemu/q-smp.c b/arch/mips/qemu/q-smp.c
deleted file mode 100644
index 4b0178d0df0b..000000000000
--- a/arch/mips/qemu/q-smp.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
7 *
8 * Symmetric Uniprocessor (TM) Support
9 */
10#include <linux/kernel.h>
11#include <linux/sched.h>
12
13/*
14 * Send inter-processor interrupt
15 */
16void core_send_ipi(int cpu, unsigned int action)
17{
18 panic(KERN_ERR "%s called", __FUNCTION__);
19}
20
21/*
22 * After we've done initial boot, this function is called to allow the
23 * board code to clean up state, if needed
24 */
25void __cpuinit prom_init_secondary(void)
26{
27}
28
29void __cpuinit prom_smp_finish(void)
30{
31}
32
33/* Hook for after all CPUs are online */
34void prom_cpus_done(void)
35{
36}
37
38void __init prom_prepare_cpus(unsigned int max_cpus)
39{
40 cpus_clear(phys_cpu_present_map);
41}
42
43/*
44 * Firmware CPU startup hook
45 */
46void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
47{
48}
49
50void __init plat_smp_setup(void)
51{
52}
53void __init plat_prepare_cpus(unsigned int max_cpus)
54{
55}
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index e3acb51b70b5..ef1564e40c8d 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -3,9 +3,11 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ 6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
7 ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o 7 ip22-platform.o ip22-reset.o ip22-setup.o
8 8
9obj-$(CONFIG_SGI_IP22) += ip22-berr.o
10obj-$(CONFIG_SGI_IP28) += ip28-berr.o
9obj-$(CONFIG_EISA) += ip22-eisa.o 11obj-$(CONFIG_EISA) += ip22-eisa.o
10 12
11EXTRA_CFLAGS += -Werror 13# EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index 01a805dcc67c..3f35d6367bec 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 4 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
5 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes 5 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
6 * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) 6 * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
7 * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28
7 */ 8 */
8 9
9#include <linux/init.h> 10#include <linux/init.h>
@@ -137,9 +138,12 @@ void __init sgimc_init(void)
137 /* Step 2: Enable all parity checking in cpu control register 138 /* Step 2: Enable all parity checking in cpu control register
138 * zero. 139 * zero.
139 */ 140 */
141 /* don't touch parity settings for IP28 */
142#ifndef CONFIG_SGI_IP28
140 tmp = sgimc->cpuctrl0; 143 tmp = sgimc->cpuctrl0;
141 tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | 144 tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
142 SGIMC_CCTRL0_R4KNOCHKPARR); 145 SGIMC_CCTRL0_R4KNOCHKPARR);
146#endif
143 sgimc->cpuctrl0 = tmp; 147 sgimc->cpuctrl0 = tmp;
144 148
145 /* Step 3: Setup the MC write buffer depth, this is controlled 149 /* Step 3: Setup the MC write buffer depth, this is controlled
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
new file mode 100644
index 000000000000..30e12e2ec4b5
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -0,0 +1,502 @@
1/*
2 * ip28-berr.c: Bus error handling.
3 *
4 * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
5 * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/seq_file.h>
12
13#include <asm/addrspace.h>
14#include <asm/system.h>
15#include <asm/traps.h>
16#include <asm/branch.h>
17#include <asm/irq_regs.h>
18#include <asm/sgi/mc.h>
19#include <asm/sgi/hpc3.h>
20#include <asm/sgi/ioc.h>
21#include <asm/sgi/ip22.h>
22#include <asm/r4kcache.h>
23#include <asm/uaccess.h>
24#include <asm/bootinfo.h>
25
26static unsigned int count_be_is_fixup;
27static unsigned int count_be_handler;
28static unsigned int count_be_interrupt;
29static int debug_be_interrupt;
30
31static unsigned int cpu_err_stat; /* Status reg for CPU */
32static unsigned int gio_err_stat; /* Status reg for GIO */
33static unsigned int cpu_err_addr; /* Error address reg for CPU */
34static unsigned int gio_err_addr; /* Error address reg for GIO */
35static unsigned int extio_stat;
36static unsigned int hpc3_berr_stat; /* Bus error interrupt status */
37
38struct hpc3_stat {
39 unsigned long addr;
40 unsigned int ctrl;
41 unsigned int cbp;
42 unsigned int ndptr;
43};
44
45static struct {
46 struct hpc3_stat pbdma[8];
47 struct hpc3_stat scsi[2];
48 struct hpc3_stat ethrx, ethtx;
49} hpc3;
50
51static struct {
52 unsigned long err_addr;
53 struct {
54 u32 lo;
55 u32 hi;
56 } tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
57} cache_tags;
58
59static inline void save_cache_tags(unsigned busaddr)
60{
61 unsigned long addr = CAC_BASE | busaddr;
62 int i;
63 cache_tags.err_addr = addr;
64
65 /*
66 * Starting with a bus-address, save secondary cache (indexed by
67 * PA[23..18:7..6]) tags first.
68 */
69 addr &= ~1L;
70#define tag cache_tags.tags[0]
71 cache_op(Index_Load_Tag_S, addr);
72 tag[0].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
73 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
74 cache_op(Index_Load_Tag_S, addr | 1L);
75 tag[1].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
76 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
77#undef tag
78
79 /*
80 * Save all primary data cache (indexed by VA[13:5]) tags which
81 * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
82 * Saving all tags and evaluating them later is easier and safer
83 * than relying on VA[13:12] from the secondary cache tags to pick
84 * matching primary tags here already.
85 */
86 addr &= (0xffL << 56) | ((1 << 12) - 1);
87#define tag cache_tags.tagd[i]
88 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
89 cache_op(Index_Load_Tag_D, addr);
90 tag[0].lo = read_c0_taglo(); /* PA[35:12] */
91 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
92 cache_op(Index_Load_Tag_D, addr | 1L);
93 tag[1].lo = read_c0_taglo(); /* PA[35:12] */
94 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
95 }
96#undef tag
97
98 /*
99 * Save primary instruction cache (indexed by VA[13:6]) tags
100 * the same way.
101 */
102 addr &= (0xffL << 56) | ((1 << 12) - 1);
103#define tag cache_tags.tagi[i]
104 for (i = 0; i < 4; ++i, addr += (1 << 12)) {
105 cache_op(Index_Load_Tag_I, addr);
106 tag[0].lo = read_c0_taglo(); /* PA[35:12] */
107 tag[0].hi = read_c0_taghi(); /* PA[39:36] */
108 cache_op(Index_Load_Tag_I, addr | 1L);
109 tag[1].lo = read_c0_taglo(); /* PA[35:12] */
110 tag[1].hi = read_c0_taghi(); /* PA[39:36] */
111 }
112#undef tag
113}
114
115#define GIO_ERRMASK 0xff00
116#define CPU_ERRMASK 0x3f00
117
118static void save_and_clear_buserr(void)
119{
120 int i;
121
122 /* save status registers */
123 cpu_err_addr = sgimc->cerr;
124 cpu_err_stat = sgimc->cstat;
125 gio_err_addr = sgimc->gerr;
126 gio_err_stat = sgimc->gstat;
127 extio_stat = sgioc->extio;
128 hpc3_berr_stat = hpc3c0->bestat;
129
130 hpc3.scsi[0].addr = (unsigned long)&hpc3c0->scsi_chan0;
131 hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
132 hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr;
133 hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
134
135 hpc3.scsi[1].addr = (unsigned long)&hpc3c0->scsi_chan1;
136 hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
137 hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr;
138 hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
139
140 hpc3.ethrx.addr = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
141 hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
142 hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr;
143 hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
144
145 hpc3.ethtx.addr = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
146 hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
147 hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr;
148 hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
149
150 for (i = 0; i < 8; ++i) {
151 /* HPC3_PDMACTRL_ISACT ? */
152 hpc3.pbdma[i].addr = (unsigned long)&hpc3c0->pbdma[i];
153 hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl;
154 hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr;
155 hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
156 }
157 i = 0;
158 if (gio_err_stat & CPU_ERRMASK)
159 i = gio_err_addr;
160 if (cpu_err_stat & CPU_ERRMASK)
161 i = cpu_err_addr;
162 save_cache_tags(i);
163
164 sgimc->cstat = sgimc->gstat = 0;
165}
166
167static void print_cache_tags(void)
168{
169 u32 scb, scw;
170 int i;
171
172 printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
173
174 /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
175 scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
176
177 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
178 for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
179 if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
180 (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
181 continue;
182 printk(KERN_ERR
183 "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n",
184 cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
185 cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
186 scb | (1 << 12)*i);
187 }
188 scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
189 for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
190 if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
191 (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
192 continue;
193 printk(KERN_ERR
194 "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n",
195 cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
196 cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
197 scb | (1 << 12)*i);
198 }
199 i = read_c0_config();
200 scb = i & (1 << 13) ? 7:6; /* scblksize = 2^[7..6] */
201 scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
202
203 i = ((1 << scw) - 1) & ~((1 << scb) - 1);
204 printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n",
205 cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
206 cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
207 scw-1, scb, i & (unsigned)cache_tags.err_addr);
208}
209
210static inline const char *cause_excode_text(int cause)
211{
212 static const char *txt[32] =
213 { "Interrupt",
214 "TLB modification",
215 "TLB (load or instruction fetch)",
216 "TLB (store)",
217 "Address error (load or instruction fetch)",
218 "Address error (store)",
219 "Bus error (instruction fetch)",
220 "Bus error (data: load or store)",
221 "Syscall",
222 "Breakpoint",
223 "Reserved instruction",
224 "Coprocessor unusable",
225 "Arithmetic Overflow",
226 "Trap",
227 "14",
228 "Floating-Point",
229 "16", "17", "18", "19", "20", "21", "22",
230 "Watch Hi/Lo",
231 "24", "25", "26", "27", "28", "29", "30", "31",
232 };
233 return txt[(cause & 0x7c) >> 2];
234}
235
236static void print_buserr(const struct pt_regs *regs)
237{
238 const int field = 2 * sizeof(unsigned long);
239 int error = 0;
240
241 if (extio_stat & EXTIO_MC_BUSERR) {
242 printk(KERN_ERR "MC Bus Error\n");
243 error |= 1;
244 }
245 if (extio_stat & EXTIO_HPC3_BUSERR) {
246 printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
247 hpc3_berr_stat,
248 (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
249 HPC3_BESTAT_PIDSHIFT,
250 (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
251 hpc3_berr_stat & HPC3_BESTAT_BLMASK);
252 error |= 2;
253 }
254 if (extio_stat & EXTIO_EISA_BUSERR) {
255 printk(KERN_ERR "EISA Bus Error\n");
256 error |= 4;
257 }
258 if (cpu_err_stat & CPU_ERRMASK) {
259 printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
260 cpu_err_stat,
261 cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
262 cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
263 cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
264 cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
265 cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
266 cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
267 cpu_err_addr);
268 error |= 8;
269 }
270 if (gio_err_stat & GIO_ERRMASK) {
271 printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
272 gio_err_stat,
273 gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
274 gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
275 gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
276 gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
277 gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
278 gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
279 gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
280 gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
281 gio_err_addr);
282 error |= 16;
283 }
284 if (!error)
285 printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
286 else {
287 printk(KERN_ERR "CP0: config %08x, "
288 "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
289 "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
290 read_c0_config(),
291 sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
292 sgimc->cmacc, sgimc->gmacc,
293 sgimc->mconfig0, sgimc->mconfig1);
294 print_cache_tags();
295 }
296 printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
297 cause_excode_text(regs->cp0_cause),
298 field, regs->cp0_epc, field, regs->regs[31]);
299}
300
301/*
302 * Check, whether MC's (virtual) DMA address caused the bus error.
303 * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
304 */
305
306static int addr_is_ram(unsigned long addr, unsigned sz)
307{
308 int i;
309
310 for (i = 0; i < boot_mem_map.nr_map; i++) {
311 unsigned long a = boot_mem_map.map[i].addr;
312 if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
313 return 1;
314 }
315 return 0;
316}
317
318static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
319{
320 /* This is likely rather similar to correct code ;-) */
321
322 vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
323
324 /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
325 if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
326 u32 ctl = sgimc->dma_ctrl;
327 if (ctl & 1) {
328 unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
329 /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
330 unsigned long pte = (lo >> 6) << 12; /* PTEBase */
331 pte += 8*((vaddr >> pgsz) & 0x1ff);
332 if (addr_is_ram(pte, 8)) {
333 /*
334 * Note: Since DMA hardware does look up
335 * translation on its own, this PTE *must*
336 * match the TLB/EntryLo-register format !
337 */
338 unsigned long a = *(unsigned long *)
339 PHYS_TO_XKSEG_UNCACHED(pte);
340 a = (a & 0x3f) << 6; /* PFN */
341 a += vaddr & ((1 << pgsz) - 1);
342 return (cpu_err_addr == a);
343 }
344 }
345 }
346 return 0;
347}
348
349static int check_vdma_memaddr(void)
350{
351 if (cpu_err_stat & CPU_ERRMASK) {
352 u32 a = sgimc->maddronly;
353
354 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
355 return (cpu_err_addr == a);
356
357 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
358 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
359 check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
360 check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
361 return 1;
362 }
363 return 0;
364}
365
366static int check_vdma_gioaddr(void)
367{
368 if (gio_err_stat & GIO_ERRMASK) {
369 u32 a = sgimc->gio_dma_trans;
370 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
371 return (gio_err_addr == a);
372 }
373 return 0;
374}
375
376/*
377 * MC sends an interrupt whenever bus or parity errors occur. In addition,
378 * if the error happened during a CPU read, it also asserts the bus error
379 * pin on the R4K. Code in bus error handler save the MC bus error registers
380 * and then clear the interrupt when this happens.
381 */
382
383static int ip28_be_interrupt(const struct pt_regs *regs)
384{
385 int i;
386
387 save_and_clear_buserr();
388 /*
389 * Try to find out, whether we got here by a mispredicted speculative
390 * load/store operation. If so, it's not fatal, we can go on.
391 */
392 /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
393 if (regs->cp0_cause & CAUSEF_EXCCODE)
394 goto mips_be_fatal;
395
396 /* Any cause other than "Bus error interrupt" (IP6) is weird. */
397 if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
398 goto mips_be_fatal;
399
400 if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
401 goto mips_be_fatal;
402
403 /* Any state other than "Memory bus error" is fatal. */
404 if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
405 goto mips_be_fatal;
406
407 /* GIO errors other than timeouts are fatal */
408 if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
409 goto mips_be_fatal;
410
411 /*
412 * Now we have an asynchronous bus error, speculatively or DMA caused.
413 * Need to search all DMA descriptors for the error address.
414 */
415 for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
416 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
417 if ((cpu_err_stat & CPU_ERRMASK) &&
418 (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
419 break;
420 if ((gio_err_stat & GIO_ERRMASK) &&
421 (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
422 break;
423 }
424 if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
425 struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
426 printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
427 " ctl %08x, ndp %08x, cbp %08x\n",
428 CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
429 goto mips_be_fatal;
430 }
431 /* Check MC's virtual DMA stuff. */
432 if (check_vdma_memaddr()) {
433 printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
434 sgimc->maddronly);
435 goto mips_be_fatal;
436 }
437 if (check_vdma_gioaddr()) {
438 printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
439 sgimc->gmaddronly);
440 goto mips_be_fatal;
441 }
442 /* A speculative bus error... */
443 if (debug_be_interrupt) {
444 print_buserr(regs);
445 printk(KERN_ERR "discarded!\n");
446 }
447 return MIPS_BE_DISCARD;
448
449mips_be_fatal:
450 print_buserr(regs);
451 return MIPS_BE_FATAL;
452}
453
454void ip22_be_interrupt(int irq)
455{
456 const struct pt_regs *regs = get_irq_regs();
457
458 count_be_interrupt++;
459
460 if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
461 /* Assume it would be too dangerous to continue ... */
462 die_if_kernel("Oops", regs);
463 force_sig(SIGBUS, current);
464 } else if (debug_be_interrupt)
465 show_regs((struct pt_regs *)regs);
466}
467
468static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
469{
470 /*
471 * We arrive here only in the unusual case of do_be() invocation,
472 * i.e. by a bus error exception without a bus error interrupt.
473 */
474 if (is_fixup) {
475 count_be_is_fixup++;
476 save_and_clear_buserr();
477 return MIPS_BE_FIXUP;
478 }
479 count_be_handler++;
480 return ip28_be_interrupt(regs);
481}
482
483void __init ip22_be_init(void)
484{
485 board_be_handler = ip28_be_handler;
486}
487
488int ip28_show_be_info(struct seq_file *m)
489{
490 seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
491 seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
492 seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
493
494 return 0;
495}
496
497static int __init debug_be_setup(char *str)
498{
499 debug_be_interrupt++;
500 return 1;
501}
502__setup("ip28_debug_be", debug_be_setup);
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 3305fa9ae66d..a49e7c85f724 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -27,7 +27,6 @@
27#include <asm/sn/hub.h> 27#include <asm/sn/hub.h>
28#include <asm/sn/intr.h> 28#include <asm/sn/intr.h>
29#include <asm/current.h> 29#include <asm/current.h>
30#include <asm/smp.h>
31#include <asm/processor.h> 30#include <asm/processor.h>
32#include <asm/mmu_context.h> 31#include <asm/mmu_context.h>
33#include <asm/thread_info.h> 32#include <asm/thread_info.h>
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
index f10d9839006d..48932ce1d730 100644
--- a/arch/mips/sgi-ip27/ip27-klnuma.c
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -11,7 +11,6 @@
11 11
12#include <asm/page.h> 12#include <asm/page.h>
13#include <asm/sections.h> 13#include <asm/sections.h>
14#include <asm/smp.h>
15#include <asm/sn/types.h> 14#include <asm/sn/types.h>
16#include <asm/sn/arch.h> 15#include <asm/sn/arch.h>
17#include <asm/sn/gda.h> 16#include <asm/sn/gda.h>
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index a70656d42191..f15fc93d6b35 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -140,30 +140,51 @@ static __init void intr_clear_all(nasid_t nasid)
140 REMOTE_HUB_CLR_INTR(nasid, i); 140 REMOTE_HUB_CLR_INTR(nasid, i);
141} 141}
142 142
143void __init plat_smp_setup(void) 143static void ip27_send_ipi_single(int destid, unsigned int action)
144{ 144{
145 cnodeid_t cnode; 145 int irq;
146 146
147 for_each_online_node(cnode) { 147 switch (action) {
148 if (cnode == 0) 148 case SMP_RESCHEDULE_YOURSELF:
149 continue; 149 irq = CPU_RESCHED_A_IRQ;
150 intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); 150 break;
151 case SMP_CALL_FUNCTION:
152 irq = CPU_CALL_A_IRQ;
153 break;
154 default:
155 panic("sendintr");
151 } 156 }
152 157
153 replicate_kernel_text(); 158 irq += cputoslice(destid);
154 159
155 /* 160 /*
156 * Assumption to be fixed: we're always booted on logical / physical 161 * Convert the compact hub number to the NASID to get the correct
157 * processor 0. While we're always running on logical processor 0 162 * part of the address space. Then set the interrupt bit associated
158 * this still means this is physical processor zero; it might for 163 * with the CPU we want to send the interrupt to.
159 * example be disabled in the firwware.
160 */ 164 */
161 alloc_cpupda(0, 0); 165 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
162} 166}
163 167
164void __init plat_prepare_cpus(unsigned int max_cpus) 168static void ip27_send_ipi_mask(cpumask_t mask, unsigned int action)
169{
170 unsigned int i;
171
172 for_each_cpu_mask(i, mask)
173 ip27_send_ipi_single(i, action);
174}
175
176static void __cpuinit ip27_init_secondary(void)
177{
178 per_cpu_init();
179 local_irq_enable();
180}
181
182static void __cpuinit ip27_smp_finish(void)
183{
184}
185
186static void __init ip27_cpus_done(void)
165{ 187{
166 /* We already did everything necessary earlier */
167} 188}
168 189
169/* 190/*
@@ -171,7 +192,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
171 * set sp to the kernel stack of the newly created idle process, gp to the proc 192 * set sp to the kernel stack of the newly created idle process, gp to the proc
172 * struct so that current_thread_info() will work. 193 * struct so that current_thread_info() will work.
173 */ 194 */
174void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle) 195static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle)
175{ 196{
176 unsigned long gp = (unsigned long)task_thread_info(idle); 197 unsigned long gp = (unsigned long)task_thread_info(idle);
177 unsigned long sp = __KSTK_TOS(idle); 198 unsigned long sp = __KSTK_TOS(idle);
@@ -181,41 +202,39 @@ void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
181 0, (void *) sp, (void *) gp); 202 0, (void *) sp, (void *) gp);
182} 203}
183 204
184void __cpuinit prom_init_secondary(void) 205static void __init ip27_smp_setup(void)
185{ 206{
186 per_cpu_init(); 207 cnodeid_t cnode;
187 local_irq_enable();
188}
189
190void __init prom_cpus_done(void)
191{
192}
193
194void __cpuinit prom_smp_finish(void)
195{
196}
197
198void core_send_ipi(int destid, unsigned int action)
199{
200 int irq;
201 208
202 switch (action) { 209 for_each_online_node(cnode) {
203 case SMP_RESCHEDULE_YOURSELF: 210 if (cnode == 0)
204 irq = CPU_RESCHED_A_IRQ; 211 continue;
205 break; 212 intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
206 case SMP_CALL_FUNCTION:
207 irq = CPU_CALL_A_IRQ;
208 break;
209 default:
210 panic("sendintr");
211 } 213 }
212 214
213 irq += cputoslice(destid); 215 replicate_kernel_text();
214 216
215 /* 217 /*
216 * Convert the compact hub number to the NASID to get the correct 218 * Assumption to be fixed: we're always booted on logical / physical
217 * part of the address space. Then set the interrupt bit associated 219 * processor 0. While we're always running on logical processor 0
218 * with the CPU we want to send the interrupt to. 220 * this still means this is physical processor zero; it might for
221 * example be disabled in the firwware.
219 */ 222 */
220 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); 223 alloc_cpupda(0, 0);
221} 224}
225
226static void __init ip27_prepare_cpus(unsigned int max_cpus)
227{
228 /* We already did everything necessary earlier */
229}
230
231struct plat_smp_ops ip27_smp_ops = {
232 .send_ipi_single = ip27_send_ipi_single,
233 .send_ipi_mask = ip27_send_ipi_mask,
234 .init_secondary = ip27_init_secondary,
235 .smp_finish = ip27_smp_finish,
236 .cpus_done = ip27_cpus_done,
237 .boot_secondary = ip27_boot_secondary,
238 .smp_setup = ip27_smp_setup,
239 .prepare_cpus = ip27_prepare_cpus,
240};
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 436ba78359ab..183c460b9ca1 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -23,6 +23,7 @@
23 23
24#include <asm/mmu_context.h> 24#include <asm/mmu_context.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/fw/cfe/cfe_api.h>
26#include <asm/sibyte/sb1250.h> 27#include <asm/sibyte/sb1250.h>
27#include <asm/sibyte/bcm1480_regs.h> 28#include <asm/sibyte/bcm1480_regs.h>
28#include <asm/sibyte/bcm1480_int.h> 29#include <asm/sibyte/bcm1480_int.h>
@@ -67,28 +68,114 @@ void __cpuinit bcm1480_smp_init(void)
67 change_c0_status(ST0_IM, imask); 68 change_c0_status(ST0_IM, imask);
68} 69}
69 70
70void __cpuinit bcm1480_smp_finish(void) 71/*
72 * These are routines for dealing with the sb1250 smp capabilities
73 * independent of board/firmware
74 */
75
76/*
77 * Simple enough; everything is set up, so just poke the appropriate mailbox
78 * register, and we should be set
79 */
80static void bcm1480_send_ipi_single(int cpu, unsigned int action)
81{
82 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
83}
84
85static void bcm1480_send_ipi_mask(cpumask_t mask, unsigned int action)
86{
87 unsigned int i;
88
89 for_each_cpu_mask(i, mask)
90 bcm1480_send_ipi_single(i, action);
91}
92
93/*
94 * Code to run on secondary just after probing the CPU
95 */
96static void __cpuinit bcm1480_init_secondary(void)
97{
98 extern void bcm1480_smp_init(void);
99
100 bcm1480_smp_init();
101}
102
103/*
104 * Do any tidying up before marking online and running the idle
105 * loop
106 */
107static void __cpuinit bcm1480_smp_finish(void)
71{ 108{
72 extern void sb1480_clockevent_init(void); 109 extern void sb1480_clockevent_init(void);
73 110
74 sb1480_clockevent_init(); 111 sb1480_clockevent_init();
75 local_irq_enable(); 112 local_irq_enable();
113 bcm1480_smp_finish();
76} 114}
77 115
78/* 116/*
79 * These are routines for dealing with the sb1250 smp capabilities 117 * Final cleanup after all secondaries booted
80 * independent of board/firmware
81 */ 118 */
119static void bcm1480_cpus_done(void)
120{
121}
82 122
83/* 123/*
84 * Simple enough; everything is set up, so just poke the appropriate mailbox 124 * Setup the PC, SP, and GP of a secondary processor and start it
85 * register, and we should be set 125 * running!
86 */ 126 */
87void core_send_ipi(int cpu, unsigned int action) 127static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)
88{ 128{
89 __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]); 129 int retval;
130
131 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
132 __KSTK_TOS(idle),
133 (unsigned long)task_thread_info(idle), 0);
134 if (retval != 0)
135 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
90} 136}
91 137
138/*
139 * Use CFE to find out how many CPUs are available, setting up
140 * phys_cpu_present_map and the logical/physical mappings.
141 * XXXKW will the boot CPU ever not be physical 0?
142 *
143 * Common setup before any secondaries are started
144 */
145static void __init bcm1480_smp_setup(void)
146{
147 int i, num;
148
149 cpus_clear(phys_cpu_present_map);
150 cpu_set(0, phys_cpu_present_map);
151 __cpu_number_map[0] = 0;
152 __cpu_logical_map[0] = 0;
153
154 for (i = 1, num = 0; i < NR_CPUS; i++) {
155 if (cfe_cpu_stop(i) == 0) {
156 cpu_set(i, phys_cpu_present_map);
157 __cpu_number_map[i] = ++num;
158 __cpu_logical_map[num] = i;
159 }
160 }
161 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
162}
163
164static void __init bcm1480_prepare_cpus(unsigned int max_cpus)
165{
166}
167
168struct plat_smp_ops bcm1480_smp_ops = {
169 .send_ipi_single = bcm1480_send_ipi_single,
170 .send_ipi_mask = bcm1480_send_ipi_mask,
171 .init_secondary = bcm1480_init_secondary,
172 .smp_finish = bcm1480_smp_finish,
173 .cpus_done = bcm1480_cpus_done,
174 .boot_secondary = bcm1480_boot_secondary,
175 .smp_setup = bcm1480_smp_setup,
176 .prepare_cpus = bcm1480_prepare_cpus,
177};
178
92void bcm1480_mailbox_interrupt(void) 179void bcm1480_mailbox_interrupt(void)
93{ 180{
94 int cpu = smp_processor_id(); 181 int cpu = smp_processor_id();
diff --git a/arch/mips/sibyte/cfe/Makefile b/arch/mips/sibyte/cfe/Makefile
index a1214937b705..02b32e142adf 100644
--- a/arch/mips/sibyte/cfe/Makefile
+++ b/arch/mips/sibyte/cfe/Makefile
@@ -1,3 +1,2 @@
1lib-y = setup.o 1lib-y = setup.o
2lib-$(CONFIG_SMP) += smp.o
3lib-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o 2lib-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c
index dbd6e6fdd3f9..33fce826f8bf 100644
--- a/arch/mips/sibyte/cfe/setup.c
+++ b/arch/mips/sibyte/cfe/setup.c
@@ -28,6 +28,7 @@
28#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
29#include <asm/reboot.h> 29#include <asm/reboot.h>
30#include <asm/sibyte/board.h> 30#include <asm/sibyte/board.h>
31#include <asm/smp-ops.h>
31 32
32#include <asm/fw/cfe/cfe_api.h> 33#include <asm/fw/cfe/cfe_api.h>
33#include <asm/fw/cfe/cfe_error.h> 34#include <asm/fw/cfe/cfe_error.h>
@@ -232,6 +233,9 @@ static int __init initrd_setup(char *str)
232 233
233#endif 234#endif
234 235
236extern struct plat_smp_ops sb_smp_ops;
237extern struct plat_smp_ops bcm1480_smp_ops;
238
235/* 239/*
236 * prom_init is called just after the cpu type is determined, from setup_arch() 240 * prom_init is called just after the cpu type is determined, from setup_arch()
237 */ 241 */
@@ -297,9 +301,6 @@ void __init prom_init(void)
297 * command line 301 * command line
298 */ 302 */
299 strcpy(arcs_cmdline, "root=/dev/ram0 "); 303 strcpy(arcs_cmdline, "root=/dev/ram0 ");
300#ifdef CONFIG_SIBYTE_PTSWARM
301 strcat(arcs_cmdline, "console=ttyS0,115200 ");
302#endif
303 } else { 304 } else {
304 /* The loader should have set the command line */ 305 /* The loader should have set the command line */
305 /* too early for panic to do any good */ 306 /* too early for panic to do any good */
@@ -340,6 +341,13 @@ void __init prom_init(void)
340 arcs_cmdline[CL_SIZE-1] = 0; 341 arcs_cmdline[CL_SIZE-1] = 0;
341 342
342 prom_meminit(); 343 prom_meminit();
344
345#if defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
346 register_smp_ops(&sb_smp_ops);
347#endif
348#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
349 register_smp_ops(&bcm1480_smp_ops);
350#endif
343} 351}
344 352
345void __init prom_free_prom_memory(void) 353void __init prom_free_prom_memory(void)
diff --git a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c
deleted file mode 100644
index 534a62912f21..000000000000
--- a/arch/mips/sibyte/cfe/smp.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19#include <linux/init.h>
20#include <linux/sched.h>
21#include <linux/smp.h>
22#include <asm/processor.h>
23
24#include <asm/fw/cfe/cfe_api.h>
25#include <asm/fw/cfe/cfe_error.h>
26
27/*
28 * Use CFE to find out how many CPUs are available, setting up
29 * phys_cpu_present_map and the logical/physical mappings.
30 * XXXKW will the boot CPU ever not be physical 0?
31 *
32 * Common setup before any secondaries are started
33 */
34void __init plat_smp_setup(void)
35{
36 int i, num;
37
38 cpus_clear(phys_cpu_present_map);
39 cpu_set(0, phys_cpu_present_map);
40 __cpu_number_map[0] = 0;
41 __cpu_logical_map[0] = 0;
42
43 for (i = 1, num = 0; i < NR_CPUS; i++) {
44 if (cfe_cpu_stop(i) == 0) {
45 cpu_set(i, phys_cpu_present_map);
46 __cpu_number_map[i] = ++num;
47 __cpu_logical_map[num] = i;
48 }
49 }
50 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
51}
52
53void __init plat_prepare_cpus(unsigned int max_cpus)
54{
55}
56
57/*
58 * Setup the PC, SP, and GP of a secondary processor and start it
59 * running!
60 */
61void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
62{
63 int retval;
64
65 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
66 __KSTK_TOS(idle),
67 (unsigned long)task_thread_info(idle), 0);
68 if (retval != 0)
69 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
70}
71
72/*
73 * Code to run on secondary just after probing the CPU
74 */
75void __cpuinit prom_init_secondary(void)
76{
77#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
78 extern void bcm1480_smp_init(void);
79 bcm1480_smp_init();
80#elif defined(CONFIG_SIBYTE_SB1250)
81 extern void sb1250_smp_init(void);
82 sb1250_smp_init();
83#else
84#error invalid SMP configuration
85#endif
86}
87
88/*
89 * Do any tidying up before marking online and running the idle
90 * loop
91 */
92void __cpuinit prom_smp_finish(void)
93{
94#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
95 extern void bcm1480_smp_finish(void);
96 bcm1480_smp_finish();
97#elif defined(CONFIG_SIBYTE_SB1250)
98 extern void sb1250_smp_finish(void);
99 sb1250_smp_finish();
100#else
101#error invalid SMP configuration
102#endif
103}
104
105/*
106 * Final cleanup after all secondaries booted
107 */
108void prom_cpus_done(void)
109{
110}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 3f52c95a4eb8..0734b933e969 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -24,6 +24,7 @@
24 24
25#include <asm/mmu_context.h> 25#include <asm/mmu_context.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/fw/cfe/cfe_api.h>
27#include <asm/sibyte/sb1250.h> 28#include <asm/sibyte/sb1250.h>
28#include <asm/sibyte/sb1250_regs.h> 29#include <asm/sibyte/sb1250_regs.h>
29#include <asm/sibyte/sb1250_int.h> 30#include <asm/sibyte/sb1250_int.h>
@@ -55,7 +56,43 @@ void __cpuinit sb1250_smp_init(void)
55 change_c0_status(ST0_IM, imask); 56 change_c0_status(ST0_IM, imask);
56} 57}
57 58
58void __cpuinit sb1250_smp_finish(void) 59/*
60 * These are routines for dealing with the sb1250 smp capabilities
61 * independent of board/firmware
62 */
63
64/*
65 * Simple enough; everything is set up, so just poke the appropriate mailbox
66 * register, and we should be set
67 */
68static void sb1250_send_ipi_single(int cpu, unsigned int action)
69{
70 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
71}
72
73static inline void sb1250_send_ipi_mask(cpumask_t mask, unsigned int action)
74{
75 unsigned int i;
76
77 for_each_cpu_mask(i, mask)
78 sb1250_send_ipi_single(i, action);
79}
80
81/*
82 * Code to run on secondary just after probing the CPU
83 */
84static void __cpuinit sb1250_init_secondary(void)
85{
86 extern void sb1250_smp_init(void);
87
88 sb1250_smp_init();
89}
90
91/*
92 * Do any tidying up before marking online and running the idle
93 * loop
94 */
95static void __cpuinit sb1250_smp_finish(void)
59{ 96{
60 extern void sb1250_clockevent_init(void); 97 extern void sb1250_clockevent_init(void);
61 98
@@ -64,19 +101,68 @@ void __cpuinit sb1250_smp_finish(void)
64} 101}
65 102
66/* 103/*
67 * These are routines for dealing with the sb1250 smp capabilities 104 * Final cleanup after all secondaries booted
68 * independent of board/firmware
69 */ 105 */
106static void sb1250_cpus_done(void)
107{
108}
70 109
71/* 110/*
72 * Simple enough; everything is set up, so just poke the appropriate mailbox 111 * Setup the PC, SP, and GP of a secondary processor and start it
73 * register, and we should be set 112 * running!
74 */ 113 */
75void core_send_ipi(int cpu, unsigned int action) 114static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)
76{ 115{
77 __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]); 116 int retval;
117
118 retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
119 __KSTK_TOS(idle),
120 (unsigned long)task_thread_info(idle), 0);
121 if (retval != 0)
122 printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
78} 123}
79 124
125/*
126 * Use CFE to find out how many CPUs are available, setting up
127 * phys_cpu_present_map and the logical/physical mappings.
128 * XXXKW will the boot CPU ever not be physical 0?
129 *
130 * Common setup before any secondaries are started
131 */
132static void __init sb1250_smp_setup(void)
133{
134 int i, num;
135
136 cpus_clear(phys_cpu_present_map);
137 cpu_set(0, phys_cpu_present_map);
138 __cpu_number_map[0] = 0;
139 __cpu_logical_map[0] = 0;
140
141 for (i = 1, num = 0; i < NR_CPUS; i++) {
142 if (cfe_cpu_stop(i) == 0) {
143 cpu_set(i, phys_cpu_present_map);
144 __cpu_number_map[i] = ++num;
145 __cpu_logical_map[num] = i;
146 }
147 }
148 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
149}
150
151static void __init sb1250_prepare_cpus(unsigned int max_cpus)
152{
153}
154
155struct plat_smp_ops sb_smp_ops = {
156 .send_ipi_single = sb1250_send_ipi_single,
157 .send_ipi_mask = sb1250_send_ipi_mask,
158 .init_secondary = sb1250_init_secondary,
159 .smp_finish = sb1250_smp_finish,
160 .cpus_done = sb1250_cpus_done,
161 .boot_secondary = sb1250_boot_secondary,
162 .smp_setup = sb1250_smp_setup,
163 .prepare_cpus = sb1250_prepare_cpus,
164};
165
80void sb1250_mailbox_interrupt(void) 166void sb1250_mailbox_interrupt(void)
81{ 167{
82 int cpu = smp_processor_id(); 168 int cpu = smp_processor_id();
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index 3a99cd62c0bd..a7dbeebe7fe6 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o 5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
6obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o 6obj-$(CONFIG_EISA) += eisa.o
7 7
8EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index b74607599971..3f8cf5eb2f06 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -117,10 +117,19 @@ static struct resource sc26xx_rsrc[] = {
117 } 117 }
118}; 118};
119 119
120static unsigned int sc26xx_data[2] = {
121 /* DTR | RTS | DSR | CTS | DCD | RI */
122 (8 << 0) | (4 << 4) | (6 << 8) | (0 << 12) | (6 << 16) | (0 << 20),
123 (3 << 0) | (2 << 4) | (1 << 8) | (2 << 12) | (3 << 16) | (4 << 20)
124};
125
120static struct platform_device sc26xx_pdev = { 126static struct platform_device sc26xx_pdev = {
121 .name = "SC26xx", 127 .name = "SC26xx",
122 .num_resources = ARRAY_SIZE(sc26xx_rsrc), 128 .num_resources = ARRAY_SIZE(sc26xx_rsrc),
123 .resource = sc26xx_rsrc 129 .resource = sc26xx_rsrc,
130 .dev = {
131 .platform_data = sc26xx_data,
132 }
124}; 133};
125 134
126static u32 a20r_ack_hwint(void) 135static u32 a20r_ack_hwint(void)
@@ -231,9 +240,9 @@ static int __init snirm_a20r_setup_devinit(void)
231 platform_device_register(&sc26xx_pdev); 240 platform_device_register(&sc26xx_pdev);
232 platform_device_register(&a20r_serial8250_device); 241 platform_device_register(&a20r_serial8250_device);
233 platform_device_register(&a20r_ds1216_device); 242 platform_device_register(&a20r_ds1216_device);
243 sni_eisa_root_init();
234 break; 244 break;
235 } 245 }
236
237 return 0; 246 return 0;
238} 247}
239 248
diff --git a/arch/mips/sni/eisa.c b/arch/mips/sni/eisa.c
new file mode 100644
index 000000000000..7396cd719900
--- /dev/null
+++ b/arch/mips/sni/eisa.c
@@ -0,0 +1,50 @@
1/*
2 * Virtual EISA root driver.
3 * Acts as a placeholder if we don't have a proper EISA bridge.
4 *
5 * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
6 * modified for SNI usage by Thomas Bogendoerfer
7 *
8 * This code is released under the GPL version 2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/eisa.h>
14#include <linux/init.h>
15
16/* The default EISA device parent (virtual root device).
17 * Now use a platform device, since that's the obvious choice. */
18
19static struct platform_device eisa_root_dev = {
20 .name = "eisa",
21 .id = 0,
22};
23
24static struct eisa_root_device eisa_bus_root = {
25 .dev = &eisa_root_dev.dev,
26 .bus_base_addr = 0,
27 .res = &ioport_resource,
28 .slots = EISA_MAX_SLOTS,
29 .dma_mask = 0xffffffff,
30 .force_probe = 1,
31};
32
33int __init sni_eisa_root_init(void)
34{
35 int r;
36
37 r = platform_device_register(&eisa_root_dev);
38 if (!r)
39 return r;
40
41 eisa_root_dev.dev.driver_data = &eisa_bus_root;
42
43 if (eisa_root_register(&eisa_bus_root)) {
44 /* A real bridge may have been registered before
45 * us. So quietly unregister. */
46 platform_device_unregister(&eisa_root_dev);
47 return -1;
48 }
49 return 0;
50}
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 9ccffdfb8289..e8e72bb3a9af 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -35,14 +35,14 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
35 if (unlikely(irq < 0)) 35 if (unlikely(irq < 0))
36 return IRQ_NONE; 36 return IRQ_NONE;
37 37
38 do_IRQ(irq); 38 generic_handle_irq(irq);
39 return IRQ_HANDLED; 39 return IRQ_HANDLED;
40} 40}
41 41
42struct irqaction sni_isa_irq = { 42struct irqaction sni_isa_irq = {
43 .handler = sni_isa_irq_handler, 43 .handler = sni_isa_irq_handler,
44 .name = "ISA", 44 .name = "ISA",
45 .flags = IRQF_SHARED 45 .flags = IRQF_SHARED | IRQF_DISABLED
46}; 46};
47 47
48/* 48/*
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index 416f397c768b..e5f12cf96e8e 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -76,6 +76,11 @@ static struct platform_device pcit_cmos_device = {
76 .resource = pcit_cmos_rsrc 76 .resource = pcit_cmos_rsrc
77}; 77};
78 78
79static struct platform_device pcit_pcspeaker_pdev = {
80 .name = "pcspkr",
81 .id = -1,
82};
83
79static struct resource sni_io_resource = { 84static struct resource sni_io_resource = {
80 .start = 0x00000000UL, 85 .start = 0x00000000UL,
81 .end = 0x03bfffffUL, 86 .end = 0x03bfffffUL,
@@ -277,11 +282,13 @@ static int __init snirm_pcit_setup_devinit(void)
277 case SNI_BRD_PCI_TOWER: 282 case SNI_BRD_PCI_TOWER:
278 platform_device_register(&pcit_serial8250_device); 283 platform_device_register(&pcit_serial8250_device);
279 platform_device_register(&pcit_cmos_device); 284 platform_device_register(&pcit_cmos_device);
285 platform_device_register(&pcit_pcspeaker_pdev);
280 break; 286 break;
281 287
282 case SNI_BRD_PCI_TOWER_CPLUS: 288 case SNI_BRD_PCI_TOWER_CPLUS:
283 platform_device_register(&pcit_cplus_serial8250_device); 289 platform_device_register(&pcit_cplus_serial8250_device);
284 platform_device_register(&pcit_cmos_device); 290 platform_device_register(&pcit_cmos_device);
291 platform_device_register(&pcit_pcspeaker_pdev);
285 break; 292 break;
286 } 293 }
287 return 0; 294 return 0;
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 67b061eef6cd..5310aa75afa4 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -5,30 +5,36 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 8 * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
9 *
10 * i8259 parts ripped out of arch/mips/kernel/i8259.c
9 */ 11 */
10 12
13#include <linux/delay.h>
11#include <linux/init.h> 14#include <linux/init.h>
12#include <linux/interrupt.h> 15#include <linux/interrupt.h>
13#include <linux/platform_device.h> 16#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 17#include <linux/serial_8250.h>
18#include <linux/io.h>
15 19
16#include <asm/sni.h> 20#include <asm/sni.h>
17#include <asm/time.h> 21#include <asm/time.h>
18#include <asm/irq_cpu.h> 22#include <asm/irq_cpu.h>
19 23
20#define PORT(_base,_irq) \ 24#define RM200_I8259A_IRQ_BASE 32
25
26#define MEMPORT(_base,_irq) \
21 { \ 27 { \
22 .iobase = _base, \ 28 .mapbase = _base, \
23 .irq = _irq, \ 29 .irq = _irq, \
24 .uartclk = 1843200, \ 30 .uartclk = 1843200, \
25 .iotype = UPIO_PORT, \ 31 .iotype = UPIO_MEM, \
26 .flags = UPF_BOOT_AUTOCONF, \ 32 .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
27 } 33 }
28 34
29static struct plat_serial8250_port rm200_data[] = { 35static struct plat_serial8250_port rm200_data[] = {
30 PORT(0x3f8, 4), 36 MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
31 PORT(0x2f8, 3), 37 MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
32 { }, 38 { },
33}; 39};
34 40
@@ -112,15 +118,311 @@ static int __init snirm_setup_devinit(void)
112 platform_device_register(&rm200_ds1216_device); 118 platform_device_register(&rm200_ds1216_device);
113 platform_device_register(&snirm_82596_rm200_pdev); 119 platform_device_register(&snirm_82596_rm200_pdev);
114 platform_device_register(&snirm_53c710_rm200_pdev); 120 platform_device_register(&snirm_53c710_rm200_pdev);
121 sni_eisa_root_init();
115 } 122 }
116 return 0; 123 return 0;
117} 124}
118 125
119device_initcall(snirm_setup_devinit); 126device_initcall(snirm_setup_devinit);
120 127
128/*
129 * RM200 has an ISA and an EISA bus. The iSA bus is only used
130 * for onboard devices and also has twi i8259 PICs. Since these
131 * PICs are no accessible via inb/outb the following code uses
132 * readb/writeb to access them
133 */
134
135DEFINE_SPINLOCK(sni_rm200_i8259A_lock);
136#define PIC_CMD 0x00
137#define PIC_IMR 0x01
138#define PIC_ISR PIC_CMD
139#define PIC_POLL PIC_ISR
140#define PIC_OCW3 PIC_ISR
141
142/* i8259A PIC related value */
143#define PIC_CASCADE_IR 2
144#define MASTER_ICW4_DEFAULT 0x01
145#define SLAVE_ICW4_DEFAULT 0x01
146
147/*
148 * This contains the irq mask for both 8259A irq controllers,
149 */
150static unsigned int rm200_cached_irq_mask = 0xffff;
151static __iomem u8 *rm200_pic_master;
152static __iomem u8 *rm200_pic_slave;
153
154#define cached_master_mask (rm200_cached_irq_mask)
155#define cached_slave_mask (rm200_cached_irq_mask >> 8)
156
157static void sni_rm200_disable_8259A_irq(unsigned int irq)
158{
159 unsigned int mask;
160 unsigned long flags;
161
162 irq -= RM200_I8259A_IRQ_BASE;
163 mask = 1 << irq;
164 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
165 rm200_cached_irq_mask |= mask;
166 if (irq & 8)
167 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
168 else
169 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
170 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
171}
172
173static void sni_rm200_enable_8259A_irq(unsigned int irq)
174{
175 unsigned int mask;
176 unsigned long flags;
177
178 irq -= RM200_I8259A_IRQ_BASE;
179 mask = ~(1 << irq);
180 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
181 rm200_cached_irq_mask &= mask;
182 if (irq & 8)
183 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
184 else
185 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
186 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
187}
188
189static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
190{
191 int value;
192 int irqmask = 1 << irq;
193
194 if (irq < 8) {
195 writeb(0x0B, rm200_pic_master + PIC_CMD);
196 value = readb(rm200_pic_master + PIC_CMD) & irqmask;
197 writeb(0x0A, rm200_pic_master + PIC_CMD);
198 return value;
199 }
200 writeb(0x0B, rm200_pic_slave + PIC_CMD); /* ISR register */
201 value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
202 writeb(0x0A, rm200_pic_slave + PIC_CMD);
203 return value;
204}
205
206/*
207 * Careful! The 8259A is a fragile beast, it pretty
208 * much _has_ to be done exactly like this (mask it
209 * first, _then_ send the EOI, and the order of EOI
210 * to the two 8259s is important!
211 */
212void sni_rm200_mask_and_ack_8259A(unsigned int irq)
213{
214 unsigned int irqmask;
215 unsigned long flags;
216
217 irq -= RM200_I8259A_IRQ_BASE;
218 irqmask = 1 << irq;
219 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
220 /*
221 * Lightweight spurious IRQ detection. We do not want
222 * to overdo spurious IRQ handling - it's usually a sign
223 * of hardware problems, so we only do the checks we can
224 * do without slowing down good hardware unnecessarily.
225 *
226 * Note that IRQ7 and IRQ15 (the two spurious IRQs
227 * usually resulting from the 8259A-1|2 PICs) occur
228 * even if the IRQ is masked in the 8259A. Thus we
229 * can check spurious 8259A IRQs without doing the
230 * quite slow i8259A_irq_real() call for every IRQ.
231 * This does not cover 100% of spurious interrupts,
232 * but should be enough to warn the user that there
233 * is something bad going on ...
234 */
235 if (rm200_cached_irq_mask & irqmask)
236 goto spurious_8259A_irq;
237 rm200_cached_irq_mask |= irqmask;
238
239handle_real_irq:
240 if (irq & 8) {
241 readb(rm200_pic_slave + PIC_IMR);
242 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
243 writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
244 writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
245 } else {
246 readb(rm200_pic_master + PIC_IMR);
247 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
248 writeb(0x60+irq, rm200_pic_master + PIC_CMD);
249 }
250 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
251 return;
252
253spurious_8259A_irq:
254 /*
255 * this is the slow path - should happen rarely.
256 */
257 if (sni_rm200_i8259A_irq_real(irq))
258 /*
259 * oops, the IRQ _is_ in service according to the
260 * 8259A - not spurious, go handle it.
261 */
262 goto handle_real_irq;
263
264 {
265 static int spurious_irq_mask;
266 /*
267 * At this point we can be sure the IRQ is spurious,
268 * lets ACK and report it. [once per IRQ]
269 */
270 if (!(spurious_irq_mask & irqmask)) {
271 printk(KERN_DEBUG
272 "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
273 spurious_irq_mask |= irqmask;
274 }
275 atomic_inc(&irq_err_count);
276 /*
277 * Theoretically we do not have to handle this IRQ,
278 * but in Linux this does not cause problems and is
279 * simpler for us.
280 */
281 goto handle_real_irq;
282 }
283}
284
285static struct irq_chip sni_rm200_i8259A_chip = {
286 .name = "RM200-XT-PIC",
287 .mask = sni_rm200_disable_8259A_irq,
288 .unmask = sni_rm200_enable_8259A_irq,
289 .mask_ack = sni_rm200_mask_and_ack_8259A,
290};
291
292/*
293 * Do the traditional i8259 interrupt polling thing. This is for the few
294 * cases where no better interrupt acknowledge method is available and we
295 * absolutely must touch the i8259.
296 */
297static inline int sni_rm200_i8259_irq(void)
298{
299 int irq;
300
301 spin_lock(&sni_rm200_i8259A_lock);
302
303 /* Perform an interrupt acknowledge cycle on controller 1. */
304 writeb(0x0C, rm200_pic_master + PIC_CMD); /* prepare for poll */
305 irq = readb(rm200_pic_master + PIC_CMD) & 7;
306 if (irq == PIC_CASCADE_IR) {
307 /*
308 * Interrupt is cascaded so perform interrupt
309 * acknowledge on controller 2.
310 */
311 writeb(0x0C, rm200_pic_slave + PIC_CMD); /* prepare for poll */
312 irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
313 }
314
315 if (unlikely(irq == 7)) {
316 /*
317 * This may be a spurious interrupt.
318 *
319 * Read the interrupt status register (ISR). If the most
320 * significant bit is not set then there is no valid
321 * interrupt.
322 */
323 writeb(0x0B, rm200_pic_master + PIC_ISR); /* ISR register */
324 if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
325 irq = -1;
326 }
327
328 spin_unlock(&sni_rm200_i8259A_lock);
329
330 return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
331}
332
333void sni_rm200_init_8259A(void)
334{
335 unsigned long flags;
336
337 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
338
339 writeb(0xff, rm200_pic_master + PIC_IMR);
340 writeb(0xff, rm200_pic_slave + PIC_IMR);
341
342 writeb(0x11, rm200_pic_master + PIC_CMD);
343 writeb(0, rm200_pic_master + PIC_IMR);
344 writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
345 writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
346 writeb(0x11, rm200_pic_slave + PIC_CMD);
347 writeb(8, rm200_pic_slave + PIC_IMR);
348 writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
349 writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
350 udelay(100); /* wait for 8259A to initialize */
351
352 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
353 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
354
355 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
356}
357
358/*
359 * IRQ2 is cascade interrupt to second interrupt controller
360 */
361static struct irqaction sni_rm200_irq2 = {
362 no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
363};
364
365static struct resource sni_rm200_pic1_resource = {
366 .name = "onboard ISA pic1",
367 .start = 0x16000020,
368 .end = 0x16000023,
369 .flags = IORESOURCE_BUSY
370};
371
372static struct resource sni_rm200_pic2_resource = {
373 .name = "onboard ISA pic2",
374 .start = 0x160000a0,
375 .end = 0x160000a3,
376 .flags = IORESOURCE_BUSY
377};
378
379/* ISA irq handler */
380static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
381{
382 int irq;
383
384 irq = sni_rm200_i8259_irq();
385 if (unlikely(irq < 0))
386 return IRQ_NONE;
387
388 do_IRQ(irq);
389 return IRQ_HANDLED;
390}
391
392struct irqaction sni_rm200_i8259A_irq = {
393 .handler = sni_rm200_i8259A_irq_handler,
394 .name = "onboard ISA",
395 .flags = IRQF_SHARED
396};
397
398void __init sni_rm200_i8259_irqs(void)
399{
400 int i;
401
402 rm200_pic_master = ioremap_nocache(0x16000020, 4);
403 if (!rm200_pic_master)
404 return;
405 rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
406 if (!rm200_pic_master) {
407 iounmap(rm200_pic_master);
408 return;
409 }
410
411 insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
412 insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
413
414 sni_rm200_init_8259A();
415
416 for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
417 set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip,
418 handle_level_irq);
419
420 setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
421}
422
121 423
122#define SNI_RM200_INT_STAT_REG 0xbc000000 424#define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
123#define SNI_RM200_INT_ENA_REG 0xbc080000 425#define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
124 426
125#define SNI_RM200_INT_START 24 427#define SNI_RM200_INT_START 24
126#define SNI_RM200_INT_END 28 428#define SNI_RM200_INT_END 28
@@ -181,17 +483,17 @@ void __init sni_rm200_irq_init(void)
181 483
182 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f; 484 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
183 485
486 sni_rm200_i8259_irqs();
184 mips_cpu_irq_init(); 487 mips_cpu_irq_init();
185 /* Actually we've got more interrupts to handle ... */ 488 /* Actually we've got more interrupts to handle ... */
186 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) 489 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
187 set_irq_chip(i, &rm200_irq_type); 490 set_irq_chip(i, &rm200_irq_type);
188 sni_hwint = sni_rm200_hwint; 491 sni_hwint = sni_rm200_hwint;
189 change_c0_status(ST0_IM, IE_IRQ0); 492 change_c0_status(ST0_IM, IE_IRQ0);
190 setup_irq(SNI_RM200_INT_START + 0, &sni_isa_irq); 493 setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
494 setup_irq(SNI_RM200_INT_START + 1, &sni_isa_irq);
191} 495}
192 496
193void __init sni_rm200_init(void) 497void __init sni_rm200_init(void)
194{ 498{
195 set_io_port_base(SNI_PORT_BASE + 0x02000000);
196 ioport_resource.end += 0x02000000;
197} 499}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index e8b26bdee24c..5484e1c62054 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -19,11 +19,17 @@
19#include <asm/sgialib.h> 19#include <asm/sgialib.h>
20#endif 20#endif
21 21
22#ifdef CONFIG_SNIPROM
23#include <asm/mipsprom.h>
24#endif
25
26#include <asm/bootinfo.h>
22#include <asm/io.h> 27#include <asm/io.h>
23#include <asm/reboot.h> 28#include <asm/reboot.h>
24#include <asm/sni.h> 29#include <asm/sni.h>
25 30
26unsigned int sni_brd_type; 31unsigned int sni_brd_type;
32EXPORT_SYMBOL(sni_brd_type);
27 33
28extern void sni_machine_restart(char *command); 34extern void sni_machine_restart(char *command);
29extern void sni_machine_power_off(void); 35extern void sni_machine_power_off(void);
@@ -47,20 +53,152 @@ static void __init sni_display_setup(void)
47#endif 53#endif
48} 54}
49 55
56static void __init sni_console_setup(void)
57{
58#ifndef CONFIG_ARC
59 char *ctype;
60 char *cdev;
61 char *baud;
62 int port;
63 static char options[8];
64
65 cdev = prom_getenv("console_dev");
66 if (strncmp(cdev, "tty", 3) == 0) {
67 ctype = prom_getenv("console");
68 switch (*ctype) {
69 default:
70 case 'l':
71 port = 0;
72 baud = prom_getenv("lbaud");
73 break;
74 case 'r':
75 port = 1;
76 baud = prom_getenv("rbaud");
77 break;
78 }
79 if (baud)
80 strcpy(options, baud);
81 if (strncmp(cdev, "tty552", 6) == 0)
82 add_preferred_console("ttyS", port,
83 baud ? options : NULL);
84 else
85 add_preferred_console("ttySC", port,
86 baud ? options : NULL);
87 }
88#endif
89}
90
91#ifdef DEBUG
92static void __init sni_idprom_dump(void)
93{
94 int i;
95
96 pr_debug("SNI IDProm dump:\n");
97 for (i = 0; i < 256; i++) {
98 if (i%16 == 0)
99 pr_debug("%04x ", i);
100
101 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
102
103 if (i % 16 == 15)
104 printk("\n");
105 }
106}
107#endif
50 108
51void __init plat_mem_setup(void) 109void __init plat_mem_setup(void)
52{ 110{
111 int cputype;
112
53 set_io_port_base(SNI_PORT_BASE); 113 set_io_port_base(SNI_PORT_BASE);
54// ioport_resource.end = sni_io_resource.end; 114// ioport_resource.end = sni_io_resource.end;
55 115
56 /* 116 /*
57 * Setup (E)ISA I/O memory access stuff 117 * Setup (E)ISA I/O memory access stuff
58 */ 118 */
59 isa_slot_offset = 0xb0000000; 119 isa_slot_offset = CKSEG1ADDR(0xb0000000);
60#ifdef CONFIG_EISA 120#ifdef CONFIG_EISA
61 EISA_bus = 1; 121 EISA_bus = 1;
62#endif 122#endif
63 123
124 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
125 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
126 switch (sni_brd_type) {
127 case SNI_BRD_TOWER_OASIC:
128 switch (cputype) {
129 case SNI_CPU_M8030:
130 system_type = "RM400-330";
131 break;
132 case SNI_CPU_M8031:
133 system_type = "RM400-430";
134 break;
135 case SNI_CPU_M8037:
136 system_type = "RM400-530";
137 break;
138 case SNI_CPU_M8034:
139 system_type = "RM400-730";
140 break;
141 default:
142 system_type = "RM400-xxx";
143 break;
144 }
145 break;
146 case SNI_BRD_MINITOWER:
147 switch (cputype) {
148 case SNI_CPU_M8021:
149 case SNI_CPU_M8043:
150 system_type = "RM400-120";
151 break;
152 case SNI_CPU_M8040:
153 system_type = "RM400-220";
154 break;
155 case SNI_CPU_M8053:
156 system_type = "RM400-225";
157 break;
158 case SNI_CPU_M8050:
159 system_type = "RM400-420";
160 break;
161 default:
162 system_type = "RM400-xxx";
163 break;
164 }
165 break;
166 case SNI_BRD_PCI_TOWER:
167 system_type = "RM400-Cxx";
168 break;
169 case SNI_BRD_RM200:
170 system_type = "RM200-xxx";
171 break;
172 case SNI_BRD_PCI_MTOWER:
173 system_type = "RM300-Cxx";
174 break;
175 case SNI_BRD_PCI_DESKTOP:
176 switch (read_c0_prid() & 0xff00) {
177 case PRID_IMP_R4600:
178 case PRID_IMP_R4700:
179 system_type = "RM200-C20";
180 break;
181 case PRID_IMP_R5000:
182 system_type = "RM200-C40";
183 break;
184 default:
185 system_type = "RM200-Cxx";
186 break;
187 }
188 break;
189 case SNI_BRD_PCI_TOWER_CPLUS:
190 system_type = "RM400-Exx";
191 break;
192 case SNI_BRD_PCI_MTOWER_CPLUS:
193 system_type = "RM300-Exx";
194 break;
195 }
196 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, system_type);
197
198#ifdef DEBUG
199 sni_idprom_dump();
200#endif
201
64 switch (sni_brd_type) { 202 switch (sni_brd_type) {
65 case SNI_BRD_10: 203 case SNI_BRD_10:
66 case SNI_BRD_10NEW: 204 case SNI_BRD_10NEW:
@@ -89,9 +227,10 @@ void __init plat_mem_setup(void)
89 pm_power_off = sni_machine_power_off; 227 pm_power_off = sni_machine_power_off;
90 228
91 sni_display_setup(); 229 sni_display_setup();
230 sni_console_setup();
92} 231}
93 232
94#if CONFIG_PCI 233#ifdef CONFIG_PCI
95 234
96#include <linux/pci.h> 235#include <linux/pci.h>
97#include <video/vga.h> 236#include <video/vga.h>
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
deleted file mode 100644
index eff4b89d7b75..000000000000
--- a/arch/mips/sni/sniprom.c
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * Big Endian PROM code for SNI RM machines
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#define DEBUG
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/string.h>
17#include <linux/console.h>
18
19#include <asm/addrspace.h>
20#include <asm/sni.h>
21#include <asm/mipsprom.h>
22#include <asm/mipsregs.h>
23#include <asm/bootinfo.h>
24
25/* special SNI prom calls */
26/*
27 * This does not exist in all proms - SINIX compares
28 * the prom env variable "version" against "2.0008"
29 * or greater. If lesser it tries to probe interesting
30 * registers
31 */
32#define PROM_GET_MEMCONF 58
33
34#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
35#define PROM_ENTRY(x) (PROM_VEC + (x))
36
37
38static int *(*__prom_putchar)(int) = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
39
40void prom_putchar(char c)
41{
42 __prom_putchar(c);
43}
44
45static char *(*__prom_getenv)(char *) = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
46static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
47
48char *prom_getenv(char *s)
49{
50 return __prom_getenv(s);
51}
52
53void __init prom_free_prom_memory(void)
54{
55}
56
57/*
58 * /proc/cpuinfo system type
59 *
60 */
61static const char *systype = "Unknown";
62const char *get_system_type(void)
63{
64 return systype;
65}
66
67#define SNI_IDPROM_BASE 0xbff00000
68#define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE+0x28) /* Memsize in 16MB quantities */
69#define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE+0x29) /* Board Type */
70#define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE+0x30) /* CPU Type */
71
72#define SNI_IDPROM_SIZE 0x1000
73
74#ifdef DEBUG
75static void __init sni_idprom_dump(void)
76{
77 int i;
78
79 pr_debug("SNI IDProm dump:\n");
80 for (i = 0; i < 256; i++) {
81 if (i%16 == 0)
82 pr_debug("%04x ", i);
83
84 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
85
86 if (i % 16 == 15)
87 printk("\n");
88 }
89}
90#endif
91
92static void __init sni_mem_init(void )
93{
94 int i, memsize;
95 struct membank {
96 u32 size;
97 u32 base;
98 u32 size2;
99 u32 pad1;
100 u32 pad2;
101 } memconf[8];
102
103 /* MemSIZE from prom in 16MByte chunks */
104 memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
105
106 pr_debug("IDProm memsize: %lu MByte\n", memsize);
107
108 /* get memory bank layout from prom */
109 __prom_get_memconf(&memconf);
110
111 pr_debug("prom_get_mem_conf memory configuration:\n");
112 for (i = 0;i < 8 && memconf[i].size; i++) {
113 if (sni_brd_type == SNI_BRD_PCI_TOWER ||
114 sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
115 if (memconf[i].base >= 0x20000000 &&
116 memconf[i].base < 0x30000000) {
117 memconf[i].base -= 0x20000000;
118 }
119 }
120 pr_debug("Bank%d: %08x @ %08x\n", i,
121 memconf[i].size, memconf[i].base);
122 add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
123 }
124}
125
126static void __init sni_console_setup(void)
127{
128 char *ctype;
129 char *cdev;
130 char *baud;
131 int port;
132 static char options[8];
133
134 cdev = prom_getenv("console_dev");
135 if (strncmp (cdev, "tty", 3) == 0) {
136 ctype = prom_getenv("console");
137 switch (*ctype) {
138 default:
139 case 'l':
140 port = 0;
141 baud = prom_getenv("lbaud");
142 break;
143 case 'r':
144 port = 1;
145 baud = prom_getenv("rbaud");
146 break;
147 }
148 if (baud)
149 strcpy(options, baud);
150 if (strncmp (cdev, "tty552", 6) == 0)
151 add_preferred_console("ttyS", port, baud ? options : NULL);
152 else
153 add_preferred_console("ttySC", port, baud ? options : NULL);
154 }
155}
156
157void __init prom_init(void)
158{
159 int argc = fw_arg0;
160 char **argv = (void *)fw_arg1;
161 int i;
162 int cputype;
163
164 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
165 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
166 switch (sni_brd_type) {
167 case SNI_BRD_TOWER_OASIC:
168 switch (cputype) {
169 case SNI_CPU_M8030:
170 systype = "RM400-330";
171 break;
172 case SNI_CPU_M8031:
173 systype = "RM400-430";
174 break;
175 case SNI_CPU_M8037:
176 systype = "RM400-530";
177 break;
178 case SNI_CPU_M8034:
179 systype = "RM400-730";
180 break;
181 default:
182 systype = "RM400-xxx";
183 break;
184 }
185 break;
186 case SNI_BRD_MINITOWER:
187 switch (cputype) {
188 case SNI_CPU_M8021:
189 case SNI_CPU_M8043:
190 systype = "RM400-120";
191 break;
192 case SNI_CPU_M8040:
193 systype = "RM400-220";
194 break;
195 case SNI_CPU_M8053:
196 systype = "RM400-225";
197 break;
198 case SNI_CPU_M8050:
199 systype = "RM400-420";
200 break;
201 default:
202 systype = "RM400-xxx";
203 break;
204 }
205 break;
206 case SNI_BRD_PCI_TOWER:
207 systype = "RM400-Cxx";
208 break;
209 case SNI_BRD_RM200:
210 systype = "RM200-xxx";
211 break;
212 case SNI_BRD_PCI_MTOWER:
213 systype = "RM300-Cxx";
214 break;
215 case SNI_BRD_PCI_DESKTOP:
216 switch (read_c0_prid() & 0xff00) {
217 case PRID_IMP_R4600:
218 case PRID_IMP_R4700:
219 systype = "RM200-C20";
220 break;
221 case PRID_IMP_R5000:
222 systype = "RM200-C40";
223 break;
224 default:
225 systype = "RM200-Cxx";
226 break;
227 }
228 break;
229 case SNI_BRD_PCI_TOWER_CPLUS:
230 systype = "RM400-Exx";
231 break;
232 case SNI_BRD_PCI_MTOWER_CPLUS:
233 systype = "RM300-Exx";
234 break;
235 }
236 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, systype);
237
238#ifdef DEBUG
239 sni_idprom_dump();
240#endif
241 sni_mem_init();
242 sni_console_setup();
243
244 /* copy prom cmdline parameters to kernel cmdline */
245 for (i = 1; i < argc; i++) {
246 strcat(arcs_cmdline, argv[i]);
247 if (i < (argc - 1))
248 strcat(arcs_cmdline, " ");
249 }
250}
251
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 6f339af08d22..796e3ce28720 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -178,6 +178,7 @@ void __init plat_time_init(void)
178 sni_a20r_timer_setup(); 178 sni_a20r_timer_setup();
179 break; 179 break;
180 } 180 }
181 setup_pit_timer();
181} 182}
182 183
183unsigned long read_persistent_clock(void) 184unsigned long read_persistent_clock(void)
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile
index 18375787e094..a7fe76a64964 100644
--- a/arch/mips/tx4927/common/Makefile
+++ b/arch/mips/tx4927/common/Makefile
@@ -1,12 +1,8 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o 5obj-y += tx4927_prom.o tx4927_irq.o
10 6
11obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o 7obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
12obj-$(CONFIG_KGDB) += tx4927_dbgio.o 8obj-$(CONFIG_KGDB) += tx4927_dbgio.o
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
deleted file mode 100644
index 36c5f200eb3d..000000000000
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Author: MontaVista Software, Inc.
3 * source@mvista.com
4 *
5 * Copyright 2001-2002 MontaVista Software Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
18 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
20 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/kernel_stat.h>
30#include <linux/module.h>
31#include <linux/signal.h>
32#include <linux/sched.h>
33#include <linux/types.h>
34#include <linux/interrupt.h>
35#include <linux/ioport.h>
36#include <linux/timex.h>
37#include <linux/slab.h>
38#include <linux/random.h>
39#include <linux/irq.h>
40#include <linux/bitops.h>
41#include <asm/bootinfo.h>
42#include <asm/io.h>
43#include <asm/irq.h>
44#include <asm/mipsregs.h>
45#include <asm/system.h>
46#include <asm/time.h>
47#include <asm/tx4927/tx4927.h>
48
49
50#undef DEBUG
51
52void dump_cp0(char *key);
53
54
55void __init plat_mem_setup(void)
56{
57#ifdef CONFIG_TOSHIBA_RBTX4927
58 {
59 extern void toshiba_rbtx4927_setup(void);
60 toshiba_rbtx4927_setup();
61 }
62#endif
63}
64
65void __init plat_time_init(void)
66{
67#ifdef CONFIG_TOSHIBA_RBTX4927
68 {
69 extern void toshiba_rbtx4927_time_init(void);
70 toshiba_rbtx4927_time_init();
71 }
72#endif
73}
74
75#ifdef DEBUG
76void print_cp0(char *key, int num, char *name, u32 val)
77{
78 printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val);
79 return;
80}
81
82void
83dump_cp0(char *key)
84{
85 if (key == NULL)
86 key = "";
87
88 print_cp0(key, 0, "INDEX ", read_c0_index());
89 print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0());
90 print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1());
91 print_cp0(key, 4, "CONTEXT ", read_c0_context());
92 print_cp0(key, 5, "PAGEMASK", read_c0_pagemask());
93 print_cp0(key, 6, "WIRED ", read_c0_wired());
94 //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr());
95 print_cp0(key, 9, "COUNT ", read_c0_count());
96 print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi());
97 print_cp0(key, 11, "COMPARE ", read_c0_compare());
98 print_cp0(key, 12, "STATUS ", read_c0_status());
99 print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff);
100 print_cp0(key, 16, "CONFIG ", read_c0_config());
101 return;
102}
103
104void print_pic(char *key, unsigned long reg, char *name)
105{
106 printk(KERN_INFO "%s pic:0x%08lx:%s=0x%08x\n", key, reg, name,
107 __raw_readl((void __iomem *)reg));
108 return;
109}
110
111
112void dump_pic(char *key)
113{
114 if (key == NULL)
115 key = "";
116
117 print_pic(key, 0xff1ff600, "IRDEN ");
118 print_pic(key, 0xff1ff604, "IRDM0 ");
119 print_pic(key, 0xff1ff608, "IRDM1 ");
120
121 print_pic(key, 0xff1ff610, "IRLVL0 ");
122 print_pic(key, 0xff1ff614, "IRLVL1 ");
123 print_pic(key, 0xff1ff618, "IRLVL2 ");
124 print_pic(key, 0xff1ff61c, "IRLVL3 ");
125 print_pic(key, 0xff1ff620, "IRLVL4 ");
126 print_pic(key, 0xff1ff624, "IRLVL5 ");
127 print_pic(key, 0xff1ff628, "IRLVL6 ");
128 print_pic(key, 0xff1ff62c, "IRLVL7 ");
129
130 print_pic(key, 0xff1ff640, "IRMSK ");
131 print_pic(key, 0xff1ff660, "IREDC ");
132 print_pic(key, 0xff1ff680, "IRPND ");
133 print_pic(key, 0xff1ff6a0, "IRCS ");
134
135 print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */
136
137 print_pic(key, 0xff1ff518, "IRPOL ");
138 print_pic(key, 0xff1ff51c, "IRRCNT ");
139 print_pic(key, 0xff1ff520, "IRMASKINT");
140 print_pic(key, 0xff1ff524, "IRMASKEXT");
141
142 return;
143}
144
145
146void print_addr(char *hdr, char *key, unsigned long addr)
147{
148 printk(KERN_INFO "%s %s:0x%08lx=0x%08x\n", hdr, key, addr,
149 __raw_readl((void __iomem *)addr));
150 return;
151}
152
153
154void dump_180(char *key)
155{
156 u32 i;
157
158 for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) {
159 print_addr("180", key, i);
160 }
161 return;
162}
163
164
165void dump_eh0(char *key)
166{
167 int i;
168 extern unsigned long exception_handlers[];
169
170 for (i = (int) exception_handlers;
171 i < (int) (exception_handlers + 20); i += 4) {
172 print_addr("eh0", key, i);
173 }
174
175 return;
176}
177
178void pk0(void)
179{
180 volatile u32 val;
181
182 __asm__ __volatile__("ori %0, $26, 0":"=r"(val)
183 );
184 printk("k0=[0x%08x]\n", val);
185}
186#endif
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 0299595ce1c4..e466e5e711d8 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -45,27 +45,19 @@
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/types.h> 47#include <linux/types.h>
48#include <linux/mm.h>
49#include <linux/swap.h>
50#include <linux/ioport.h> 48#include <linux/ioport.h>
51#include <linux/sched.h>
52#include <linux/interrupt.h> 49#include <linux/interrupt.h>
53#include <linux/pci.h> 50#include <linux/pci.h>
54#include <linux/timex.h>
55#include <linux/pm.h> 51#include <linux/pm.h>
56#include <linux/platform_device.h> 52#include <linux/platform_device.h>
53#include <linux/clk.h>
57 54
58#include <asm/bootinfo.h> 55#include <asm/bootinfo.h>
59#include <asm/page.h>
60#include <asm/io.h> 56#include <asm/io.h>
61#include <asm/irq.h>
62#include <asm/irq_regs.h>
63#include <asm/processor.h> 57#include <asm/processor.h>
64#include <asm/reboot.h> 58#include <asm/reboot.h>
65#include <asm/time.h> 59#include <asm/time.h>
66#include <asm/txx9tmr.h> 60#include <asm/txx9tmr.h>
67#include <linux/bootmem.h>
68#include <linux/blkdev.h>
69#ifdef CONFIG_TOSHIBA_FPCIB0 61#ifdef CONFIG_TOSHIBA_FPCIB0
70#include <asm/tx4927/smsc_fdc37m81x.h> 62#include <asm/tx4927/smsc_fdc37m81x.h>
71#endif 63#endif
@@ -73,42 +65,26 @@
73#ifdef CONFIG_PCI 65#ifdef CONFIG_PCI
74#include <asm/tx4927/tx4927_pci.h> 66#include <asm/tx4927/tx4927_pci.h>
75#endif 67#endif
76#ifdef CONFIG_BLK_DEV_IDEPCI
77#include <linux/hdreg.h>
78#include <linux/ide.h>
79#endif
80#ifdef CONFIG_SERIAL_TXX9 68#ifdef CONFIG_SERIAL_TXX9
81#include <linux/tty.h>
82#include <linux/serial.h>
83#include <linux/serial_core.h> 69#include <linux/serial_core.h>
84#endif 70#endif
85 71
86#undef TOSHIBA_RBTX4927_SETUP_DEBUG 72#undef TOSHIBA_RBTX4927_SETUP_DEBUG
87 73
88#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 74#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
89#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000
90
91#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 )
92#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 )
93#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 )
94
95#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
96#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) 75#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )
97#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) 76#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )
98#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) 77#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )
99#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) 78#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
100#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 )
101 79
102#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff 80#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff
103#endif 81#endif
104 82
105#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 83#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
106static const u32 toshiba_rbtx4927_setup_debug_flag = 84static const u32 toshiba_rbtx4927_setup_debug_flag =
107 (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | 85 (TOSHIBA_RBTX4927_SETUP_SETUP |
108 TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
109 TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
110 | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | 86 | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
111 TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); 87 TOSHIBA_RBTX4927_SETUP_PCI2);
112#endif 88#endif
113 89
114#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG 90#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
@@ -718,7 +694,7 @@ void toshiba_rbtx4927_power_off(void)
718 /* no return */ 694 /* no return */
719} 695}
720 696
721void __init toshiba_rbtx4927_setup(void) 697void __init plat_mem_setup(void)
722{ 698{
723 int i; 699 int i;
724 u32 cp0_config; 700 u32 cp0_config;
@@ -741,13 +717,6 @@ void __init toshiba_rbtx4927_setup(void)
741 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); 717 cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
742 write_c0_config(cp0_config); 718 write_c0_config(cp0_config);
743 719
744#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG
745 {
746 extern void dump_cp0(char *);
747 dump_cp0("toshiba_rbtx4927_early_fw_fixup");
748 }
749#endif
750
751 set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); 720 set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET);
752 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, 721 TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP,
753 ":mips_io_port_base=0x%08lx\n", 722 ":mips_io_port_base=0x%08lx\n",
@@ -835,6 +804,8 @@ void __init toshiba_rbtx4927_setup(void)
835 } 804 }
836 805
837 /* CCFG */ 806 /* CCFG */
807 /* do reset on watchdog */
808 tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR;
838 /* enable Timeout BusError */ 809 /* enable Timeout BusError */
839 if (tx4927_ccfg_toeon) 810 if (tx4927_ccfg_toeon)
840 tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; 811 tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE;
@@ -936,8 +907,7 @@ void __init toshiba_rbtx4927_setup(void)
936 "+\n"); 907 "+\n");
937} 908}
938 909
939void __init 910void __init plat_time_init(void)
940toshiba_rbtx4927_time_init(void)
941{ 911{
942 mips_hpt_frequency = tx4927_cpu_clock / 2; 912 mips_hpt_frequency = tx4927_cpu_clock / 2;
943 if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) 913 if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
@@ -977,3 +947,55 @@ static int __init rbtx4927_ne_init(void)
977 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 947 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
978} 948}
979device_initcall(rbtx4927_ne_init); 949device_initcall(rbtx4927_ne_init);
950
951/* Watchdog support */
952
953static int __init txx9_wdt_init(unsigned long base)
954{
955 struct resource res = {
956 .start = base,
957 .end = base + 0x100 - 1,
958 .flags = IORESOURCE_MEM,
959 };
960 struct platform_device *dev =
961 platform_device_register_simple("txx9wdt", -1, &res, 1);
962 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
963}
964
965static int __init rbtx4927_wdt_init(void)
966{
967 return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
968}
969device_initcall(rbtx4927_wdt_init);
970
971/* Minimum CLK support */
972
973struct clk *clk_get(struct device *dev, const char *id)
974{
975 if (!strcmp(id, "imbus_clk"))
976 return (struct clk *)50000000;
977 return ERR_PTR(-ENOENT);
978}
979EXPORT_SYMBOL(clk_get);
980
981int clk_enable(struct clk *clk)
982{
983 return 0;
984}
985EXPORT_SYMBOL(clk_enable);
986
987void clk_disable(struct clk *clk)
988{
989}
990EXPORT_SYMBOL(clk_disable);
991
992unsigned long clk_get_rate(struct clk *clk)
993{
994 return (unsigned long)clk;
995}
996EXPORT_SYMBOL(clk_get_rate);
997
998void clk_put(struct clk *clk)
999{
1000}
1001EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
index 8352eca67906..56aa1ed1ee0c 100644
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -1,12 +1,8 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += prom.o setup.o irq.o 5obj-y += prom.o irq.o
10obj-$(CONFIG_KGDB) += dbgio.o 6obj-$(CONFIG_KGDB) += dbgio.o
11 7
12EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
deleted file mode 100644
index 3ba4101d141e..000000000000
--- a/arch/mips/tx4938/common/setup.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/setup.c
3 *
4 * common tx4938 setup routines
5 *
6 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
7 * terms of the GNU General Public License version 2. This program is
8 * licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 *
11 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
12 */
13
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/kernel_stat.h>
17#include <linux/module.h>
18#include <linux/signal.h>
19#include <linux/sched.h>
20#include <linux/types.h>
21#include <linux/interrupt.h>
22#include <linux/ioport.h>
23#include <linux/timex.h>
24#include <linux/slab.h>
25#include <linux/random.h>
26#include <linux/irq.h>
27#include <linux/bitops.h>
28#include <asm/bootinfo.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mipsregs.h>
32#include <asm/system.h>
33#include <asm/time.h>
34#include <asm/tx4938/rbtx4938.h>
35
36extern void toshiba_rbtx4938_setup(void);
37
38void __init tx4938_setup(void);
39void dump_cp0(char *key);
40
41void __init
42plat_mem_setup(void)
43{
44 toshiba_rbtx4938_setup();
45}
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/Makefile b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
index 675bb1c3e40c..2316dd7dd1bd 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/Makefile
+++ b/arch/mips/tx4938/toshiba_rbtx4938/Makefile
@@ -1,10 +1,6 @@
1# 1#
2# Makefile for common code for Toshiba TX4927 based systems 2# Makefile for common code for Toshiba TX4927 based systems
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y += prom.o setup.o irq.o spi_eeprom.o 5obj-y += prom.o setup.o irq.o spi_eeprom.o
10 6
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/prom.c b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
index 69f21c1b7942..1644bffa501a 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/prom.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/prom.c
@@ -47,7 +47,6 @@ void __init prom_init(void)
47#ifndef CONFIG_TX4938_NAND_BOOT 47#ifndef CONFIG_TX4938_NAND_BOOT
48 prom_init_cmdline(); 48 prom_init_cmdline();
49#endif 49#endif
50 mips_machtype = MACH_TOSHIBA_RBTX4938;
51 50
52 msize = tx4938_get_mem_size(); 51 msize = tx4938_get_mem_size();
53 add_memory_region(0, msize << 20, BOOT_MEM_RAM); 52 add_memory_region(0, msize << 20, BOOT_MEM_RAM);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 632e5d201353..61249f049cd6 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -24,16 +24,12 @@
24 24
25#include <asm/wbflush.h> 25#include <asm/wbflush.h>
26#include <asm/reboot.h> 26#include <asm/reboot.h>
27#include <asm/irq.h>
28#include <asm/time.h> 27#include <asm/time.h>
29#include <asm/txx9tmr.h> 28#include <asm/txx9tmr.h>
30#include <asm/uaccess.h>
31#include <asm/io.h> 29#include <asm/io.h>
32#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
33#include <asm/tx4938/rbtx4938.h> 31#include <asm/tx4938/rbtx4938.h>
34#ifdef CONFIG_SERIAL_TXX9 32#ifdef CONFIG_SERIAL_TXX9
35#include <linux/tty.h>
36#include <linux/serial.h>
37#include <linux/serial_core.h> 33#include <linux/serial_core.h>
38#endif 34#endif
39#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
@@ -728,6 +724,8 @@ void __init tx4938_board_setup(void)
728 /* CCFG */ 724 /* CCFG */
729 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ 725 /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */
730 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; 726 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW;
727 /* do reset on watchdog */
728 tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR;
731 /* clear PCIC1 reset */ 729 /* clear PCIC1 reset */
732 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) 730 if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST)
733 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; 731 tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST;
@@ -855,7 +853,7 @@ void __init plat_time_init(void)
855 txx9_gbus_clock / 2); 853 txx9_gbus_clock / 2);
856} 854}
857 855
858void __init toshiba_rbtx4938_setup(void) 856void __init plat_mem_setup(void)
859{ 857{
860 unsigned long long pcfg; 858 unsigned long long pcfg;
861 char *argptr; 859 char *argptr;
@@ -1125,12 +1123,35 @@ static int __init rbtx4938_spi_init(void)
1125} 1123}
1126arch_initcall(rbtx4938_spi_init); 1124arch_initcall(rbtx4938_spi_init);
1127 1125
1126/* Watchdog support */
1127
1128static int __init txx9_wdt_init(unsigned long base)
1129{
1130 struct resource res = {
1131 .start = base,
1132 .end = base + 0x100 - 1,
1133 .flags = IORESOURCE_MEM,
1134 .parent = &tx4938_reg_resource,
1135 };
1136 struct platform_device *dev =
1137 platform_device_register_simple("txx9wdt", -1, &res, 1);
1138 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
1139}
1140
1141static int __init rbtx4938_wdt_init(void)
1142{
1143 return txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
1144}
1145device_initcall(rbtx4938_wdt_init);
1146
1128/* Minimum CLK support */ 1147/* Minimum CLK support */
1129 1148
1130struct clk *clk_get(struct device *dev, const char *id) 1149struct clk *clk_get(struct device *dev, const char *id)
1131{ 1150{
1132 if (!strcmp(id, "spi-baseclk")) 1151 if (!strcmp(id, "spi-baseclk"))
1133 return (struct clk *)(txx9_gbus_clock / 2 / 4); 1152 return (struct clk *)(txx9_gbus_clock / 2 / 4);
1153 if (!strcmp(id, "imbus_clk"))
1154 return (struct clk *)(txx9_gbus_clock / 2);
1134 return ERR_PTR(-ENOENT); 1155 return ERR_PTR(-ENOENT);
1135} 1156}
1136EXPORT_SYMBOL(clk_get); 1157EXPORT_SYMBOL(clk_get);
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index 8d760df686c4..76d4b5ed3fc0 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -40,6 +40,8 @@ void __init plat_time_init(void)
40{ 40{
41 unsigned long tclock; 41 unsigned long tclock;
42 42
43 vr41xx_calculate_clock_frequency();
44
43 tclock = vr41xx_get_tclock_frequency(); 45 tclock = vr41xx_get_tclock_frequency();
44 if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 || 46 if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 ||
45 current_cpu_data.processor_id == PRID_VR4131_REV2_1) 47 current_cpu_data.processor_id == PRID_VR4131_REV2_1)
@@ -50,8 +52,6 @@ void __init plat_time_init(void)
50 52
51void __init plat_mem_setup(void) 53void __init plat_mem_setup(void)
52{ 54{
53 vr41xx_calculate_clock_frequency();
54
55 iomem_resource_init(); 55 iomem_resource_init();
56} 56}
57 57
diff --git a/arch/mips/vr41xx/nec-cmbvr4133/setup.c b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
index 58e47686b499..7723d2011b08 100644
--- a/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+++ b/arch/mips/vr41xx/nec-cmbvr4133/setup.c
@@ -50,7 +50,7 @@ static struct mtd_partition cmbvr4133_mtd_parts[] = {
50 } 50 }
51}; 51};
52 52
53#define number_partitions (sizeof(cmbvr4133_mtd_parts)/sizeof(struct mtd_partition)) 53#define number_partitions ARRAY_SIZE(cmbvr4133_mtd_parts)
54#endif 54#endif
55 55
56extern void i8259_init(void); 56extern void i8259_init(void);
@@ -64,8 +64,6 @@ static void __init nec_cmbvr4133_setup(void)
64#endif 64#endif
65 set_io_port_base(KSEG1ADDR(0x16000000)); 65 set_io_port_base(KSEG1ADDR(0x16000000));
66 66
67 mips_machtype = MACH_NEC_CMBVR4133;
68
69#ifdef CONFIG_PCI 67#ifdef CONFIG_PCI
70#ifdef CONFIG_ROCKHOPPER 68#ifdef CONFIG_ROCKHOPPER
71 ali_m5229_preinit(); 69 ali_m5229_preinit();
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 40d0ff9b81ab..50b4a3a25d0a 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -172,11 +172,11 @@ SECTIONS
172 __init_begin = .; 172 __init_begin = .;
173 .init.text : { 173 .init.text : {
174 _sinittext = .; 174 _sinittext = .;
175 *(.init.text) 175 INIT_TEXT
176 _einittext = .; 176 _einittext = .;
177 } 177 }
178 .init.data : { 178 .init.data : {
179 *(.init.data) 179 INIT_DATA
180 } 180 }
181 . = ALIGN(16); 181 . = ALIGN(16);
182 .init.setup : { 182 .init.setup : {
@@ -215,10 +215,10 @@ SECTIONS
215 * from .altinstructions and .eh_frame 215 * from .altinstructions and .eh_frame
216 */ 216 */
217 .exit.text : { 217 .exit.text : {
218 *(.exit.text) 218 EXIT_TEXT
219 } 219 }
220 .exit.data : { 220 .exit.data : {
221 *(.exit.data) 221 EXIT_DATA
222 } 222 }
223#ifdef CONFIG_BLK_DEV_INITRD 223#ifdef CONFIG_BLK_DEV_INITRD
224 . = ALIGN(PAGE_SIZE); 224 . = ALIGN(PAGE_SIZE);
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 18e32719d0ed..4b1d98b8135e 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -65,7 +65,7 @@ obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib))))
65obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) 65obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat))))
66 66
67quiet_cmd_copy_zlib = COPY $@ 67quiet_cmd_copy_zlib = COPY $@
68 cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ 68 cmd_copy_zlib = sed "s@__used@@;s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
69 69
70quiet_cmd_copy_zlibheader = COPY $@ 70quiet_cmd_copy_zlibheader = COPY $@
71 cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@ 71 cmd_copy_zlibheader = sed "s@<linux/\([^>]*\).*@\"\1\"@" $< > $@
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 25d9a96484dd..c8127f832df0 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -158,7 +158,7 @@ static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
158 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \ 158 unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
159 return sprintf(buf, "%lx\n", val); \ 159 return sprintf(buf, "%lx\n", val); \
160} \ 160} \
161static ssize_t __attribute_used__ \ 161static ssize_t __used \
162 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \ 162 store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
163{ \ 163{ \
164 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \ 164 struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f66fa5d966b0..0afb9e31d2a0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -23,7 +23,7 @@ SECTIONS
23 /* Sections to be discarded. */ 23 /* Sections to be discarded. */
24 /DISCARD/ : { 24 /DISCARD/ : {
25 *(.exitcall.exit) 25 *(.exitcall.exit)
26 *(.exit.data) 26 EXIT_DATA
27 } 27 }
28 28
29 . = KERNELBASE; 29 . = KERNELBASE;
@@ -76,17 +76,19 @@ SECTIONS
76 76
77 .init.text : { 77 .init.text : {
78 _sinittext = .; 78 _sinittext = .;
79 *(.init.text) 79 INIT_TEXT
80 _einittext = .; 80 _einittext = .;
81 } 81 }
82 82
83 /* .exit.text is discarded at runtime, not link time, 83 /* .exit.text is discarded at runtime, not link time,
84 * to deal with references from __bug_table 84 * to deal with references from __bug_table
85 */ 85 */
86 .exit.text : { *(.exit.text) } 86 .exit.text : {
87 EXIT_TEXT
88 }
87 89
88 .init.data : { 90 .init.data : {
89 *(.init.data); 91 INIT_DATA
90 __vtop_table_begin = .; 92 __vtop_table_begin = .;
91 *(.vtop_fixup); 93 *(.vtop_fixup);
92 __vtop_table_end = .; 94 __vtop_table_end = .;
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index cddc250a6a5c..446a8bbb847b 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -172,15 +172,15 @@ static void power4_stop(void)
172} 172}
173 173
174/* Fake functions used by canonicalize_pc */ 174/* Fake functions used by canonicalize_pc */
175static void __attribute_used__ hypervisor_bucket(void) 175static void __used hypervisor_bucket(void)
176{ 176{
177} 177}
178 178
179static void __attribute_used__ rtas_bucket(void) 179static void __used rtas_bucket(void)
180{ 180{
181} 181}
182 182
183static void __attribute_used__ kernel_unknown_bucket(void) 183static void __used kernel_unknown_bucket(void)
184{ 184{
185} 185}
186 186
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 98c1212674f6..52b64fcbdfc5 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -97,14 +97,14 @@ SECTIONS
97 __init_begin = .; 97 __init_begin = .;
98 .init.text : { 98 .init.text : {
99 _sinittext = .; 99 _sinittext = .;
100 *(.init.text) 100 INIT_TEXT
101 _einittext = .; 101 _einittext = .;
102 } 102 }
103 /* .exit.text is discarded at runtime, not link time, 103 /* .exit.text is discarded at runtime, not link time,
104 to deal with references from __bug_table */ 104 to deal with references from __bug_table */
105 .exit.text : { *(.exit.text) } 105 .exit.text : { EXIT_TEXT }
106 .init.data : { 106 .init.data : {
107 *(.init.data); 107 INIT_DATA
108 __vtop_table_begin = .; 108 __vtop_table_begin = .;
109 *(.vtop_fixup); 109 *(.vtop_fixup);
110 __vtop_table_end = .; 110 __vtop_table_end = .;
@@ -164,6 +164,6 @@ SECTIONS
164 /* Sections to be discarded. */ 164 /* Sections to be discarded. */
165 /DISCARD/ : { 165 /DISCARD/ : {
166 *(.exitcall.exit) 166 *(.exitcall.exit)
167 *(.exit.data) 167 EXIT_DATA
168 } 168 }
169} 169}
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 936159199346..7d43c3cd3ef3 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -97,7 +97,7 @@ SECTIONS
97 __init_begin = .; 97 __init_begin = .;
98 .init.text : { 98 .init.text : {
99 _sinittext = .; 99 _sinittext = .;
100 *(.init.text) 100 INIT_TEXT
101 _einittext = .; 101 _einittext = .;
102 } 102 }
103 /* 103 /*
@@ -105,11 +105,11 @@ SECTIONS
105 * to deal with references from __bug_table 105 * to deal with references from __bug_table
106 */ 106 */
107 .exit.text : { 107 .exit.text : {
108 *(.exit.text) 108 EXIT_TEXT
109 } 109 }
110 110
111 .init.data : { 111 .init.data : {
112 *(.init.data) 112 INIT_DATA
113 } 113 }
114 . = ALIGN(0x100); 114 . = ALIGN(0x100);
115 .init.setup : { 115 .init.setup : {
@@ -156,7 +156,7 @@ SECTIONS
156 156
157 /* Sections to be discarded */ 157 /* Sections to be discarded */
158 /DISCARD/ : { 158 /DISCARD/ : {
159 *(.exit.data) 159 EXIT_DATA
160 *(.exitcall.exit) 160 *(.exitcall.exit)
161 } 161 }
162 162
diff --git a/arch/sh/kernel/vmlinux_32.lds.S b/arch/sh/kernel/vmlinux_32.lds.S
index d549fac6d3e7..c7113786ecd4 100644
--- a/arch/sh/kernel/vmlinux_32.lds.S
+++ b/arch/sh/kernel/vmlinux_32.lds.S
@@ -84,9 +84,9 @@ SECTIONS
84 . = ALIGN(PAGE_SIZE); /* Init code and data */ 84 . = ALIGN(PAGE_SIZE); /* Init code and data */
85 __init_begin = .; 85 __init_begin = .;
86 _sinittext = .; 86 _sinittext = .;
87 .init.text : { *(.init.text) } 87 .init.text : { INIT_TEXT }
88 _einittext = .; 88 _einittext = .;
89 .init.data : { *(.init.data) } 89 .init.data : { INIT_DATA }
90 90
91 . = ALIGN(16); 91 . = ALIGN(16);
92 __setup_start = .; 92 __setup_start = .;
@@ -122,8 +122,8 @@ SECTIONS
122 * .exit.text is discarded at runtime, not link time, to deal with 122 * .exit.text is discarded at runtime, not link time, to deal with
123 * references from __bug_table 123 * references from __bug_table
124 */ 124 */
125 .exit.text : { *(.exit.text) } 125 .exit.text : { EXIT_TEXT }
126 .exit.data : { *(.exit.data) } 126 .exit.data : { EXIT_DATA }
127 127
128 . = ALIGN(PAGE_SIZE); 128 . = ALIGN(PAGE_SIZE);
129 .bss : { 129 .bss : {
diff --git a/arch/sh/kernel/vmlinux_64.lds.S b/arch/sh/kernel/vmlinux_64.lds.S
index 2fd0f7401484..3f1bd6392bb3 100644
--- a/arch/sh/kernel/vmlinux_64.lds.S
+++ b/arch/sh/kernel/vmlinux_64.lds.S
@@ -96,9 +96,9 @@ SECTIONS
96 . = ALIGN(PAGE_SIZE); /* Init code and data */ 96 . = ALIGN(PAGE_SIZE); /* Init code and data */
97 __init_begin = .; 97 __init_begin = .;
98 _sinittext = .; 98 _sinittext = .;
99 .init.text : C_PHYS(.init.text) { *(.init.text) } 99 .init.text : C_PHYS(.init.text) { INIT_TEXT }
100 _einittext = .; 100 _einittext = .;
101 .init.data : C_PHYS(.init.data) { *(.init.data) } 101 .init.data : C_PHYS(.init.data) { INIT_DATA }
102 . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */ 102 . = ALIGN(L1_CACHE_BYTES); /* Better if Cache Line aligned */
103 __setup_start = .; 103 __setup_start = .;
104 .init.setup : C_PHYS(.init.setup) { *(.init.setup) } 104 .init.setup : C_PHYS(.init.setup) { *(.init.setup) }
@@ -134,8 +134,8 @@ SECTIONS
134 * .exit.text is discarded at runtime, not link time, to deal with 134 * .exit.text is discarded at runtime, not link time, to deal with
135 * references from __bug_table 135 * references from __bug_table
136 */ 136 */
137 .exit.text : C_PHYS(.exit.text) { *(.exit.text) } 137 .exit.text : C_PHYS(.exit.text) { EXIT_TEXT }
138 .exit.data : C_PHYS(.exit.data) { *(.exit.data) } 138 .exit.data : C_PHYS(.exit.data) { EXIT_DATA }
139 139
140 . = ALIGN(PAGE_SIZE); 140 . = ALIGN(PAGE_SIZE);
141 .bss : C_PHYS(.bss) { 141 .bss : C_PHYS(.bss) {
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index a8b4200f9cc3..216147d6e61f 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -48,12 +48,12 @@ SECTIONS
48 __init_begin = .; 48 __init_begin = .;
49 .init.text : { 49 .init.text : {
50 _sinittext = .; 50 _sinittext = .;
51 *(.init.text) 51 INIT_TEXT
52 _einittext = .; 52 _einittext = .;
53 } 53 }
54 __init_text_end = .; 54 __init_text_end = .;
55 .init.data : { 55 .init.data : {
56 *(.init.data) 56 INIT_DATA
57 } 57 }
58 . = ALIGN(16); 58 . = ALIGN(16);
59 .init.setup : { 59 .init.setup : {
@@ -102,8 +102,8 @@ SECTIONS
102 _end = . ; 102 _end = . ;
103 PROVIDE (end = .); 103 PROVIDE (end = .);
104 /DISCARD/ : { 104 /DISCARD/ : {
105 *(.exit.text) 105 EXIT_TEXT
106 *(.exit.data) 106 EXIT_DATA
107 *(.exitcall.exit) 107 *(.exitcall.exit)
108 } 108 }
109 109
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 953be816fa25..dc7bf1b6321c 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -175,7 +175,7 @@ unsigned long compute_effective_address(struct pt_regs *regs,
175} 175}
176 176
177/* This is just to make gcc think die_if_kernel does return... */ 177/* This is just to make gcc think die_if_kernel does return... */
178static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs) 178static void __used unaligned_panic(char *str, struct pt_regs *regs)
179{ 179{
180 die_if_kernel(str, regs); 180 die_if_kernel(str, regs);
181} 181}
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 9fcd503bc04a..01f809617e5e 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -56,11 +56,11 @@ SECTIONS
56 .init.text : { 56 .init.text : {
57 __init_begin = .; 57 __init_begin = .;
58 _sinittext = .; 58 _sinittext = .;
59 *(.init.text) 59 INIT_TEXT
60 _einittext = .; 60 _einittext = .;
61 } 61 }
62 .init.data : { 62 .init.data : {
63 *(.init.data) 63 INIT_DATA
64 } 64 }
65 . = ALIGN(16); 65 . = ALIGN(16);
66 .init.setup : { 66 .init.setup : {
@@ -137,8 +137,8 @@ SECTIONS
137 PROVIDE (end = .); 137 PROVIDE (end = .);
138 138
139 /DISCARD/ : { 139 /DISCARD/ : {
140 *(.exit.text) 140 EXIT_TEXT
141 *(.exit.data) 141 EXIT_DATA
142 *(.exitcall.exit) 142 *(.exitcall.exit)
143 } 143 }
144 144
diff --git a/arch/um/include/init.h b/arch/um/include/init.h
index d4de7c0120ce..cebc6cae9190 100644
--- a/arch/um/include/init.h
+++ b/arch/um/include/init.h
@@ -42,15 +42,15 @@ typedef void (*exitcall_t)(void);
42 42
43/* These are for everybody (although not all archs will actually 43/* These are for everybody (although not all archs will actually
44 discard it in modules) */ 44 discard it in modules) */
45#define __init __attribute__ ((__section__ (".init.text"))) 45#define __init __section(.init.text)
46#define __initdata __attribute__ ((__section__ (".init.data"))) 46#define __initdata __section(.init.data)
47#define __exitdata __attribute__ ((__section__(".exit.data"))) 47#define __exitdata __section(.exit.data)
48#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) 48#define __exit_call __used __section(.exitcall.exit)
49 49
50#ifdef MODULE 50#ifdef MODULE
51#define __exit __attribute__ ((__section__(".exit.text"))) 51#define __exit __section(.exit.text)
52#else 52#else
53#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) 53#define __exit __used __section(.exit.text)
54#endif 54#endif
55 55
56#endif 56#endif
@@ -103,16 +103,16 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
103 * Mark functions and data as being only used at initialization 103 * Mark functions and data as being only used at initialization
104 * or exit time. 104 * or exit time.
105 */ 105 */
106#define __uml_init_setup __attribute_used__ __attribute__ ((__section__ (".uml.setup.init"))) 106#define __uml_init_setup __used __section(.uml.setup.init)
107#define __uml_setup_help __attribute_used__ __attribute__ ((__section__ (".uml.help.init"))) 107#define __uml_setup_help __used __section(.uml.help.init)
108#define __uml_init_call __attribute_used__ __attribute__ ((__section__ (".uml.initcall.init"))) 108#define __uml_init_call __used __section(.uml.initcall.init)
109#define __uml_postsetup_call __attribute_used__ __attribute__ ((__section__ (".uml.postsetup.init"))) 109#define __uml_postsetup_call __used __section(.uml.postsetup.init)
110#define __uml_exit_call __attribute_used__ __attribute__ ((__section__ (".uml.exitcall.exit"))) 110#define __uml_exit_call __used __section(.uml.exitcall.exit)
111 111
112#ifndef __KERNEL__ 112#ifndef __KERNEL__
113 113
114#define __define_initcall(level,fn) \ 114#define __define_initcall(level,fn) \
115 static initcall_t __initcall_##fn __attribute_used__ \ 115 static initcall_t __initcall_##fn __used \
116 __attribute__((__section__(".initcall" level ".init"))) = fn 116 __attribute__((__section__(".initcall" level ".init"))) = fn
117 117
118/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll 118/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
@@ -122,7 +122,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
122 122
123#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn 123#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
124 124
125#define __init_call __attribute_used__ __attribute__ ((__section__ (".initcall.init"))) 125#define __init_call __used __section(.initcall.init)
126 126
127#endif 127#endif
128 128
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 3866f4960f04..26090b7f323e 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -17,7 +17,7 @@ SECTIONS
17 __init_begin = .; 17 __init_begin = .;
18 .init.text : { 18 .init.text : {
19 _sinittext = .; 19 _sinittext = .;
20 *(.init.text) 20 INIT_TEXT
21 _einittext = .; 21 _einittext = .;
22 } 22 }
23 23
@@ -84,7 +84,7 @@ SECTIONS
84 84
85 #include "asm/common.lds.S" 85 #include "asm/common.lds.S"
86 86
87 init.data : { *(.init.data) } 87 init.data : { INIT_DATA }
88 88
89 /* Ensure the __preinit_array_start label is properly aligned. We 89 /* Ensure the __preinit_array_start label is properly aligned. We
90 could instead move the label definition inside the section, but 90 could instead move the label definition inside the section, but
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 13df191e2b41..5828c1d54505 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -23,7 +23,7 @@ SECTIONS
23 __init_begin = .; 23 __init_begin = .;
24 .init.text : { 24 .init.text : {
25 _sinittext = .; 25 _sinittext = .;
26 *(.init.text) 26 INIT_TEXT
27 _einittext = .; 27 _einittext = .;
28 } 28 }
29 . = ALIGN(4096); 29 . = ALIGN(4096);
@@ -48,7 +48,7 @@ SECTIONS
48 48
49 #include "asm/common.lds.S" 49 #include "asm/common.lds.S"
50 50
51 init.data : { *(init.data) } 51 init.data : { INIT_DATA }
52 .data : 52 .data :
53 { 53 {
54 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ 54 . = ALIGN(KERNEL_STACK_SIZE); /* init_task */
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 6172599b4ce2..d08cd1d27f27 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -114,7 +114,7 @@
114#define DATA_CONTENTS \ 114#define DATA_CONTENTS \
115 __sdata = . ; \ 115 __sdata = . ; \
116 DATA_DATA \ 116 DATA_DATA \
117 *(.exit.data) /* 2.5 convention */ \ 117 EXIT_DATA /* 2.5 convention */ \
118 *(.data.exit) /* 2.4 convention */ \ 118 *(.data.exit) /* 2.4 convention */ \
119 . = ALIGN (16) ; \ 119 . = ALIGN (16) ; \
120 *(.data.cacheline_aligned) \ 120 *(.data.cacheline_aligned) \
@@ -157,9 +157,9 @@
157 . = ALIGN (4096) ; \ 157 . = ALIGN (4096) ; \
158 __init_start = . ; \ 158 __init_start = . ; \
159 __sinittext = .; \ 159 __sinittext = .; \
160 *(.init.text) /* 2.5 convention */ \ 160 INIT_TEXT /* 2.5 convention */ \
161 __einittext = .; \ 161 __einittext = .; \
162 *(.init.data) \ 162 INIT_DATA \
163 *(.text.init) /* 2.4 convention */ \ 163 *(.text.init) /* 2.4 convention */ \
164 *(.data.init) \ 164 *(.data.init) \
165 INITCALL_CONTENTS \ 165 INITCALL_CONTENTS \
@@ -170,7 +170,7 @@
170#define ROMK_INIT_RAM_CONTENTS \ 170#define ROMK_INIT_RAM_CONTENTS \
171 . = ALIGN (4096) ; \ 171 . = ALIGN (4096) ; \
172 __init_start = . ; \ 172 __init_start = . ; \
173 *(.init.data) /* 2.5 convention */ \ 173 INIT_DATA /* 2.5 convention */ \
174 *(.data.init) /* 2.4 convention */ \ 174 *(.data.init) /* 2.4 convention */ \
175 __init_end = . ; \ 175 __init_end = . ; \
176 . = ALIGN (4096) ; 176 . = ALIGN (4096) ;
@@ -179,7 +179,7 @@
179 should go into ROM. */ 179 should go into ROM. */
180#define ROMK_INIT_ROM_CONTENTS \ 180#define ROMK_INIT_ROM_CONTENTS \
181 _sinittext = .; \ 181 _sinittext = .; \
182 *(.init.text) /* 2.5 convention */ \ 182 INIT_TEXT /* 2.5 convention */ \
183 _einittext = .; \ 183 _einittext = .; \
184 *(.text.init) /* 2.4 convention */ \ 184 *(.text.init) /* 2.4 convention */ \
185 INITCALL_CONTENTS \ 185 INITCALL_CONTENTS \
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index 7d72cce00529..84c913f38f98 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -131,10 +131,12 @@ SECTIONS
131 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 131 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
132 __init_begin = .; 132 __init_begin = .;
133 _sinittext = .; 133 _sinittext = .;
134 *(.init.text) 134 INIT_TEXT
135 _einittext = .; 135 _einittext = .;
136 } 136 }
137 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } 137 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
138 INIT_DATA
139 }
138 . = ALIGN(16); 140 . = ALIGN(16);
139 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { 141 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
140 __setup_start = .; 142 __setup_start = .;
@@ -169,8 +171,12 @@ SECTIONS
169 } 171 }
170 /* .exit.text is discard at runtime, not link time, to deal with references 172 /* .exit.text is discard at runtime, not link time, to deal with references
171 from .altinstructions and .eh_frame */ 173 from .altinstructions and .eh_frame */
172 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } 174 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
173 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } 175 EXIT_TEXT
176 }
177 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
178 EXIT_DATA
179 }
174#if defined(CONFIG_BLK_DEV_INITRD) 180#if defined(CONFIG_BLK_DEV_INITRD)
175 . = ALIGN(4096); 181 . = ALIGN(4096);
176 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { 182 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index ba8ea97abd21..ea5386944e67 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -155,12 +155,15 @@ SECTIONS
155 __init_begin = .; 155 __init_begin = .;
156 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 156 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
157 _sinittext = .; 157 _sinittext = .;
158 *(.init.text) 158 INIT_TEXT
159 _einittext = .; 159 _einittext = .;
160 } 160 }
161 __initdata_begin = .; 161 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
162 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } 162 __initdata_begin = .;
163 __initdata_end = .; 163 INIT_DATA
164 __initdata_end = .;
165 }
166
164 . = ALIGN(16); 167 . = ALIGN(16);
165 __setup_start = .; 168 __setup_start = .;
166 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } 169 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
@@ -187,8 +190,12 @@ SECTIONS
187 } 190 }
188 /* .exit.text is discard at runtime, not link time, to deal with references 191 /* .exit.text is discard at runtime, not link time, to deal with references
189 from .altinstructions and .eh_frame */ 192 from .altinstructions and .eh_frame */
190 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } 193 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
191 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } 194 EXIT_TEXT
195 }
196 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
197 EXIT_DATA
198 }
192 199
193/* vdso blob that is mapped into user space */ 200/* vdso blob that is mapped into user space */
194 vdso_start = . ; 201 vdso_start = . ;
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ac4ed52034db..7d0f55a4982d 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -136,13 +136,13 @@ SECTIONS
136 __init_begin = .; 136 __init_begin = .;
137 .init.text : { 137 .init.text : {
138 _sinittext = .; 138 _sinittext = .;
139 *(.init.literal) *(.init.text) 139 *(.init.literal) INIT_TEXT
140 _einittext = .; 140 _einittext = .;
141 } 141 }
142 142
143 .init.data : 143 .init.data :
144 { 144 {
145 *(.init.data) 145 INIT_DATA
146 . = ALIGN(0x4); 146 . = ALIGN(0x4);
147 __tagtable_begin = .; 147 __tagtable_begin = .;
148 *(.taglist) 148 *(.taglist)
@@ -278,8 +278,9 @@ SECTIONS
278 /* Sections to be discarded */ 278 /* Sections to be discarded */
279 /DISCARD/ : 279 /DISCARD/ :
280 { 280 {
281 *(.exit.literal .exit.text) 281 *(.exit.literal)
282 *(.exit.data) 282 EXIT_TEXT
283 EXIT_DATA
283 *(.exitcall.exit) 284 *(.exitcall.exit)
284 } 285 }
285 286
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 10aec22a8f98..64e304a2f884 100644
--- a/arch/xtensa/mm/Makefile
+++ b/arch/xtensa/mm/Makefile
@@ -1,9 +1,5 @@
1# 1#
2# Makefile for the Linux/Xtensa-specific parts of the memory manager. 2# Makefile for the Linux/Xtensa-specific parts of the memory manager.
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y := init.o fault.o tlb.o misc.o cache.o 5obj-y := init.o fault.o tlb.o misc.o cache.o
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile
index 5b394e9620e5..af96e314d71f 100644
--- a/arch/xtensa/platform-iss/Makefile
+++ b/arch/xtensa/platform-iss/Makefile
@@ -3,11 +3,6 @@
3# Makefile for the Xtensa Instruction Set Simulator (ISS) 3# Makefile for the Xtensa Instruction Set Simulator (ISS)
4# "prom monitor" library routines under Linux. 4# "prom monitor" library routines under Linux.
5# 5#
6# Note! Dependencies are done automagically by 'make dep', which also
7# removes any old dependencies. DON'T put your own dependencies here
8# unless it's something special (ie not a .c file).
9#
10# Note 2! The CFLAGS definitions are in the main makefile...
11 6
12obj-y = io.o console.o setup.o network.o 7obj-y = io.o console.o setup.o network.o
13 8
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 06a86fe6a78d..de28dfd3b96c 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -2,9 +2,5 @@ obj-$(CONFIG_PM) += sysfs.o
2obj-$(CONFIG_PM_SLEEP) += main.o 2obj-$(CONFIG_PM_SLEEP) += main.o
3obj-$(CONFIG_PM_TRACE) += trace.o 3obj-$(CONFIG_PM_TRACE) += trace.o
4 4
5ifeq ($(CONFIG_DEBUG_DRIVER),y) 5ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
6EXTRA_CFLAGS += -DDEBUG 6ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG
7endif
8ifeq ($(CONFIG_PM_VERBOSE),y)
9EXTRA_CFLAGS += -DDEBUG
10endif
diff --git a/drivers/infiniband/hw/cxgb3/Makefile b/drivers/infiniband/hw/cxgb3/Makefile
index 36b98989b15e..7e7b5a66f042 100644
--- a/drivers/infiniband/hw/cxgb3/Makefile
+++ b/drivers/infiniband/hw/cxgb3/Makefile
@@ -1,5 +1,4 @@
1EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3 \ 1EXTRA_CFLAGS += -Idrivers/net/cxgb3
2 -I$(TOPDIR)/drivers/infiniband/hw/cxgb3/core
3 2
4obj-$(CONFIG_INFINIBAND_CXGB3) += iw_cxgb3.o 3obj-$(CONFIG_INFINIBAND_CXGB3) += iw_cxgb3.o
5 4
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index b242cee656e7..80e3f03b5041 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -31,8 +31,8 @@ extern struct rio_route_ops __end_rio_route_ops[];
31 31
32/* Helpers internal to the RIO core code */ 32/* Helpers internal to the RIO core code */
33#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \ 33#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \
34 static struct rio_route_ops __rio_route_ops __attribute_used__ \ 34 static struct rio_route_ops __rio_route_ops __used \
35 __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook }; 35 __section(section)= { vid, did, add_hook, get_hook };
36 36
37/** 37/**
38 * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations 38 * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
diff --git a/fs/Kconfig b/fs/Kconfig
index 9656139d2e99..219ec06a8c7e 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -236,6 +236,7 @@ config JBD_DEBUG
236 236
237config JBD2 237config JBD2
238 tristate 238 tristate
239 select CRC32
239 help 240 help
240 This is a generic journaling layer for block devices that support 241 This is a generic journaling layer for block devices that support
241 both 32-bit and 64-bit block numbers. It is currently used by 242 both 32-bit and 64-bit block numbers. It is currently used by
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 33fe39ad4e03..0cc3597c1197 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -546,11 +546,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
546 dentry->d_op = &afs_fs_dentry_operations; 546 dentry->d_op = &afs_fs_dentry_operations;
547 547
548 d_add(dentry, inode); 548 d_add(dentry, inode);
549 _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }", 549 _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }",
550 fid.vnode, 550 fid.vnode,
551 fid.unique, 551 fid.unique,
552 dentry->d_inode->i_ino, 552 dentry->d_inode->i_ino,
553 dentry->d_inode->i_version); 553 (unsigned long long)dentry->d_inode->i_version);
554 554
555 return NULL; 555 return NULL;
556} 556}
@@ -630,9 +630,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
630 * been deleted and replaced, and the original vnode ID has 630 * been deleted and replaced, and the original vnode ID has
631 * been reused */ 631 * been reused */
632 if (fid.unique != vnode->fid.unique) { 632 if (fid.unique != vnode->fid.unique) {
633 _debug("%s: file deleted (uq %u -> %u I:%lu)", 633 _debug("%s: file deleted (uq %u -> %u I:%llu)",
634 dentry->d_name.name, fid.unique, 634 dentry->d_name.name, fid.unique,
635 vnode->fid.unique, dentry->d_inode->i_version); 635 vnode->fid.unique,
636 (unsigned long long)dentry->d_inode->i_version);
636 spin_lock(&vnode->lock); 637 spin_lock(&vnode->lock);
637 set_bit(AFS_VNODE_DELETED, &vnode->flags); 638 set_bit(AFS_VNODE_DELETED, &vnode->flags);
638 spin_unlock(&vnode->lock); 639 spin_unlock(&vnode->lock);
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index d196840127c6..84750c8e9f95 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -301,7 +301,8 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
301 301
302 inode = dentry->d_inode; 302 inode = dentry->d_inode;
303 303
304 _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); 304 _enter("{ ino=%lu v=%llu }", inode->i_ino,
305 (unsigned long long)inode->i_version);
305 306
306 generic_fillattr(inode, stat); 307 generic_fillattr(inode, stat);
307 return 0; 308 return 0;
diff --git a/fs/buffer.c b/fs/buffer.c
index 7249e014819e..456c9ab7705b 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3213,6 +3213,50 @@ static int buffer_cpu_notify(struct notifier_block *self,
3213 return NOTIFY_OK; 3213 return NOTIFY_OK;
3214} 3214}
3215 3215
3216/**
3217 * bh_uptodate_or_lock: Test whether the buffer is uptodate
3218 * @bh: struct buffer_head
3219 *
3220 * Return true if the buffer is up-to-date and false,
3221 * with the buffer locked, if not.
3222 */
3223int bh_uptodate_or_lock(struct buffer_head *bh)
3224{
3225 if (!buffer_uptodate(bh)) {
3226 lock_buffer(bh);
3227 if (!buffer_uptodate(bh))
3228 return 0;
3229 unlock_buffer(bh);
3230 }
3231 return 1;
3232}
3233EXPORT_SYMBOL(bh_uptodate_or_lock);
3234
3235/**
3236 * bh_submit_read: Submit a locked buffer for reading
3237 * @bh: struct buffer_head
3238 *
3239 * Returns zero on success and -EIO on error.
3240 */
3241int bh_submit_read(struct buffer_head *bh)
3242{
3243 BUG_ON(!buffer_locked(bh));
3244
3245 if (buffer_uptodate(bh)) {
3246 unlock_buffer(bh);
3247 return 0;
3248 }
3249
3250 get_bh(bh);
3251 bh->b_end_io = end_buffer_read_sync;
3252 submit_bh(READ, bh);
3253 wait_on_buffer(bh);
3254 if (buffer_uptodate(bh))
3255 return 0;
3256 return -EIO;
3257}
3258EXPORT_SYMBOL(bh_submit_read);
3259
3216void __init buffer_init(void) 3260void __init buffer_init(void)
3217{ 3261{
3218 int nrpages; 3262 int nrpages;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index da8cb3b3592c..ffdc022cae64 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1376,7 +1376,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
1376 return -EINVAL; 1376 return -EINVAL;
1377} 1377}
1378 1378
1379static __attribute_used__ int 1379static __used int
1380ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) 1380ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg)
1381{ 1381{
1382 return -EINVAL; 1382 return -EINVAL;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 154e25f13d77..6abaf75163f0 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -680,11 +680,31 @@ static int ext2_check_descriptors (struct super_block * sb)
680static loff_t ext2_max_size(int bits) 680static loff_t ext2_max_size(int bits)
681{ 681{
682 loff_t res = EXT2_NDIR_BLOCKS; 682 loff_t res = EXT2_NDIR_BLOCKS;
683 /* This constant is calculated to be the largest file size for a 683 int meta_blocks;
684 * dense, 4k-blocksize file such that the total number of 684 loff_t upper_limit;
685
686 /* This is calculated to be the largest file size for a
687 * dense, file such that the total number of
685 * sectors in the file, including data and all indirect blocks, 688 * sectors in the file, including data and all indirect blocks,
686 * does not exceed 2^32. */ 689 * does not exceed 2^32 -1
687 const loff_t upper_limit = 0x1ff7fffd000LL; 690 * __u32 i_blocks representing the total number of
691 * 512 bytes blocks of the file
692 */
693 upper_limit = (1LL << 32) - 1;
694
695 /* total blocks in file system block size */
696 upper_limit >>= (bits - 9);
697
698
699 /* indirect blocks */
700 meta_blocks = 1;
701 /* double indirect blocks */
702 meta_blocks += 1 + (1LL << (bits-2));
703 /* tripple indirect blocks */
704 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
705
706 upper_limit -= meta_blocks;
707 upper_limit <<= bits;
688 708
689 res += 1LL << (bits-2); 709 res += 1LL << (bits-2);
690 res += 1LL << (2*(bits-2)); 710 res += 1LL << (2*(bits-2));
@@ -692,6 +712,10 @@ static loff_t ext2_max_size(int bits)
692 res <<= bits; 712 res <<= bits;
693 if (res > upper_limit) 713 if (res > upper_limit)
694 res = upper_limit; 714 res = upper_limit;
715
716 if (res > MAX_LFS_FILESIZE)
717 res = MAX_LFS_FILESIZE;
718
695 return res; 719 return res;
696} 720}
697 721
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index cb14de1502c3..f3675cc630e9 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1436,11 +1436,31 @@ static void ext3_orphan_cleanup (struct super_block * sb,
1436static loff_t ext3_max_size(int bits) 1436static loff_t ext3_max_size(int bits)
1437{ 1437{
1438 loff_t res = EXT3_NDIR_BLOCKS; 1438 loff_t res = EXT3_NDIR_BLOCKS;
1439 /* This constant is calculated to be the largest file size for a 1439 int meta_blocks;
1440 * dense, 4k-blocksize file such that the total number of 1440 loff_t upper_limit;
1441
1442 /* This is calculated to be the largest file size for a
1443 * dense, file such that the total number of
1441 * sectors in the file, including data and all indirect blocks, 1444 * sectors in the file, including data and all indirect blocks,
1442 * does not exceed 2^32. */ 1445 * does not exceed 2^32 -1
1443 const loff_t upper_limit = 0x1ff7fffd000LL; 1446 * __u32 i_blocks representing the total number of
1447 * 512 bytes blocks of the file
1448 */
1449 upper_limit = (1LL << 32) - 1;
1450
1451 /* total blocks in file system block size */
1452 upper_limit >>= (bits - 9);
1453
1454
1455 /* indirect blocks */
1456 meta_blocks = 1;
1457 /* double indirect blocks */
1458 meta_blocks += 1 + (1LL << (bits-2));
1459 /* tripple indirect blocks */
1460 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
1461
1462 upper_limit -= meta_blocks;
1463 upper_limit <<= bits;
1444 1464
1445 res += 1LL << (bits-2); 1465 res += 1LL << (bits-2);
1446 res += 1LL << (2*(bits-2)); 1466 res += 1LL << (2*(bits-2));
@@ -1448,6 +1468,10 @@ static loff_t ext3_max_size(int bits)
1448 res <<= bits; 1468 res <<= bits;
1449 if (res > upper_limit) 1469 if (res > upper_limit)
1450 res = upper_limit; 1470 res = upper_limit;
1471
1472 if (res > MAX_LFS_FILESIZE)
1473 res = MAX_LFS_FILESIZE;
1474
1451 return res; 1475 return res;
1452} 1476}
1453 1477
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
index ae6e7e502ac9..ac6fa8ca0a2f 100644
--- a/fs/ext4/Makefile
+++ b/fs/ext4/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
6 6
7ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ 7ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
8 ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ 8 ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \
9 ext4_jbd2.o 9 ext4_jbd2.o migrate.o mballoc.o
10 10
11ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 11ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
12ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o 12ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 71ee95e534fd..ac75ea953d83 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -29,7 +29,7 @@
29 * Calculate the block group number and offset, given a block number 29 * Calculate the block group number and offset, given a block number
30 */ 30 */
31void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, 31void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
32 unsigned long *blockgrpp, ext4_grpblk_t *offsetp) 32 ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
33{ 33{
34 struct ext4_super_block *es = EXT4_SB(sb)->s_es; 34 struct ext4_super_block *es = EXT4_SB(sb)->s_es;
35 ext4_grpblk_t offset; 35 ext4_grpblk_t offset;
@@ -46,7 +46,7 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
46/* Initializes an uninitialized block bitmap if given, and returns the 46/* Initializes an uninitialized block bitmap if given, and returns the
47 * number of blocks free in the group. */ 47 * number of blocks free in the group. */
48unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, 48unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
49 int block_group, struct ext4_group_desc *gdp) 49 ext4_group_t block_group, struct ext4_group_desc *gdp)
50{ 50{
51 unsigned long start; 51 unsigned long start;
52 int bit, bit_max; 52 int bit, bit_max;
@@ -60,7 +60,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
60 * essentially implementing a per-group read-only flag. */ 60 * essentially implementing a per-group read-only flag. */
61 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { 61 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
62 ext4_error(sb, __FUNCTION__, 62 ext4_error(sb, __FUNCTION__,
63 "Checksum bad for group %u\n", block_group); 63 "Checksum bad for group %lu\n", block_group);
64 gdp->bg_free_blocks_count = 0; 64 gdp->bg_free_blocks_count = 0;
65 gdp->bg_free_inodes_count = 0; 65 gdp->bg_free_inodes_count = 0;
66 gdp->bg_itable_unused = 0; 66 gdp->bg_itable_unused = 0;
@@ -153,7 +153,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
153 * group descriptor 153 * group descriptor
154 */ 154 */
155struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, 155struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
156 unsigned int block_group, 156 ext4_group_t block_group,
157 struct buffer_head ** bh) 157 struct buffer_head ** bh)
158{ 158{
159 unsigned long group_desc; 159 unsigned long group_desc;
@@ -164,7 +164,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
164 if (block_group >= sbi->s_groups_count) { 164 if (block_group >= sbi->s_groups_count) {
165 ext4_error (sb, "ext4_get_group_desc", 165 ext4_error (sb, "ext4_get_group_desc",
166 "block_group >= groups_count - " 166 "block_group >= groups_count - "
167 "block_group = %d, groups_count = %lu", 167 "block_group = %lu, groups_count = %lu",
168 block_group, sbi->s_groups_count); 168 block_group, sbi->s_groups_count);
169 169
170 return NULL; 170 return NULL;
@@ -176,7 +176,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
176 if (!sbi->s_group_desc[group_desc]) { 176 if (!sbi->s_group_desc[group_desc]) {
177 ext4_error (sb, "ext4_get_group_desc", 177 ext4_error (sb, "ext4_get_group_desc",
178 "Group descriptor not loaded - " 178 "Group descriptor not loaded - "
179 "block_group = %d, group_desc = %lu, desc = %lu", 179 "block_group = %lu, group_desc = %lu, desc = %lu",
180 block_group, group_desc, offset); 180 block_group, group_desc, offset);
181 return NULL; 181 return NULL;
182 } 182 }
@@ -189,18 +189,70 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
189 return desc; 189 return desc;
190} 190}
191 191
192static int ext4_valid_block_bitmap(struct super_block *sb,
193 struct ext4_group_desc *desc,
194 unsigned int block_group,
195 struct buffer_head *bh)
196{
197 ext4_grpblk_t offset;
198 ext4_grpblk_t next_zero_bit;
199 ext4_fsblk_t bitmap_blk;
200 ext4_fsblk_t group_first_block;
201
202 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
203 /* with FLEX_BG, the inode/block bitmaps and itable
204 * blocks may not be in the group at all
205 * so the bitmap validation will be skipped for those groups
206 * or it has to also read the block group where the bitmaps
207 * are located to verify they are set.
208 */
209 return 1;
210 }
211 group_first_block = ext4_group_first_block_no(sb, block_group);
212
213 /* check whether block bitmap block number is set */
214 bitmap_blk = ext4_block_bitmap(sb, desc);
215 offset = bitmap_blk - group_first_block;
216 if (!ext4_test_bit(offset, bh->b_data))
217 /* bad block bitmap */
218 goto err_out;
219
220 /* check whether the inode bitmap block number is set */
221 bitmap_blk = ext4_inode_bitmap(sb, desc);
222 offset = bitmap_blk - group_first_block;
223 if (!ext4_test_bit(offset, bh->b_data))
224 /* bad block bitmap */
225 goto err_out;
226
227 /* check whether the inode table block number is set */
228 bitmap_blk = ext4_inode_table(sb, desc);
229 offset = bitmap_blk - group_first_block;
230 next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
231 offset + EXT4_SB(sb)->s_itb_per_group,
232 offset);
233 if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group)
234 /* good bitmap for inode tables */
235 return 1;
236
237err_out:
238 ext4_error(sb, __FUNCTION__,
239 "Invalid block bitmap - "
240 "block_group = %d, block = %llu",
241 block_group, bitmap_blk);
242 return 0;
243}
192/** 244/**
193 * read_block_bitmap() 245 * read_block_bitmap()
194 * @sb: super block 246 * @sb: super block
195 * @block_group: given block group 247 * @block_group: given block group
196 * 248 *
197 * Read the bitmap for a given block_group, reading into the specified 249 * Read the bitmap for a given block_group,and validate the
198 * slot in the superblock's bitmap cache. 250 * bits for block/inode/inode tables are set in the bitmaps
199 * 251 *
200 * Return buffer_head on success or NULL in case of failure. 252 * Return buffer_head on success or NULL in case of failure.
201 */ 253 */
202struct buffer_head * 254struct buffer_head *
203read_block_bitmap(struct super_block *sb, unsigned int block_group) 255read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
204{ 256{
205 struct ext4_group_desc * desc; 257 struct ext4_group_desc * desc;
206 struct buffer_head * bh = NULL; 258 struct buffer_head * bh = NULL;
@@ -210,25 +262,36 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
210 if (!desc) 262 if (!desc)
211 return NULL; 263 return NULL;
212 bitmap_blk = ext4_block_bitmap(sb, desc); 264 bitmap_blk = ext4_block_bitmap(sb, desc);
265 bh = sb_getblk(sb, bitmap_blk);
266 if (unlikely(!bh)) {
267 ext4_error(sb, __FUNCTION__,
268 "Cannot read block bitmap - "
269 "block_group = %d, block_bitmap = %llu",
270 (int)block_group, (unsigned long long)bitmap_blk);
271 return NULL;
272 }
273 if (bh_uptodate_or_lock(bh))
274 return bh;
275
213 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 276 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
214 bh = sb_getblk(sb, bitmap_blk); 277 ext4_init_block_bitmap(sb, bh, block_group, desc);
215 if (!buffer_uptodate(bh)) { 278 set_buffer_uptodate(bh);
216 lock_buffer(bh); 279 unlock_buffer(bh);
217 if (!buffer_uptodate(bh)) { 280 return bh;
218 ext4_init_block_bitmap(sb, bh, block_group,
219 desc);
220 set_buffer_uptodate(bh);
221 }
222 unlock_buffer(bh);
223 }
224 } else {
225 bh = sb_bread(sb, bitmap_blk);
226 } 281 }
227 if (!bh) 282 if (bh_submit_read(bh) < 0) {
228 ext4_error (sb, __FUNCTION__, 283 put_bh(bh);
284 ext4_error(sb, __FUNCTION__,
229 "Cannot read block bitmap - " 285 "Cannot read block bitmap - "
230 "block_group = %d, block_bitmap = %llu", 286 "block_group = %d, block_bitmap = %llu",
231 block_group, bitmap_blk); 287 (int)block_group, (unsigned long long)bitmap_blk);
288 return NULL;
289 }
290 if (!ext4_valid_block_bitmap(sb, desc, block_group, bh)) {
291 put_bh(bh);
292 return NULL;
293 }
294
232 return bh; 295 return bh;
233} 296}
234/* 297/*
@@ -320,7 +383,7 @@ restart:
320 */ 383 */
321static int 384static int
322goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal, 385goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal,
323 unsigned int group, struct super_block * sb) 386 ext4_group_t group, struct super_block *sb)
324{ 387{
325 ext4_fsblk_t group_first_block, group_last_block; 388 ext4_fsblk_t group_first_block, group_last_block;
326 389
@@ -463,7 +526,7 @@ static inline int rsv_is_empty(struct ext4_reserve_window *rsv)
463 * when setting the reservation window size through ioctl before the file 526 * when setting the reservation window size through ioctl before the file
464 * is open for write (needs block allocation). 527 * is open for write (needs block allocation).
465 * 528 *
466 * Needs truncate_mutex protection prior to call this function. 529 * Needs down_write(i_data_sem) protection prior to call this function.
467 */ 530 */
468void ext4_init_block_alloc_info(struct inode *inode) 531void ext4_init_block_alloc_info(struct inode *inode)
469{ 532{
@@ -514,6 +577,8 @@ void ext4_discard_reservation(struct inode *inode)
514 struct ext4_reserve_window_node *rsv; 577 struct ext4_reserve_window_node *rsv;
515 spinlock_t *rsv_lock = &EXT4_SB(inode->i_sb)->s_rsv_window_lock; 578 spinlock_t *rsv_lock = &EXT4_SB(inode->i_sb)->s_rsv_window_lock;
516 579
580 ext4_mb_discard_inode_preallocations(inode);
581
517 if (!block_i) 582 if (!block_i)
518 return; 583 return;
519 584
@@ -540,7 +605,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
540{ 605{
541 struct buffer_head *bitmap_bh = NULL; 606 struct buffer_head *bitmap_bh = NULL;
542 struct buffer_head *gd_bh; 607 struct buffer_head *gd_bh;
543 unsigned long block_group; 608 ext4_group_t block_group;
544 ext4_grpblk_t bit; 609 ext4_grpblk_t bit;
545 unsigned long i; 610 unsigned long i;
546 unsigned long overflow; 611 unsigned long overflow;
@@ -587,11 +652,13 @@ do_more:
587 in_range(ext4_inode_bitmap(sb, desc), block, count) || 652 in_range(ext4_inode_bitmap(sb, desc), block, count) ||
588 in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || 653 in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
589 in_range(block + count - 1, ext4_inode_table(sb, desc), 654 in_range(block + count - 1, ext4_inode_table(sb, desc),
590 sbi->s_itb_per_group)) 655 sbi->s_itb_per_group)) {
591 ext4_error (sb, "ext4_free_blocks", 656 ext4_error (sb, "ext4_free_blocks",
592 "Freeing blocks in system zones - " 657 "Freeing blocks in system zones - "
593 "Block = %llu, count = %lu", 658 "Block = %llu, count = %lu",
594 block, count); 659 block, count);
660 goto error_return;
661 }
595 662
596 /* 663 /*
597 * We are about to start releasing blocks in the bitmap, 664 * We are about to start releasing blocks in the bitmap,
@@ -720,19 +787,29 @@ error_return:
720 * @inode: inode 787 * @inode: inode
721 * @block: start physical block to free 788 * @block: start physical block to free
722 * @count: number of blocks to count 789 * @count: number of blocks to count
790 * @metadata: Are these metadata blocks
723 */ 791 */
724void ext4_free_blocks(handle_t *handle, struct inode *inode, 792void ext4_free_blocks(handle_t *handle, struct inode *inode,
725 ext4_fsblk_t block, unsigned long count) 793 ext4_fsblk_t block, unsigned long count,
794 int metadata)
726{ 795{
727 struct super_block * sb; 796 struct super_block * sb;
728 unsigned long dquot_freed_blocks; 797 unsigned long dquot_freed_blocks;
729 798
799 /* this isn't the right place to decide whether block is metadata
800 * inode.c/extents.c knows better, but for safety ... */
801 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) ||
802 ext4_should_journal_data(inode))
803 metadata = 1;
804
730 sb = inode->i_sb; 805 sb = inode->i_sb;
731 if (!sb) { 806
732 printk ("ext4_free_blocks: nonexistent device"); 807 if (!test_opt(sb, MBALLOC) || !EXT4_SB(sb)->s_group_info)
733 return; 808 ext4_free_blocks_sb(handle, sb, block, count,
734 } 809 &dquot_freed_blocks);
735 ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); 810 else
811 ext4_mb_free_blocks(handle, inode, block, count,
812 metadata, &dquot_freed_blocks);
736 if (dquot_freed_blocks) 813 if (dquot_freed_blocks)
737 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); 814 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
738 return; 815 return;
@@ -920,9 +997,10 @@ claim_block(spinlock_t *lock, ext4_grpblk_t block, struct buffer_head *bh)
920 * ext4_journal_release_buffer(), else we'll run out of credits. 997 * ext4_journal_release_buffer(), else we'll run out of credits.
921 */ 998 */
922static ext4_grpblk_t 999static ext4_grpblk_t
923ext4_try_to_allocate(struct super_block *sb, handle_t *handle, int group, 1000ext4_try_to_allocate(struct super_block *sb, handle_t *handle,
924 struct buffer_head *bitmap_bh, ext4_grpblk_t grp_goal, 1001 ext4_group_t group, struct buffer_head *bitmap_bh,
925 unsigned long *count, struct ext4_reserve_window *my_rsv) 1002 ext4_grpblk_t grp_goal, unsigned long *count,
1003 struct ext4_reserve_window *my_rsv)
926{ 1004{
927 ext4_fsblk_t group_first_block; 1005 ext4_fsblk_t group_first_block;
928 ext4_grpblk_t start, end; 1006 ext4_grpblk_t start, end;
@@ -1156,7 +1234,7 @@ static int find_next_reservable_window(
1156 */ 1234 */
1157static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv, 1235static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv,
1158 ext4_grpblk_t grp_goal, struct super_block *sb, 1236 ext4_grpblk_t grp_goal, struct super_block *sb,
1159 unsigned int group, struct buffer_head *bitmap_bh) 1237 ext4_group_t group, struct buffer_head *bitmap_bh)
1160{ 1238{
1161 struct ext4_reserve_window_node *search_head; 1239 struct ext4_reserve_window_node *search_head;
1162 ext4_fsblk_t group_first_block, group_end_block, start_block; 1240 ext4_fsblk_t group_first_block, group_end_block, start_block;
@@ -1354,7 +1432,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv,
1354 */ 1432 */
1355static ext4_grpblk_t 1433static ext4_grpblk_t
1356ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, 1434ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
1357 unsigned int group, struct buffer_head *bitmap_bh, 1435 ext4_group_t group, struct buffer_head *bitmap_bh,
1358 ext4_grpblk_t grp_goal, 1436 ext4_grpblk_t grp_goal,
1359 struct ext4_reserve_window_node * my_rsv, 1437 struct ext4_reserve_window_node * my_rsv,
1360 unsigned long *count, int *errp) 1438 unsigned long *count, int *errp)
@@ -1510,7 +1588,7 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
1510} 1588}
1511 1589
1512/** 1590/**
1513 * ext4_new_blocks() -- core block(s) allocation function 1591 * ext4_new_blocks_old() -- core block(s) allocation function
1514 * @handle: handle to this transaction 1592 * @handle: handle to this transaction
1515 * @inode: file inode 1593 * @inode: file inode
1516 * @goal: given target block(filesystem wide) 1594 * @goal: given target block(filesystem wide)
@@ -1523,17 +1601,17 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries)
1523 * any specific goal block. 1601 * any specific goal block.
1524 * 1602 *
1525 */ 1603 */
1526ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, 1604ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode,
1527 ext4_fsblk_t goal, unsigned long *count, int *errp) 1605 ext4_fsblk_t goal, unsigned long *count, int *errp)
1528{ 1606{
1529 struct buffer_head *bitmap_bh = NULL; 1607 struct buffer_head *bitmap_bh = NULL;
1530 struct buffer_head *gdp_bh; 1608 struct buffer_head *gdp_bh;
1531 unsigned long group_no; 1609 ext4_group_t group_no;
1532 int goal_group; 1610 ext4_group_t goal_group;
1533 ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */ 1611 ext4_grpblk_t grp_target_blk; /* blockgroup relative goal block */
1534 ext4_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/ 1612 ext4_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/
1535 ext4_fsblk_t ret_block; /* filesyetem-wide allocated block */ 1613 ext4_fsblk_t ret_block; /* filesyetem-wide allocated block */
1536 int bgi; /* blockgroup iteration index */ 1614 ext4_group_t bgi; /* blockgroup iteration index */
1537 int fatal = 0, err; 1615 int fatal = 0, err;
1538 int performed_allocation = 0; 1616 int performed_allocation = 0;
1539 ext4_grpblk_t free_blocks; /* number of free blocks in a group */ 1617 ext4_grpblk_t free_blocks; /* number of free blocks in a group */
@@ -1544,10 +1622,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
1544 struct ext4_reserve_window_node *my_rsv = NULL; 1622 struct ext4_reserve_window_node *my_rsv = NULL;
1545 struct ext4_block_alloc_info *block_i; 1623 struct ext4_block_alloc_info *block_i;
1546 unsigned short windowsz = 0; 1624 unsigned short windowsz = 0;
1547#ifdef EXT4FS_DEBUG 1625 ext4_group_t ngroups;
1548 static int goal_hits, goal_attempts;
1549#endif
1550 unsigned long ngroups;
1551 unsigned long num = *count; 1626 unsigned long num = *count;
1552 1627
1553 *errp = -ENOSPC; 1628 *errp = -ENOSPC;
@@ -1567,7 +1642,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
1567 1642
1568 sbi = EXT4_SB(sb); 1643 sbi = EXT4_SB(sb);
1569 es = EXT4_SB(sb)->s_es; 1644 es = EXT4_SB(sb)->s_es;
1570 ext4_debug("goal=%lu.\n", goal); 1645 ext4_debug("goal=%llu.\n", goal);
1571 /* 1646 /*
1572 * Allocate a block from reservation only when 1647 * Allocate a block from reservation only when
1573 * filesystem is mounted with reservation(default,-o reservation), and 1648 * filesystem is mounted with reservation(default,-o reservation), and
@@ -1677,7 +1752,7 @@ retry_alloc:
1677 1752
1678allocated: 1753allocated:
1679 1754
1680 ext4_debug("using block group %d(%d)\n", 1755 ext4_debug("using block group %lu(%d)\n",
1681 group_no, gdp->bg_free_blocks_count); 1756 group_no, gdp->bg_free_blocks_count);
1682 1757
1683 BUFFER_TRACE(gdp_bh, "get_write_access"); 1758 BUFFER_TRACE(gdp_bh, "get_write_access");
@@ -1692,11 +1767,13 @@ allocated:
1692 in_range(ret_block, ext4_inode_table(sb, gdp), 1767 in_range(ret_block, ext4_inode_table(sb, gdp),
1693 EXT4_SB(sb)->s_itb_per_group) || 1768 EXT4_SB(sb)->s_itb_per_group) ||
1694 in_range(ret_block + num - 1, ext4_inode_table(sb, gdp), 1769 in_range(ret_block + num - 1, ext4_inode_table(sb, gdp),
1695 EXT4_SB(sb)->s_itb_per_group)) 1770 EXT4_SB(sb)->s_itb_per_group)) {
1696 ext4_error(sb, "ext4_new_block", 1771 ext4_error(sb, "ext4_new_block",
1697 "Allocating block in system zone - " 1772 "Allocating block in system zone - "
1698 "blocks from %llu, length %lu", 1773 "blocks from %llu, length %lu",
1699 ret_block, num); 1774 ret_block, num);
1775 goto out;
1776 }
1700 1777
1701 performed_allocation = 1; 1778 performed_allocation = 1;
1702 1779
@@ -1743,9 +1820,6 @@ allocated:
1743 * list of some description. We don't know in advance whether 1820 * list of some description. We don't know in advance whether
1744 * the caller wants to use it as metadata or data. 1821 * the caller wants to use it as metadata or data.
1745 */ 1822 */
1746 ext4_debug("allocating block %lu. Goal hits %d of %d.\n",
1747 ret_block, goal_hits, goal_attempts);
1748
1749 spin_lock(sb_bgl_lock(sbi, group_no)); 1823 spin_lock(sb_bgl_lock(sbi, group_no));
1750 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) 1824 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
1751 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 1825 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
@@ -1787,13 +1861,46 @@ out:
1787} 1861}
1788 1862
1789ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode, 1863ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode,
1790 ext4_fsblk_t goal, int *errp) 1864 ext4_fsblk_t goal, int *errp)
1791{ 1865{
1792 unsigned long count = 1; 1866 struct ext4_allocation_request ar;
1867 ext4_fsblk_t ret;
1793 1868
1794 return ext4_new_blocks(handle, inode, goal, &count, errp); 1869 if (!test_opt(inode->i_sb, MBALLOC)) {
1870 unsigned long count = 1;
1871 ret = ext4_new_blocks_old(handle, inode, goal, &count, errp);
1872 return ret;
1873 }
1874
1875 memset(&ar, 0, sizeof(ar));
1876 ar.inode = inode;
1877 ar.goal = goal;
1878 ar.len = 1;
1879 ret = ext4_mb_new_blocks(handle, &ar, errp);
1880 return ret;
1881}
1882
1883ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
1884 ext4_fsblk_t goal, unsigned long *count, int *errp)
1885{
1886 struct ext4_allocation_request ar;
1887 ext4_fsblk_t ret;
1888
1889 if (!test_opt(inode->i_sb, MBALLOC)) {
1890 ret = ext4_new_blocks_old(handle, inode, goal, count, errp);
1891 return ret;
1892 }
1893
1894 memset(&ar, 0, sizeof(ar));
1895 ar.inode = inode;
1896 ar.goal = goal;
1897 ar.len = *count;
1898 ret = ext4_mb_new_blocks(handle, &ar, errp);
1899 *count = ar.len;
1900 return ret;
1795} 1901}
1796 1902
1903
1797/** 1904/**
1798 * ext4_count_free_blocks() -- count filesystem free blocks 1905 * ext4_count_free_blocks() -- count filesystem free blocks
1799 * @sb: superblock 1906 * @sb: superblock
@@ -1804,8 +1911,8 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
1804{ 1911{
1805 ext4_fsblk_t desc_count; 1912 ext4_fsblk_t desc_count;
1806 struct ext4_group_desc *gdp; 1913 struct ext4_group_desc *gdp;
1807 int i; 1914 ext4_group_t i;
1808 unsigned long ngroups = EXT4_SB(sb)->s_groups_count; 1915 ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
1809#ifdef EXT4FS_DEBUG 1916#ifdef EXT4FS_DEBUG
1810 struct ext4_super_block *es; 1917 struct ext4_super_block *es;
1811 ext4_fsblk_t bitmap_count; 1918 ext4_fsblk_t bitmap_count;
@@ -1829,14 +1936,14 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
1829 continue; 1936 continue;
1830 1937
1831 x = ext4_count_free(bitmap_bh, sb->s_blocksize); 1938 x = ext4_count_free(bitmap_bh, sb->s_blocksize);
1832 printk("group %d: stored = %d, counted = %lu\n", 1939 printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
1833 i, le16_to_cpu(gdp->bg_free_blocks_count), x); 1940 i, le16_to_cpu(gdp->bg_free_blocks_count), x);
1834 bitmap_count += x; 1941 bitmap_count += x;
1835 } 1942 }
1836 brelse(bitmap_bh); 1943 brelse(bitmap_bh);
1837 printk("ext4_count_free_blocks: stored = %llu" 1944 printk("ext4_count_free_blocks: stored = %llu"
1838 ", computed = %llu, %llu\n", 1945 ", computed = %llu, %llu\n",
1839 EXT4_FREE_BLOCKS_COUNT(es), 1946 ext4_free_blocks_count(es),
1840 desc_count, bitmap_count); 1947 desc_count, bitmap_count);
1841 return bitmap_count; 1948 return bitmap_count;
1842#else 1949#else
@@ -1853,7 +1960,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
1853#endif 1960#endif
1854} 1961}
1855 1962
1856static inline int test_root(int a, int b) 1963static inline int test_root(ext4_group_t a, int b)
1857{ 1964{
1858 int num = b; 1965 int num = b;
1859 1966
@@ -1862,7 +1969,7 @@ static inline int test_root(int a, int b)
1862 return num == a; 1969 return num == a;
1863} 1970}
1864 1971
1865static int ext4_group_sparse(int group) 1972static int ext4_group_sparse(ext4_group_t group)
1866{ 1973{
1867 if (group <= 1) 1974 if (group <= 1)
1868 return 1; 1975 return 1;
@@ -1880,7 +1987,7 @@ static int ext4_group_sparse(int group)
1880 * Return the number of blocks used by the superblock (primary or backup) 1987 * Return the number of blocks used by the superblock (primary or backup)
1881 * in this group. Currently this will be only 0 or 1. 1988 * in this group. Currently this will be only 0 or 1.
1882 */ 1989 */
1883int ext4_bg_has_super(struct super_block *sb, int group) 1990int ext4_bg_has_super(struct super_block *sb, ext4_group_t group)
1884{ 1991{
1885 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 1992 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
1886 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && 1993 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
@@ -1889,18 +1996,20 @@ int ext4_bg_has_super(struct super_block *sb, int group)
1889 return 1; 1996 return 1;
1890} 1997}
1891 1998
1892static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, int group) 1999static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
2000 ext4_group_t group)
1893{ 2001{
1894 unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb); 2002 unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
1895 unsigned long first = metagroup * EXT4_DESC_PER_BLOCK(sb); 2003 ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb);
1896 unsigned long last = first + EXT4_DESC_PER_BLOCK(sb) - 1; 2004 ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
1897 2005
1898 if (group == first || group == first + 1 || group == last) 2006 if (group == first || group == first + 1 || group == last)
1899 return 1; 2007 return 1;
1900 return 0; 2008 return 0;
1901} 2009}
1902 2010
1903static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group) 2011static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
2012 ext4_group_t group)
1904{ 2013{
1905 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 2014 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
1906 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && 2015 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
@@ -1918,7 +2027,7 @@ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group)
1918 * (primary or backup) in this group. In the future there may be a 2027 * (primary or backup) in this group. In the future there may be a
1919 * different number of descriptor blocks in each group. 2028 * different number of descriptor blocks in each group.
1920 */ 2029 */
1921unsigned long ext4_bg_num_gdb(struct super_block *sb, int group) 2030unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
1922{ 2031{
1923 unsigned long first_meta_bg = 2032 unsigned long first_meta_bg =
1924 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg); 2033 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index f612bef98315..33888bb58144 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -67,7 +67,7 @@ int ext4_check_dir_entry (const char * function, struct inode * dir,
67 unsigned long offset) 67 unsigned long offset)
68{ 68{
69 const char * error_msg = NULL; 69 const char * error_msg = NULL;
70 const int rlen = le16_to_cpu(de->rec_len); 70 const int rlen = ext4_rec_len_from_disk(de->rec_len);
71 71
72 if (rlen < EXT4_DIR_REC_LEN(1)) 72 if (rlen < EXT4_DIR_REC_LEN(1))
73 error_msg = "rec_len is smaller than minimal"; 73 error_msg = "rec_len is smaller than minimal";
@@ -124,7 +124,7 @@ static int ext4_readdir(struct file * filp,
124 offset = filp->f_pos & (sb->s_blocksize - 1); 124 offset = filp->f_pos & (sb->s_blocksize - 1);
125 125
126 while (!error && !stored && filp->f_pos < inode->i_size) { 126 while (!error && !stored && filp->f_pos < inode->i_size) {
127 unsigned long blk = filp->f_pos >> EXT4_BLOCK_SIZE_BITS(sb); 127 ext4_lblk_t blk = filp->f_pos >> EXT4_BLOCK_SIZE_BITS(sb);
128 struct buffer_head map_bh; 128 struct buffer_head map_bh;
129 struct buffer_head *bh = NULL; 129 struct buffer_head *bh = NULL;
130 130
@@ -172,10 +172,10 @@ revalidate:
172 * least that it is non-zero. A 172 * least that it is non-zero. A
173 * failure will be detected in the 173 * failure will be detected in the
174 * dirent test below. */ 174 * dirent test below. */
175 if (le16_to_cpu(de->rec_len) < 175 if (ext4_rec_len_from_disk(de->rec_len)
176 EXT4_DIR_REC_LEN(1)) 176 < EXT4_DIR_REC_LEN(1))
177 break; 177 break;
178 i += le16_to_cpu(de->rec_len); 178 i += ext4_rec_len_from_disk(de->rec_len);
179 } 179 }
180 offset = i; 180 offset = i;
181 filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1)) 181 filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
@@ -197,7 +197,7 @@ revalidate:
197 ret = stored; 197 ret = stored;
198 goto out; 198 goto out;
199 } 199 }
200 offset += le16_to_cpu(de->rec_len); 200 offset += ext4_rec_len_from_disk(de->rec_len);
201 if (le32_to_cpu(de->inode)) { 201 if (le32_to_cpu(de->inode)) {
202 /* We might block in the next section 202 /* We might block in the next section
203 * if the data destination is 203 * if the data destination is
@@ -219,7 +219,7 @@ revalidate:
219 goto revalidate; 219 goto revalidate;
220 stored ++; 220 stored ++;
221 } 221 }
222 filp->f_pos += le16_to_cpu(de->rec_len); 222 filp->f_pos += ext4_rec_len_from_disk(de->rec_len);
223 } 223 }
224 offset = 0; 224 offset = 0;
225 brelse (bh); 225 brelse (bh);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 85287742f2ae..bc7081f1fbe8 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -61,7 +61,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex)
61 * idx_pblock: 61 * idx_pblock:
62 * combine low and high parts of a leaf physical block number into ext4_fsblk_t 62 * combine low and high parts of a leaf physical block number into ext4_fsblk_t
63 */ 63 */
64static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) 64ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
65{ 65{
66 ext4_fsblk_t block; 66 ext4_fsblk_t block;
67 67
@@ -75,7 +75,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
75 * stores a large physical block number into an extent struct, 75 * stores a large physical block number into an extent struct,
76 * breaking it into parts 76 * breaking it into parts
77 */ 77 */
78static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) 78void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
79{ 79{
80 ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); 80 ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
81 ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); 81 ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
@@ -144,7 +144,7 @@ static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
144 144
145static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, 145static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
146 struct ext4_ext_path *path, 146 struct ext4_ext_path *path,
147 ext4_fsblk_t block) 147 ext4_lblk_t block)
148{ 148{
149 struct ext4_inode_info *ei = EXT4_I(inode); 149 struct ext4_inode_info *ei = EXT4_I(inode);
150 ext4_fsblk_t bg_start; 150 ext4_fsblk_t bg_start;
@@ -367,13 +367,14 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path)
367 * the header must be checked before calling this 367 * the header must be checked before calling this
368 */ 368 */
369static void 369static void
370ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) 370ext4_ext_binsearch_idx(struct inode *inode,
371 struct ext4_ext_path *path, ext4_lblk_t block)
371{ 372{
372 struct ext4_extent_header *eh = path->p_hdr; 373 struct ext4_extent_header *eh = path->p_hdr;
373 struct ext4_extent_idx *r, *l, *m; 374 struct ext4_extent_idx *r, *l, *m;
374 375
375 376
376 ext_debug("binsearch for %d(idx): ", block); 377 ext_debug("binsearch for %u(idx): ", block);
377 378
378 l = EXT_FIRST_INDEX(eh) + 1; 379 l = EXT_FIRST_INDEX(eh) + 1;
379 r = EXT_LAST_INDEX(eh); 380 r = EXT_LAST_INDEX(eh);
@@ -425,7 +426,8 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc
425 * the header must be checked before calling this 426 * the header must be checked before calling this
426 */ 427 */
427static void 428static void
428ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) 429ext4_ext_binsearch(struct inode *inode,
430 struct ext4_ext_path *path, ext4_lblk_t block)
429{ 431{
430 struct ext4_extent_header *eh = path->p_hdr; 432 struct ext4_extent_header *eh = path->p_hdr;
431 struct ext4_extent *r, *l, *m; 433 struct ext4_extent *r, *l, *m;
@@ -438,7 +440,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
438 return; 440 return;
439 } 441 }
440 442
441 ext_debug("binsearch for %d: ", block); 443 ext_debug("binsearch for %u: ", block);
442 444
443 l = EXT_FIRST_EXTENT(eh) + 1; 445 l = EXT_FIRST_EXTENT(eh) + 1;
444 r = EXT_LAST_EXTENT(eh); 446 r = EXT_LAST_EXTENT(eh);
@@ -494,7 +496,8 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
494} 496}
495 497
496struct ext4_ext_path * 498struct ext4_ext_path *
497ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) 499ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
500 struct ext4_ext_path *path)
498{ 501{
499 struct ext4_extent_header *eh; 502 struct ext4_extent_header *eh;
500 struct buffer_head *bh; 503 struct buffer_head *bh;
@@ -763,7 +766,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
763 while (k--) { 766 while (k--) {
764 oldblock = newblock; 767 oldblock = newblock;
765 newblock = ablocks[--a]; 768 newblock = ablocks[--a];
766 bh = sb_getblk(inode->i_sb, (ext4_fsblk_t)newblock); 769 bh = sb_getblk(inode->i_sb, newblock);
767 if (!bh) { 770 if (!bh) {
768 err = -EIO; 771 err = -EIO;
769 goto cleanup; 772 goto cleanup;
@@ -783,9 +786,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
783 fidx->ei_block = border; 786 fidx->ei_block = border;
784 ext4_idx_store_pblock(fidx, oldblock); 787 ext4_idx_store_pblock(fidx, oldblock);
785 788
786 ext_debug("int.index at %d (block %llu): %lu -> %llu\n", i, 789 ext_debug("int.index at %d (block %llu): %u -> %llu\n",
787 newblock, (unsigned long) le32_to_cpu(border), 790 i, newblock, le32_to_cpu(border), oldblock);
788 oldblock);
789 /* copy indexes */ 791 /* copy indexes */
790 m = 0; 792 m = 0;
791 path[i].p_idx++; 793 path[i].p_idx++;
@@ -851,7 +853,7 @@ cleanup:
851 for (i = 0; i < depth; i++) { 853 for (i = 0; i < depth; i++) {
852 if (!ablocks[i]) 854 if (!ablocks[i])
853 continue; 855 continue;
854 ext4_free_blocks(handle, inode, ablocks[i], 1); 856 ext4_free_blocks(handle, inode, ablocks[i], 1, 1);
855 } 857 }
856 } 858 }
857 kfree(ablocks); 859 kfree(ablocks);
@@ -979,8 +981,8 @@ repeat:
979 /* refill path */ 981 /* refill path */
980 ext4_ext_drop_refs(path); 982 ext4_ext_drop_refs(path);
981 path = ext4_ext_find_extent(inode, 983 path = ext4_ext_find_extent(inode,
982 le32_to_cpu(newext->ee_block), 984 (ext4_lblk_t)le32_to_cpu(newext->ee_block),
983 path); 985 path);
984 if (IS_ERR(path)) 986 if (IS_ERR(path))
985 err = PTR_ERR(path); 987 err = PTR_ERR(path);
986 } else { 988 } else {
@@ -992,8 +994,8 @@ repeat:
992 /* refill path */ 994 /* refill path */
993 ext4_ext_drop_refs(path); 995 ext4_ext_drop_refs(path);
994 path = ext4_ext_find_extent(inode, 996 path = ext4_ext_find_extent(inode,
995 le32_to_cpu(newext->ee_block), 997 (ext4_lblk_t)le32_to_cpu(newext->ee_block),
996 path); 998 path);
997 if (IS_ERR(path)) { 999 if (IS_ERR(path)) {
998 err = PTR_ERR(path); 1000 err = PTR_ERR(path);
999 goto out; 1001 goto out;
@@ -1015,13 +1017,157 @@ out:
1015} 1017}
1016 1018
1017/* 1019/*
1020 * search the closest allocated block to the left for *logical
1021 * and returns it at @logical + it's physical address at @phys
1022 * if *logical is the smallest allocated block, the function
1023 * returns 0 at @phys
1024 * return value contains 0 (success) or error code
1025 */
1026int
1027ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
1028 ext4_lblk_t *logical, ext4_fsblk_t *phys)
1029{
1030 struct ext4_extent_idx *ix;
1031 struct ext4_extent *ex;
1032 int depth, ee_len;
1033
1034 BUG_ON(path == NULL);
1035 depth = path->p_depth;
1036 *phys = 0;
1037
1038 if (depth == 0 && path->p_ext == NULL)
1039 return 0;
1040
1041 /* usually extent in the path covers blocks smaller
1042 * then *logical, but it can be that extent is the
1043 * first one in the file */
1044
1045 ex = path[depth].p_ext;
1046 ee_len = ext4_ext_get_actual_len(ex);
1047 if (*logical < le32_to_cpu(ex->ee_block)) {
1048 BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
1049 while (--depth >= 0) {
1050 ix = path[depth].p_idx;
1051 BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
1052 }
1053 return 0;
1054 }
1055
1056 BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
1057
1058 *logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
1059 *phys = ext_pblock(ex) + ee_len - 1;
1060 return 0;
1061}
1062
1063/*
1064 * search the closest allocated block to the right for *logical
1065 * and returns it at @logical + it's physical address at @phys
1066 * if *logical is the smallest allocated block, the function
1067 * returns 0 at @phys
1068 * return value contains 0 (success) or error code
1069 */
1070int
1071ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
1072 ext4_lblk_t *logical, ext4_fsblk_t *phys)
1073{
1074 struct buffer_head *bh = NULL;
1075 struct ext4_extent_header *eh;
1076 struct ext4_extent_idx *ix;
1077 struct ext4_extent *ex;
1078 ext4_fsblk_t block;
1079 int depth, ee_len;
1080
1081 BUG_ON(path == NULL);
1082 depth = path->p_depth;
1083 *phys = 0;
1084
1085 if (depth == 0 && path->p_ext == NULL)
1086 return 0;
1087
1088 /* usually extent in the path covers blocks smaller
1089 * then *logical, but it can be that extent is the
1090 * first one in the file */
1091
1092 ex = path[depth].p_ext;
1093 ee_len = ext4_ext_get_actual_len(ex);
1094 if (*logical < le32_to_cpu(ex->ee_block)) {
1095 BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
1096 while (--depth >= 0) {
1097 ix = path[depth].p_idx;
1098 BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
1099 }
1100 *logical = le32_to_cpu(ex->ee_block);
1101 *phys = ext_pblock(ex);
1102 return 0;
1103 }
1104
1105 BUG_ON(*logical < (le32_to_cpu(ex->ee_block) + ee_len));
1106
1107 if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
1108 /* next allocated block in this leaf */
1109 ex++;
1110 *logical = le32_to_cpu(ex->ee_block);
1111 *phys = ext_pblock(ex);
1112 return 0;
1113 }
1114
1115 /* go up and search for index to the right */
1116 while (--depth >= 0) {
1117 ix = path[depth].p_idx;
1118 if (ix != EXT_LAST_INDEX(path[depth].p_hdr))
1119 break;
1120 }
1121
1122 if (depth < 0) {
1123 /* we've gone up to the root and
1124 * found no index to the right */
1125 return 0;
1126 }
1127
1128 /* we've found index to the right, let's
1129 * follow it and find the closest allocated
1130 * block to the right */
1131 ix++;
1132 block = idx_pblock(ix);
1133 while (++depth < path->p_depth) {
1134 bh = sb_bread(inode->i_sb, block);
1135 if (bh == NULL)
1136 return -EIO;
1137 eh = ext_block_hdr(bh);
1138 if (ext4_ext_check_header(inode, eh, depth)) {
1139 put_bh(bh);
1140 return -EIO;
1141 }
1142 ix = EXT_FIRST_INDEX(eh);
1143 block = idx_pblock(ix);
1144 put_bh(bh);
1145 }
1146
1147 bh = sb_bread(inode->i_sb, block);
1148 if (bh == NULL)
1149 return -EIO;
1150 eh = ext_block_hdr(bh);
1151 if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {
1152 put_bh(bh);
1153 return -EIO;
1154 }
1155 ex = EXT_FIRST_EXTENT(eh);
1156 *logical = le32_to_cpu(ex->ee_block);
1157 *phys = ext_pblock(ex);
1158 put_bh(bh);
1159 return 0;
1160
1161}
1162
1163/*
1018 * ext4_ext_next_allocated_block: 1164 * ext4_ext_next_allocated_block:
1019 * returns allocated block in subsequent extent or EXT_MAX_BLOCK. 1165 * returns allocated block in subsequent extent or EXT_MAX_BLOCK.
1020 * NOTE: it considers block number from index entry as 1166 * NOTE: it considers block number from index entry as
1021 * allocated block. Thus, index entries have to be consistent 1167 * allocated block. Thus, index entries have to be consistent
1022 * with leaves. 1168 * with leaves.
1023 */ 1169 */
1024static unsigned long 1170static ext4_lblk_t
1025ext4_ext_next_allocated_block(struct ext4_ext_path *path) 1171ext4_ext_next_allocated_block(struct ext4_ext_path *path)
1026{ 1172{
1027 int depth; 1173 int depth;
@@ -1054,7 +1200,7 @@ ext4_ext_next_allocated_block(struct ext4_ext_path *path)
1054 * ext4_ext_next_leaf_block: 1200 * ext4_ext_next_leaf_block:
1055 * returns first allocated block from next leaf or EXT_MAX_BLOCK 1201 * returns first allocated block from next leaf or EXT_MAX_BLOCK
1056 */ 1202 */
1057static unsigned ext4_ext_next_leaf_block(struct inode *inode, 1203static ext4_lblk_t ext4_ext_next_leaf_block(struct inode *inode,
1058 struct ext4_ext_path *path) 1204 struct ext4_ext_path *path)
1059{ 1205{
1060 int depth; 1206 int depth;
@@ -1072,7 +1218,8 @@ static unsigned ext4_ext_next_leaf_block(struct inode *inode,
1072 while (depth >= 0) { 1218 while (depth >= 0) {
1073 if (path[depth].p_idx != 1219 if (path[depth].p_idx !=
1074 EXT_LAST_INDEX(path[depth].p_hdr)) 1220 EXT_LAST_INDEX(path[depth].p_hdr))
1075 return le32_to_cpu(path[depth].p_idx[1].ei_block); 1221 return (ext4_lblk_t)
1222 le32_to_cpu(path[depth].p_idx[1].ei_block);
1076 depth--; 1223 depth--;
1077 } 1224 }
1078 1225
@@ -1085,7 +1232,7 @@ static unsigned ext4_ext_next_leaf_block(struct inode *inode,
1085 * then we have to correct all indexes above. 1232 * then we have to correct all indexes above.
1086 * TODO: do we need to correct tree in all cases? 1233 * TODO: do we need to correct tree in all cases?
1087 */ 1234 */
1088int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, 1235static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
1089 struct ext4_ext_path *path) 1236 struct ext4_ext_path *path)
1090{ 1237{
1091 struct ext4_extent_header *eh; 1238 struct ext4_extent_header *eh;
@@ -1171,7 +1318,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1171 if (ext1_ee_len + ext2_ee_len > max_len) 1318 if (ext1_ee_len + ext2_ee_len > max_len)
1172 return 0; 1319 return 0;
1173#ifdef AGGRESSIVE_TEST 1320#ifdef AGGRESSIVE_TEST
1174 if (le16_to_cpu(ex1->ee_len) >= 4) 1321 if (ext1_ee_len >= 4)
1175 return 0; 1322 return 0;
1176#endif 1323#endif
1177 1324
@@ -1239,7 +1386,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode,
1239 struct ext4_extent *newext, 1386 struct ext4_extent *newext,
1240 struct ext4_ext_path *path) 1387 struct ext4_ext_path *path)
1241{ 1388{
1242 unsigned long b1, b2; 1389 ext4_lblk_t b1, b2;
1243 unsigned int depth, len1; 1390 unsigned int depth, len1;
1244 unsigned int ret = 0; 1391 unsigned int ret = 0;
1245 1392
@@ -1260,7 +1407,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode,
1260 goto out; 1407 goto out;
1261 } 1408 }
1262 1409
1263 /* check for wrap through zero */ 1410 /* check for wrap through zero on extent logical start block*/
1264 if (b1 + len1 < b1) { 1411 if (b1 + len1 < b1) {
1265 len1 = EXT_MAX_BLOCK - b1; 1412 len1 = EXT_MAX_BLOCK - b1;
1266 newext->ee_len = cpu_to_le16(len1); 1413 newext->ee_len = cpu_to_le16(len1);
@@ -1290,7 +1437,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1290 struct ext4_extent *ex, *fex; 1437 struct ext4_extent *ex, *fex;
1291 struct ext4_extent *nearex; /* nearest extent */ 1438 struct ext4_extent *nearex; /* nearest extent */
1292 struct ext4_ext_path *npath = NULL; 1439 struct ext4_ext_path *npath = NULL;
1293 int depth, len, err, next; 1440 int depth, len, err;
1441 ext4_lblk_t next;
1294 unsigned uninitialized = 0; 1442 unsigned uninitialized = 0;
1295 1443
1296 BUG_ON(ext4_ext_get_actual_len(newext) == 0); 1444 BUG_ON(ext4_ext_get_actual_len(newext) == 0);
@@ -1435,114 +1583,8 @@ cleanup:
1435 return err; 1583 return err;
1436} 1584}
1437 1585
1438int ext4_ext_walk_space(struct inode *inode, unsigned long block,
1439 unsigned long num, ext_prepare_callback func,
1440 void *cbdata)
1441{
1442 struct ext4_ext_path *path = NULL;
1443 struct ext4_ext_cache cbex;
1444 struct ext4_extent *ex;
1445 unsigned long next, start = 0, end = 0;
1446 unsigned long last = block + num;
1447 int depth, exists, err = 0;
1448
1449 BUG_ON(func == NULL);
1450 BUG_ON(inode == NULL);
1451
1452 while (block < last && block != EXT_MAX_BLOCK) {
1453 num = last - block;
1454 /* find extent for this block */
1455 path = ext4_ext_find_extent(inode, block, path);
1456 if (IS_ERR(path)) {
1457 err = PTR_ERR(path);
1458 path = NULL;
1459 break;
1460 }
1461
1462 depth = ext_depth(inode);
1463 BUG_ON(path[depth].p_hdr == NULL);
1464 ex = path[depth].p_ext;
1465 next = ext4_ext_next_allocated_block(path);
1466
1467 exists = 0;
1468 if (!ex) {
1469 /* there is no extent yet, so try to allocate
1470 * all requested space */
1471 start = block;
1472 end = block + num;
1473 } else if (le32_to_cpu(ex->ee_block) > block) {
1474 /* need to allocate space before found extent */
1475 start = block;
1476 end = le32_to_cpu(ex->ee_block);
1477 if (block + num < end)
1478 end = block + num;
1479 } else if (block >= le32_to_cpu(ex->ee_block)
1480 + ext4_ext_get_actual_len(ex)) {
1481 /* need to allocate space after found extent */
1482 start = block;
1483 end = block + num;
1484 if (end >= next)
1485 end = next;
1486 } else if (block >= le32_to_cpu(ex->ee_block)) {
1487 /*
1488 * some part of requested space is covered
1489 * by found extent
1490 */
1491 start = block;
1492 end = le32_to_cpu(ex->ee_block)
1493 + ext4_ext_get_actual_len(ex);
1494 if (block + num < end)
1495 end = block + num;
1496 exists = 1;
1497 } else {
1498 BUG();
1499 }
1500 BUG_ON(end <= start);
1501
1502 if (!exists) {
1503 cbex.ec_block = start;
1504 cbex.ec_len = end - start;
1505 cbex.ec_start = 0;
1506 cbex.ec_type = EXT4_EXT_CACHE_GAP;
1507 } else {
1508 cbex.ec_block = le32_to_cpu(ex->ee_block);
1509 cbex.ec_len = ext4_ext_get_actual_len(ex);
1510 cbex.ec_start = ext_pblock(ex);
1511 cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
1512 }
1513
1514 BUG_ON(cbex.ec_len == 0);
1515 err = func(inode, path, &cbex, cbdata);
1516 ext4_ext_drop_refs(path);
1517
1518 if (err < 0)
1519 break;
1520 if (err == EXT_REPEAT)
1521 continue;
1522 else if (err == EXT_BREAK) {
1523 err = 0;
1524 break;
1525 }
1526
1527 if (ext_depth(inode) != depth) {
1528 /* depth was changed. we have to realloc path */
1529 kfree(path);
1530 path = NULL;
1531 }
1532
1533 block = cbex.ec_block + cbex.ec_len;
1534 }
1535
1536 if (path) {
1537 ext4_ext_drop_refs(path);
1538 kfree(path);
1539 }
1540
1541 return err;
1542}
1543
1544static void 1586static void
1545ext4_ext_put_in_cache(struct inode *inode, __u32 block, 1587ext4_ext_put_in_cache(struct inode *inode, ext4_lblk_t block,
1546 __u32 len, ext4_fsblk_t start, int type) 1588 __u32 len, ext4_fsblk_t start, int type)
1547{ 1589{
1548 struct ext4_ext_cache *cex; 1590 struct ext4_ext_cache *cex;
@@ -1561,10 +1603,11 @@ ext4_ext_put_in_cache(struct inode *inode, __u32 block,
1561 */ 1603 */
1562static void 1604static void
1563ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, 1605ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
1564 unsigned long block) 1606 ext4_lblk_t block)
1565{ 1607{
1566 int depth = ext_depth(inode); 1608 int depth = ext_depth(inode);
1567 unsigned long lblock, len; 1609 unsigned long len;
1610 ext4_lblk_t lblock;
1568 struct ext4_extent *ex; 1611 struct ext4_extent *ex;
1569 1612
1570 ex = path[depth].p_ext; 1613 ex = path[depth].p_ext;
@@ -1576,32 +1619,34 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
1576 } else if (block < le32_to_cpu(ex->ee_block)) { 1619 } else if (block < le32_to_cpu(ex->ee_block)) {
1577 lblock = block; 1620 lblock = block;
1578 len = le32_to_cpu(ex->ee_block) - block; 1621 len = le32_to_cpu(ex->ee_block) - block;
1579 ext_debug("cache gap(before): %lu [%lu:%lu]", 1622 ext_debug("cache gap(before): %u [%u:%u]",
1580 (unsigned long) block, 1623 block,
1581 (unsigned long) le32_to_cpu(ex->ee_block), 1624 le32_to_cpu(ex->ee_block),
1582 (unsigned long) ext4_ext_get_actual_len(ex)); 1625 ext4_ext_get_actual_len(ex));
1583 } else if (block >= le32_to_cpu(ex->ee_block) 1626 } else if (block >= le32_to_cpu(ex->ee_block)
1584 + ext4_ext_get_actual_len(ex)) { 1627 + ext4_ext_get_actual_len(ex)) {
1628 ext4_lblk_t next;
1585 lblock = le32_to_cpu(ex->ee_block) 1629 lblock = le32_to_cpu(ex->ee_block)
1586 + ext4_ext_get_actual_len(ex); 1630 + ext4_ext_get_actual_len(ex);
1587 len = ext4_ext_next_allocated_block(path); 1631
1588 ext_debug("cache gap(after): [%lu:%lu] %lu", 1632 next = ext4_ext_next_allocated_block(path);
1589 (unsigned long) le32_to_cpu(ex->ee_block), 1633 ext_debug("cache gap(after): [%u:%u] %u",
1590 (unsigned long) ext4_ext_get_actual_len(ex), 1634 le32_to_cpu(ex->ee_block),
1591 (unsigned long) block); 1635 ext4_ext_get_actual_len(ex),
1592 BUG_ON(len == lblock); 1636 block);
1593 len = len - lblock; 1637 BUG_ON(next == lblock);
1638 len = next - lblock;
1594 } else { 1639 } else {
1595 lblock = len = 0; 1640 lblock = len = 0;
1596 BUG(); 1641 BUG();
1597 } 1642 }
1598 1643
1599 ext_debug(" -> %lu:%lu\n", (unsigned long) lblock, len); 1644 ext_debug(" -> %u:%lu\n", lblock, len);
1600 ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); 1645 ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP);
1601} 1646}
1602 1647
1603static int 1648static int
1604ext4_ext_in_cache(struct inode *inode, unsigned long block, 1649ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
1605 struct ext4_extent *ex) 1650 struct ext4_extent *ex)
1606{ 1651{
1607 struct ext4_ext_cache *cex; 1652 struct ext4_ext_cache *cex;
@@ -1618,11 +1663,9 @@ ext4_ext_in_cache(struct inode *inode, unsigned long block,
1618 ex->ee_block = cpu_to_le32(cex->ec_block); 1663 ex->ee_block = cpu_to_le32(cex->ec_block);
1619 ext4_ext_store_pblock(ex, cex->ec_start); 1664 ext4_ext_store_pblock(ex, cex->ec_start);
1620 ex->ee_len = cpu_to_le16(cex->ec_len); 1665 ex->ee_len = cpu_to_le16(cex->ec_len);
1621 ext_debug("%lu cached by %lu:%lu:%llu\n", 1666 ext_debug("%u cached by %u:%u:%llu\n",
1622 (unsigned long) block, 1667 block,
1623 (unsigned long) cex->ec_block, 1668 cex->ec_block, cex->ec_len, cex->ec_start);
1624 (unsigned long) cex->ec_len,
1625 cex->ec_start);
1626 return cex->ec_type; 1669 return cex->ec_type;
1627 } 1670 }
1628 1671
@@ -1636,7 +1679,7 @@ ext4_ext_in_cache(struct inode *inode, unsigned long block,
1636 * It's used in truncate case only, thus all requests are for 1679 * It's used in truncate case only, thus all requests are for
1637 * last index in the block only. 1680 * last index in the block only.
1638 */ 1681 */
1639int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, 1682static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
1640 struct ext4_ext_path *path) 1683 struct ext4_ext_path *path)
1641{ 1684{
1642 struct buffer_head *bh; 1685 struct buffer_head *bh;
@@ -1657,7 +1700,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
1657 ext_debug("index is empty, remove it, free block %llu\n", leaf); 1700 ext_debug("index is empty, remove it, free block %llu\n", leaf);
1658 bh = sb_find_get_block(inode->i_sb, leaf); 1701 bh = sb_find_get_block(inode->i_sb, leaf);
1659 ext4_forget(handle, 1, inode, bh, leaf); 1702 ext4_forget(handle, 1, inode, bh, leaf);
1660 ext4_free_blocks(handle, inode, leaf, 1); 1703 ext4_free_blocks(handle, inode, leaf, 1, 1);
1661 return err; 1704 return err;
1662} 1705}
1663 1706
@@ -1666,7 +1709,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
1666 * This routine returns max. credits that the extent tree can consume. 1709 * This routine returns max. credits that the extent tree can consume.
1667 * It should be OK for low-performance paths like ->writepage() 1710 * It should be OK for low-performance paths like ->writepage()
1668 * To allow many writing processes to fit into a single transaction, 1711 * To allow many writing processes to fit into a single transaction,
1669 * the caller should calculate credits under truncate_mutex and 1712 * the caller should calculate credits under i_data_sem and
1670 * pass the actual path. 1713 * pass the actual path.
1671 */ 1714 */
1672int ext4_ext_calc_credits_for_insert(struct inode *inode, 1715int ext4_ext_calc_credits_for_insert(struct inode *inode,
@@ -1714,12 +1757,14 @@ int ext4_ext_calc_credits_for_insert(struct inode *inode,
1714 1757
1715static int ext4_remove_blocks(handle_t *handle, struct inode *inode, 1758static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
1716 struct ext4_extent *ex, 1759 struct ext4_extent *ex,
1717 unsigned long from, unsigned long to) 1760 ext4_lblk_t from, ext4_lblk_t to)
1718{ 1761{
1719 struct buffer_head *bh; 1762 struct buffer_head *bh;
1720 unsigned short ee_len = ext4_ext_get_actual_len(ex); 1763 unsigned short ee_len = ext4_ext_get_actual_len(ex);
1721 int i; 1764 int i, metadata = 0;
1722 1765
1766 if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
1767 metadata = 1;
1723#ifdef EXTENTS_STATS 1768#ifdef EXTENTS_STATS
1724 { 1769 {
1725 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 1770 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -1738,42 +1783,45 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
1738 if (from >= le32_to_cpu(ex->ee_block) 1783 if (from >= le32_to_cpu(ex->ee_block)
1739 && to == le32_to_cpu(ex->ee_block) + ee_len - 1) { 1784 && to == le32_to_cpu(ex->ee_block) + ee_len - 1) {
1740 /* tail removal */ 1785 /* tail removal */
1741 unsigned long num; 1786 ext4_lblk_t num;
1742 ext4_fsblk_t start; 1787 ext4_fsblk_t start;
1788
1743 num = le32_to_cpu(ex->ee_block) + ee_len - from; 1789 num = le32_to_cpu(ex->ee_block) + ee_len - from;
1744 start = ext_pblock(ex) + ee_len - num; 1790 start = ext_pblock(ex) + ee_len - num;
1745 ext_debug("free last %lu blocks starting %llu\n", num, start); 1791 ext_debug("free last %u blocks starting %llu\n", num, start);
1746 for (i = 0; i < num; i++) { 1792 for (i = 0; i < num; i++) {
1747 bh = sb_find_get_block(inode->i_sb, start + i); 1793 bh = sb_find_get_block(inode->i_sb, start + i);
1748 ext4_forget(handle, 0, inode, bh, start + i); 1794 ext4_forget(handle, 0, inode, bh, start + i);
1749 } 1795 }
1750 ext4_free_blocks(handle, inode, start, num); 1796 ext4_free_blocks(handle, inode, start, num, metadata);
1751 } else if (from == le32_to_cpu(ex->ee_block) 1797 } else if (from == le32_to_cpu(ex->ee_block)
1752 && to <= le32_to_cpu(ex->ee_block) + ee_len - 1) { 1798 && to <= le32_to_cpu(ex->ee_block) + ee_len - 1) {
1753 printk("strange request: removal %lu-%lu from %u:%u\n", 1799 printk(KERN_INFO "strange request: removal %u-%u from %u:%u\n",
1754 from, to, le32_to_cpu(ex->ee_block), ee_len); 1800 from, to, le32_to_cpu(ex->ee_block), ee_len);
1755 } else { 1801 } else {
1756 printk("strange request: removal(2) %lu-%lu from %u:%u\n", 1802 printk(KERN_INFO "strange request: removal(2) "
1757 from, to, le32_to_cpu(ex->ee_block), ee_len); 1803 "%u-%u from %u:%u\n",
1804 from, to, le32_to_cpu(ex->ee_block), ee_len);
1758 } 1805 }
1759 return 0; 1806 return 0;
1760} 1807}
1761 1808
1762static int 1809static int
1763ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, 1810ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
1764 struct ext4_ext_path *path, unsigned long start) 1811 struct ext4_ext_path *path, ext4_lblk_t start)
1765{ 1812{
1766 int err = 0, correct_index = 0; 1813 int err = 0, correct_index = 0;
1767 int depth = ext_depth(inode), credits; 1814 int depth = ext_depth(inode), credits;
1768 struct ext4_extent_header *eh; 1815 struct ext4_extent_header *eh;
1769 unsigned a, b, block, num; 1816 ext4_lblk_t a, b, block;
1770 unsigned long ex_ee_block; 1817 unsigned num;
1818 ext4_lblk_t ex_ee_block;
1771 unsigned short ex_ee_len; 1819 unsigned short ex_ee_len;
1772 unsigned uninitialized = 0; 1820 unsigned uninitialized = 0;
1773 struct ext4_extent *ex; 1821 struct ext4_extent *ex;
1774 1822
1775 /* the header must be checked already in ext4_ext_remove_space() */ 1823 /* the header must be checked already in ext4_ext_remove_space() */
1776 ext_debug("truncate since %lu in leaf\n", start); 1824 ext_debug("truncate since %u in leaf\n", start);
1777 if (!path[depth].p_hdr) 1825 if (!path[depth].p_hdr)
1778 path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); 1826 path[depth].p_hdr = ext_block_hdr(path[depth].p_bh);
1779 eh = path[depth].p_hdr; 1827 eh = path[depth].p_hdr;
@@ -1904,7 +1952,7 @@ ext4_ext_more_to_rm(struct ext4_ext_path *path)
1904 return 1; 1952 return 1;
1905} 1953}
1906 1954
1907int ext4_ext_remove_space(struct inode *inode, unsigned long start) 1955static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
1908{ 1956{
1909 struct super_block *sb = inode->i_sb; 1957 struct super_block *sb = inode->i_sb;
1910 int depth = ext_depth(inode); 1958 int depth = ext_depth(inode);
@@ -1912,7 +1960,7 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start)
1912 handle_t *handle; 1960 handle_t *handle;
1913 int i = 0, err = 0; 1961 int i = 0, err = 0;
1914 1962
1915 ext_debug("truncate since %lu\n", start); 1963 ext_debug("truncate since %u\n", start);
1916 1964
1917 /* probably first extent we're gonna free will be last in block */ 1965 /* probably first extent we're gonna free will be last in block */
1918 handle = ext4_journal_start(inode, depth + 1); 1966 handle = ext4_journal_start(inode, depth + 1);
@@ -2094,17 +2142,19 @@ void ext4_ext_release(struct super_block *sb)
2094 * b> Splits in two extents: Write is happening at either end of the extent 2142 * b> Splits in two extents: Write is happening at either end of the extent
2095 * c> Splits in three extents: Somone is writing in middle of the extent 2143 * c> Splits in three extents: Somone is writing in middle of the extent
2096 */ 2144 */
2097int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode, 2145static int ext4_ext_convert_to_initialized(handle_t *handle,
2098 struct ext4_ext_path *path, 2146 struct inode *inode,
2099 ext4_fsblk_t iblock, 2147 struct ext4_ext_path *path,
2100 unsigned long max_blocks) 2148 ext4_lblk_t iblock,
2149 unsigned long max_blocks)
2101{ 2150{
2102 struct ext4_extent *ex, newex; 2151 struct ext4_extent *ex, newex;
2103 struct ext4_extent *ex1 = NULL; 2152 struct ext4_extent *ex1 = NULL;
2104 struct ext4_extent *ex2 = NULL; 2153 struct ext4_extent *ex2 = NULL;
2105 struct ext4_extent *ex3 = NULL; 2154 struct ext4_extent *ex3 = NULL;
2106 struct ext4_extent_header *eh; 2155 struct ext4_extent_header *eh;
2107 unsigned int allocated, ee_block, ee_len, depth; 2156 ext4_lblk_t ee_block;
2157 unsigned int allocated, ee_len, depth;
2108 ext4_fsblk_t newblock; 2158 ext4_fsblk_t newblock;
2109 int err = 0; 2159 int err = 0;
2110 int ret = 0; 2160 int ret = 0;
@@ -2225,8 +2275,13 @@ out:
2225 return err ? err : allocated; 2275 return err ? err : allocated;
2226} 2276}
2227 2277
2278/*
2279 * Need to be called with
2280 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
2281 * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
2282 */
2228int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 2283int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2229 ext4_fsblk_t iblock, 2284 ext4_lblk_t iblock,
2230 unsigned long max_blocks, struct buffer_head *bh_result, 2285 unsigned long max_blocks, struct buffer_head *bh_result,
2231 int create, int extend_disksize) 2286 int create, int extend_disksize)
2232{ 2287{
@@ -2236,11 +2291,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2236 ext4_fsblk_t goal, newblock; 2291 ext4_fsblk_t goal, newblock;
2237 int err = 0, depth, ret; 2292 int err = 0, depth, ret;
2238 unsigned long allocated = 0; 2293 unsigned long allocated = 0;
2294 struct ext4_allocation_request ar;
2239 2295
2240 __clear_bit(BH_New, &bh_result->b_state); 2296 __clear_bit(BH_New, &bh_result->b_state);
2241 ext_debug("blocks %d/%lu requested for inode %u\n", (int) iblock, 2297 ext_debug("blocks %u/%lu requested for inode %u\n",
2242 max_blocks, (unsigned) inode->i_ino); 2298 iblock, max_blocks, inode->i_ino);
2243 mutex_lock(&EXT4_I(inode)->truncate_mutex);
2244 2299
2245 /* check in cache */ 2300 /* check in cache */
2246 goal = ext4_ext_in_cache(inode, iblock, &newex); 2301 goal = ext4_ext_in_cache(inode, iblock, &newex);
@@ -2260,7 +2315,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2260 - le32_to_cpu(newex.ee_block) 2315 - le32_to_cpu(newex.ee_block)
2261 + ext_pblock(&newex); 2316 + ext_pblock(&newex);
2262 /* number of remaining blocks in the extent */ 2317 /* number of remaining blocks in the extent */
2263 allocated = le16_to_cpu(newex.ee_len) - 2318 allocated = ext4_ext_get_actual_len(&newex) -
2264 (iblock - le32_to_cpu(newex.ee_block)); 2319 (iblock - le32_to_cpu(newex.ee_block));
2265 goto out; 2320 goto out;
2266 } else { 2321 } else {
@@ -2288,7 +2343,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2288 2343
2289 ex = path[depth].p_ext; 2344 ex = path[depth].p_ext;
2290 if (ex) { 2345 if (ex) {
2291 unsigned long ee_block = le32_to_cpu(ex->ee_block); 2346 ext4_lblk_t ee_block = le32_to_cpu(ex->ee_block);
2292 ext4_fsblk_t ee_start = ext_pblock(ex); 2347 ext4_fsblk_t ee_start = ext_pblock(ex);
2293 unsigned short ee_len; 2348 unsigned short ee_len;
2294 2349
@@ -2302,7 +2357,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2302 newblock = iblock - ee_block + ee_start; 2357 newblock = iblock - ee_block + ee_start;
2303 /* number of remaining blocks in the extent */ 2358 /* number of remaining blocks in the extent */
2304 allocated = ee_len - (iblock - ee_block); 2359 allocated = ee_len - (iblock - ee_block);
2305 ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, 2360 ext_debug("%u fit into %lu:%d -> %llu\n", iblock,
2306 ee_block, ee_len, newblock); 2361 ee_block, ee_len, newblock);
2307 2362
2308 /* Do not put uninitialized extent in the cache */ 2363 /* Do not put uninitialized extent in the cache */
@@ -2320,9 +2375,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2320 ret = ext4_ext_convert_to_initialized(handle, inode, 2375 ret = ext4_ext_convert_to_initialized(handle, inode,
2321 path, iblock, 2376 path, iblock,
2322 max_blocks); 2377 max_blocks);
2323 if (ret <= 0) 2378 if (ret <= 0) {
2379 err = ret;
2324 goto out2; 2380 goto out2;
2325 else 2381 } else
2326 allocated = ret; 2382 allocated = ret;
2327 goto outnew; 2383 goto outnew;
2328 } 2384 }
@@ -2347,8 +2403,15 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2347 if (S_ISREG(inode->i_mode) && (!EXT4_I(inode)->i_block_alloc_info)) 2403 if (S_ISREG(inode->i_mode) && (!EXT4_I(inode)->i_block_alloc_info))
2348 ext4_init_block_alloc_info(inode); 2404 ext4_init_block_alloc_info(inode);
2349 2405
2350 /* allocate new block */ 2406 /* find neighbour allocated blocks */
2351 goal = ext4_ext_find_goal(inode, path, iblock); 2407 ar.lleft = iblock;
2408 err = ext4_ext_search_left(inode, path, &ar.lleft, &ar.pleft);
2409 if (err)
2410 goto out2;
2411 ar.lright = iblock;
2412 err = ext4_ext_search_right(inode, path, &ar.lright, &ar.pright);
2413 if (err)
2414 goto out2;
2352 2415
2353 /* 2416 /*
2354 * See if request is beyond maximum number of blocks we can have in 2417 * See if request is beyond maximum number of blocks we can have in
@@ -2368,10 +2431,21 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2368 newex.ee_len = cpu_to_le16(max_blocks); 2431 newex.ee_len = cpu_to_le16(max_blocks);
2369 err = ext4_ext_check_overlap(inode, &newex, path); 2432 err = ext4_ext_check_overlap(inode, &newex, path);
2370 if (err) 2433 if (err)
2371 allocated = le16_to_cpu(newex.ee_len); 2434 allocated = ext4_ext_get_actual_len(&newex);
2372 else 2435 else
2373 allocated = max_blocks; 2436 allocated = max_blocks;
2374 newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err); 2437
2438 /* allocate new block */
2439 ar.inode = inode;
2440 ar.goal = ext4_ext_find_goal(inode, path, iblock);
2441 ar.logical = iblock;
2442 ar.len = allocated;
2443 if (S_ISREG(inode->i_mode))
2444 ar.flags = EXT4_MB_HINT_DATA;
2445 else
2446 /* disable in-core preallocation for non-regular files */
2447 ar.flags = 0;
2448 newblock = ext4_mb_new_blocks(handle, &ar, &err);
2375 if (!newblock) 2449 if (!newblock)
2376 goto out2; 2450 goto out2;
2377 ext_debug("allocate new block: goal %llu, found %llu/%lu\n", 2451 ext_debug("allocate new block: goal %llu, found %llu/%lu\n",
@@ -2379,14 +2453,17 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2379 2453
2380 /* try to insert new extent into found leaf and return */ 2454 /* try to insert new extent into found leaf and return */
2381 ext4_ext_store_pblock(&newex, newblock); 2455 ext4_ext_store_pblock(&newex, newblock);
2382 newex.ee_len = cpu_to_le16(allocated); 2456 newex.ee_len = cpu_to_le16(ar.len);
2383 if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */ 2457 if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */
2384 ext4_ext_mark_uninitialized(&newex); 2458 ext4_ext_mark_uninitialized(&newex);
2385 err = ext4_ext_insert_extent(handle, inode, path, &newex); 2459 err = ext4_ext_insert_extent(handle, inode, path, &newex);
2386 if (err) { 2460 if (err) {
2387 /* free data blocks we just allocated */ 2461 /* free data blocks we just allocated */
2462 /* not a good idea to call discard here directly,
2463 * but otherwise we'd need to call it every free() */
2464 ext4_mb_discard_inode_preallocations(inode);
2388 ext4_free_blocks(handle, inode, ext_pblock(&newex), 2465 ext4_free_blocks(handle, inode, ext_pblock(&newex),
2389 le16_to_cpu(newex.ee_len)); 2466 ext4_ext_get_actual_len(&newex), 0);
2390 goto out2; 2467 goto out2;
2391 } 2468 }
2392 2469
@@ -2395,6 +2472,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2395 2472
2396 /* previous routine could use block we allocated */ 2473 /* previous routine could use block we allocated */
2397 newblock = ext_pblock(&newex); 2474 newblock = ext_pblock(&newex);
2475 allocated = ext4_ext_get_actual_len(&newex);
2398outnew: 2476outnew:
2399 __set_bit(BH_New, &bh_result->b_state); 2477 __set_bit(BH_New, &bh_result->b_state);
2400 2478
@@ -2414,8 +2492,6 @@ out2:
2414 ext4_ext_drop_refs(path); 2492 ext4_ext_drop_refs(path);
2415 kfree(path); 2493 kfree(path);
2416 } 2494 }
2417 mutex_unlock(&EXT4_I(inode)->truncate_mutex);
2418
2419 return err ? err : allocated; 2495 return err ? err : allocated;
2420} 2496}
2421 2497
@@ -2423,7 +2499,7 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2423{ 2499{
2424 struct address_space *mapping = inode->i_mapping; 2500 struct address_space *mapping = inode->i_mapping;
2425 struct super_block *sb = inode->i_sb; 2501 struct super_block *sb = inode->i_sb;
2426 unsigned long last_block; 2502 ext4_lblk_t last_block;
2427 handle_t *handle; 2503 handle_t *handle;
2428 int err = 0; 2504 int err = 0;
2429 2505
@@ -2445,9 +2521,11 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2445 if (page) 2521 if (page)
2446 ext4_block_truncate_page(handle, page, mapping, inode->i_size); 2522 ext4_block_truncate_page(handle, page, mapping, inode->i_size);
2447 2523
2448 mutex_lock(&EXT4_I(inode)->truncate_mutex); 2524 down_write(&EXT4_I(inode)->i_data_sem);
2449 ext4_ext_invalidate_cache(inode); 2525 ext4_ext_invalidate_cache(inode);
2450 2526
2527 ext4_mb_discard_inode_preallocations(inode);
2528
2451 /* 2529 /*
2452 * TODO: optimization is possible here. 2530 * TODO: optimization is possible here.
2453 * Probably we need not scan at all, 2531 * Probably we need not scan at all,
@@ -2481,7 +2559,7 @@ out_stop:
2481 if (inode->i_nlink) 2559 if (inode->i_nlink)
2482 ext4_orphan_del(handle, inode); 2560 ext4_orphan_del(handle, inode);
2483 2561
2484 mutex_unlock(&EXT4_I(inode)->truncate_mutex); 2562 up_write(&EXT4_I(inode)->i_data_sem);
2485 ext4_journal_stop(handle); 2563 ext4_journal_stop(handle);
2486} 2564}
2487 2565
@@ -2516,7 +2594,8 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
2516long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) 2594long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
2517{ 2595{
2518 handle_t *handle; 2596 handle_t *handle;
2519 ext4_fsblk_t block, max_blocks; 2597 ext4_lblk_t block;
2598 unsigned long max_blocks;
2520 ext4_fsblk_t nblocks = 0; 2599 ext4_fsblk_t nblocks = 0;
2521 int ret = 0; 2600 int ret = 0;
2522 int ret2 = 0; 2601 int ret2 = 0;
@@ -2544,6 +2623,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
2544 * modify 1 super block, 1 block bitmap and 1 group descriptor. 2623 * modify 1 super block, 1 block bitmap and 1 group descriptor.
2545 */ 2624 */
2546 credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; 2625 credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
2626 down_write((&EXT4_I(inode)->i_data_sem));
2547retry: 2627retry:
2548 while (ret >= 0 && ret < max_blocks) { 2628 while (ret >= 0 && ret < max_blocks) {
2549 block = block + ret; 2629 block = block + ret;
@@ -2557,12 +2637,12 @@ retry:
2557 ret = ext4_ext_get_blocks(handle, inode, block, 2637 ret = ext4_ext_get_blocks(handle, inode, block,
2558 max_blocks, &map_bh, 2638 max_blocks, &map_bh,
2559 EXT4_CREATE_UNINITIALIZED_EXT, 0); 2639 EXT4_CREATE_UNINITIALIZED_EXT, 0);
2560 WARN_ON(!ret); 2640 WARN_ON(ret <= 0);
2561 if (!ret) { 2641 if (ret <= 0) {
2562 ext4_error(inode->i_sb, "ext4_fallocate", 2642 ext4_error(inode->i_sb, "ext4_fallocate",
2563 "ext4_ext_get_blocks returned 0! inode#%lu" 2643 "ext4_ext_get_blocks returned error: "
2564 ", block=%llu, max_blocks=%llu", 2644 "inode#%lu, block=%u, max_blocks=%lu",
2565 inode->i_ino, block, max_blocks); 2645 inode->i_ino, block, max_blocks);
2566 ret = -EIO; 2646 ret = -EIO;
2567 ext4_mark_inode_dirty(handle, inode); 2647 ext4_mark_inode_dirty(handle, inode);
2568 ret2 = ext4_journal_stop(handle); 2648 ret2 = ext4_journal_stop(handle);
@@ -2600,6 +2680,7 @@ retry:
2600 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 2680 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
2601 goto retry; 2681 goto retry;
2602 2682
2683 up_write((&EXT4_I(inode)->i_data_sem));
2603 /* 2684 /*
2604 * Time to update the file size. 2685 * Time to update the file size.
2605 * Update only when preallocation was requested beyond the file size. 2686 * Update only when preallocation was requested beyond the file size.
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 1a81cd66d63b..ac35ec58db55 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -37,9 +37,9 @@ static int ext4_release_file (struct inode * inode, struct file * filp)
37 if ((filp->f_mode & FMODE_WRITE) && 37 if ((filp->f_mode & FMODE_WRITE) &&
38 (atomic_read(&inode->i_writecount) == 1)) 38 (atomic_read(&inode->i_writecount) == 1))
39 { 39 {
40 mutex_lock(&EXT4_I(inode)->truncate_mutex); 40 down_write(&EXT4_I(inode)->i_data_sem);
41 ext4_discard_reservation(inode); 41 ext4_discard_reservation(inode);
42 mutex_unlock(&EXT4_I(inode)->truncate_mutex); 42 up_write(&EXT4_I(inode)->i_data_sem);
43 } 43 }
44 if (is_dx(inode) && filp->private_data) 44 if (is_dx(inode) && filp->private_data)
45 ext4_htree_free_dir_info(filp->private_data); 45 ext4_htree_free_dir_info(filp->private_data);
@@ -56,8 +56,25 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
56 ssize_t ret; 56 ssize_t ret;
57 int err; 57 int err;
58 58
59 ret = generic_file_aio_write(iocb, iov, nr_segs, pos); 59 /*
60 * If we have encountered a bitmap-format file, the size limit
61 * is smaller than s_maxbytes, which is for extent-mapped files.
62 */
63
64 if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) {
65 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
66 size_t length = iov_length(iov, nr_segs);
60 67
68 if (pos > sbi->s_bitmap_maxbytes)
69 return -EFBIG;
70
71 if (pos + length > sbi->s_bitmap_maxbytes) {
72 nr_segs = iov_shorten((struct iovec *)iov, nr_segs,
73 sbi->s_bitmap_maxbytes - pos);
74 }
75 }
76
77 ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
61 /* 78 /*
62 * Skip flushing if there was an error, or if nothing was written. 79 * Skip flushing if there was an error, or if nothing was written.
63 */ 80 */
diff --git a/fs/ext4/group.h b/fs/ext4/group.h
index 1577910bb58b..7eb0604e7eea 100644
--- a/fs/ext4/group.h
+++ b/fs/ext4/group.h
@@ -14,14 +14,16 @@ extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
14extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, 14extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
15 struct ext4_group_desc *gdp); 15 struct ext4_group_desc *gdp);
16struct buffer_head *read_block_bitmap(struct super_block *sb, 16struct buffer_head *read_block_bitmap(struct super_block *sb,
17 unsigned int block_group); 17 ext4_group_t block_group);
18extern unsigned ext4_init_block_bitmap(struct super_block *sb, 18extern unsigned ext4_init_block_bitmap(struct super_block *sb,
19 struct buffer_head *bh, int group, 19 struct buffer_head *bh,
20 ext4_group_t group,
20 struct ext4_group_desc *desc); 21 struct ext4_group_desc *desc);
21#define ext4_free_blocks_after_init(sb, group, desc) \ 22#define ext4_free_blocks_after_init(sb, group, desc) \
22 ext4_init_block_bitmap(sb, NULL, group, desc) 23 ext4_init_block_bitmap(sb, NULL, group, desc)
23extern unsigned ext4_init_inode_bitmap(struct super_block *sb, 24extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
24 struct buffer_head *bh, int group, 25 struct buffer_head *bh,
26 ext4_group_t group,
25 struct ext4_group_desc *desc); 27 struct ext4_group_desc *desc);
26extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap); 28extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
27#endif /* _LINUX_EXT4_GROUP_H */ 29#endif /* _LINUX_EXT4_GROUP_H */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index c61f37fd3f05..575b5215c808 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -64,8 +64,8 @@ void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
64} 64}
65 65
66/* Initializes an uninitialized inode bitmap */ 66/* Initializes an uninitialized inode bitmap */
67unsigned ext4_init_inode_bitmap(struct super_block *sb, 67unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
68 struct buffer_head *bh, int block_group, 68 ext4_group_t block_group,
69 struct ext4_group_desc *gdp) 69 struct ext4_group_desc *gdp)
70{ 70{
71 struct ext4_sb_info *sbi = EXT4_SB(sb); 71 struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -75,7 +75,7 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb,
75 /* If checksum is bad mark all blocks and inodes use to prevent 75 /* If checksum is bad mark all blocks and inodes use to prevent
76 * allocation, essentially implementing a per-group read-only flag. */ 76 * allocation, essentially implementing a per-group read-only flag. */
77 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { 77 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
78 ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n", 78 ext4_error(sb, __FUNCTION__, "Checksum bad for group %lu\n",
79 block_group); 79 block_group);
80 gdp->bg_free_blocks_count = 0; 80 gdp->bg_free_blocks_count = 0;
81 gdp->bg_free_inodes_count = 0; 81 gdp->bg_free_inodes_count = 0;
@@ -98,7 +98,7 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb,
98 * Return buffer_head of bitmap on success or NULL. 98 * Return buffer_head of bitmap on success or NULL.
99 */ 99 */
100static struct buffer_head * 100static struct buffer_head *
101read_inode_bitmap(struct super_block * sb, unsigned long block_group) 101read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
102{ 102{
103 struct ext4_group_desc *desc; 103 struct ext4_group_desc *desc;
104 struct buffer_head *bh = NULL; 104 struct buffer_head *bh = NULL;
@@ -152,7 +152,7 @@ void ext4_free_inode (handle_t *handle, struct inode * inode)
152 unsigned long ino; 152 unsigned long ino;
153 struct buffer_head *bitmap_bh = NULL; 153 struct buffer_head *bitmap_bh = NULL;
154 struct buffer_head *bh2; 154 struct buffer_head *bh2;
155 unsigned long block_group; 155 ext4_group_t block_group;
156 unsigned long bit; 156 unsigned long bit;
157 struct ext4_group_desc * gdp; 157 struct ext4_group_desc * gdp;
158 struct ext4_super_block * es; 158 struct ext4_super_block * es;
@@ -260,12 +260,14 @@ error_return:
260 * For other inodes, search forward from the parent directory\'s block 260 * For other inodes, search forward from the parent directory\'s block
261 * group to find a free inode. 261 * group to find a free inode.
262 */ 262 */
263static int find_group_dir(struct super_block *sb, struct inode *parent) 263static int find_group_dir(struct super_block *sb, struct inode *parent,
264 ext4_group_t *best_group)
264{ 265{
265 int ngroups = EXT4_SB(sb)->s_groups_count; 266 ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
266 unsigned int freei, avefreei; 267 unsigned int freei, avefreei;
267 struct ext4_group_desc *desc, *best_desc = NULL; 268 struct ext4_group_desc *desc, *best_desc = NULL;
268 int group, best_group = -1; 269 ext4_group_t group;
270 int ret = -1;
269 271
270 freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter); 272 freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter);
271 avefreei = freei / ngroups; 273 avefreei = freei / ngroups;
@@ -279,11 +281,12 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
279 if (!best_desc || 281 if (!best_desc ||
280 (le16_to_cpu(desc->bg_free_blocks_count) > 282 (le16_to_cpu(desc->bg_free_blocks_count) >
281 le16_to_cpu(best_desc->bg_free_blocks_count))) { 283 le16_to_cpu(best_desc->bg_free_blocks_count))) {
282 best_group = group; 284 *best_group = group;
283 best_desc = desc; 285 best_desc = desc;
286 ret = 0;
284 } 287 }
285 } 288 }
286 return best_group; 289 return ret;
287} 290}
288 291
289/* 292/*
@@ -314,12 +317,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
314#define INODE_COST 64 317#define INODE_COST 64
315#define BLOCK_COST 256 318#define BLOCK_COST 256
316 319
317static int find_group_orlov(struct super_block *sb, struct inode *parent) 320static int find_group_orlov(struct super_block *sb, struct inode *parent,
321 ext4_group_t *group)
318{ 322{
319 int parent_group = EXT4_I(parent)->i_block_group; 323 ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
320 struct ext4_sb_info *sbi = EXT4_SB(sb); 324 struct ext4_sb_info *sbi = EXT4_SB(sb);
321 struct ext4_super_block *es = sbi->s_es; 325 struct ext4_super_block *es = sbi->s_es;
322 int ngroups = sbi->s_groups_count; 326 ext4_group_t ngroups = sbi->s_groups_count;
323 int inodes_per_group = EXT4_INODES_PER_GROUP(sb); 327 int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
324 unsigned int freei, avefreei; 328 unsigned int freei, avefreei;
325 ext4_fsblk_t freeb, avefreeb; 329 ext4_fsblk_t freeb, avefreeb;
@@ -327,7 +331,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
327 unsigned int ndirs; 331 unsigned int ndirs;
328 int max_debt, max_dirs, min_inodes; 332 int max_debt, max_dirs, min_inodes;
329 ext4_grpblk_t min_blocks; 333 ext4_grpblk_t min_blocks;
330 int group = -1, i; 334 ext4_group_t i;
331 struct ext4_group_desc *desc; 335 struct ext4_group_desc *desc;
332 336
333 freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); 337 freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
@@ -340,13 +344,14 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
340 if ((parent == sb->s_root->d_inode) || 344 if ((parent == sb->s_root->d_inode) ||
341 (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) { 345 (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) {
342 int best_ndir = inodes_per_group; 346 int best_ndir = inodes_per_group;
343 int best_group = -1; 347 ext4_group_t grp;
348 int ret = -1;
344 349
345 get_random_bytes(&group, sizeof(group)); 350 get_random_bytes(&grp, sizeof(grp));
346 parent_group = (unsigned)group % ngroups; 351 parent_group = (unsigned)grp % ngroups;
347 for (i = 0; i < ngroups; i++) { 352 for (i = 0; i < ngroups; i++) {
348 group = (parent_group + i) % ngroups; 353 grp = (parent_group + i) % ngroups;
349 desc = ext4_get_group_desc (sb, group, NULL); 354 desc = ext4_get_group_desc(sb, grp, NULL);
350 if (!desc || !desc->bg_free_inodes_count) 355 if (!desc || !desc->bg_free_inodes_count)
351 continue; 356 continue;
352 if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir) 357 if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
@@ -355,11 +360,12 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
355 continue; 360 continue;
356 if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb) 361 if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb)
357 continue; 362 continue;
358 best_group = group; 363 *group = grp;
364 ret = 0;
359 best_ndir = le16_to_cpu(desc->bg_used_dirs_count); 365 best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
360 } 366 }
361 if (best_group >= 0) 367 if (ret == 0)
362 return best_group; 368 return ret;
363 goto fallback; 369 goto fallback;
364 } 370 }
365 371
@@ -380,8 +386,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
380 max_debt = 1; 386 max_debt = 1;
381 387
382 for (i = 0; i < ngroups; i++) { 388 for (i = 0; i < ngroups; i++) {
383 group = (parent_group + i) % ngroups; 389 *group = (parent_group + i) % ngroups;
384 desc = ext4_get_group_desc (sb, group, NULL); 390 desc = ext4_get_group_desc(sb, *group, NULL);
385 if (!desc || !desc->bg_free_inodes_count) 391 if (!desc || !desc->bg_free_inodes_count)
386 continue; 392 continue;
387 if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs) 393 if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
@@ -390,17 +396,16 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
390 continue; 396 continue;
391 if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks) 397 if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks)
392 continue; 398 continue;
393 return group; 399 return 0;
394 } 400 }
395 401
396fallback: 402fallback:
397 for (i = 0; i < ngroups; i++) { 403 for (i = 0; i < ngroups; i++) {
398 group = (parent_group + i) % ngroups; 404 *group = (parent_group + i) % ngroups;
399 desc = ext4_get_group_desc (sb, group, NULL); 405 desc = ext4_get_group_desc(sb, *group, NULL);
400 if (!desc || !desc->bg_free_inodes_count) 406 if (desc && desc->bg_free_inodes_count &&
401 continue; 407 le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
402 if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei) 408 return 0;
403 return group;
404 } 409 }
405 410
406 if (avefreei) { 411 if (avefreei) {
@@ -415,21 +420,22 @@ fallback:
415 return -1; 420 return -1;
416} 421}
417 422
418static int find_group_other(struct super_block *sb, struct inode *parent) 423static int find_group_other(struct super_block *sb, struct inode *parent,
424 ext4_group_t *group)
419{ 425{
420 int parent_group = EXT4_I(parent)->i_block_group; 426 ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
421 int ngroups = EXT4_SB(sb)->s_groups_count; 427 ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
422 struct ext4_group_desc *desc; 428 struct ext4_group_desc *desc;
423 int group, i; 429 ext4_group_t i;
424 430
425 /* 431 /*
426 * Try to place the inode in its parent directory 432 * Try to place the inode in its parent directory
427 */ 433 */
428 group = parent_group; 434 *group = parent_group;
429 desc = ext4_get_group_desc (sb, group, NULL); 435 desc = ext4_get_group_desc(sb, *group, NULL);
430 if (desc && le16_to_cpu(desc->bg_free_inodes_count) && 436 if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
431 le16_to_cpu(desc->bg_free_blocks_count)) 437 le16_to_cpu(desc->bg_free_blocks_count))
432 return group; 438 return 0;
433 439
434 /* 440 /*
435 * We're going to place this inode in a different blockgroup from its 441 * We're going to place this inode in a different blockgroup from its
@@ -440,33 +446,33 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
440 * 446 *
441 * So add our directory's i_ino into the starting point for the hash. 447 * So add our directory's i_ino into the starting point for the hash.
442 */ 448 */
443 group = (group + parent->i_ino) % ngroups; 449 *group = (*group + parent->i_ino) % ngroups;
444 450
445 /* 451 /*
446 * Use a quadratic hash to find a group with a free inode and some free 452 * Use a quadratic hash to find a group with a free inode and some free
447 * blocks. 453 * blocks.
448 */ 454 */
449 for (i = 1; i < ngroups; i <<= 1) { 455 for (i = 1; i < ngroups; i <<= 1) {
450 group += i; 456 *group += i;
451 if (group >= ngroups) 457 if (*group >= ngroups)
452 group -= ngroups; 458 *group -= ngroups;
453 desc = ext4_get_group_desc (sb, group, NULL); 459 desc = ext4_get_group_desc(sb, *group, NULL);
454 if (desc && le16_to_cpu(desc->bg_free_inodes_count) && 460 if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
455 le16_to_cpu(desc->bg_free_blocks_count)) 461 le16_to_cpu(desc->bg_free_blocks_count))
456 return group; 462 return 0;
457 } 463 }
458 464
459 /* 465 /*
460 * That failed: try linear search for a free inode, even if that group 466 * That failed: try linear search for a free inode, even if that group
461 * has no free blocks. 467 * has no free blocks.
462 */ 468 */
463 group = parent_group; 469 *group = parent_group;
464 for (i = 0; i < ngroups; i++) { 470 for (i = 0; i < ngroups; i++) {
465 if (++group >= ngroups) 471 if (++*group >= ngroups)
466 group = 0; 472 *group = 0;
467 desc = ext4_get_group_desc (sb, group, NULL); 473 desc = ext4_get_group_desc(sb, *group, NULL);
468 if (desc && le16_to_cpu(desc->bg_free_inodes_count)) 474 if (desc && le16_to_cpu(desc->bg_free_inodes_count))
469 return group; 475 return 0;
470 } 476 }
471 477
472 return -1; 478 return -1;
@@ -487,16 +493,17 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
487 struct super_block *sb; 493 struct super_block *sb;
488 struct buffer_head *bitmap_bh = NULL; 494 struct buffer_head *bitmap_bh = NULL;
489 struct buffer_head *bh2; 495 struct buffer_head *bh2;
490 int group; 496 ext4_group_t group = 0;
491 unsigned long ino = 0; 497 unsigned long ino = 0;
492 struct inode * inode; 498 struct inode * inode;
493 struct ext4_group_desc * gdp = NULL; 499 struct ext4_group_desc * gdp = NULL;
494 struct ext4_super_block * es; 500 struct ext4_super_block * es;
495 struct ext4_inode_info *ei; 501 struct ext4_inode_info *ei;
496 struct ext4_sb_info *sbi; 502 struct ext4_sb_info *sbi;
497 int err = 0; 503 int ret2, err = 0;
498 struct inode *ret; 504 struct inode *ret;
499 int i, free = 0; 505 ext4_group_t i;
506 int free = 0;
500 507
501 /* Cannot create files in a deleted directory */ 508 /* Cannot create files in a deleted directory */
502 if (!dir || !dir->i_nlink) 509 if (!dir || !dir->i_nlink)
@@ -512,14 +519,14 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
512 es = sbi->s_es; 519 es = sbi->s_es;
513 if (S_ISDIR(mode)) { 520 if (S_ISDIR(mode)) {
514 if (test_opt (sb, OLDALLOC)) 521 if (test_opt (sb, OLDALLOC))
515 group = find_group_dir(sb, dir); 522 ret2 = find_group_dir(sb, dir, &group);
516 else 523 else
517 group = find_group_orlov(sb, dir); 524 ret2 = find_group_orlov(sb, dir, &group);
518 } else 525 } else
519 group = find_group_other(sb, dir); 526 ret2 = find_group_other(sb, dir, &group);
520 527
521 err = -ENOSPC; 528 err = -ENOSPC;
522 if (group == -1) 529 if (ret2 == -1)
523 goto out; 530 goto out;
524 531
525 for (i = 0; i < sbi->s_groups_count; i++) { 532 for (i = 0; i < sbi->s_groups_count; i++) {
@@ -583,7 +590,7 @@ got:
583 ino > EXT4_INODES_PER_GROUP(sb)) { 590 ino > EXT4_INODES_PER_GROUP(sb)) {
584 ext4_error(sb, __FUNCTION__, 591 ext4_error(sb, __FUNCTION__,
585 "reserved inode or inode > inodes count - " 592 "reserved inode or inode > inodes count - "
586 "block_group = %d, inode=%lu", group, 593 "block_group = %lu, inode=%lu", group,
587 ino + group * EXT4_INODES_PER_GROUP(sb)); 594 ino + group * EXT4_INODES_PER_GROUP(sb));
588 err = -EIO; 595 err = -EIO;
589 goto fail; 596 goto fail;
@@ -702,7 +709,6 @@ got:
702 if (!S_ISDIR(mode)) 709 if (!S_ISDIR(mode))
703 ei->i_flags &= ~EXT4_DIRSYNC_FL; 710 ei->i_flags &= ~EXT4_DIRSYNC_FL;
704 ei->i_file_acl = 0; 711 ei->i_file_acl = 0;
705 ei->i_dir_acl = 0;
706 ei->i_dtime = 0; 712 ei->i_dtime = 0;
707 ei->i_block_alloc_info = NULL; 713 ei->i_block_alloc_info = NULL;
708 ei->i_block_group = group; 714 ei->i_block_group = group;
@@ -741,13 +747,10 @@ got:
741 if (test_opt(sb, EXTENTS)) { 747 if (test_opt(sb, EXTENTS)) {
742 EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; 748 EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
743 ext4_ext_tree_init(handle, inode); 749 ext4_ext_tree_init(handle, inode);
744 if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) { 750 err = ext4_update_incompat_feature(handle, sb,
745 err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); 751 EXT4_FEATURE_INCOMPAT_EXTENTS);
746 if (err) goto fail; 752 if (err)
747 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS); 753 goto fail;
748 BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "call ext4_journal_dirty_metadata");
749 err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
750 }
751 } 754 }
752 755
753 ext4_debug("allocating inode %lu\n", inode->i_ino); 756 ext4_debug("allocating inode %lu\n", inode->i_ino);
@@ -777,7 +780,7 @@ fail_drop:
777struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino) 780struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
778{ 781{
779 unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); 782 unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
780 unsigned long block_group; 783 ext4_group_t block_group;
781 int bit; 784 int bit;
782 struct buffer_head *bitmap_bh = NULL; 785 struct buffer_head *bitmap_bh = NULL;
783 struct inode *inode = NULL; 786 struct inode *inode = NULL;
@@ -833,7 +836,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb)
833{ 836{
834 unsigned long desc_count; 837 unsigned long desc_count;
835 struct ext4_group_desc *gdp; 838 struct ext4_group_desc *gdp;
836 int i; 839 ext4_group_t i;
837#ifdef EXT4FS_DEBUG 840#ifdef EXT4FS_DEBUG
838 struct ext4_super_block *es; 841 struct ext4_super_block *es;
839 unsigned long bitmap_count, x; 842 unsigned long bitmap_count, x;
@@ -854,7 +857,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb)
854 continue; 857 continue;
855 858
856 x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); 859 x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
857 printk("group %d: stored = %d, counted = %lu\n", 860 printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
858 i, le16_to_cpu(gdp->bg_free_inodes_count), x); 861 i, le16_to_cpu(gdp->bg_free_inodes_count), x);
859 bitmap_count += x; 862 bitmap_count += x;
860 } 863 }
@@ -879,7 +882,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb)
879unsigned long ext4_count_dirs (struct super_block * sb) 882unsigned long ext4_count_dirs (struct super_block * sb)
880{ 883{
881 unsigned long count = 0; 884 unsigned long count = 0;
882 int i; 885 ext4_group_t i;
883 886
884 for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { 887 for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
885 struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL); 888 struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5489703d9573..bb717cbb749c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -105,7 +105,7 @@ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
105 */ 105 */
106static unsigned long blocks_for_truncate(struct inode *inode) 106static unsigned long blocks_for_truncate(struct inode *inode)
107{ 107{
108 unsigned long needed; 108 ext4_lblk_t needed;
109 109
110 needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); 110 needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
111 111
@@ -243,13 +243,6 @@ static inline void add_chain(Indirect *p, struct buffer_head *bh, __le32 *v)
243 p->bh = bh; 243 p->bh = bh;
244} 244}
245 245
246static int verify_chain(Indirect *from, Indirect *to)
247{
248 while (from <= to && from->key == *from->p)
249 from++;
250 return (from > to);
251}
252
253/** 246/**
254 * ext4_block_to_path - parse the block number into array of offsets 247 * ext4_block_to_path - parse the block number into array of offsets
255 * @inode: inode in question (we are only interested in its superblock) 248 * @inode: inode in question (we are only interested in its superblock)
@@ -282,7 +275,8 @@ static int verify_chain(Indirect *from, Indirect *to)
282 */ 275 */
283 276
284static int ext4_block_to_path(struct inode *inode, 277static int ext4_block_to_path(struct inode *inode,
285 long i_block, int offsets[4], int *boundary) 278 ext4_lblk_t i_block,
279 ext4_lblk_t offsets[4], int *boundary)
286{ 280{
287 int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb); 281 int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb);
288 int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb); 282 int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb);
@@ -313,7 +307,10 @@ static int ext4_block_to_path(struct inode *inode,
313 offsets[n++] = i_block & (ptrs - 1); 307 offsets[n++] = i_block & (ptrs - 1);
314 final = ptrs; 308 final = ptrs;
315 } else { 309 } else {
316 ext4_warning(inode->i_sb, "ext4_block_to_path", "block > big"); 310 ext4_warning(inode->i_sb, "ext4_block_to_path",
311 "block %lu > max",
312 i_block + direct_blocks +
313 indirect_blocks + double_blocks);
317 } 314 }
318 if (boundary) 315 if (boundary)
319 *boundary = final - 1 - (i_block & (ptrs - 1)); 316 *boundary = final - 1 - (i_block & (ptrs - 1));
@@ -344,12 +341,14 @@ static int ext4_block_to_path(struct inode *inode,
344 * (pointer to last triple returned, *@err == 0) 341 * (pointer to last triple returned, *@err == 0)
345 * or when it gets an IO error reading an indirect block 342 * or when it gets an IO error reading an indirect block
346 * (ditto, *@err == -EIO) 343 * (ditto, *@err == -EIO)
347 * or when it notices that chain had been changed while it was reading
348 * (ditto, *@err == -EAGAIN)
349 * or when it reads all @depth-1 indirect blocks successfully and finds 344 * or when it reads all @depth-1 indirect blocks successfully and finds
350 * the whole chain, all way to the data (returns %NULL, *err == 0). 345 * the whole chain, all way to the data (returns %NULL, *err == 0).
346 *
347 * Need to be called with
348 * down_read(&EXT4_I(inode)->i_data_sem)
351 */ 349 */
352static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets, 350static Indirect *ext4_get_branch(struct inode *inode, int depth,
351 ext4_lblk_t *offsets,
353 Indirect chain[4], int *err) 352 Indirect chain[4], int *err)
354{ 353{
355 struct super_block *sb = inode->i_sb; 354 struct super_block *sb = inode->i_sb;
@@ -365,9 +364,6 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets,
365 bh = sb_bread(sb, le32_to_cpu(p->key)); 364 bh = sb_bread(sb, le32_to_cpu(p->key));
366 if (!bh) 365 if (!bh)
367 goto failure; 366 goto failure;
368 /* Reader: pointers */
369 if (!verify_chain(chain, p))
370 goto changed;
371 add_chain(++p, bh, (__le32*)bh->b_data + *++offsets); 367 add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
372 /* Reader: end */ 368 /* Reader: end */
373 if (!p->key) 369 if (!p->key)
@@ -375,10 +371,6 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets,
375 } 371 }
376 return NULL; 372 return NULL;
377 373
378changed:
379 brelse(bh);
380 *err = -EAGAIN;
381 goto no_block;
382failure: 374failure:
383 *err = -EIO; 375 *err = -EIO;
384no_block: 376no_block:
@@ -445,7 +437,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
445 * stores it in *@goal and returns zero. 437 * stores it in *@goal and returns zero.
446 */ 438 */
447 439
448static ext4_fsblk_t ext4_find_goal(struct inode *inode, long block, 440static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
449 Indirect chain[4], Indirect *partial) 441 Indirect chain[4], Indirect *partial)
450{ 442{
451 struct ext4_block_alloc_info *block_i; 443 struct ext4_block_alloc_info *block_i;
@@ -559,7 +551,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
559 return ret; 551 return ret;
560failed_out: 552failed_out:
561 for (i = 0; i <index; i++) 553 for (i = 0; i <index; i++)
562 ext4_free_blocks(handle, inode, new_blocks[i], 1); 554 ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
563 return ret; 555 return ret;
564} 556}
565 557
@@ -590,7 +582,7 @@ failed_out:
590 */ 582 */
591static int ext4_alloc_branch(handle_t *handle, struct inode *inode, 583static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
592 int indirect_blks, int *blks, ext4_fsblk_t goal, 584 int indirect_blks, int *blks, ext4_fsblk_t goal,
593 int *offsets, Indirect *branch) 585 ext4_lblk_t *offsets, Indirect *branch)
594{ 586{
595 int blocksize = inode->i_sb->s_blocksize; 587 int blocksize = inode->i_sb->s_blocksize;
596 int i, n = 0; 588 int i, n = 0;
@@ -658,9 +650,9 @@ failed:
658 ext4_journal_forget(handle, branch[i].bh); 650 ext4_journal_forget(handle, branch[i].bh);
659 } 651 }
660 for (i = 0; i <indirect_blks; i++) 652 for (i = 0; i <indirect_blks; i++)
661 ext4_free_blocks(handle, inode, new_blocks[i], 1); 653 ext4_free_blocks(handle, inode, new_blocks[i], 1, 0);
662 654
663 ext4_free_blocks(handle, inode, new_blocks[i], num); 655 ext4_free_blocks(handle, inode, new_blocks[i], num, 0);
664 656
665 return err; 657 return err;
666} 658}
@@ -680,7 +672,7 @@ failed:
680 * chain to new block and return 0. 672 * chain to new block and return 0.
681 */ 673 */
682static int ext4_splice_branch(handle_t *handle, struct inode *inode, 674static int ext4_splice_branch(handle_t *handle, struct inode *inode,
683 long block, Indirect *where, int num, int blks) 675 ext4_lblk_t block, Indirect *where, int num, int blks)
684{ 676{
685 int i; 677 int i;
686 int err = 0; 678 int err = 0;
@@ -757,9 +749,10 @@ err_out:
757 for (i = 1; i <= num; i++) { 749 for (i = 1; i <= num; i++) {
758 BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget"); 750 BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget");
759 ext4_journal_forget(handle, where[i].bh); 751 ext4_journal_forget(handle, where[i].bh);
760 ext4_free_blocks(handle,inode,le32_to_cpu(where[i-1].key),1); 752 ext4_free_blocks(handle, inode,
753 le32_to_cpu(where[i-1].key), 1, 0);
761 } 754 }
762 ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks); 755 ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks, 0);
763 756
764 return err; 757 return err;
765} 758}
@@ -782,14 +775,19 @@ err_out:
782 * return > 0, # of blocks mapped or allocated. 775 * return > 0, # of blocks mapped or allocated.
783 * return = 0, if plain lookup failed. 776 * return = 0, if plain lookup failed.
784 * return < 0, error case. 777 * return < 0, error case.
778 *
779 *
780 * Need to be called with
781 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
782 * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
785 */ 783 */
786int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, 784int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
787 sector_t iblock, unsigned long maxblocks, 785 ext4_lblk_t iblock, unsigned long maxblocks,
788 struct buffer_head *bh_result, 786 struct buffer_head *bh_result,
789 int create, int extend_disksize) 787 int create, int extend_disksize)
790{ 788{
791 int err = -EIO; 789 int err = -EIO;
792 int offsets[4]; 790 ext4_lblk_t offsets[4];
793 Indirect chain[4]; 791 Indirect chain[4];
794 Indirect *partial; 792 Indirect *partial;
795 ext4_fsblk_t goal; 793 ext4_fsblk_t goal;
@@ -803,7 +801,8 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
803 801
804 J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); 802 J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL));
805 J_ASSERT(handle != NULL || create == 0); 803 J_ASSERT(handle != NULL || create == 0);
806 depth = ext4_block_to_path(inode,iblock,offsets,&blocks_to_boundary); 804 depth = ext4_block_to_path(inode, iblock, offsets,
805 &blocks_to_boundary);
807 806
808 if (depth == 0) 807 if (depth == 0)
809 goto out; 808 goto out;
@@ -819,18 +818,6 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
819 while (count < maxblocks && count <= blocks_to_boundary) { 818 while (count < maxblocks && count <= blocks_to_boundary) {
820 ext4_fsblk_t blk; 819 ext4_fsblk_t blk;
821 820
822 if (!verify_chain(chain, partial)) {
823 /*
824 * Indirect block might be removed by
825 * truncate while we were reading it.
826 * Handling of that case: forget what we've
827 * got now. Flag the err as EAGAIN, so it
828 * will reread.
829 */
830 err = -EAGAIN;
831 count = 0;
832 break;
833 }
834 blk = le32_to_cpu(*(chain[depth-1].p + count)); 821 blk = le32_to_cpu(*(chain[depth-1].p + count));
835 822
836 if (blk == first_block + count) 823 if (blk == first_block + count)
@@ -838,44 +825,13 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
838 else 825 else
839 break; 826 break;
840 } 827 }
841 if (err != -EAGAIN) 828 goto got_it;
842 goto got_it;
843 } 829 }
844 830
845 /* Next simple case - plain lookup or failed read of indirect block */ 831 /* Next simple case - plain lookup or failed read of indirect block */
846 if (!create || err == -EIO) 832 if (!create || err == -EIO)
847 goto cleanup; 833 goto cleanup;
848 834
849 mutex_lock(&ei->truncate_mutex);
850
851 /*
852 * If the indirect block is missing while we are reading
853 * the chain(ext4_get_branch() returns -EAGAIN err), or
854 * if the chain has been changed after we grab the semaphore,
855 * (either because another process truncated this branch, or
856 * another get_block allocated this branch) re-grab the chain to see if
857 * the request block has been allocated or not.
858 *
859 * Since we already block the truncate/other get_block
860 * at this point, we will have the current copy of the chain when we
861 * splice the branch into the tree.
862 */
863 if (err == -EAGAIN || !verify_chain(chain, partial)) {
864 while (partial > chain) {
865 brelse(partial->bh);
866 partial--;
867 }
868 partial = ext4_get_branch(inode, depth, offsets, chain, &err);
869 if (!partial) {
870 count++;
871 mutex_unlock(&ei->truncate_mutex);
872 if (err)
873 goto cleanup;
874 clear_buffer_new(bh_result);
875 goto got_it;
876 }
877 }
878
879 /* 835 /*
880 * Okay, we need to do block allocation. Lazily initialize the block 836 * Okay, we need to do block allocation. Lazily initialize the block
881 * allocation info here if necessary 837 * allocation info here if necessary
@@ -911,13 +867,12 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
911 err = ext4_splice_branch(handle, inode, iblock, 867 err = ext4_splice_branch(handle, inode, iblock,
912 partial, indirect_blks, count); 868 partial, indirect_blks, count);
913 /* 869 /*
914 * i_disksize growing is protected by truncate_mutex. Don't forget to 870 * i_disksize growing is protected by i_data_sem. Don't forget to
915 * protect it if you're about to implement concurrent 871 * protect it if you're about to implement concurrent
916 * ext4_get_block() -bzzz 872 * ext4_get_block() -bzzz
917 */ 873 */
918 if (!err && extend_disksize && inode->i_size > ei->i_disksize) 874 if (!err && extend_disksize && inode->i_size > ei->i_disksize)
919 ei->i_disksize = inode->i_size; 875 ei->i_disksize = inode->i_size;
920 mutex_unlock(&ei->truncate_mutex);
921 if (err) 876 if (err)
922 goto cleanup; 877 goto cleanup;
923 878
@@ -942,6 +897,47 @@ out:
942 897
943#define DIO_CREDITS (EXT4_RESERVE_TRANS_BLOCKS + 32) 898#define DIO_CREDITS (EXT4_RESERVE_TRANS_BLOCKS + 32)
944 899
900int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
901 unsigned long max_blocks, struct buffer_head *bh,
902 int create, int extend_disksize)
903{
904 int retval;
905 /*
906 * Try to see if we can get the block without requesting
907 * for new file system block.
908 */
909 down_read((&EXT4_I(inode)->i_data_sem));
910 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
911 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
912 bh, 0, 0);
913 } else {
914 retval = ext4_get_blocks_handle(handle,
915 inode, block, max_blocks, bh, 0, 0);
916 }
917 up_read((&EXT4_I(inode)->i_data_sem));
918 if (!create || (retval > 0))
919 return retval;
920
921 /*
922 * We need to allocate new blocks which will result
923 * in i_data update
924 */
925 down_write((&EXT4_I(inode)->i_data_sem));
926 /*
927 * We need to check for EXT4 here because migrate
928 * could have changed the inode type in between
929 */
930 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
931 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
932 bh, create, extend_disksize);
933 } else {
934 retval = ext4_get_blocks_handle(handle, inode, block,
935 max_blocks, bh, create, extend_disksize);
936 }
937 up_write((&EXT4_I(inode)->i_data_sem));
938 return retval;
939}
940
945static int ext4_get_block(struct inode *inode, sector_t iblock, 941static int ext4_get_block(struct inode *inode, sector_t iblock,
946 struct buffer_head *bh_result, int create) 942 struct buffer_head *bh_result, int create)
947{ 943{
@@ -996,7 +992,7 @@ get_block:
996 * `handle' can be NULL if create is zero 992 * `handle' can be NULL if create is zero
997 */ 993 */
998struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, 994struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
999 long block, int create, int *errp) 995 ext4_lblk_t block, int create, int *errp)
1000{ 996{
1001 struct buffer_head dummy; 997 struct buffer_head dummy;
1002 int fatal = 0, err; 998 int fatal = 0, err;
@@ -1063,7 +1059,7 @@ err:
1063} 1059}
1064 1060
1065struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, 1061struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
1066 int block, int create, int *err) 1062 ext4_lblk_t block, int create, int *err)
1067{ 1063{
1068 struct buffer_head * bh; 1064 struct buffer_head * bh;
1069 1065
@@ -1446,7 +1442,7 @@ static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
1446 * ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ... 1442 * ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ...
1447 * 1443 *
1448 * Same applies to ext4_get_block(). We will deadlock on various things like 1444 * Same applies to ext4_get_block(). We will deadlock on various things like
1449 * lock_journal and i_truncate_mutex. 1445 * lock_journal and i_data_sem
1450 * 1446 *
1451 * Setting PF_MEMALLOC here doesn't work - too many internal memory 1447 * Setting PF_MEMALLOC here doesn't work - too many internal memory
1452 * allocations fail. 1448 * allocations fail.
@@ -1828,7 +1824,8 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page,
1828{ 1824{
1829 ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT; 1825 ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
1830 unsigned offset = from & (PAGE_CACHE_SIZE-1); 1826 unsigned offset = from & (PAGE_CACHE_SIZE-1);
1831 unsigned blocksize, iblock, length, pos; 1827 unsigned blocksize, length, pos;
1828 ext4_lblk_t iblock;
1832 struct inode *inode = mapping->host; 1829 struct inode *inode = mapping->host;
1833 struct buffer_head *bh; 1830 struct buffer_head *bh;
1834 int err = 0; 1831 int err = 0;
@@ -1964,7 +1961,7 @@ static inline int all_zeroes(__le32 *p, __le32 *q)
1964 * (no partially truncated stuff there). */ 1961 * (no partially truncated stuff there). */
1965 1962
1966static Indirect *ext4_find_shared(struct inode *inode, int depth, 1963static Indirect *ext4_find_shared(struct inode *inode, int depth,
1967 int offsets[4], Indirect chain[4], __le32 *top) 1964 ext4_lblk_t offsets[4], Indirect chain[4], __le32 *top)
1968{ 1965{
1969 Indirect *partial, *p; 1966 Indirect *partial, *p;
1970 int k, err; 1967 int k, err;
@@ -2048,15 +2045,15 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
2048 for (p = first; p < last; p++) { 2045 for (p = first; p < last; p++) {
2049 u32 nr = le32_to_cpu(*p); 2046 u32 nr = le32_to_cpu(*p);
2050 if (nr) { 2047 if (nr) {
2051 struct buffer_head *bh; 2048 struct buffer_head *tbh;
2052 2049
2053 *p = 0; 2050 *p = 0;
2054 bh = sb_find_get_block(inode->i_sb, nr); 2051 tbh = sb_find_get_block(inode->i_sb, nr);
2055 ext4_forget(handle, 0, inode, bh, nr); 2052 ext4_forget(handle, 0, inode, tbh, nr);
2056 } 2053 }
2057 } 2054 }
2058 2055
2059 ext4_free_blocks(handle, inode, block_to_free, count); 2056 ext4_free_blocks(handle, inode, block_to_free, count, 0);
2060} 2057}
2061 2058
2062/** 2059/**
@@ -2229,7 +2226,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
2229 ext4_journal_test_restart(handle, inode); 2226 ext4_journal_test_restart(handle, inode);
2230 } 2227 }
2231 2228
2232 ext4_free_blocks(handle, inode, nr, 1); 2229 ext4_free_blocks(handle, inode, nr, 1, 1);
2233 2230
2234 if (parent_bh) { 2231 if (parent_bh) {
2235 /* 2232 /*
@@ -2289,12 +2286,12 @@ void ext4_truncate(struct inode *inode)
2289 __le32 *i_data = ei->i_data; 2286 __le32 *i_data = ei->i_data;
2290 int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); 2287 int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb);
2291 struct address_space *mapping = inode->i_mapping; 2288 struct address_space *mapping = inode->i_mapping;
2292 int offsets[4]; 2289 ext4_lblk_t offsets[4];
2293 Indirect chain[4]; 2290 Indirect chain[4];
2294 Indirect *partial; 2291 Indirect *partial;
2295 __le32 nr = 0; 2292 __le32 nr = 0;
2296 int n; 2293 int n;
2297 long last_block; 2294 ext4_lblk_t last_block;
2298 unsigned blocksize = inode->i_sb->s_blocksize; 2295 unsigned blocksize = inode->i_sb->s_blocksize;
2299 struct page *page; 2296 struct page *page;
2300 2297
@@ -2320,8 +2317,10 @@ void ext4_truncate(struct inode *inode)
2320 return; 2317 return;
2321 } 2318 }
2322 2319
2323 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) 2320 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
2324 return ext4_ext_truncate(inode, page); 2321 ext4_ext_truncate(inode, page);
2322 return;
2323 }
2325 2324
2326 handle = start_transaction(inode); 2325 handle = start_transaction(inode);
2327 if (IS_ERR(handle)) { 2326 if (IS_ERR(handle)) {
@@ -2369,7 +2368,7 @@ void ext4_truncate(struct inode *inode)
2369 * From here we block out all ext4_get_block() callers who want to 2368 * From here we block out all ext4_get_block() callers who want to
2370 * modify the block allocation tree. 2369 * modify the block allocation tree.
2371 */ 2370 */
2372 mutex_lock(&ei->truncate_mutex); 2371 down_write(&ei->i_data_sem);
2373 2372
2374 if (n == 1) { /* direct blocks */ 2373 if (n == 1) { /* direct blocks */
2375 ext4_free_data(handle, inode, NULL, i_data+offsets[0], 2374 ext4_free_data(handle, inode, NULL, i_data+offsets[0],
@@ -2433,7 +2432,7 @@ do_indirects:
2433 2432
2434 ext4_discard_reservation(inode); 2433 ext4_discard_reservation(inode);
2435 2434
2436 mutex_unlock(&ei->truncate_mutex); 2435 up_write(&ei->i_data_sem);
2437 inode->i_mtime = inode->i_ctime = ext4_current_time(inode); 2436 inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
2438 ext4_mark_inode_dirty(handle, inode); 2437 ext4_mark_inode_dirty(handle, inode);
2439 2438
@@ -2460,7 +2459,8 @@ out_stop:
2460static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, 2459static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,
2461 unsigned long ino, struct ext4_iloc *iloc) 2460 unsigned long ino, struct ext4_iloc *iloc)
2462{ 2461{
2463 unsigned long desc, group_desc, block_group; 2462 unsigned long desc, group_desc;
2463 ext4_group_t block_group;
2464 unsigned long offset; 2464 unsigned long offset;
2465 ext4_fsblk_t block; 2465 ext4_fsblk_t block;
2466 struct buffer_head *bh; 2466 struct buffer_head *bh;
@@ -2547,7 +2547,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
2547 struct ext4_group_desc *desc; 2547 struct ext4_group_desc *desc;
2548 int inodes_per_buffer; 2548 int inodes_per_buffer;
2549 int inode_offset, i; 2549 int inode_offset, i;
2550 int block_group; 2550 ext4_group_t block_group;
2551 int start; 2551 int start;
2552 2552
2553 block_group = (inode->i_ino - 1) / 2553 block_group = (inode->i_ino - 1) /
@@ -2660,6 +2660,28 @@ void ext4_get_inode_flags(struct ext4_inode_info *ei)
2660 if (flags & S_DIRSYNC) 2660 if (flags & S_DIRSYNC)
2661 ei->i_flags |= EXT4_DIRSYNC_FL; 2661 ei->i_flags |= EXT4_DIRSYNC_FL;
2662} 2662}
2663static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
2664 struct ext4_inode_info *ei)
2665{
2666 blkcnt_t i_blocks ;
2667 struct inode *inode = &(ei->vfs_inode);
2668 struct super_block *sb = inode->i_sb;
2669
2670 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
2671 EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
2672 /* we are using combined 48 bit field */
2673 i_blocks = ((u64)le16_to_cpu(raw_inode->i_blocks_high)) << 32 |
2674 le32_to_cpu(raw_inode->i_blocks_lo);
2675 if (ei->i_flags & EXT4_HUGE_FILE_FL) {
2676 /* i_blocks represent file system block size */
2677 return i_blocks << (inode->i_blkbits - 9);
2678 } else {
2679 return i_blocks;
2680 }
2681 } else {
2682 return le32_to_cpu(raw_inode->i_blocks_lo);
2683 }
2684}
2663 2685
2664void ext4_read_inode(struct inode * inode) 2686void ext4_read_inode(struct inode * inode)
2665{ 2687{
@@ -2687,7 +2709,6 @@ void ext4_read_inode(struct inode * inode)
2687 inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; 2709 inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
2688 } 2710 }
2689 inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); 2711 inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
2690 inode->i_size = le32_to_cpu(raw_inode->i_size);
2691 2712
2692 ei->i_state = 0; 2713 ei->i_state = 0;
2693 ei->i_dir_start_lookup = 0; 2714 ei->i_dir_start_lookup = 0;
@@ -2709,19 +2730,15 @@ void ext4_read_inode(struct inode * inode)
2709 * recovery code: that's fine, we're about to complete 2730 * recovery code: that's fine, we're about to complete
2710 * the process of deleting those. */ 2731 * the process of deleting those. */
2711 } 2732 }
2712 inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
2713 ei->i_flags = le32_to_cpu(raw_inode->i_flags); 2733 ei->i_flags = le32_to_cpu(raw_inode->i_flags);
2714 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); 2734 inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
2735 ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
2715 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 2736 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
2716 cpu_to_le32(EXT4_OS_HURD)) 2737 cpu_to_le32(EXT4_OS_HURD)) {
2717 ei->i_file_acl |= 2738 ei->i_file_acl |=
2718 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; 2739 ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
2719 if (!S_ISREG(inode->i_mode)) {
2720 ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
2721 } else {
2722 inode->i_size |=
2723 ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
2724 } 2740 }
2741 inode->i_size = ext4_isize(raw_inode);
2725 ei->i_disksize = inode->i_size; 2742 ei->i_disksize = inode->i_size;
2726 inode->i_generation = le32_to_cpu(raw_inode->i_generation); 2743 inode->i_generation = le32_to_cpu(raw_inode->i_generation);
2727 ei->i_block_group = iloc.block_group; 2744 ei->i_block_group = iloc.block_group;
@@ -2765,6 +2782,13 @@ void ext4_read_inode(struct inode * inode)
2765 EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode); 2782 EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode);
2766 EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode); 2783 EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
2767 2784
2785 inode->i_version = le32_to_cpu(raw_inode->i_disk_version);
2786 if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
2787 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
2788 inode->i_version |=
2789 (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;
2790 }
2791
2768 if (S_ISREG(inode->i_mode)) { 2792 if (S_ISREG(inode->i_mode)) {
2769 inode->i_op = &ext4_file_inode_operations; 2793 inode->i_op = &ext4_file_inode_operations;
2770 inode->i_fop = &ext4_file_operations; 2794 inode->i_fop = &ext4_file_operations;
@@ -2797,6 +2821,55 @@ bad_inode:
2797 return; 2821 return;
2798} 2822}
2799 2823
2824static int ext4_inode_blocks_set(handle_t *handle,
2825 struct ext4_inode *raw_inode,
2826 struct ext4_inode_info *ei)
2827{
2828 struct inode *inode = &(ei->vfs_inode);
2829 u64 i_blocks = inode->i_blocks;
2830 struct super_block *sb = inode->i_sb;
2831 int err = 0;
2832
2833 if (i_blocks <= ~0U) {
2834 /*
2835 * i_blocks can be represnted in a 32 bit variable
2836 * as multiple of 512 bytes
2837 */
2838 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
2839 raw_inode->i_blocks_high = 0;
2840 ei->i_flags &= ~EXT4_HUGE_FILE_FL;
2841 } else if (i_blocks <= 0xffffffffffffULL) {
2842 /*
2843 * i_blocks can be represented in a 48 bit variable
2844 * as multiple of 512 bytes
2845 */
2846 err = ext4_update_rocompat_feature(handle, sb,
2847 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
2848 if (err)
2849 goto err_out;
2850 /* i_block is stored in the split 48 bit fields */
2851 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
2852 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
2853 ei->i_flags &= ~EXT4_HUGE_FILE_FL;
2854 } else {
2855 /*
2856 * i_blocks should be represented in a 48 bit variable
2857 * as multiple of file system block size
2858 */
2859 err = ext4_update_rocompat_feature(handle, sb,
2860 EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
2861 if (err)
2862 goto err_out;
2863 ei->i_flags |= EXT4_HUGE_FILE_FL;
2864 /* i_block is stored in file system block size */
2865 i_blocks = i_blocks >> (inode->i_blkbits - 9);
2866 raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
2867 raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
2868 }
2869err_out:
2870 return err;
2871}
2872
2800/* 2873/*
2801 * Post the struct inode info into an on-disk inode location in the 2874 * Post the struct inode info into an on-disk inode location in the
2802 * buffer-cache. This gobbles the caller's reference to the 2875 * buffer-cache. This gobbles the caller's reference to the
@@ -2845,47 +2918,42 @@ static int ext4_do_update_inode(handle_t *handle,
2845 raw_inode->i_gid_high = 0; 2918 raw_inode->i_gid_high = 0;
2846 } 2919 }
2847 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); 2920 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
2848 raw_inode->i_size = cpu_to_le32(ei->i_disksize);
2849 2921
2850 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode); 2922 EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
2851 EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode); 2923 EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode);
2852 EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode); 2924 EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
2853 EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode); 2925 EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode);
2854 2926
2855 raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); 2927 if (ext4_inode_blocks_set(handle, raw_inode, ei))
2928 goto out_brelse;
2856 raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); 2929 raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
2857 raw_inode->i_flags = cpu_to_le32(ei->i_flags); 2930 raw_inode->i_flags = cpu_to_le32(ei->i_flags);
2858 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != 2931 if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
2859 cpu_to_le32(EXT4_OS_HURD)) 2932 cpu_to_le32(EXT4_OS_HURD))
2860 raw_inode->i_file_acl_high = 2933 raw_inode->i_file_acl_high =
2861 cpu_to_le16(ei->i_file_acl >> 32); 2934 cpu_to_le16(ei->i_file_acl >> 32);
2862 raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl); 2935 raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
2863 if (!S_ISREG(inode->i_mode)) { 2936 ext4_isize_set(raw_inode, ei->i_disksize);
2864 raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); 2937 if (ei->i_disksize > 0x7fffffffULL) {
2865 } else { 2938 struct super_block *sb = inode->i_sb;
2866 raw_inode->i_size_high = 2939 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
2867 cpu_to_le32(ei->i_disksize >> 32); 2940 EXT4_FEATURE_RO_COMPAT_LARGE_FILE) ||
2868 if (ei->i_disksize > 0x7fffffffULL) { 2941 EXT4_SB(sb)->s_es->s_rev_level ==
2869 struct super_block *sb = inode->i_sb; 2942 cpu_to_le32(EXT4_GOOD_OLD_REV)) {
2870 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, 2943 /* If this is the first large file
2871 EXT4_FEATURE_RO_COMPAT_LARGE_FILE) || 2944 * created, add a flag to the superblock.
2872 EXT4_SB(sb)->s_es->s_rev_level == 2945 */
2873 cpu_to_le32(EXT4_GOOD_OLD_REV)) { 2946 err = ext4_journal_get_write_access(handle,
2874 /* If this is the first large file 2947 EXT4_SB(sb)->s_sbh);
2875 * created, add a flag to the superblock. 2948 if (err)
2876 */ 2949 goto out_brelse;
2877 err = ext4_journal_get_write_access(handle, 2950 ext4_update_dynamic_rev(sb);
2878 EXT4_SB(sb)->s_sbh); 2951 EXT4_SET_RO_COMPAT_FEATURE(sb,
2879 if (err)
2880 goto out_brelse;
2881 ext4_update_dynamic_rev(sb);
2882 EXT4_SET_RO_COMPAT_FEATURE(sb,
2883 EXT4_FEATURE_RO_COMPAT_LARGE_FILE); 2952 EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
2884 sb->s_dirt = 1; 2953 sb->s_dirt = 1;
2885 handle->h_sync = 1; 2954 handle->h_sync = 1;
2886 err = ext4_journal_dirty_metadata(handle, 2955 err = ext4_journal_dirty_metadata(handle,
2887 EXT4_SB(sb)->s_sbh); 2956 EXT4_SB(sb)->s_sbh);
2888 }
2889 } 2957 }
2890 } 2958 }
2891 raw_inode->i_generation = cpu_to_le32(inode->i_generation); 2959 raw_inode->i_generation = cpu_to_le32(inode->i_generation);
@@ -2903,8 +2971,14 @@ static int ext4_do_update_inode(handle_t *handle,
2903 } else for (block = 0; block < EXT4_N_BLOCKS; block++) 2971 } else for (block = 0; block < EXT4_N_BLOCKS; block++)
2904 raw_inode->i_block[block] = ei->i_data[block]; 2972 raw_inode->i_block[block] = ei->i_data[block];
2905 2973
2906 if (ei->i_extra_isize) 2974 raw_inode->i_disk_version = cpu_to_le32(inode->i_version);
2975 if (ei->i_extra_isize) {
2976 if (EXT4_FITS_IN_INODE(raw_inode, ei, i_version_hi))
2977 raw_inode->i_version_hi =
2978 cpu_to_le32(inode->i_version >> 32);
2907 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 2979 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
2980 }
2981
2908 2982
2909 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); 2983 BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
2910 rc = ext4_journal_dirty_metadata(handle, bh); 2984 rc = ext4_journal_dirty_metadata(handle, bh);
@@ -3024,6 +3098,17 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
3024 ext4_journal_stop(handle); 3098 ext4_journal_stop(handle);
3025 } 3099 }
3026 3100
3101 if (attr->ia_valid & ATTR_SIZE) {
3102 if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) {
3103 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
3104
3105 if (attr->ia_size > sbi->s_bitmap_maxbytes) {
3106 error = -EFBIG;
3107 goto err_out;
3108 }
3109 }
3110 }
3111
3027 if (S_ISREG(inode->i_mode) && 3112 if (S_ISREG(inode->i_mode) &&
3028 attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) { 3113 attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
3029 handle_t *handle; 3114 handle_t *handle;
@@ -3120,6 +3205,9 @@ int ext4_mark_iloc_dirty(handle_t *handle,
3120{ 3205{
3121 int err = 0; 3206 int err = 0;
3122 3207
3208 if (test_opt(inode->i_sb, I_VERSION))
3209 inode_inc_iversion(inode);
3210
3123 /* the do_update_inode consumes one bh->b_count */ 3211 /* the do_update_inode consumes one bh->b_count */
3124 get_bh(iloc->bh); 3212 get_bh(iloc->bh);
3125 3213
@@ -3158,8 +3246,10 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
3158 * Expand an inode by new_extra_isize bytes. 3246 * Expand an inode by new_extra_isize bytes.
3159 * Returns 0 on success or negative error number on failure. 3247 * Returns 0 on success or negative error number on failure.
3160 */ 3248 */
3161int ext4_expand_extra_isize(struct inode *inode, unsigned int new_extra_isize, 3249static int ext4_expand_extra_isize(struct inode *inode,
3162 struct ext4_iloc iloc, handle_t *handle) 3250 unsigned int new_extra_isize,
3251 struct ext4_iloc iloc,
3252 handle_t *handle)
3163{ 3253{
3164 struct ext4_inode *raw_inode; 3254 struct ext4_inode *raw_inode;
3165 struct ext4_xattr_ibody_header *header; 3255 struct ext4_xattr_ibody_header *header;
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index e7f894bdb420..2ed7c37f897e 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -199,7 +199,7 @@ flags_err:
199 * need to allocate reservation structure for this inode 199 * need to allocate reservation structure for this inode
200 * before set the window size 200 * before set the window size
201 */ 201 */
202 mutex_lock(&ei->truncate_mutex); 202 down_write(&ei->i_data_sem);
203 if (!ei->i_block_alloc_info) 203 if (!ei->i_block_alloc_info)
204 ext4_init_block_alloc_info(inode); 204 ext4_init_block_alloc_info(inode);
205 205
@@ -207,7 +207,7 @@ flags_err:
207 struct ext4_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node; 207 struct ext4_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
208 rsv->rsv_goal_size = rsv_window_size; 208 rsv->rsv_goal_size = rsv_window_size;
209 } 209 }
210 mutex_unlock(&ei->truncate_mutex); 210 up_write(&ei->i_data_sem);
211 return 0; 211 return 0;
212 } 212 }
213 case EXT4_IOC_GROUP_EXTEND: { 213 case EXT4_IOC_GROUP_EXTEND: {
@@ -254,6 +254,9 @@ flags_err:
254 return err; 254 return err;
255 } 255 }
256 256
257 case EXT4_IOC_MIGRATE:
258 return ext4_ext_migrate(inode, filp, cmd, arg);
259
257 default: 260 default:
258 return -ENOTTY; 261 return -ENOTTY;
259 } 262 }
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
new file mode 100644
index 000000000000..76e5fedc0a0b
--- /dev/null
+++ b/fs/ext4/mballoc.c
@@ -0,0 +1,4552 @@
1/*
2 * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
3 * Written by Alex Tomas <alex@clusterfs.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public Licens
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17 */
18
19
20/*
21 * mballoc.c contains the multiblocks allocation routines
22 */
23
24#include <linux/time.h>
25#include <linux/fs.h>
26#include <linux/namei.h>
27#include <linux/ext4_jbd2.h>
28#include <linux/ext4_fs.h>
29#include <linux/quotaops.h>
30#include <linux/buffer_head.h>
31#include <linux/module.h>
32#include <linux/swap.h>
33#include <linux/proc_fs.h>
34#include <linux/pagemap.h>
35#include <linux/seq_file.h>
36#include <linux/version.h>
37#include "group.h"
38
39/*
40 * MUSTDO:
41 * - test ext4_ext_search_left() and ext4_ext_search_right()
42 * - search for metadata in few groups
43 *
44 * TODO v4:
45 * - normalization should take into account whether file is still open
46 * - discard preallocations if no free space left (policy?)
47 * - don't normalize tails
48 * - quota
49 * - reservation for superuser
50 *
51 * TODO v3:
52 * - bitmap read-ahead (proposed by Oleg Drokin aka green)
53 * - track min/max extents in each group for better group selection
54 * - mb_mark_used() may allocate chunk right after splitting buddy
55 * - tree of groups sorted by number of free blocks
56 * - error handling
57 */
58
59/*
60 * The allocation request involve request for multiple number of blocks
61 * near to the goal(block) value specified.
62 *
63 * During initialization phase of the allocator we decide to use the group
64 * preallocation or inode preallocation depending on the size file. The
65 * size of the file could be the resulting file size we would have after
66 * allocation or the current file size which ever is larger. If the size is
67 * less that sbi->s_mb_stream_request we select the group
68 * preallocation. The default value of s_mb_stream_request is 16
69 * blocks. This can also be tuned via
70 * /proc/fs/ext4/<partition>/stream_req. The value is represented in terms
71 * of number of blocks.
72 *
73 * The main motivation for having small file use group preallocation is to
74 * ensure that we have small file closer in the disk.
75 *
76 * First stage the allocator looks at the inode prealloc list
77 * ext4_inode_info->i_prealloc_list contain list of prealloc spaces for
78 * this particular inode. The inode prealloc space is represented as:
79 *
80 * pa_lstart -> the logical start block for this prealloc space
81 * pa_pstart -> the physical start block for this prealloc space
82 * pa_len -> lenght for this prealloc space
83 * pa_free -> free space available in this prealloc space
84 *
85 * The inode preallocation space is used looking at the _logical_ start
86 * block. If only the logical file block falls within the range of prealloc
87 * space we will consume the particular prealloc space. This make sure that
88 * that the we have contiguous physical blocks representing the file blocks
89 *
90 * The important thing to be noted in case of inode prealloc space is that
91 * we don't modify the values associated to inode prealloc space except
92 * pa_free.
93 *
94 * If we are not able to find blocks in the inode prealloc space and if we
95 * have the group allocation flag set then we look at the locality group
96 * prealloc space. These are per CPU prealloc list repreasented as
97 *
98 * ext4_sb_info.s_locality_groups[smp_processor_id()]
99 *
100 * The reason for having a per cpu locality group is to reduce the contention
101 * between CPUs. It is possible to get scheduled at this point.
102 *
103 * The locality group prealloc space is used looking at whether we have
104 * enough free space (pa_free) withing the prealloc space.
105 *
106 * If we can't allocate blocks via inode prealloc or/and locality group
107 * prealloc then we look at the buddy cache. The buddy cache is represented
108 * by ext4_sb_info.s_buddy_cache (struct inode) whose file offset gets
109 * mapped to the buddy and bitmap information regarding different
110 * groups. The buddy information is attached to buddy cache inode so that
111 * we can access them through the page cache. The information regarding
112 * each group is loaded via ext4_mb_load_buddy. The information involve
113 * block bitmap and buddy information. The information are stored in the
114 * inode as:
115 *
116 * { page }
117 * [ group 0 buddy][ group 0 bitmap] [group 1][ group 1]...
118 *
119 *
120 * one block each for bitmap and buddy information. So for each group we
121 * take up 2 blocks. A page can contain blocks_per_page (PAGE_CACHE_SIZE /
122 * blocksize) blocks. So it can have information regarding groups_per_page
123 * which is blocks_per_page/2
124 *
125 * The buddy cache inode is not stored on disk. The inode is thrown
126 * away when the filesystem is unmounted.
127 *
128 * We look for count number of blocks in the buddy cache. If we were able
129 * to locate that many free blocks we return with additional information
130 * regarding rest of the contiguous physical block available
131 *
132 * Before allocating blocks via buddy cache we normalize the request
133 * blocks. This ensure we ask for more blocks that we needed. The extra
134 * blocks that we get after allocation is added to the respective prealloc
135 * list. In case of inode preallocation we follow a list of heuristics
136 * based on file size. This can be found in ext4_mb_normalize_request. If
137 * we are doing a group prealloc we try to normalize the request to
138 * sbi->s_mb_group_prealloc. Default value of s_mb_group_prealloc is set to
139 * 512 blocks. This can be tuned via
140 * /proc/fs/ext4/<partition/group_prealloc. The value is represented in
141 * terms of number of blocks. If we have mounted the file system with -O
142 * stripe=<value> option the group prealloc request is normalized to the
143 * stripe value (sbi->s_stripe)
144 *
145 * The regular allocator(using the buddy cache) support few tunables.
146 *
147 * /proc/fs/ext4/<partition>/min_to_scan
148 * /proc/fs/ext4/<partition>/max_to_scan
149 * /proc/fs/ext4/<partition>/order2_req
150 *
151 * The regular allocator use buddy scan only if the request len is power of
152 * 2 blocks and the order of allocation is >= sbi->s_mb_order2_reqs. The
153 * value of s_mb_order2_reqs can be tuned via
154 * /proc/fs/ext4/<partition>/order2_req. If the request len is equal to
155 * stripe size (sbi->s_stripe), we try to search for contigous block in
156 * stripe size. This should result in better allocation on RAID setup. If
157 * not we search in the specific group using bitmap for best extents. The
158 * tunable min_to_scan and max_to_scan controll the behaviour here.
159 * min_to_scan indicate how long the mballoc __must__ look for a best
160 * extent and max_to_scanindicate how long the mballoc __can__ look for a
161 * best extent in the found extents. Searching for the blocks starts with
162 * the group specified as the goal value in allocation context via
163 * ac_g_ex. Each group is first checked based on the criteria whether it
164 * can used for allocation. ext4_mb_good_group explains how the groups are
165 * checked.
166 *
167 * Both the prealloc space are getting populated as above. So for the first
168 * request we will hit the buddy cache which will result in this prealloc
169 * space getting filled. The prealloc space is then later used for the
170 * subsequent request.
171 */
172
173/*
174 * mballoc operates on the following data:
175 * - on-disk bitmap
176 * - in-core buddy (actually includes buddy and bitmap)
177 * - preallocation descriptors (PAs)
178 *
179 * there are two types of preallocations:
180 * - inode
181 * assiged to specific inode and can be used for this inode only.
182 * it describes part of inode's space preallocated to specific
183 * physical blocks. any block from that preallocated can be used
184 * independent. the descriptor just tracks number of blocks left
185 * unused. so, before taking some block from descriptor, one must
186 * make sure corresponded logical block isn't allocated yet. this
187 * also means that freeing any block within descriptor's range
188 * must discard all preallocated blocks.
189 * - locality group
190 * assigned to specific locality group which does not translate to
191 * permanent set of inodes: inode can join and leave group. space
192 * from this type of preallocation can be used for any inode. thus
193 * it's consumed from the beginning to the end.
194 *
195 * relation between them can be expressed as:
196 * in-core buddy = on-disk bitmap + preallocation descriptors
197 *
198 * this mean blocks mballoc considers used are:
199 * - allocated blocks (persistent)
200 * - preallocated blocks (non-persistent)
201 *
202 * consistency in mballoc world means that at any time a block is either
203 * free or used in ALL structures. notice: "any time" should not be read
204 * literally -- time is discrete and delimited by locks.
205 *
206 * to keep it simple, we don't use block numbers, instead we count number of
207 * blocks: how many blocks marked used/free in on-disk bitmap, buddy and PA.
208 *
209 * all operations can be expressed as:
210 * - init buddy: buddy = on-disk + PAs
211 * - new PA: buddy += N; PA = N
212 * - use inode PA: on-disk += N; PA -= N
213 * - discard inode PA buddy -= on-disk - PA; PA = 0
214 * - use locality group PA on-disk += N; PA -= N
215 * - discard locality group PA buddy -= PA; PA = 0
216 * note: 'buddy -= on-disk - PA' is used to show that on-disk bitmap
217 * is used in real operation because we can't know actual used
218 * bits from PA, only from on-disk bitmap
219 *
220 * if we follow this strict logic, then all operations above should be atomic.
221 * given some of them can block, we'd have to use something like semaphores
222 * killing performance on high-end SMP hardware. let's try to relax it using
223 * the following knowledge:
224 * 1) if buddy is referenced, it's already initialized
225 * 2) while block is used in buddy and the buddy is referenced,
226 * nobody can re-allocate that block
227 * 3) we work on bitmaps and '+' actually means 'set bits'. if on-disk has
228 * bit set and PA claims same block, it's OK. IOW, one can set bit in
229 * on-disk bitmap if buddy has same bit set or/and PA covers corresponded
230 * block
231 *
232 * so, now we're building a concurrency table:
233 * - init buddy vs.
234 * - new PA
235 * blocks for PA are allocated in the buddy, buddy must be referenced
236 * until PA is linked to allocation group to avoid concurrent buddy init
237 * - use inode PA
238 * we need to make sure that either on-disk bitmap or PA has uptodate data
239 * given (3) we care that PA-=N operation doesn't interfere with init
240 * - discard inode PA
241 * the simplest way would be to have buddy initialized by the discard
242 * - use locality group PA
243 * again PA-=N must be serialized with init
244 * - discard locality group PA
245 * the simplest way would be to have buddy initialized by the discard
246 * - new PA vs.
247 * - use inode PA
248 * i_data_sem serializes them
249 * - discard inode PA
250 * discard process must wait until PA isn't used by another process
251 * - use locality group PA
252 * some mutex should serialize them
253 * - discard locality group PA
254 * discard process must wait until PA isn't used by another process
255 * - use inode PA
256 * - use inode PA
257 * i_data_sem or another mutex should serializes them
258 * - discard inode PA
259 * discard process must wait until PA isn't used by another process
260 * - use locality group PA
261 * nothing wrong here -- they're different PAs covering different blocks
262 * - discard locality group PA
263 * discard process must wait until PA isn't used by another process
264 *
265 * now we're ready to make few consequences:
266 * - PA is referenced and while it is no discard is possible
267 * - PA is referenced until block isn't marked in on-disk bitmap
268 * - PA changes only after on-disk bitmap
269 * - discard must not compete with init. either init is done before
270 * any discard or they're serialized somehow
271 * - buddy init as sum of on-disk bitmap and PAs is done atomically
272 *
273 * a special case when we've used PA to emptiness. no need to modify buddy
274 * in this case, but we should care about concurrent init
275 *
276 */
277
278 /*
279 * Logic in few words:
280 *
281 * - allocation:
282 * load group
283 * find blocks
284 * mark bits in on-disk bitmap
285 * release group
286 *
287 * - use preallocation:
288 * find proper PA (per-inode or group)
289 * load group
290 * mark bits in on-disk bitmap
291 * release group
292 * release PA
293 *
294 * - free:
295 * load group
296 * mark bits in on-disk bitmap
297 * release group
298 *
299 * - discard preallocations in group:
300 * mark PAs deleted
301 * move them onto local list
302 * load on-disk bitmap
303 * load group
304 * remove PA from object (inode or locality group)
305 * mark free blocks in-core
306 *
307 * - discard inode's preallocations:
308 */
309
310/*
311 * Locking rules
312 *
313 * Locks:
314 * - bitlock on a group (group)
315 * - object (inode/locality) (object)
316 * - per-pa lock (pa)
317 *
318 * Paths:
319 * - new pa
320 * object
321 * group
322 *
323 * - find and use pa:
324 * pa
325 *
326 * - release consumed pa:
327 * pa
328 * group
329 * object
330 *
331 * - generate in-core bitmap:
332 * group
333 * pa
334 *
335 * - discard all for given object (inode, locality group):
336 * object
337 * pa
338 * group
339 *
340 * - discard all for given group:
341 * group
342 * pa
343 * group
344 * object
345 *
346 */
347
348/*
349 * with AGGRESSIVE_CHECK allocator runs consistency checks over
350 * structures. these checks slow things down a lot
351 */
352#define AGGRESSIVE_CHECK__
353
354/*
355 * with DOUBLE_CHECK defined mballoc creates persistent in-core
356 * bitmaps, maintains and uses them to check for double allocations
357 */
358#define DOUBLE_CHECK__
359
360/*
361 */
362#define MB_DEBUG__
363#ifdef MB_DEBUG
364#define mb_debug(fmt, a...) printk(fmt, ##a)
365#else
366#define mb_debug(fmt, a...)
367#endif
368
369/*
370 * with EXT4_MB_HISTORY mballoc stores last N allocations in memory
371 * and you can monitor it in /proc/fs/ext4/<dev>/mb_history
372 */
373#define EXT4_MB_HISTORY
374#define EXT4_MB_HISTORY_ALLOC 1 /* allocation */
375#define EXT4_MB_HISTORY_PREALLOC 2 /* preallocated blocks used */
376#define EXT4_MB_HISTORY_DISCARD 4 /* preallocation discarded */
377#define EXT4_MB_HISTORY_FREE 8 /* free */
378
379#define EXT4_MB_HISTORY_DEFAULT (EXT4_MB_HISTORY_ALLOC | \
380 EXT4_MB_HISTORY_PREALLOC)
381
382/*
383 * How long mballoc can look for a best extent (in found extents)
384 */
385#define MB_DEFAULT_MAX_TO_SCAN 200
386
387/*
388 * How long mballoc must look for a best extent
389 */
390#define MB_DEFAULT_MIN_TO_SCAN 10
391
392/*
393 * How many groups mballoc will scan looking for the best chunk
394 */
395#define MB_DEFAULT_MAX_GROUPS_TO_SCAN 5
396
397/*
398 * with 'ext4_mb_stats' allocator will collect stats that will be
399 * shown at umount. The collecting costs though!
400 */
401#define MB_DEFAULT_STATS 1
402
403/*
404 * files smaller than MB_DEFAULT_STREAM_THRESHOLD are served
405 * by the stream allocator, which purpose is to pack requests
406 * as close each to other as possible to produce smooth I/O traffic
407 * We use locality group prealloc space for stream request.
408 * We can tune the same via /proc/fs/ext4/<parition>/stream_req
409 */
410#define MB_DEFAULT_STREAM_THRESHOLD 16 /* 64K */
411
412/*
413 * for which requests use 2^N search using buddies
414 */
415#define MB_DEFAULT_ORDER2_REQS 2
416
417/*
418 * default group prealloc size 512 blocks
419 */
420#define MB_DEFAULT_GROUP_PREALLOC 512
421
422static struct kmem_cache *ext4_pspace_cachep;
423
424#ifdef EXT4_BB_MAX_BLOCKS
425#undef EXT4_BB_MAX_BLOCKS
426#endif
427#define EXT4_BB_MAX_BLOCKS 30
428
429struct ext4_free_metadata {
430 ext4_group_t group;
431 unsigned short num;
432 ext4_grpblk_t blocks[EXT4_BB_MAX_BLOCKS];
433 struct list_head list;
434};
435
436struct ext4_group_info {
437 unsigned long bb_state;
438 unsigned long bb_tid;
439 struct ext4_free_metadata *bb_md_cur;
440 unsigned short bb_first_free;
441 unsigned short bb_free;
442 unsigned short bb_fragments;
443 struct list_head bb_prealloc_list;
444#ifdef DOUBLE_CHECK
445 void *bb_bitmap;
446#endif
447 unsigned short bb_counters[];
448};
449
450#define EXT4_GROUP_INFO_NEED_INIT_BIT 0
451#define EXT4_GROUP_INFO_LOCKED_BIT 1
452
453#define EXT4_MB_GRP_NEED_INIT(grp) \
454 (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
455
456
457struct ext4_prealloc_space {
458 struct list_head pa_inode_list;
459 struct list_head pa_group_list;
460 union {
461 struct list_head pa_tmp_list;
462 struct rcu_head pa_rcu;
463 } u;
464 spinlock_t pa_lock;
465 atomic_t pa_count;
466 unsigned pa_deleted;
467 ext4_fsblk_t pa_pstart; /* phys. block */
468 ext4_lblk_t pa_lstart; /* log. block */
469 unsigned short pa_len; /* len of preallocated chunk */
470 unsigned short pa_free; /* how many blocks are free */
471 unsigned short pa_linear; /* consumed in one direction
472 * strictly, for grp prealloc */
473 spinlock_t *pa_obj_lock;
474 struct inode *pa_inode; /* hack, for history only */
475};
476
477
478struct ext4_free_extent {
479 ext4_lblk_t fe_logical;
480 ext4_grpblk_t fe_start;
481 ext4_group_t fe_group;
482 int fe_len;
483};
484
485/*
486 * Locality group:
487 * we try to group all related changes together
488 * so that writeback can flush/allocate them together as well
489 */
490struct ext4_locality_group {
491 /* for allocator */
492 struct mutex lg_mutex; /* to serialize allocates */
493 struct list_head lg_prealloc_list;/* list of preallocations */
494 spinlock_t lg_prealloc_lock;
495};
496
497struct ext4_allocation_context {
498 struct inode *ac_inode;
499 struct super_block *ac_sb;
500
501 /* original request */
502 struct ext4_free_extent ac_o_ex;
503
504 /* goal request (after normalization) */
505 struct ext4_free_extent ac_g_ex;
506
507 /* the best found extent */
508 struct ext4_free_extent ac_b_ex;
509
510 /* copy of the bext found extent taken before preallocation efforts */
511 struct ext4_free_extent ac_f_ex;
512
513 /* number of iterations done. we have to track to limit searching */
514 unsigned long ac_ex_scanned;
515 __u16 ac_groups_scanned;
516 __u16 ac_found;
517 __u16 ac_tail;
518 __u16 ac_buddy;
519 __u16 ac_flags; /* allocation hints */
520 __u8 ac_status;
521 __u8 ac_criteria;
522 __u8 ac_repeats;
523 __u8 ac_2order; /* if request is to allocate 2^N blocks and
524 * N > 0, the field stores N, otherwise 0 */
525 __u8 ac_op; /* operation, for history only */
526 struct page *ac_bitmap_page;
527 struct page *ac_buddy_page;
528 struct ext4_prealloc_space *ac_pa;
529 struct ext4_locality_group *ac_lg;
530};
531
532#define AC_STATUS_CONTINUE 1
533#define AC_STATUS_FOUND 2
534#define AC_STATUS_BREAK 3
535
536struct ext4_mb_history {
537 struct ext4_free_extent orig; /* orig allocation */
538 struct ext4_free_extent goal; /* goal allocation */
539 struct ext4_free_extent result; /* result allocation */
540 unsigned pid;
541 unsigned ino;
542 __u16 found; /* how many extents have been found */
543 __u16 groups; /* how many groups have been scanned */
544 __u16 tail; /* what tail broke some buddy */
545 __u16 buddy; /* buddy the tail ^^^ broke */
546 __u16 flags;
547 __u8 cr:3; /* which phase the result extent was found at */
548 __u8 op:4;
549 __u8 merged:1;
550};
551
552struct ext4_buddy {
553 struct page *bd_buddy_page;
554 void *bd_buddy;
555 struct page *bd_bitmap_page;
556 void *bd_bitmap;
557 struct ext4_group_info *bd_info;
558 struct super_block *bd_sb;
559 __u16 bd_blkbits;
560 ext4_group_t bd_group;
561};
562#define EXT4_MB_BITMAP(e4b) ((e4b)->bd_bitmap)
563#define EXT4_MB_BUDDY(e4b) ((e4b)->bd_buddy)
564
565#ifndef EXT4_MB_HISTORY
566static inline void ext4_mb_store_history(struct ext4_allocation_context *ac)
567{
568 return;
569}
570#else
571static void ext4_mb_store_history(struct ext4_allocation_context *ac);
572#endif
573
574#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
575
576static struct proc_dir_entry *proc_root_ext4;
577struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
578ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode,
579 ext4_fsblk_t goal, unsigned long *count, int *errp);
580
581static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
582 ext4_group_t group);
583static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *);
584static void ext4_mb_free_committed_blocks(struct super_block *);
585static void ext4_mb_return_to_preallocation(struct inode *inode,
586 struct ext4_buddy *e4b, sector_t block,
587 int count);
588static void ext4_mb_put_pa(struct ext4_allocation_context *,
589 struct super_block *, struct ext4_prealloc_space *pa);
590static int ext4_mb_init_per_dev_proc(struct super_block *sb);
591static int ext4_mb_destroy_per_dev_proc(struct super_block *sb);
592
593
594static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
595{
596 struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
597
598 bit_spin_lock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state));
599}
600
601static inline void ext4_unlock_group(struct super_block *sb,
602 ext4_group_t group)
603{
604 struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
605
606 bit_spin_unlock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state));
607}
608
609static inline int ext4_is_group_locked(struct super_block *sb,
610 ext4_group_t group)
611{
612 struct ext4_group_info *grinfo = ext4_get_group_info(sb, group);
613
614 return bit_spin_is_locked(EXT4_GROUP_INFO_LOCKED_BIT,
615 &(grinfo->bb_state));
616}
617
618static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
619 struct ext4_free_extent *fex)
620{
621 ext4_fsblk_t block;
622
623 block = (ext4_fsblk_t) fex->fe_group * EXT4_BLOCKS_PER_GROUP(sb)
624 + fex->fe_start
625 + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
626 return block;
627}
628
629#if BITS_PER_LONG == 64
630#define mb_correct_addr_and_bit(bit, addr) \
631{ \
632 bit += ((unsigned long) addr & 7UL) << 3; \
633 addr = (void *) ((unsigned long) addr & ~7UL); \
634}
635#elif BITS_PER_LONG == 32
636#define mb_correct_addr_and_bit(bit, addr) \
637{ \
638 bit += ((unsigned long) addr & 3UL) << 3; \
639 addr = (void *) ((unsigned long) addr & ~3UL); \
640}
641#else
642#error "how many bits you are?!"
643#endif
644
645static inline int mb_test_bit(int bit, void *addr)
646{
647 /*
648 * ext4_test_bit on architecture like powerpc
649 * needs unsigned long aligned address
650 */
651 mb_correct_addr_and_bit(bit, addr);
652 return ext4_test_bit(bit, addr);
653}
654
655static inline void mb_set_bit(int bit, void *addr)
656{
657 mb_correct_addr_and_bit(bit, addr);
658 ext4_set_bit(bit, addr);
659}
660
661static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr)
662{
663 mb_correct_addr_and_bit(bit, addr);
664 ext4_set_bit_atomic(lock, bit, addr);
665}
666
667static inline void mb_clear_bit(int bit, void *addr)
668{
669 mb_correct_addr_and_bit(bit, addr);
670 ext4_clear_bit(bit, addr);
671}
672
673static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr)
674{
675 mb_correct_addr_and_bit(bit, addr);
676 ext4_clear_bit_atomic(lock, bit, addr);
677}
678
679static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
680{
681 char *bb;
682
683 /* FIXME!! is this needed */
684 BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
685 BUG_ON(max == NULL);
686
687 if (order > e4b->bd_blkbits + 1) {
688 *max = 0;
689 return NULL;
690 }
691
692 /* at order 0 we see each particular block */
693 *max = 1 << (e4b->bd_blkbits + 3);
694 if (order == 0)
695 return EXT4_MB_BITMAP(e4b);
696
697 bb = EXT4_MB_BUDDY(e4b) + EXT4_SB(e4b->bd_sb)->s_mb_offsets[order];
698 *max = EXT4_SB(e4b->bd_sb)->s_mb_maxs[order];
699
700 return bb;
701}
702
703#ifdef DOUBLE_CHECK
704static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b,
705 int first, int count)
706{
707 int i;
708 struct super_block *sb = e4b->bd_sb;
709
710 if (unlikely(e4b->bd_info->bb_bitmap == NULL))
711 return;
712 BUG_ON(!ext4_is_group_locked(sb, e4b->bd_group));
713 for (i = 0; i < count; i++) {
714 if (!mb_test_bit(first + i, e4b->bd_info->bb_bitmap)) {
715 ext4_fsblk_t blocknr;
716 blocknr = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb);
717 blocknr += first + i;
718 blocknr +=
719 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
720
721 ext4_error(sb, __FUNCTION__, "double-free of inode"
722 " %lu's block %llu(bit %u in group %lu)\n",
723 inode ? inode->i_ino : 0, blocknr,
724 first + i, e4b->bd_group);
725 }
726 mb_clear_bit(first + i, e4b->bd_info->bb_bitmap);
727 }
728}
729
730static void mb_mark_used_double(struct ext4_buddy *e4b, int first, int count)
731{
732 int i;
733
734 if (unlikely(e4b->bd_info->bb_bitmap == NULL))
735 return;
736 BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group));
737 for (i = 0; i < count; i++) {
738 BUG_ON(mb_test_bit(first + i, e4b->bd_info->bb_bitmap));
739 mb_set_bit(first + i, e4b->bd_info->bb_bitmap);
740 }
741}
742
743static void mb_cmp_bitmaps(struct ext4_buddy *e4b, void *bitmap)
744{
745 if (memcmp(e4b->bd_info->bb_bitmap, bitmap, e4b->bd_sb->s_blocksize)) {
746 unsigned char *b1, *b2;
747 int i;
748 b1 = (unsigned char *) e4b->bd_info->bb_bitmap;
749 b2 = (unsigned char *) bitmap;
750 for (i = 0; i < e4b->bd_sb->s_blocksize; i++) {
751 if (b1[i] != b2[i]) {
752 printk("corruption in group %lu at byte %u(%u):"
753 " %x in copy != %x on disk/prealloc\n",
754 e4b->bd_group, i, i * 8, b1[i], b2[i]);
755 BUG();
756 }
757 }
758 }
759}
760
761#else
762static inline void mb_free_blocks_double(struct inode *inode,
763 struct ext4_buddy *e4b, int first, int count)
764{
765 return;
766}
767static inline void mb_mark_used_double(struct ext4_buddy *e4b,
768 int first, int count)
769{
770 return;
771}
772static inline void mb_cmp_bitmaps(struct ext4_buddy *e4b, void *bitmap)
773{
774 return;
775}
776#endif
777
778#ifdef AGGRESSIVE_CHECK
779
780#define MB_CHECK_ASSERT(assert) \
781do { \
782 if (!(assert)) { \
783 printk(KERN_EMERG \
784 "Assertion failure in %s() at %s:%d: \"%s\"\n", \
785 function, file, line, # assert); \
786 BUG(); \
787 } \
788} while (0)
789
790static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
791 const char *function, int line)
792{
793 struct super_block *sb = e4b->bd_sb;
794 int order = e4b->bd_blkbits + 1;
795 int max;
796 int max2;
797 int i;
798 int j;
799 int k;
800 int count;
801 struct ext4_group_info *grp;
802 int fragments = 0;
803 int fstart;
804 struct list_head *cur;
805 void *buddy;
806 void *buddy2;
807
808 if (!test_opt(sb, MBALLOC))
809 return 0;
810
811 {
812 static int mb_check_counter;
813 if (mb_check_counter++ % 100 != 0)
814 return 0;
815 }
816
817 while (order > 1) {
818 buddy = mb_find_buddy(e4b, order, &max);
819 MB_CHECK_ASSERT(buddy);
820 buddy2 = mb_find_buddy(e4b, order - 1, &max2);
821 MB_CHECK_ASSERT(buddy2);
822 MB_CHECK_ASSERT(buddy != buddy2);
823 MB_CHECK_ASSERT(max * 2 == max2);
824
825 count = 0;
826 for (i = 0; i < max; i++) {
827
828 if (mb_test_bit(i, buddy)) {
829 /* only single bit in buddy2 may be 1 */
830 if (!mb_test_bit(i << 1, buddy2)) {
831 MB_CHECK_ASSERT(
832 mb_test_bit((i<<1)+1, buddy2));
833 } else if (!mb_test_bit((i << 1) + 1, buddy2)) {
834 MB_CHECK_ASSERT(
835 mb_test_bit(i << 1, buddy2));
836 }
837 continue;
838 }
839
840 /* both bits in buddy2 must be 0 */
841 MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2));
842 MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2));
843
844 for (j = 0; j < (1 << order); j++) {
845 k = (i * (1 << order)) + j;
846 MB_CHECK_ASSERT(
847 !mb_test_bit(k, EXT4_MB_BITMAP(e4b)));
848 }
849 count++;
850 }
851 MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count);
852 order--;
853 }
854
855 fstart = -1;
856 buddy = mb_find_buddy(e4b, 0, &max);
857 for (i = 0; i < max; i++) {
858 if (!mb_test_bit(i, buddy)) {
859 MB_CHECK_ASSERT(i >= e4b->bd_info->bb_first_free);
860 if (fstart == -1) {
861 fragments++;
862 fstart = i;
863 }
864 continue;
865 }
866 fstart = -1;
867 /* check used bits only */
868 for (j = 0; j < e4b->bd_blkbits + 1; j++) {
869 buddy2 = mb_find_buddy(e4b, j, &max2);
870 k = i >> j;
871 MB_CHECK_ASSERT(k < max2);
872 MB_CHECK_ASSERT(mb_test_bit(k, buddy2));
873 }
874 }
875 MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info));
876 MB_CHECK_ASSERT(e4b->bd_info->bb_fragments == fragments);
877
878 grp = ext4_get_group_info(sb, e4b->bd_group);
879 buddy = mb_find_buddy(e4b, 0, &max);
880 list_for_each(cur, &grp->bb_prealloc_list) {
881 ext4_group_t groupnr;
882 struct ext4_prealloc_space *pa;
883 pa = list_entry(cur, struct ext4_prealloc_space, group_list);
884 ext4_get_group_no_and_offset(sb, pa->pstart, &groupnr, &k);
885 MB_CHECK_ASSERT(groupnr == e4b->bd_group);
886 for (i = 0; i < pa->len; i++)
887 MB_CHECK_ASSERT(mb_test_bit(k + i, buddy));
888 }
889 return 0;
890}
891#undef MB_CHECK_ASSERT
892#define mb_check_buddy(e4b) __mb_check_buddy(e4b, \
893 __FILE__, __FUNCTION__, __LINE__)
894#else
895#define mb_check_buddy(e4b)
896#endif
897
898/* FIXME!! need more doc */
899static void ext4_mb_mark_free_simple(struct super_block *sb,
900 void *buddy, unsigned first, int len,
901 struct ext4_group_info *grp)
902{
903 struct ext4_sb_info *sbi = EXT4_SB(sb);
904 unsigned short min;
905 unsigned short max;
906 unsigned short chunk;
907 unsigned short border;
908
909 BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb));
910
911 border = 2 << sb->s_blocksize_bits;
912
913 while (len > 0) {
914 /* find how many blocks can be covered since this position */
915 max = ffs(first | border) - 1;
916
917 /* find how many blocks of power 2 we need to mark */
918 min = fls(len) - 1;
919
920 if (max < min)
921 min = max;
922 chunk = 1 << min;
923
924 /* mark multiblock chunks only */
925 grp->bb_counters[min]++;
926 if (min > 0)
927 mb_clear_bit(first >> min,
928 buddy + sbi->s_mb_offsets[min]);
929
930 len -= chunk;
931 first += chunk;
932 }
933}
934
935static void ext4_mb_generate_buddy(struct super_block *sb,
936 void *buddy, void *bitmap, ext4_group_t group)
937{
938 struct ext4_group_info *grp = ext4_get_group_info(sb, group);
939 unsigned short max = EXT4_BLOCKS_PER_GROUP(sb);
940 unsigned short i = 0;
941 unsigned short first;
942 unsigned short len;
943 unsigned free = 0;
944 unsigned fragments = 0;
945 unsigned long long period = get_cycles();
946
947 /* initialize buddy from bitmap which is aggregation
948 * of on-disk bitmap and preallocations */
949 i = ext4_find_next_zero_bit(bitmap, max, 0);
950 grp->bb_first_free = i;
951 while (i < max) {
952 fragments++;
953 first = i;
954 i = ext4_find_next_bit(bitmap, max, i);
955 len = i - first;
956 free += len;
957 if (len > 1)
958 ext4_mb_mark_free_simple(sb, buddy, first, len, grp);
959 else
960 grp->bb_counters[0]++;
961 if (i < max)
962 i = ext4_find_next_zero_bit(bitmap, max, i);
963 }
964 grp->bb_fragments = fragments;
965
966 if (free != grp->bb_free) {
967 printk(KERN_DEBUG
968 "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n",
969 group, free, grp->bb_free);
970 grp->bb_free = free;
971 }
972
973 clear_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
974
975 period = get_cycles() - period;
976 spin_lock(&EXT4_SB(sb)->s_bal_lock);
977 EXT4_SB(sb)->s_mb_buddies_generated++;
978 EXT4_SB(sb)->s_mb_generation_time += period;
979 spin_unlock(&EXT4_SB(sb)->s_bal_lock);
980}
981
982/* The buddy information is attached the buddy cache inode
983 * for convenience. The information regarding each group
984 * is loaded via ext4_mb_load_buddy. The information involve
985 * block bitmap and buddy information. The information are
986 * stored in the inode as
987 *
988 * { page }
989 * [ group 0 buddy][ group 0 bitmap] [group 1][ group 1]...
990 *
991 *
992 * one block each for bitmap and buddy information.
993 * So for each group we take up 2 blocks. A page can
994 * contain blocks_per_page (PAGE_CACHE_SIZE / blocksize) blocks.
995 * So it can have information regarding groups_per_page which
996 * is blocks_per_page/2
997 */
998
999static int ext4_mb_init_cache(struct page *page, char *incore)
1000{
1001 int blocksize;
1002 int blocks_per_page;
1003 int groups_per_page;
1004 int err = 0;
1005 int i;
1006 ext4_group_t first_group;
1007 int first_block;
1008 struct super_block *sb;
1009 struct buffer_head *bhs;
1010 struct buffer_head **bh;
1011 struct inode *inode;
1012 char *data;
1013 char *bitmap;
1014
1015 mb_debug("init page %lu\n", page->index);
1016
1017 inode = page->mapping->host;
1018 sb = inode->i_sb;
1019 blocksize = 1 << inode->i_blkbits;
1020 blocks_per_page = PAGE_CACHE_SIZE / blocksize;
1021
1022 groups_per_page = blocks_per_page >> 1;
1023 if (groups_per_page == 0)
1024 groups_per_page = 1;
1025
1026 /* allocate buffer_heads to read bitmaps */
1027 if (groups_per_page > 1) {
1028 err = -ENOMEM;
1029 i = sizeof(struct buffer_head *) * groups_per_page;
1030 bh = kzalloc(i, GFP_NOFS);
1031 if (bh == NULL)
1032 goto out;
1033 } else
1034 bh = &bhs;
1035
1036 first_group = page->index * blocks_per_page / 2;
1037
1038 /* read all groups the page covers into the cache */
1039 for (i = 0; i < groups_per_page; i++) {
1040 struct ext4_group_desc *desc;
1041
1042 if (first_group + i >= EXT4_SB(sb)->s_groups_count)
1043 break;
1044
1045 err = -EIO;
1046 desc = ext4_get_group_desc(sb, first_group + i, NULL);
1047 if (desc == NULL)
1048 goto out;
1049
1050 err = -ENOMEM;
1051 bh[i] = sb_getblk(sb, ext4_block_bitmap(sb, desc));
1052 if (bh[i] == NULL)
1053 goto out;
1054
1055 if (bh_uptodate_or_lock(bh[i]))
1056 continue;
1057
1058 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
1059 ext4_init_block_bitmap(sb, bh[i],
1060 first_group + i, desc);
1061 set_buffer_uptodate(bh[i]);
1062 unlock_buffer(bh[i]);
1063 continue;
1064 }
1065 get_bh(bh[i]);
1066 bh[i]->b_end_io = end_buffer_read_sync;
1067 submit_bh(READ, bh[i]);
1068 mb_debug("read bitmap for group %lu\n", first_group + i);
1069 }
1070
1071 /* wait for I/O completion */
1072 for (i = 0; i < groups_per_page && bh[i]; i++)
1073 wait_on_buffer(bh[i]);
1074
1075 err = -EIO;
1076 for (i = 0; i < groups_per_page && bh[i]; i++)
1077 if (!buffer_uptodate(bh[i]))
1078 goto out;
1079
1080 first_block = page->index * blocks_per_page;
1081 for (i = 0; i < blocks_per_page; i++) {
1082 int group;
1083 struct ext4_group_info *grinfo;
1084
1085 group = (first_block + i) >> 1;
1086 if (group >= EXT4_SB(sb)->s_groups_count)
1087 break;
1088
1089 /*
1090 * data carry information regarding this
1091 * particular group in the format specified
1092 * above
1093 *
1094 */
1095 data = page_address(page) + (i * blocksize);
1096 bitmap = bh[group - first_group]->b_data;
1097
1098 /*
1099 * We place the buddy block and bitmap block
1100 * close together
1101 */
1102 if ((first_block + i) & 1) {
1103 /* this is block of buddy */
1104 BUG_ON(incore == NULL);
1105 mb_debug("put buddy for group %u in page %lu/%x\n",
1106 group, page->index, i * blocksize);
1107 memset(data, 0xff, blocksize);
1108 grinfo = ext4_get_group_info(sb, group);
1109 grinfo->bb_fragments = 0;
1110 memset(grinfo->bb_counters, 0,
1111 sizeof(unsigned short)*(sb->s_blocksize_bits+2));
1112 /*
1113 * incore got set to the group block bitmap below
1114 */
1115 ext4_mb_generate_buddy(sb, data, incore, group);
1116 incore = NULL;
1117 } else {
1118 /* this is block of bitmap */
1119 BUG_ON(incore != NULL);
1120 mb_debug("put bitmap for group %u in page %lu/%x\n",
1121 group, page->index, i * blocksize);
1122
1123 /* see comments in ext4_mb_put_pa() */
1124 ext4_lock_group(sb, group);
1125 memcpy(data, bitmap, blocksize);
1126
1127 /* mark all preallocated blks used in in-core bitmap */
1128 ext4_mb_generate_from_pa(sb, data, group);
1129 ext4_unlock_group(sb, group);
1130
1131 /* set incore so that the buddy information can be
1132 * generated using this
1133 */
1134 incore = data;
1135 }
1136 }
1137 SetPageUptodate(page);
1138
1139out:
1140 if (bh) {
1141 for (i = 0; i < groups_per_page && bh[i]; i++)
1142 brelse(bh[i]);
1143 if (bh != &bhs)
1144 kfree(bh);
1145 }
1146 return err;
1147}
1148
1149static int ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
1150 struct ext4_buddy *e4b)
1151{
1152 struct ext4_sb_info *sbi = EXT4_SB(sb);
1153 struct inode *inode = sbi->s_buddy_cache;
1154 int blocks_per_page;
1155 int block;
1156 int pnum;
1157 int poff;
1158 struct page *page;
1159
1160 mb_debug("load group %lu\n", group);
1161
1162 blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
1163
1164 e4b->bd_blkbits = sb->s_blocksize_bits;
1165 e4b->bd_info = ext4_get_group_info(sb, group);
1166 e4b->bd_sb = sb;
1167 e4b->bd_group = group;
1168 e4b->bd_buddy_page = NULL;
1169 e4b->bd_bitmap_page = NULL;
1170
1171 /*
1172 * the buddy cache inode stores the block bitmap
1173 * and buddy information in consecutive blocks.
1174 * So for each group we need two blocks.
1175 */
1176 block = group * 2;
1177 pnum = block / blocks_per_page;
1178 poff = block % blocks_per_page;
1179
1180 /* we could use find_or_create_page(), but it locks page
1181 * what we'd like to avoid in fast path ... */
1182 page = find_get_page(inode->i_mapping, pnum);
1183 if (page == NULL || !PageUptodate(page)) {
1184 if (page)
1185 page_cache_release(page);
1186 page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
1187 if (page) {
1188 BUG_ON(page->mapping != inode->i_mapping);
1189 if (!PageUptodate(page)) {
1190 ext4_mb_init_cache(page, NULL);
1191 mb_cmp_bitmaps(e4b, page_address(page) +
1192 (poff * sb->s_blocksize));
1193 }
1194 unlock_page(page);
1195 }
1196 }
1197 if (page == NULL || !PageUptodate(page))
1198 goto err;
1199 e4b->bd_bitmap_page = page;
1200 e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize);
1201 mark_page_accessed(page);
1202
1203 block++;
1204 pnum = block / blocks_per_page;
1205 poff = block % blocks_per_page;
1206
1207 page = find_get_page(inode->i_mapping, pnum);
1208 if (page == NULL || !PageUptodate(page)) {
1209 if (page)
1210 page_cache_release(page);
1211 page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
1212 if (page) {
1213 BUG_ON(page->mapping != inode->i_mapping);
1214 if (!PageUptodate(page))
1215 ext4_mb_init_cache(page, e4b->bd_bitmap);
1216
1217 unlock_page(page);
1218 }
1219 }
1220 if (page == NULL || !PageUptodate(page))
1221 goto err;
1222 e4b->bd_buddy_page = page;
1223 e4b->bd_buddy = page_address(page) + (poff * sb->s_blocksize);
1224 mark_page_accessed(page);
1225
1226 BUG_ON(e4b->bd_bitmap_page == NULL);
1227 BUG_ON(e4b->bd_buddy_page == NULL);
1228
1229 return 0;
1230
1231err:
1232 if (e4b->bd_bitmap_page)
1233 page_cache_release(e4b->bd_bitmap_page);
1234 if (e4b->bd_buddy_page)
1235 page_cache_release(e4b->bd_buddy_page);
1236 e4b->bd_buddy = NULL;
1237 e4b->bd_bitmap = NULL;
1238 return -EIO;
1239}
1240
1241static void ext4_mb_release_desc(struct ext4_buddy *e4b)
1242{
1243 if (e4b->bd_bitmap_page)
1244 page_cache_release(e4b->bd_bitmap_page);
1245 if (e4b->bd_buddy_page)
1246 page_cache_release(e4b->bd_buddy_page);
1247}
1248
1249
1250static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
1251{
1252 int order = 1;
1253 void *bb;
1254
1255 BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
1256 BUG_ON(block >= (1 << (e4b->bd_blkbits + 3)));
1257
1258 bb = EXT4_MB_BUDDY(e4b);
1259 while (order <= e4b->bd_blkbits + 1) {
1260 block = block >> 1;
1261 if (!mb_test_bit(block, bb)) {
1262 /* this block is part of buddy of order 'order' */
1263 return order;
1264 }
1265 bb += 1 << (e4b->bd_blkbits - order);
1266 order++;
1267 }
1268 return 0;
1269}
1270
1271static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len)
1272{
1273 __u32 *addr;
1274
1275 len = cur + len;
1276 while (cur < len) {
1277 if ((cur & 31) == 0 && (len - cur) >= 32) {
1278 /* fast path: clear whole word at once */
1279 addr = bm + (cur >> 3);
1280 *addr = 0;
1281 cur += 32;
1282 continue;
1283 }
1284 mb_clear_bit_atomic(lock, cur, bm);
1285 cur++;
1286 }
1287}
1288
1289static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len)
1290{
1291 __u32 *addr;
1292
1293 len = cur + len;
1294 while (cur < len) {
1295 if ((cur & 31) == 0 && (len - cur) >= 32) {
1296 /* fast path: set whole word at once */
1297 addr = bm + (cur >> 3);
1298 *addr = 0xffffffff;
1299 cur += 32;
1300 continue;
1301 }
1302 mb_set_bit_atomic(lock, cur, bm);
1303 cur++;
1304 }
1305}
1306
1307static int mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
1308 int first, int count)
1309{
1310 int block = 0;
1311 int max = 0;
1312 int order;
1313 void *buddy;
1314 void *buddy2;
1315 struct super_block *sb = e4b->bd_sb;
1316
1317 BUG_ON(first + count > (sb->s_blocksize << 3));
1318 BUG_ON(!ext4_is_group_locked(sb, e4b->bd_group));
1319 mb_check_buddy(e4b);
1320 mb_free_blocks_double(inode, e4b, first, count);
1321
1322 e4b->bd_info->bb_free += count;
1323 if (first < e4b->bd_info->bb_first_free)
1324 e4b->bd_info->bb_first_free = first;
1325
1326 /* let's maintain fragments counter */
1327 if (first != 0)
1328 block = !mb_test_bit(first - 1, EXT4_MB_BITMAP(e4b));
1329 if (first + count < EXT4_SB(sb)->s_mb_maxs[0])
1330 max = !mb_test_bit(first + count, EXT4_MB_BITMAP(e4b));
1331 if (block && max)
1332 e4b->bd_info->bb_fragments--;
1333 else if (!block && !max)
1334 e4b->bd_info->bb_fragments++;
1335
1336 /* let's maintain buddy itself */
1337 while (count-- > 0) {
1338 block = first++;
1339 order = 0;
1340
1341 if (!mb_test_bit(block, EXT4_MB_BITMAP(e4b))) {
1342 ext4_fsblk_t blocknr;
1343 blocknr = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb);
1344 blocknr += block;
1345 blocknr +=
1346 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
1347
1348 ext4_error(sb, __FUNCTION__, "double-free of inode"
1349 " %lu's block %llu(bit %u in group %lu)\n",
1350 inode ? inode->i_ino : 0, blocknr, block,
1351 e4b->bd_group);
1352 }
1353 mb_clear_bit(block, EXT4_MB_BITMAP(e4b));
1354 e4b->bd_info->bb_counters[order]++;
1355
1356 /* start of the buddy */
1357 buddy = mb_find_buddy(e4b, order, &max);
1358
1359 do {
1360 block &= ~1UL;
1361 if (mb_test_bit(block, buddy) ||
1362 mb_test_bit(block + 1, buddy))
1363 break;
1364
1365 /* both the buddies are free, try to coalesce them */
1366 buddy2 = mb_find_buddy(e4b, order + 1, &max);
1367
1368 if (!buddy2)
1369 break;
1370
1371 if (order > 0) {
1372 /* for special purposes, we don't set
1373 * free bits in bitmap */
1374 mb_set_bit(block, buddy);
1375 mb_set_bit(block + 1, buddy);
1376 }
1377 e4b->bd_info->bb_counters[order]--;
1378 e4b->bd_info->bb_counters[order]--;
1379
1380 block = block >> 1;
1381 order++;
1382 e4b->bd_info->bb_counters[order]++;
1383
1384 mb_clear_bit(block, buddy2);
1385 buddy = buddy2;
1386 } while (1);
1387 }
1388 mb_check_buddy(e4b);
1389
1390 return 0;
1391}
1392
1393static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
1394 int needed, struct ext4_free_extent *ex)
1395{
1396 int next = block;
1397 int max;
1398 int ord;
1399 void *buddy;
1400
1401 BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group));
1402 BUG_ON(ex == NULL);
1403
1404 buddy = mb_find_buddy(e4b, order, &max);
1405 BUG_ON(buddy == NULL);
1406 BUG_ON(block >= max);
1407 if (mb_test_bit(block, buddy)) {
1408 ex->fe_len = 0;
1409 ex->fe_start = 0;
1410 ex->fe_group = 0;
1411 return 0;
1412 }
1413
1414 /* FIXME dorp order completely ? */
1415 if (likely(order == 0)) {
1416 /* find actual order */
1417 order = mb_find_order_for_block(e4b, block);
1418 block = block >> order;
1419 }
1420
1421 ex->fe_len = 1 << order;
1422 ex->fe_start = block << order;
1423 ex->fe_group = e4b->bd_group;
1424
1425 /* calc difference from given start */
1426 next = next - ex->fe_start;
1427 ex->fe_len -= next;
1428 ex->fe_start += next;
1429
1430 while (needed > ex->fe_len &&
1431 (buddy = mb_find_buddy(e4b, order, &max))) {
1432
1433 if (block + 1 >= max)
1434 break;
1435
1436 next = (block + 1) * (1 << order);
1437 if (mb_test_bit(next, EXT4_MB_BITMAP(e4b)))
1438 break;
1439
1440 ord = mb_find_order_for_block(e4b, next);
1441
1442 order = ord;
1443 block = next >> order;
1444 ex->fe_len += 1 << order;
1445 }
1446
1447 BUG_ON(ex->fe_start + ex->fe_len > (1 << (e4b->bd_blkbits + 3)));
1448 return ex->fe_len;
1449}
1450
1451static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
1452{
1453 int ord;
1454 int mlen = 0;
1455 int max = 0;
1456 int cur;
1457 int start = ex->fe_start;
1458 int len = ex->fe_len;
1459 unsigned ret = 0;
1460 int len0 = len;
1461 void *buddy;
1462
1463 BUG_ON(start + len > (e4b->bd_sb->s_blocksize << 3));
1464 BUG_ON(e4b->bd_group != ex->fe_group);
1465 BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group));
1466 mb_check_buddy(e4b);
1467 mb_mark_used_double(e4b, start, len);
1468
1469 e4b->bd_info->bb_free -= len;
1470 if (e4b->bd_info->bb_first_free == start)
1471 e4b->bd_info->bb_first_free += len;
1472
1473 /* let's maintain fragments counter */
1474 if (start != 0)
1475 mlen = !mb_test_bit(start - 1, EXT4_MB_BITMAP(e4b));
1476 if (start + len < EXT4_SB(e4b->bd_sb)->s_mb_maxs[0])
1477 max = !mb_test_bit(start + len, EXT4_MB_BITMAP(e4b));
1478 if (mlen && max)
1479 e4b->bd_info->bb_fragments++;
1480 else if (!mlen && !max)
1481 e4b->bd_info->bb_fragments--;
1482
1483 /* let's maintain buddy itself */
1484 while (len) {
1485 ord = mb_find_order_for_block(e4b, start);
1486
1487 if (((start >> ord) << ord) == start && len >= (1 << ord)) {
1488 /* the whole chunk may be allocated at once! */
1489 mlen = 1 << ord;
1490 buddy = mb_find_buddy(e4b, ord, &max);
1491 BUG_ON((start >> ord) >= max);
1492 mb_set_bit(start >> ord, buddy);
1493 e4b->bd_info->bb_counters[ord]--;
1494 start += mlen;
1495 len -= mlen;
1496 BUG_ON(len < 0);
1497 continue;
1498 }
1499
1500 /* store for history */
1501 if (ret == 0)
1502 ret = len | (ord << 16);
1503
1504 /* we have to split large buddy */
1505 BUG_ON(ord <= 0);
1506 buddy = mb_find_buddy(e4b, ord, &max);
1507 mb_set_bit(start >> ord, buddy);
1508 e4b->bd_info->bb_counters[ord]--;
1509
1510 ord--;
1511 cur = (start >> ord) & ~1U;
1512 buddy = mb_find_buddy(e4b, ord, &max);
1513 mb_clear_bit(cur, buddy);
1514 mb_clear_bit(cur + 1, buddy);
1515 e4b->bd_info->bb_counters[ord]++;
1516 e4b->bd_info->bb_counters[ord]++;
1517 }
1518
1519 mb_set_bits(sb_bgl_lock(EXT4_SB(e4b->bd_sb), ex->fe_group),
1520 EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
1521 mb_check_buddy(e4b);
1522
1523 return ret;
1524}
1525
1526/*
1527 * Must be called under group lock!
1528 */
1529static void ext4_mb_use_best_found(struct ext4_allocation_context *ac,
1530 struct ext4_buddy *e4b)
1531{
1532 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
1533 int ret;
1534
1535 BUG_ON(ac->ac_b_ex.fe_group != e4b->bd_group);
1536 BUG_ON(ac->ac_status == AC_STATUS_FOUND);
1537
1538 ac->ac_b_ex.fe_len = min(ac->ac_b_ex.fe_len, ac->ac_g_ex.fe_len);
1539 ac->ac_b_ex.fe_logical = ac->ac_g_ex.fe_logical;
1540 ret = mb_mark_used(e4b, &ac->ac_b_ex);
1541
1542 /* preallocation can change ac_b_ex, thus we store actually
1543 * allocated blocks for history */
1544 ac->ac_f_ex = ac->ac_b_ex;
1545
1546 ac->ac_status = AC_STATUS_FOUND;
1547 ac->ac_tail = ret & 0xffff;
1548 ac->ac_buddy = ret >> 16;
1549
1550 /* XXXXXXX: SUCH A HORRIBLE **CK */
1551 /*FIXME!! Why ? */
1552 ac->ac_bitmap_page = e4b->bd_bitmap_page;
1553 get_page(ac->ac_bitmap_page);
1554 ac->ac_buddy_page = e4b->bd_buddy_page;
1555 get_page(ac->ac_buddy_page);
1556
1557 /* store last allocated for subsequent stream allocation */
1558 if ((ac->ac_flags & EXT4_MB_HINT_DATA)) {
1559 spin_lock(&sbi->s_md_lock);
1560 sbi->s_mb_last_group = ac->ac_f_ex.fe_group;
1561 sbi->s_mb_last_start = ac->ac_f_ex.fe_start;
1562 spin_unlock(&sbi->s_md_lock);
1563 }
1564}
1565
1566/*
1567 * regular allocator, for general purposes allocation
1568 */
1569
1570static void ext4_mb_check_limits(struct ext4_allocation_context *ac,
1571 struct ext4_buddy *e4b,
1572 int finish_group)
1573{
1574 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
1575 struct ext4_free_extent *bex = &ac->ac_b_ex;
1576 struct ext4_free_extent *gex = &ac->ac_g_ex;
1577 struct ext4_free_extent ex;
1578 int max;
1579
1580 /*
1581 * We don't want to scan for a whole year
1582 */
1583 if (ac->ac_found > sbi->s_mb_max_to_scan &&
1584 !(ac->ac_flags & EXT4_MB_HINT_FIRST)) {
1585 ac->ac_status = AC_STATUS_BREAK;
1586 return;
1587 }
1588
1589 /*
1590 * Haven't found good chunk so far, let's continue
1591 */
1592 if (bex->fe_len < gex->fe_len)
1593 return;
1594
1595 if ((finish_group || ac->ac_found > sbi->s_mb_min_to_scan)
1596 && bex->fe_group == e4b->bd_group) {
1597 /* recheck chunk's availability - we don't know
1598 * when it was found (within this lock-unlock
1599 * period or not) */
1600 max = mb_find_extent(e4b, 0, bex->fe_start, gex->fe_len, &ex);
1601 if (max >= gex->fe_len) {
1602 ext4_mb_use_best_found(ac, e4b);
1603 return;
1604 }
1605 }
1606}
1607
1608/*
1609 * The routine checks whether found extent is good enough. If it is,
1610 * then the extent gets marked used and flag is set to the context
1611 * to stop scanning. Otherwise, the extent is compared with the
1612 * previous found extent and if new one is better, then it's stored
1613 * in the context. Later, the best found extent will be used, if
1614 * mballoc can't find good enough extent.
1615 *
1616 * FIXME: real allocation policy is to be designed yet!
1617 */
1618static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,
1619 struct ext4_free_extent *ex,
1620 struct ext4_buddy *e4b)
1621{
1622 struct ext4_free_extent *bex = &ac->ac_b_ex;
1623 struct ext4_free_extent *gex = &ac->ac_g_ex;
1624
1625 BUG_ON(ex->fe_len <= 0);
1626 BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
1627 BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
1628 BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);
1629
1630 ac->ac_found++;
1631
1632 /*
1633 * The special case - take what you catch first
1634 */
1635 if (unlikely(ac->ac_flags & EXT4_MB_HINT_FIRST)) {
1636 *bex = *ex;
1637 ext4_mb_use_best_found(ac, e4b);
1638 return;
1639 }
1640
1641 /*
1642 * Let's check whether the chuck is good enough
1643 */
1644 if (ex->fe_len == gex->fe_len) {
1645 *bex = *ex;
1646 ext4_mb_use_best_found(ac, e4b);
1647 return;
1648 }
1649
1650 /*
1651 * If this is first found extent, just store it in the context
1652 */
1653 if (bex->fe_len == 0) {
1654 *bex = *ex;
1655 return;
1656 }
1657
1658 /*
1659 * If new found extent is better, store it in the context
1660 */
1661 if (bex->fe_len < gex->fe_len) {
1662 /* if the request isn't satisfied, any found extent
1663 * larger than previous best one is better */
1664 if (ex->fe_len > bex->fe_len)
1665 *bex = *ex;
1666 } else if (ex->fe_len > gex->fe_len) {
1667 /* if the request is satisfied, then we try to find
1668 * an extent that still satisfy the request, but is
1669 * smaller than previous one */
1670 if (ex->fe_len < bex->fe_len)
1671 *bex = *ex;
1672 }
1673
1674 ext4_mb_check_limits(ac, e4b, 0);
1675}
1676
1677static int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
1678 struct ext4_buddy *e4b)
1679{
1680 struct ext4_free_extent ex = ac->ac_b_ex;
1681 ext4_group_t group = ex.fe_group;
1682 int max;
1683 int err;
1684
1685 BUG_ON(ex.fe_len <= 0);
1686 err = ext4_mb_load_buddy(ac->ac_sb, group, e4b);
1687 if (err)
1688 return err;
1689
1690 ext4_lock_group(ac->ac_sb, group);
1691 max = mb_find_extent(e4b, 0, ex.fe_start, ex.fe_len, &ex);
1692
1693 if (max > 0) {
1694 ac->ac_b_ex = ex;
1695 ext4_mb_use_best_found(ac, e4b);
1696 }
1697
1698 ext4_unlock_group(ac->ac_sb, group);
1699 ext4_mb_release_desc(e4b);
1700
1701 return 0;
1702}
1703
1704static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
1705 struct ext4_buddy *e4b)
1706{
1707 ext4_group_t group = ac->ac_g_ex.fe_group;
1708 int max;
1709 int err;
1710 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
1711 struct ext4_super_block *es = sbi->s_es;
1712 struct ext4_free_extent ex;
1713
1714 if (!(ac->ac_flags & EXT4_MB_HINT_TRY_GOAL))
1715 return 0;
1716
1717 err = ext4_mb_load_buddy(ac->ac_sb, group, e4b);
1718 if (err)
1719 return err;
1720
1721 ext4_lock_group(ac->ac_sb, group);
1722 max = mb_find_extent(e4b, 0, ac->ac_g_ex.fe_start,
1723 ac->ac_g_ex.fe_len, &ex);
1724
1725 if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
1726 ext4_fsblk_t start;
1727
1728 start = (e4b->bd_group * EXT4_BLOCKS_PER_GROUP(ac->ac_sb)) +
1729 ex.fe_start + le32_to_cpu(es->s_first_data_block);
1730 /* use do_div to get remainder (would be 64-bit modulo) */
1731 if (do_div(start, sbi->s_stripe) == 0) {
1732 ac->ac_found++;
1733 ac->ac_b_ex = ex;
1734 ext4_mb_use_best_found(ac, e4b);
1735 }
1736 } else if (max >= ac->ac_g_ex.fe_len) {
1737 BUG_ON(ex.fe_len <= 0);
1738 BUG_ON(ex.fe_group != ac->ac_g_ex.fe_group);
1739 BUG_ON(ex.fe_start != ac->ac_g_ex.fe_start);
1740 ac->ac_found++;
1741 ac->ac_b_ex = ex;
1742 ext4_mb_use_best_found(ac, e4b);
1743 } else if (max > 0 && (ac->ac_flags & EXT4_MB_HINT_MERGE)) {
1744 /* Sometimes, caller may want to merge even small
1745 * number of blocks to an existing extent */
1746 BUG_ON(ex.fe_len <= 0);
1747 BUG_ON(ex.fe_group != ac->ac_g_ex.fe_group);
1748 BUG_ON(ex.fe_start != ac->ac_g_ex.fe_start);
1749 ac->ac_found++;
1750 ac->ac_b_ex = ex;
1751 ext4_mb_use_best_found(ac, e4b);
1752 }
1753 ext4_unlock_group(ac->ac_sb, group);
1754 ext4_mb_release_desc(e4b);
1755
1756 return 0;
1757}
1758
1759/*
1760 * The routine scans buddy structures (not bitmap!) from given order
1761 * to max order and tries to find big enough chunk to satisfy the req
1762 */
1763static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
1764 struct ext4_buddy *e4b)
1765{
1766 struct super_block *sb = ac->ac_sb;
1767 struct ext4_group_info *grp = e4b->bd_info;
1768 void *buddy;
1769 int i;
1770 int k;
1771 int max;
1772
1773 BUG_ON(ac->ac_2order <= 0);
1774 for (i = ac->ac_2order; i <= sb->s_blocksize_bits + 1; i++) {
1775 if (grp->bb_counters[i] == 0)
1776 continue;
1777
1778 buddy = mb_find_buddy(e4b, i, &max);
1779 BUG_ON(buddy == NULL);
1780
1781 k = ext4_find_next_zero_bit(buddy, max, 0);
1782 BUG_ON(k >= max);
1783
1784 ac->ac_found++;
1785
1786 ac->ac_b_ex.fe_len = 1 << i;
1787 ac->ac_b_ex.fe_start = k << i;
1788 ac->ac_b_ex.fe_group = e4b->bd_group;
1789
1790 ext4_mb_use_best_found(ac, e4b);
1791
1792 BUG_ON(ac->ac_b_ex.fe_len != ac->ac_g_ex.fe_len);
1793
1794 if (EXT4_SB(sb)->s_mb_stats)
1795 atomic_inc(&EXT4_SB(sb)->s_bal_2orders);
1796
1797 break;
1798 }
1799}
1800
1801/*
1802 * The routine scans the group and measures all found extents.
1803 * In order to optimize scanning, caller must pass number of
1804 * free blocks in the group, so the routine can know upper limit.
1805 */
1806static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
1807 struct ext4_buddy *e4b)
1808{
1809 struct super_block *sb = ac->ac_sb;
1810 void *bitmap = EXT4_MB_BITMAP(e4b);
1811 struct ext4_free_extent ex;
1812 int i;
1813 int free;
1814
1815 free = e4b->bd_info->bb_free;
1816 BUG_ON(free <= 0);
1817
1818 i = e4b->bd_info->bb_first_free;
1819
1820 while (free && ac->ac_status == AC_STATUS_CONTINUE) {
1821 i = ext4_find_next_zero_bit(bitmap,
1822 EXT4_BLOCKS_PER_GROUP(sb), i);
1823 if (i >= EXT4_BLOCKS_PER_GROUP(sb)) {
1824 BUG_ON(free != 0);
1825 break;
1826 }
1827
1828 mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex);
1829 BUG_ON(ex.fe_len <= 0);
1830 BUG_ON(free < ex.fe_len);
1831
1832 ext4_mb_measure_extent(ac, &ex, e4b);
1833
1834 i += ex.fe_len;
1835 free -= ex.fe_len;
1836 }
1837
1838 ext4_mb_check_limits(ac, e4b, 1);
1839}
1840
1841/*
1842 * This is a special case for storages like raid5
1843 * we try to find stripe-aligned chunks for stripe-size requests
1844 * XXX should do so at least for multiples of stripe size as well
1845 */
1846static void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
1847 struct ext4_buddy *e4b)
1848{
1849 struct super_block *sb = ac->ac_sb;
1850 struct ext4_sb_info *sbi = EXT4_SB(sb);
1851 void *bitmap = EXT4_MB_BITMAP(e4b);
1852 struct ext4_free_extent ex;
1853 ext4_fsblk_t first_group_block;
1854 ext4_fsblk_t a;
1855 ext4_grpblk_t i;
1856 int max;
1857
1858 BUG_ON(sbi->s_stripe == 0);
1859
1860 /* find first stripe-aligned block in group */
1861 first_group_block = e4b->bd_group * EXT4_BLOCKS_PER_GROUP(sb)
1862 + le32_to_cpu(sbi->s_es->s_first_data_block);
1863 a = first_group_block + sbi->s_stripe - 1;
1864 do_div(a, sbi->s_stripe);
1865 i = (a * sbi->s_stripe) - first_group_block;
1866
1867 while (i < EXT4_BLOCKS_PER_GROUP(sb)) {
1868 if (!mb_test_bit(i, bitmap)) {
1869 max = mb_find_extent(e4b, 0, i, sbi->s_stripe, &ex);
1870 if (max >= sbi->s_stripe) {
1871 ac->ac_found++;
1872 ac->ac_b_ex = ex;
1873 ext4_mb_use_best_found(ac, e4b);
1874 break;
1875 }
1876 }
1877 i += sbi->s_stripe;
1878 }
1879}
1880
1881static int ext4_mb_good_group(struct ext4_allocation_context *ac,
1882 ext4_group_t group, int cr)
1883{
1884 unsigned free, fragments;
1885 unsigned i, bits;
1886 struct ext4_group_desc *desc;
1887 struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
1888
1889 BUG_ON(cr < 0 || cr >= 4);
1890 BUG_ON(EXT4_MB_GRP_NEED_INIT(grp));
1891
1892 free = grp->bb_free;
1893 fragments = grp->bb_fragments;
1894 if (free == 0)
1895 return 0;
1896 if (fragments == 0)
1897 return 0;
1898
1899 switch (cr) {
1900 case 0:
1901 BUG_ON(ac->ac_2order == 0);
1902 /* If this group is uninitialized, skip it initially */
1903 desc = ext4_get_group_desc(ac->ac_sb, group, NULL);
1904 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
1905 return 0;
1906
1907 bits = ac->ac_sb->s_blocksize_bits + 1;
1908 for (i = ac->ac_2order; i <= bits; i++)
1909 if (grp->bb_counters[i] > 0)
1910 return 1;
1911 break;
1912 case 1:
1913 if ((free / fragments) >= ac->ac_g_ex.fe_len)
1914 return 1;
1915 break;
1916 case 2:
1917 if (free >= ac->ac_g_ex.fe_len)
1918 return 1;
1919 break;
1920 case 3:
1921 return 1;
1922 default:
1923 BUG();
1924 }
1925
1926 return 0;
1927}
1928
1929static int ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
1930{
1931 ext4_group_t group;
1932 ext4_group_t i;
1933 int cr;
1934 int err = 0;
1935 int bsbits;
1936 struct ext4_sb_info *sbi;
1937 struct super_block *sb;
1938 struct ext4_buddy e4b;
1939 loff_t size, isize;
1940
1941 sb = ac->ac_sb;
1942 sbi = EXT4_SB(sb);
1943 BUG_ON(ac->ac_status == AC_STATUS_FOUND);
1944
1945 /* first, try the goal */
1946 err = ext4_mb_find_by_goal(ac, &e4b);
1947 if (err || ac->ac_status == AC_STATUS_FOUND)
1948 goto out;
1949
1950 if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
1951 goto out;
1952
1953 /*
1954 * ac->ac2_order is set only if the fe_len is a power of 2
1955 * if ac2_order is set we also set criteria to 0 so that we
1956 * try exact allocation using buddy.
1957 */
1958 i = fls(ac->ac_g_ex.fe_len);
1959 ac->ac_2order = 0;
1960 /*
1961 * We search using buddy data only if the order of the request
1962 * is greater than equal to the sbi_s_mb_order2_reqs
1963 * You can tune it via /proc/fs/ext4/<partition>/order2_req
1964 */
1965 if (i >= sbi->s_mb_order2_reqs) {
1966 /*
1967 * This should tell if fe_len is exactly power of 2
1968 */
1969 if ((ac->ac_g_ex.fe_len & (~(1 << (i - 1)))) == 0)
1970 ac->ac_2order = i - 1;
1971 }
1972
1973 bsbits = ac->ac_sb->s_blocksize_bits;
1974 /* if stream allocation is enabled, use global goal */
1975 size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
1976 isize = i_size_read(ac->ac_inode) >> bsbits;
1977 if (size < isize)
1978 size = isize;
1979
1980 if (size < sbi->s_mb_stream_request &&
1981 (ac->ac_flags & EXT4_MB_HINT_DATA)) {
1982 /* TBD: may be hot point */
1983 spin_lock(&sbi->s_md_lock);
1984 ac->ac_g_ex.fe_group = sbi->s_mb_last_group;
1985 ac->ac_g_ex.fe_start = sbi->s_mb_last_start;
1986 spin_unlock(&sbi->s_md_lock);
1987 }
1988
1989 /* searching for the right group start from the goal value specified */
1990 group = ac->ac_g_ex.fe_group;
1991
1992 /* Let's just scan groups to find more-less suitable blocks */
1993 cr = ac->ac_2order ? 0 : 1;
1994 /*
1995 * cr == 0 try to get exact allocation,
1996 * cr == 3 try to get anything
1997 */
1998repeat:
1999 for (; cr < 4 && ac->ac_status == AC_STATUS_CONTINUE; cr++) {
2000 ac->ac_criteria = cr;
2001 for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) {
2002 struct ext4_group_info *grp;
2003 struct ext4_group_desc *desc;
2004
2005 if (group == EXT4_SB(sb)->s_groups_count)
2006 group = 0;
2007
2008 /* quick check to skip empty groups */
2009 grp = ext4_get_group_info(ac->ac_sb, group);
2010 if (grp->bb_free == 0)
2011 continue;
2012
2013 /*
2014 * if the group is already init we check whether it is
2015 * a good group and if not we don't load the buddy
2016 */
2017 if (EXT4_MB_GRP_NEED_INIT(grp)) {
2018 /*
2019 * we need full data about the group
2020 * to make a good selection
2021 */
2022 err = ext4_mb_load_buddy(sb, group, &e4b);
2023 if (err)
2024 goto out;
2025 ext4_mb_release_desc(&e4b);
2026 }
2027
2028 /*
2029 * If the particular group doesn't satisfy our
2030 * criteria we continue with the next group
2031 */
2032 if (!ext4_mb_good_group(ac, group, cr))
2033 continue;
2034
2035 err = ext4_mb_load_buddy(sb, group, &e4b);
2036 if (err)
2037 goto out;
2038
2039 ext4_lock_group(sb, group);
2040 if (!ext4_mb_good_group(ac, group, cr)) {
2041 /* someone did allocation from this group */
2042 ext4_unlock_group(sb, group);
2043 ext4_mb_release_desc(&e4b);
2044 continue;
2045 }
2046
2047 ac->ac_groups_scanned++;
2048 desc = ext4_get_group_desc(sb, group, NULL);
2049 if (cr == 0 || (desc->bg_flags &
2050 cpu_to_le16(EXT4_BG_BLOCK_UNINIT) &&
2051 ac->ac_2order != 0))
2052 ext4_mb_simple_scan_group(ac, &e4b);
2053 else if (cr == 1 &&
2054 ac->ac_g_ex.fe_len == sbi->s_stripe)
2055 ext4_mb_scan_aligned(ac, &e4b);
2056 else
2057 ext4_mb_complex_scan_group(ac, &e4b);
2058
2059 ext4_unlock_group(sb, group);
2060 ext4_mb_release_desc(&e4b);
2061
2062 if (ac->ac_status != AC_STATUS_CONTINUE)
2063 break;
2064 }
2065 }
2066
2067 if (ac->ac_b_ex.fe_len > 0 && ac->ac_status != AC_STATUS_FOUND &&
2068 !(ac->ac_flags & EXT4_MB_HINT_FIRST)) {
2069 /*
2070 * We've been searching too long. Let's try to allocate
2071 * the best chunk we've found so far
2072 */
2073
2074 ext4_mb_try_best_found(ac, &e4b);
2075 if (ac->ac_status != AC_STATUS_FOUND) {
2076 /*
2077 * Someone more lucky has already allocated it.
2078 * The only thing we can do is just take first
2079 * found block(s)
2080 printk(KERN_DEBUG "EXT4-fs: someone won our chunk\n");
2081 */
2082 ac->ac_b_ex.fe_group = 0;
2083 ac->ac_b_ex.fe_start = 0;
2084 ac->ac_b_ex.fe_len = 0;
2085 ac->ac_status = AC_STATUS_CONTINUE;
2086 ac->ac_flags |= EXT4_MB_HINT_FIRST;
2087 cr = 3;
2088 atomic_inc(&sbi->s_mb_lost_chunks);
2089 goto repeat;
2090 }
2091 }
2092out:
2093 return err;
2094}
2095
2096#ifdef EXT4_MB_HISTORY
2097struct ext4_mb_proc_session {
2098 struct ext4_mb_history *history;
2099 struct super_block *sb;
2100 int start;
2101 int max;
2102};
2103
2104static void *ext4_mb_history_skip_empty(struct ext4_mb_proc_session *s,
2105 struct ext4_mb_history *hs,
2106 int first)
2107{
2108 if (hs == s->history + s->max)
2109 hs = s->history;
2110 if (!first && hs == s->history + s->start)
2111 return NULL;
2112 while (hs->orig.fe_len == 0) {
2113 hs++;
2114 if (hs == s->history + s->max)
2115 hs = s->history;
2116 if (hs == s->history + s->start)
2117 return NULL;
2118 }
2119 return hs;
2120}
2121
2122static void *ext4_mb_seq_history_start(struct seq_file *seq, loff_t *pos)
2123{
2124 struct ext4_mb_proc_session *s = seq->private;
2125 struct ext4_mb_history *hs;
2126 int l = *pos;
2127
2128 if (l == 0)
2129 return SEQ_START_TOKEN;
2130 hs = ext4_mb_history_skip_empty(s, s->history + s->start, 1);
2131 if (!hs)
2132 return NULL;
2133 while (--l && (hs = ext4_mb_history_skip_empty(s, ++hs, 0)) != NULL);
2134 return hs;
2135}
2136
2137static void *ext4_mb_seq_history_next(struct seq_file *seq, void *v,
2138 loff_t *pos)
2139{
2140 struct ext4_mb_proc_session *s = seq->private;
2141 struct ext4_mb_history *hs = v;
2142
2143 ++*pos;
2144 if (v == SEQ_START_TOKEN)
2145 return ext4_mb_history_skip_empty(s, s->history + s->start, 1);
2146 else
2147 return ext4_mb_history_skip_empty(s, ++hs, 0);
2148}
2149
2150static int ext4_mb_seq_history_show(struct seq_file *seq, void *v)
2151{
2152 char buf[25], buf2[25], buf3[25], *fmt;
2153 struct ext4_mb_history *hs = v;
2154
2155 if (v == SEQ_START_TOKEN) {
2156 seq_printf(seq, "%-5s %-8s %-23s %-23s %-23s %-5s "
2157 "%-5s %-2s %-5s %-5s %-5s %-6s\n",
2158 "pid", "inode", "original", "goal", "result", "found",
2159 "grps", "cr", "flags", "merge", "tail", "broken");
2160 return 0;
2161 }
2162
2163 if (hs->op == EXT4_MB_HISTORY_ALLOC) {
2164 fmt = "%-5u %-8u %-23s %-23s %-23s %-5u %-5u %-2u "
2165 "%-5u %-5s %-5u %-6u\n";
2166 sprintf(buf2, "%lu/%d/%u@%u", hs->result.fe_group,
2167 hs->result.fe_start, hs->result.fe_len,
2168 hs->result.fe_logical);
2169 sprintf(buf, "%lu/%d/%u@%u", hs->orig.fe_group,
2170 hs->orig.fe_start, hs->orig.fe_len,
2171 hs->orig.fe_logical);
2172 sprintf(buf3, "%lu/%d/%u@%u", hs->goal.fe_group,
2173 hs->goal.fe_start, hs->goal.fe_len,
2174 hs->goal.fe_logical);
2175 seq_printf(seq, fmt, hs->pid, hs->ino, buf, buf3, buf2,
2176 hs->found, hs->groups, hs->cr, hs->flags,
2177 hs->merged ? "M" : "", hs->tail,
2178 hs->buddy ? 1 << hs->buddy : 0);
2179 } else if (hs->op == EXT4_MB_HISTORY_PREALLOC) {
2180 fmt = "%-5u %-8u %-23s %-23s %-23s\n";
2181 sprintf(buf2, "%lu/%d/%u@%u", hs->result.fe_group,
2182 hs->result.fe_start, hs->result.fe_len,
2183 hs->result.fe_logical);
2184 sprintf(buf, "%lu/%d/%u@%u", hs->orig.fe_group,
2185 hs->orig.fe_start, hs->orig.fe_len,
2186 hs->orig.fe_logical);
2187 seq_printf(seq, fmt, hs->pid, hs->ino, buf, "", buf2);
2188 } else if (hs->op == EXT4_MB_HISTORY_DISCARD) {
2189 sprintf(buf2, "%lu/%d/%u", hs->result.fe_group,
2190 hs->result.fe_start, hs->result.fe_len);
2191 seq_printf(seq, "%-5u %-8u %-23s discard\n",
2192 hs->pid, hs->ino, buf2);
2193 } else if (hs->op == EXT4_MB_HISTORY_FREE) {
2194 sprintf(buf2, "%lu/%d/%u", hs->result.fe_group,
2195 hs->result.fe_start, hs->result.fe_len);
2196 seq_printf(seq, "%-5u %-8u %-23s free\n",
2197 hs->pid, hs->ino, buf2);
2198 }
2199 return 0;
2200}
2201
2202static void ext4_mb_seq_history_stop(struct seq_file *seq, void *v)
2203{
2204}
2205
2206static struct seq_operations ext4_mb_seq_history_ops = {
2207 .start = ext4_mb_seq_history_start,
2208 .next = ext4_mb_seq_history_next,
2209 .stop = ext4_mb_seq_history_stop,
2210 .show = ext4_mb_seq_history_show,
2211};
2212
2213static int ext4_mb_seq_history_open(struct inode *inode, struct file *file)
2214{
2215 struct super_block *sb = PDE(inode)->data;
2216 struct ext4_sb_info *sbi = EXT4_SB(sb);
2217 struct ext4_mb_proc_session *s;
2218 int rc;
2219 int size;
2220
2221 s = kmalloc(sizeof(*s), GFP_KERNEL);
2222 if (s == NULL)
2223 return -ENOMEM;
2224 s->sb = sb;
2225 size = sizeof(struct ext4_mb_history) * sbi->s_mb_history_max;
2226 s->history = kmalloc(size, GFP_KERNEL);
2227 if (s->history == NULL) {
2228 kfree(s);
2229 return -ENOMEM;
2230 }
2231
2232 spin_lock(&sbi->s_mb_history_lock);
2233 memcpy(s->history, sbi->s_mb_history, size);
2234 s->max = sbi->s_mb_history_max;
2235 s->start = sbi->s_mb_history_cur % s->max;
2236 spin_unlock(&sbi->s_mb_history_lock);
2237
2238 rc = seq_open(file, &ext4_mb_seq_history_ops);
2239 if (rc == 0) {
2240 struct seq_file *m = (struct seq_file *)file->private_data;
2241 m->private = s;
2242 } else {
2243 kfree(s->history);
2244 kfree(s);
2245 }
2246 return rc;
2247
2248}
2249
2250static int ext4_mb_seq_history_release(struct inode *inode, struct file *file)
2251{
2252 struct seq_file *seq = (struct seq_file *)file->private_data;
2253 struct ext4_mb_proc_session *s = seq->private;
2254 kfree(s->history);
2255 kfree(s);
2256 return seq_release(inode, file);
2257}
2258
2259static ssize_t ext4_mb_seq_history_write(struct file *file,
2260 const char __user *buffer,
2261 size_t count, loff_t *ppos)
2262{
2263 struct seq_file *seq = (struct seq_file *)file->private_data;
2264 struct ext4_mb_proc_session *s = seq->private;
2265 struct super_block *sb = s->sb;
2266 char str[32];
2267 int value;
2268
2269 if (count >= sizeof(str)) {
2270 printk(KERN_ERR "EXT4-fs: %s string too long, max %u bytes\n",
2271 "mb_history", (int)sizeof(str));
2272 return -EOVERFLOW;
2273 }
2274
2275 if (copy_from_user(str, buffer, count))
2276 return -EFAULT;
2277
2278 value = simple_strtol(str, NULL, 0);
2279 if (value < 0)
2280 return -ERANGE;
2281 EXT4_SB(sb)->s_mb_history_filter = value;
2282
2283 return count;
2284}
2285
2286static struct file_operations ext4_mb_seq_history_fops = {
2287 .owner = THIS_MODULE,
2288 .open = ext4_mb_seq_history_open,
2289 .read = seq_read,
2290 .write = ext4_mb_seq_history_write,
2291 .llseek = seq_lseek,
2292 .release = ext4_mb_seq_history_release,
2293};
2294
2295static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
2296{
2297 struct super_block *sb = seq->private;
2298 struct ext4_sb_info *sbi = EXT4_SB(sb);
2299 ext4_group_t group;
2300
2301 if (*pos < 0 || *pos >= sbi->s_groups_count)
2302 return NULL;
2303
2304 group = *pos + 1;
2305 return (void *) group;
2306}
2307
2308static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos)
2309{
2310 struct super_block *sb = seq->private;
2311 struct ext4_sb_info *sbi = EXT4_SB(sb);
2312 ext4_group_t group;
2313
2314 ++*pos;
2315 if (*pos < 0 || *pos >= sbi->s_groups_count)
2316 return NULL;
2317 group = *pos + 1;
2318 return (void *) group;;
2319}
2320
2321static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
2322{
2323 struct super_block *sb = seq->private;
2324 long group = (long) v;
2325 int i;
2326 int err;
2327 struct ext4_buddy e4b;
2328 struct sg {
2329 struct ext4_group_info info;
2330 unsigned short counters[16];
2331 } sg;
2332
2333 group--;
2334 if (group == 0)
2335 seq_printf(seq, "#%-5s: %-5s %-5s %-5s "
2336 "[ %-5s %-5s %-5s %-5s %-5s %-5s %-5s "
2337 "%-5s %-5s %-5s %-5s %-5s %-5s %-5s ]\n",
2338 "group", "free", "frags", "first",
2339 "2^0", "2^1", "2^2", "2^3", "2^4", "2^5", "2^6",
2340 "2^7", "2^8", "2^9", "2^10", "2^11", "2^12", "2^13");
2341
2342 i = (sb->s_blocksize_bits + 2) * sizeof(sg.info.bb_counters[0]) +
2343 sizeof(struct ext4_group_info);
2344 err = ext4_mb_load_buddy(sb, group, &e4b);
2345 if (err) {
2346 seq_printf(seq, "#%-5lu: I/O error\n", group);
2347 return 0;
2348 }
2349 ext4_lock_group(sb, group);
2350 memcpy(&sg, ext4_get_group_info(sb, group), i);
2351 ext4_unlock_group(sb, group);
2352 ext4_mb_release_desc(&e4b);
2353
2354 seq_printf(seq, "#%-5lu: %-5u %-5u %-5u [", group, sg.info.bb_free,
2355 sg.info.bb_fragments, sg.info.bb_first_free);
2356 for (i = 0; i <= 13; i++)
2357 seq_printf(seq, " %-5u", i <= sb->s_blocksize_bits + 1 ?
2358 sg.info.bb_counters[i] : 0);
2359 seq_printf(seq, " ]\n");
2360
2361 return 0;
2362}
2363
2364static void ext4_mb_seq_groups_stop(struct seq_file *seq, void *v)
2365{
2366}
2367
2368static struct seq_operations ext4_mb_seq_groups_ops = {
2369 .start = ext4_mb_seq_groups_start,
2370 .next = ext4_mb_seq_groups_next,
2371 .stop = ext4_mb_seq_groups_stop,
2372 .show = ext4_mb_seq_groups_show,
2373};
2374
2375static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
2376{
2377 struct super_block *sb = PDE(inode)->data;
2378 int rc;
2379
2380 rc = seq_open(file, &ext4_mb_seq_groups_ops);
2381 if (rc == 0) {
2382 struct seq_file *m = (struct seq_file *)file->private_data;
2383 m->private = sb;
2384 }
2385 return rc;
2386
2387}
2388
2389static struct file_operations ext4_mb_seq_groups_fops = {
2390 .owner = THIS_MODULE,
2391 .open = ext4_mb_seq_groups_open,
2392 .read = seq_read,
2393 .llseek = seq_lseek,
2394 .release = seq_release,
2395};
2396
2397static void ext4_mb_history_release(struct super_block *sb)
2398{
2399 struct ext4_sb_info *sbi = EXT4_SB(sb);
2400
2401 remove_proc_entry("mb_groups", sbi->s_mb_proc);
2402 remove_proc_entry("mb_history", sbi->s_mb_proc);
2403
2404 kfree(sbi->s_mb_history);
2405}
2406
2407static void ext4_mb_history_init(struct super_block *sb)
2408{
2409 struct ext4_sb_info *sbi = EXT4_SB(sb);
2410 int i;
2411
2412 if (sbi->s_mb_proc != NULL) {
2413 struct proc_dir_entry *p;
2414 p = create_proc_entry("mb_history", S_IRUGO, sbi->s_mb_proc);
2415 if (p) {
2416 p->proc_fops = &ext4_mb_seq_history_fops;
2417 p->data = sb;
2418 }
2419 p = create_proc_entry("mb_groups", S_IRUGO, sbi->s_mb_proc);
2420 if (p) {
2421 p->proc_fops = &ext4_mb_seq_groups_fops;
2422 p->data = sb;
2423 }
2424 }
2425
2426 sbi->s_mb_history_max = 1000;
2427 sbi->s_mb_history_cur = 0;
2428 spin_lock_init(&sbi->s_mb_history_lock);
2429 i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history);
2430 sbi->s_mb_history = kmalloc(i, GFP_KERNEL);
2431 if (likely(sbi->s_mb_history != NULL))
2432 memset(sbi->s_mb_history, 0, i);
2433 /* if we can't allocate history, then we simple won't use it */
2434}
2435
2436static void ext4_mb_store_history(struct ext4_allocation_context *ac)
2437{
2438 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
2439 struct ext4_mb_history h;
2440
2441 if (unlikely(sbi->s_mb_history == NULL))
2442 return;
2443
2444 if (!(ac->ac_op & sbi->s_mb_history_filter))
2445 return;
2446
2447 h.op = ac->ac_op;
2448 h.pid = current->pid;
2449 h.ino = ac->ac_inode ? ac->ac_inode->i_ino : 0;
2450 h.orig = ac->ac_o_ex;
2451 h.result = ac->ac_b_ex;
2452 h.flags = ac->ac_flags;
2453 h.found = ac->ac_found;
2454 h.groups = ac->ac_groups_scanned;
2455 h.cr = ac->ac_criteria;
2456 h.tail = ac->ac_tail;
2457 h.buddy = ac->ac_buddy;
2458 h.merged = 0;
2459 if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) {
2460 if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
2461 ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
2462 h.merged = 1;
2463 h.goal = ac->ac_g_ex;
2464 h.result = ac->ac_f_ex;
2465 }
2466
2467 spin_lock(&sbi->s_mb_history_lock);
2468 memcpy(sbi->s_mb_history + sbi->s_mb_history_cur, &h, sizeof(h));
2469 if (++sbi->s_mb_history_cur >= sbi->s_mb_history_max)
2470 sbi->s_mb_history_cur = 0;
2471 spin_unlock(&sbi->s_mb_history_lock);
2472}
2473
2474#else
2475#define ext4_mb_history_release(sb)
2476#define ext4_mb_history_init(sb)
2477#endif
2478
2479static int ext4_mb_init_backend(struct super_block *sb)
2480{
2481 ext4_group_t i;
2482 int j, len, metalen;
2483 struct ext4_sb_info *sbi = EXT4_SB(sb);
2484 int num_meta_group_infos =
2485 (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) >>
2486 EXT4_DESC_PER_BLOCK_BITS(sb);
2487 struct ext4_group_info **meta_group_info;
2488
2489 /* An 8TB filesystem with 64-bit pointers requires a 4096 byte
2490 * kmalloc. A 128kb malloc should suffice for a 256TB filesystem.
2491 * So a two level scheme suffices for now. */
2492 sbi->s_group_info = kmalloc(sizeof(*sbi->s_group_info) *
2493 num_meta_group_infos, GFP_KERNEL);
2494 if (sbi->s_group_info == NULL) {
2495 printk(KERN_ERR "EXT4-fs: can't allocate buddy meta group\n");
2496 return -ENOMEM;
2497 }
2498 sbi->s_buddy_cache = new_inode(sb);
2499 if (sbi->s_buddy_cache == NULL) {
2500 printk(KERN_ERR "EXT4-fs: can't get new inode\n");
2501 goto err_freesgi;
2502 }
2503 EXT4_I(sbi->s_buddy_cache)->i_disksize = 0;
2504
2505 metalen = sizeof(*meta_group_info) << EXT4_DESC_PER_BLOCK_BITS(sb);
2506 for (i = 0; i < num_meta_group_infos; i++) {
2507 if ((i + 1) == num_meta_group_infos)
2508 metalen = sizeof(*meta_group_info) *
2509 (sbi->s_groups_count -
2510 (i << EXT4_DESC_PER_BLOCK_BITS(sb)));
2511 meta_group_info = kmalloc(metalen, GFP_KERNEL);
2512 if (meta_group_info == NULL) {
2513 printk(KERN_ERR "EXT4-fs: can't allocate mem for a "
2514 "buddy group\n");
2515 goto err_freemeta;
2516 }
2517 sbi->s_group_info[i] = meta_group_info;
2518 }
2519
2520 /*
2521 * calculate needed size. if change bb_counters size,
2522 * don't forget about ext4_mb_generate_buddy()
2523 */
2524 len = sizeof(struct ext4_group_info);
2525 len += sizeof(unsigned short) * (sb->s_blocksize_bits + 2);
2526 for (i = 0; i < sbi->s_groups_count; i++) {
2527 struct ext4_group_desc *desc;
2528
2529 meta_group_info =
2530 sbi->s_group_info[i >> EXT4_DESC_PER_BLOCK_BITS(sb)];
2531 j = i & (EXT4_DESC_PER_BLOCK(sb) - 1);
2532
2533 meta_group_info[j] = kzalloc(len, GFP_KERNEL);
2534 if (meta_group_info[j] == NULL) {
2535 printk(KERN_ERR "EXT4-fs: can't allocate buddy mem\n");
2536 i--;
2537 goto err_freebuddy;
2538 }
2539 desc = ext4_get_group_desc(sb, i, NULL);
2540 if (desc == NULL) {
2541 printk(KERN_ERR
2542 "EXT4-fs: can't read descriptor %lu\n", i);
2543 goto err_freebuddy;
2544 }
2545 memset(meta_group_info[j], 0, len);
2546 set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT,
2547 &(meta_group_info[j]->bb_state));
2548
2549 /*
2550 * initialize bb_free to be able to skip
2551 * empty groups without initialization
2552 */
2553 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
2554 meta_group_info[j]->bb_free =
2555 ext4_free_blocks_after_init(sb, i, desc);
2556 } else {
2557 meta_group_info[j]->bb_free =
2558 le16_to_cpu(desc->bg_free_blocks_count);
2559 }
2560
2561 INIT_LIST_HEAD(&meta_group_info[j]->bb_prealloc_list);
2562
2563#ifdef DOUBLE_CHECK
2564 {
2565 struct buffer_head *bh;
2566 meta_group_info[j]->bb_bitmap =
2567 kmalloc(sb->s_blocksize, GFP_KERNEL);
2568 BUG_ON(meta_group_info[j]->bb_bitmap == NULL);
2569 bh = read_block_bitmap(sb, i);
2570 BUG_ON(bh == NULL);
2571 memcpy(meta_group_info[j]->bb_bitmap, bh->b_data,
2572 sb->s_blocksize);
2573 put_bh(bh);
2574 }
2575#endif
2576
2577 }
2578
2579 return 0;
2580
2581err_freebuddy:
2582 while (i >= 0) {
2583 kfree(ext4_get_group_info(sb, i));
2584 i--;
2585 }
2586 i = num_meta_group_infos;
2587err_freemeta:
2588 while (--i >= 0)
2589 kfree(sbi->s_group_info[i]);
2590 iput(sbi->s_buddy_cache);
2591err_freesgi:
2592 kfree(sbi->s_group_info);
2593 return -ENOMEM;
2594}
2595
2596int ext4_mb_init(struct super_block *sb, int needs_recovery)
2597{
2598 struct ext4_sb_info *sbi = EXT4_SB(sb);
2599 unsigned i;
2600 unsigned offset;
2601 unsigned max;
2602
2603 if (!test_opt(sb, MBALLOC))
2604 return 0;
2605
2606 i = (sb->s_blocksize_bits + 2) * sizeof(unsigned short);
2607
2608 sbi->s_mb_offsets = kmalloc(i, GFP_KERNEL);
2609 if (sbi->s_mb_offsets == NULL) {
2610 clear_opt(sbi->s_mount_opt, MBALLOC);
2611 return -ENOMEM;
2612 }
2613 sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL);
2614 if (sbi->s_mb_maxs == NULL) {
2615 clear_opt(sbi->s_mount_opt, MBALLOC);
2616 kfree(sbi->s_mb_maxs);
2617 return -ENOMEM;
2618 }
2619
2620 /* order 0 is regular bitmap */
2621 sbi->s_mb_maxs[0] = sb->s_blocksize << 3;
2622 sbi->s_mb_offsets[0] = 0;
2623
2624 i = 1;
2625 offset = 0;
2626 max = sb->s_blocksize << 2;
2627 do {
2628 sbi->s_mb_offsets[i] = offset;
2629 sbi->s_mb_maxs[i] = max;
2630 offset += 1 << (sb->s_blocksize_bits - i);
2631 max = max >> 1;
2632 i++;
2633 } while (i <= sb->s_blocksize_bits + 1);
2634
2635 /* init file for buddy data */
2636 i = ext4_mb_init_backend(sb);
2637 if (i) {
2638 clear_opt(sbi->s_mount_opt, MBALLOC);
2639 kfree(sbi->s_mb_offsets);
2640 kfree(sbi->s_mb_maxs);
2641 return i;
2642 }
2643
2644 spin_lock_init(&sbi->s_md_lock);
2645 INIT_LIST_HEAD(&sbi->s_active_transaction);
2646 INIT_LIST_HEAD(&sbi->s_closed_transaction);
2647 INIT_LIST_HEAD(&sbi->s_committed_transaction);
2648 spin_lock_init(&sbi->s_bal_lock);
2649
2650 sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN;
2651 sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN;
2652 sbi->s_mb_stats = MB_DEFAULT_STATS;
2653 sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD;
2654 sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS;
2655 sbi->s_mb_history_filter = EXT4_MB_HISTORY_DEFAULT;
2656 sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC;
2657
2658 i = sizeof(struct ext4_locality_group) * NR_CPUS;
2659 sbi->s_locality_groups = kmalloc(i, GFP_KERNEL);
2660 if (sbi->s_locality_groups == NULL) {
2661 clear_opt(sbi->s_mount_opt, MBALLOC);
2662 kfree(sbi->s_mb_offsets);
2663 kfree(sbi->s_mb_maxs);
2664 return -ENOMEM;
2665 }
2666 for (i = 0; i < NR_CPUS; i++) {
2667 struct ext4_locality_group *lg;
2668 lg = &sbi->s_locality_groups[i];
2669 mutex_init(&lg->lg_mutex);
2670 INIT_LIST_HEAD(&lg->lg_prealloc_list);
2671 spin_lock_init(&lg->lg_prealloc_lock);
2672 }
2673
2674 ext4_mb_init_per_dev_proc(sb);
2675 ext4_mb_history_init(sb);
2676
2677 printk("EXT4-fs: mballoc enabled\n");
2678 return 0;
2679}
2680
2681/* need to called with ext4 group lock (ext4_lock_group) */
2682static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
2683{
2684 struct ext4_prealloc_space *pa;
2685 struct list_head *cur, *tmp;
2686 int count = 0;
2687
2688 list_for_each_safe(cur, tmp, &grp->bb_prealloc_list) {
2689 pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list);
2690 list_del(&pa->pa_group_list);
2691 count++;
2692 kfree(pa);
2693 }
2694 if (count)
2695 mb_debug("mballoc: %u PAs left\n", count);
2696
2697}
2698
2699int ext4_mb_release(struct super_block *sb)
2700{
2701 ext4_group_t i;
2702 int num_meta_group_infos;
2703 struct ext4_group_info *grinfo;
2704 struct ext4_sb_info *sbi = EXT4_SB(sb);
2705
2706 if (!test_opt(sb, MBALLOC))
2707 return 0;
2708
2709 /* release freed, non-committed blocks */
2710 spin_lock(&sbi->s_md_lock);
2711 list_splice_init(&sbi->s_closed_transaction,
2712 &sbi->s_committed_transaction);
2713 list_splice_init(&sbi->s_active_transaction,
2714 &sbi->s_committed_transaction);
2715 spin_unlock(&sbi->s_md_lock);
2716 ext4_mb_free_committed_blocks(sb);
2717
2718 if (sbi->s_group_info) {
2719 for (i = 0; i < sbi->s_groups_count; i++) {
2720 grinfo = ext4_get_group_info(sb, i);
2721#ifdef DOUBLE_CHECK
2722 kfree(grinfo->bb_bitmap);
2723#endif
2724 ext4_lock_group(sb, i);
2725 ext4_mb_cleanup_pa(grinfo);
2726 ext4_unlock_group(sb, i);
2727 kfree(grinfo);
2728 }
2729 num_meta_group_infos = (sbi->s_groups_count +
2730 EXT4_DESC_PER_BLOCK(sb) - 1) >>
2731 EXT4_DESC_PER_BLOCK_BITS(sb);
2732 for (i = 0; i < num_meta_group_infos; i++)
2733 kfree(sbi->s_group_info[i]);
2734 kfree(sbi->s_group_info);
2735 }
2736 kfree(sbi->s_mb_offsets);
2737 kfree(sbi->s_mb_maxs);
2738 if (sbi->s_buddy_cache)
2739 iput(sbi->s_buddy_cache);
2740 if (sbi->s_mb_stats) {
2741 printk(KERN_INFO
2742 "EXT4-fs: mballoc: %u blocks %u reqs (%u success)\n",
2743 atomic_read(&sbi->s_bal_allocated),
2744 atomic_read(&sbi->s_bal_reqs),
2745 atomic_read(&sbi->s_bal_success));
2746 printk(KERN_INFO
2747 "EXT4-fs: mballoc: %u extents scanned, %u goal hits, "
2748 "%u 2^N hits, %u breaks, %u lost\n",
2749 atomic_read(&sbi->s_bal_ex_scanned),
2750 atomic_read(&sbi->s_bal_goals),
2751 atomic_read(&sbi->s_bal_2orders),
2752 atomic_read(&sbi->s_bal_breaks),
2753 atomic_read(&sbi->s_mb_lost_chunks));
2754 printk(KERN_INFO
2755 "EXT4-fs: mballoc: %lu generated and it took %Lu\n",
2756 sbi->s_mb_buddies_generated++,
2757 sbi->s_mb_generation_time);
2758 printk(KERN_INFO
2759 "EXT4-fs: mballoc: %u preallocated, %u discarded\n",
2760 atomic_read(&sbi->s_mb_preallocated),
2761 atomic_read(&sbi->s_mb_discarded));
2762 }
2763
2764 kfree(sbi->s_locality_groups);
2765
2766 ext4_mb_history_release(sb);
2767 ext4_mb_destroy_per_dev_proc(sb);
2768
2769 return 0;
2770}
2771
2772static void ext4_mb_free_committed_blocks(struct super_block *sb)
2773{
2774 struct ext4_sb_info *sbi = EXT4_SB(sb);
2775 int err;
2776 int i;
2777 int count = 0;
2778 int count2 = 0;
2779 struct ext4_free_metadata *md;
2780 struct ext4_buddy e4b;
2781
2782 if (list_empty(&sbi->s_committed_transaction))
2783 return;
2784
2785 /* there is committed blocks to be freed yet */
2786 do {
2787 /* get next array of blocks */
2788 md = NULL;
2789 spin_lock(&sbi->s_md_lock);
2790 if (!list_empty(&sbi->s_committed_transaction)) {
2791 md = list_entry(sbi->s_committed_transaction.next,
2792 struct ext4_free_metadata, list);
2793 list_del(&md->list);
2794 }
2795 spin_unlock(&sbi->s_md_lock);
2796
2797 if (md == NULL)
2798 break;
2799
2800 mb_debug("gonna free %u blocks in group %lu (0x%p):",
2801 md->num, md->group, md);
2802
2803 err = ext4_mb_load_buddy(sb, md->group, &e4b);
2804 /* we expect to find existing buddy because it's pinned */
2805 BUG_ON(err != 0);
2806
2807 /* there are blocks to put in buddy to make them really free */
2808 count += md->num;
2809 count2++;
2810 ext4_lock_group(sb, md->group);
2811 for (i = 0; i < md->num; i++) {
2812 mb_debug(" %u", md->blocks[i]);
2813 err = mb_free_blocks(NULL, &e4b, md->blocks[i], 1);
2814 BUG_ON(err != 0);
2815 }
2816 mb_debug("\n");
2817 ext4_unlock_group(sb, md->group);
2818
2819 /* balance refcounts from ext4_mb_free_metadata() */
2820 page_cache_release(e4b.bd_buddy_page);
2821 page_cache_release(e4b.bd_bitmap_page);
2822
2823 kfree(md);
2824 ext4_mb_release_desc(&e4b);
2825
2826 } while (md);
2827
2828 mb_debug("freed %u blocks in %u structures\n", count, count2);
2829}
2830
2831#define EXT4_ROOT "ext4"
2832#define EXT4_MB_STATS_NAME "stats"
2833#define EXT4_MB_MAX_TO_SCAN_NAME "max_to_scan"
2834#define EXT4_MB_MIN_TO_SCAN_NAME "min_to_scan"
2835#define EXT4_MB_ORDER2_REQ "order2_req"
2836#define EXT4_MB_STREAM_REQ "stream_req"
2837#define EXT4_MB_GROUP_PREALLOC "group_prealloc"
2838
2839
2840
2841#define MB_PROC_VALUE_READ(name) \
2842static int ext4_mb_read_##name(char *page, char **start, \
2843 off_t off, int count, int *eof, void *data) \
2844{ \
2845 struct ext4_sb_info *sbi = data; \
2846 int len; \
2847 *eof = 1; \
2848 if (off != 0) \
2849 return 0; \
2850 len = sprintf(page, "%ld\n", sbi->s_mb_##name); \
2851 *start = page; \
2852 return len; \
2853}
2854
2855#define MB_PROC_VALUE_WRITE(name) \
2856static int ext4_mb_write_##name(struct file *file, \
2857 const char __user *buf, unsigned long cnt, void *data) \
2858{ \
2859 struct ext4_sb_info *sbi = data; \
2860 char str[32]; \
2861 long value; \
2862 if (cnt >= sizeof(str)) \
2863 return -EINVAL; \
2864 if (copy_from_user(str, buf, cnt)) \
2865 return -EFAULT; \
2866 value = simple_strtol(str, NULL, 0); \
2867 if (value <= 0) \
2868 return -ERANGE; \
2869 sbi->s_mb_##name = value; \
2870 return cnt; \
2871}
2872
2873MB_PROC_VALUE_READ(stats);
2874MB_PROC_VALUE_WRITE(stats);
2875MB_PROC_VALUE_READ(max_to_scan);
2876MB_PROC_VALUE_WRITE(max_to_scan);
2877MB_PROC_VALUE_READ(min_to_scan);
2878MB_PROC_VALUE_WRITE(min_to_scan);
2879MB_PROC_VALUE_READ(order2_reqs);
2880MB_PROC_VALUE_WRITE(order2_reqs);
2881MB_PROC_VALUE_READ(stream_request);
2882MB_PROC_VALUE_WRITE(stream_request);
2883MB_PROC_VALUE_READ(group_prealloc);
2884MB_PROC_VALUE_WRITE(group_prealloc);
2885
2886#define MB_PROC_HANDLER(name, var) \
2887do { \
2888 proc = create_proc_entry(name, mode, sbi->s_mb_proc); \
2889 if (proc == NULL) { \
2890 printk(KERN_ERR "EXT4-fs: can't to create %s\n", name); \
2891 goto err_out; \
2892 } \
2893 proc->data = sbi; \
2894 proc->read_proc = ext4_mb_read_##var ; \
2895 proc->write_proc = ext4_mb_write_##var; \
2896} while (0)
2897
2898static int ext4_mb_init_per_dev_proc(struct super_block *sb)
2899{
2900 mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
2901 struct ext4_sb_info *sbi = EXT4_SB(sb);
2902 struct proc_dir_entry *proc;
2903 char devname[64];
2904
2905 snprintf(devname, sizeof(devname) - 1, "%s",
2906 bdevname(sb->s_bdev, devname));
2907 sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4);
2908
2909 MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats);
2910 MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan);
2911 MB_PROC_HANDLER(EXT4_MB_MIN_TO_SCAN_NAME, min_to_scan);
2912 MB_PROC_HANDLER(EXT4_MB_ORDER2_REQ, order2_reqs);
2913 MB_PROC_HANDLER(EXT4_MB_STREAM_REQ, stream_request);
2914 MB_PROC_HANDLER(EXT4_MB_GROUP_PREALLOC, group_prealloc);
2915
2916 return 0;
2917
2918err_out:
2919 printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname);
2920 remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
2921 remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
2922 remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
2923 remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
2924 remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
2925 remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
2926 remove_proc_entry(devname, proc_root_ext4);
2927 sbi->s_mb_proc = NULL;
2928
2929 return -ENOMEM;
2930}
2931
2932static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
2933{
2934 struct ext4_sb_info *sbi = EXT4_SB(sb);
2935 char devname[64];
2936
2937 if (sbi->s_mb_proc == NULL)
2938 return -EINVAL;
2939
2940 snprintf(devname, sizeof(devname) - 1, "%s",
2941 bdevname(sb->s_bdev, devname));
2942 remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc);
2943 remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc);
2944 remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc);
2945 remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
2946 remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
2947 remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
2948 remove_proc_entry(devname, proc_root_ext4);
2949
2950 return 0;
2951}
2952
2953int __init init_ext4_mballoc(void)
2954{
2955 ext4_pspace_cachep =
2956 kmem_cache_create("ext4_prealloc_space",
2957 sizeof(struct ext4_prealloc_space),
2958 0, SLAB_RECLAIM_ACCOUNT, NULL);
2959 if (ext4_pspace_cachep == NULL)
2960 return -ENOMEM;
2961
2962#ifdef CONFIG_PROC_FS
2963 proc_root_ext4 = proc_mkdir(EXT4_ROOT, proc_root_fs);
2964 if (proc_root_ext4 == NULL)
2965 printk(KERN_ERR "EXT4-fs: Unable to create %s\n", EXT4_ROOT);
2966#endif
2967
2968 return 0;
2969}
2970
2971void exit_ext4_mballoc(void)
2972{
2973 /* XXX: synchronize_rcu(); */
2974 kmem_cache_destroy(ext4_pspace_cachep);
2975#ifdef CONFIG_PROC_FS
2976 remove_proc_entry(EXT4_ROOT, proc_root_fs);
2977#endif
2978}
2979
2980
2981/*
2982 * Check quota and mark choosed space (ac->ac_b_ex) non-free in bitmaps
2983 * Returns 0 if success or error code
2984 */
2985static int ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2986 handle_t *handle)
2987{
2988 struct buffer_head *bitmap_bh = NULL;
2989 struct ext4_super_block *es;
2990 struct ext4_group_desc *gdp;
2991 struct buffer_head *gdp_bh;
2992 struct ext4_sb_info *sbi;
2993 struct super_block *sb;
2994 ext4_fsblk_t block;
2995 int err;
2996
2997 BUG_ON(ac->ac_status != AC_STATUS_FOUND);
2998 BUG_ON(ac->ac_b_ex.fe_len <= 0);
2999
3000 sb = ac->ac_sb;
3001 sbi = EXT4_SB(sb);
3002 es = sbi->s_es;
3003
3004 ext4_debug("using block group %lu(%d)\n", ac->ac_b_ex.fe_group,
3005 gdp->bg_free_blocks_count);
3006
3007 err = -EIO;
3008 bitmap_bh = read_block_bitmap(sb, ac->ac_b_ex.fe_group);
3009 if (!bitmap_bh)
3010 goto out_err;
3011
3012 err = ext4_journal_get_write_access(handle, bitmap_bh);
3013 if (err)
3014 goto out_err;
3015
3016 err = -EIO;
3017 gdp = ext4_get_group_desc(sb, ac->ac_b_ex.fe_group, &gdp_bh);
3018 if (!gdp)
3019 goto out_err;
3020
3021 err = ext4_journal_get_write_access(handle, gdp_bh);
3022 if (err)
3023 goto out_err;
3024
3025 block = ac->ac_b_ex.fe_group * EXT4_BLOCKS_PER_GROUP(sb)
3026 + ac->ac_b_ex.fe_start
3027 + le32_to_cpu(es->s_first_data_block);
3028
3029 if (block == ext4_block_bitmap(sb, gdp) ||
3030 block == ext4_inode_bitmap(sb, gdp) ||
3031 in_range(block, ext4_inode_table(sb, gdp),
3032 EXT4_SB(sb)->s_itb_per_group)) {
3033
3034 ext4_error(sb, __FUNCTION__,
3035 "Allocating block in system zone - block = %llu",
3036 block);
3037 }
3038#ifdef AGGRESSIVE_CHECK
3039 {
3040 int i;
3041 for (i = 0; i < ac->ac_b_ex.fe_len; i++) {
3042 BUG_ON(mb_test_bit(ac->ac_b_ex.fe_start + i,
3043 bitmap_bh->b_data));
3044 }
3045 }
3046#endif
3047 mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data,
3048 ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
3049
3050 spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
3051 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
3052 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
3053 gdp->bg_free_blocks_count =
3054 cpu_to_le16(ext4_free_blocks_after_init(sb,
3055 ac->ac_b_ex.fe_group,
3056 gdp));
3057 }
3058 gdp->bg_free_blocks_count =
3059 cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)
3060 - ac->ac_b_ex.fe_len);
3061 gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
3062 spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
3063 percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
3064
3065 err = ext4_journal_dirty_metadata(handle, bitmap_bh);
3066 if (err)
3067 goto out_err;
3068 err = ext4_journal_dirty_metadata(handle, gdp_bh);
3069
3070out_err:
3071 sb->s_dirt = 1;
3072 put_bh(bitmap_bh);
3073 return err;
3074}
3075
3076/*
3077 * here we normalize request for locality group
3078 * Group request are normalized to s_strip size if we set the same via mount
3079 * option. If not we set it to s_mb_group_prealloc which can be configured via
3080 * /proc/fs/ext4/<partition>/group_prealloc
3081 *
3082 * XXX: should we try to preallocate more than the group has now?
3083 */
3084static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac)
3085{
3086 struct super_block *sb = ac->ac_sb;
3087 struct ext4_locality_group *lg = ac->ac_lg;
3088
3089 BUG_ON(lg == NULL);
3090 if (EXT4_SB(sb)->s_stripe)
3091 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_stripe;
3092 else
3093 ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_mb_group_prealloc;
3094 mb_debug("#%u: goal %lu blocks for locality group\n",
3095 current->pid, ac->ac_g_ex.fe_len);
3096}
3097
3098/*
3099 * Normalization means making request better in terms of
3100 * size and alignment
3101 */
3102static void ext4_mb_normalize_request(struct ext4_allocation_context *ac,
3103 struct ext4_allocation_request *ar)
3104{
3105 int bsbits, max;
3106 ext4_lblk_t end;
3107 struct list_head *cur;
3108 loff_t size, orig_size, start_off;
3109 ext4_lblk_t start, orig_start;
3110 struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
3111
3112 /* do normalize only data requests, metadata requests
3113 do not need preallocation */
3114 if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
3115 return;
3116
3117 /* sometime caller may want exact blocks */
3118 if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
3119 return;
3120
3121 /* caller may indicate that preallocation isn't
3122 * required (it's a tail, for example) */
3123 if (ac->ac_flags & EXT4_MB_HINT_NOPREALLOC)
3124 return;
3125
3126 if (ac->ac_flags & EXT4_MB_HINT_GROUP_ALLOC) {
3127 ext4_mb_normalize_group_request(ac);
3128 return ;
3129 }
3130
3131 bsbits = ac->ac_sb->s_blocksize_bits;
3132
3133 /* first, let's learn actual file size
3134 * given current request is allocated */
3135 size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
3136 size = size << bsbits;
3137 if (size < i_size_read(ac->ac_inode))
3138 size = i_size_read(ac->ac_inode);
3139
3140 /* max available blocks in a free group */
3141 max = EXT4_BLOCKS_PER_GROUP(ac->ac_sb) - 1 - 1 -
3142 EXT4_SB(ac->ac_sb)->s_itb_per_group;
3143
3144#define NRL_CHECK_SIZE(req, size, max,bits) \
3145 (req <= (size) || max <= ((size) >> bits))
3146
3147 /* first, try to predict filesize */
3148 /* XXX: should this table be tunable? */
3149 start_off = 0;
3150 if (size <= 16 * 1024) {
3151 size = 16 * 1024;
3152 } else if (size <= 32 * 1024) {
3153 size = 32 * 1024;
3154 } else if (size <= 64 * 1024) {
3155 size = 64 * 1024;
3156 } else if (size <= 128 * 1024) {
3157 size = 128 * 1024;
3158 } else if (size <= 256 * 1024) {
3159 size = 256 * 1024;
3160 } else if (size <= 512 * 1024) {
3161 size = 512 * 1024;
3162 } else if (size <= 1024 * 1024) {
3163 size = 1024 * 1024;
3164 } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, bsbits)) {
3165 start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
3166 (20 - bsbits)) << 20;
3167 size = 1024 * 1024;
3168 } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, bsbits)) {
3169 start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
3170 (22 - bsbits)) << 22;
3171 size = 4 * 1024 * 1024;
3172 } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len,
3173 (8<<20)>>bsbits, max, bsbits)) {
3174 start_off = ((loff_t)ac->ac_o_ex.fe_logical >>
3175 (23 - bsbits)) << 23;
3176 size = 8 * 1024 * 1024;
3177 } else {
3178 start_off = (loff_t)ac->ac_o_ex.fe_logical << bsbits;
3179 size = ac->ac_o_ex.fe_len << bsbits;
3180 }
3181 orig_size = size = size >> bsbits;
3182 orig_start = start = start_off >> bsbits;
3183
3184 /* don't cover already allocated blocks in selected range */
3185 if (ar->pleft && start <= ar->lleft) {
3186 size -= ar->lleft + 1 - start;
3187 start = ar->lleft + 1;
3188 }
3189 if (ar->pright && start + size - 1 >= ar->lright)
3190 size -= start + size - ar->lright;
3191
3192 end = start + size;
3193
3194 /* check we don't cross already preallocated blocks */
3195 rcu_read_lock();
3196 list_for_each_rcu(cur, &ei->i_prealloc_list) {
3197 struct ext4_prealloc_space *pa;
3198 unsigned long pa_end;
3199
3200 pa = list_entry(cur, struct ext4_prealloc_space, pa_inode_list);
3201
3202 if (pa->pa_deleted)
3203 continue;
3204 spin_lock(&pa->pa_lock);
3205 if (pa->pa_deleted) {
3206 spin_unlock(&pa->pa_lock);
3207 continue;
3208 }
3209
3210 pa_end = pa->pa_lstart + pa->pa_len;
3211
3212 /* PA must not overlap original request */
3213 BUG_ON(!(ac->ac_o_ex.fe_logical >= pa_end ||
3214 ac->ac_o_ex.fe_logical < pa->pa_lstart));
3215
3216 /* skip PA normalized request doesn't overlap with */
3217 if (pa->pa_lstart >= end) {
3218 spin_unlock(&pa->pa_lock);
3219 continue;
3220 }
3221 if (pa_end <= start) {
3222 spin_unlock(&pa->pa_lock);
3223 continue;
3224 }
3225 BUG_ON(pa->pa_lstart <= start && pa_end >= end);
3226
3227 if (pa_end <= ac->ac_o_ex.fe_logical) {
3228 BUG_ON(pa_end < start);
3229 start = pa_end;
3230 }
3231
3232 if (pa->pa_lstart > ac->ac_o_ex.fe_logical) {
3233 BUG_ON(pa->pa_lstart > end);
3234 end = pa->pa_lstart;
3235 }
3236 spin_unlock(&pa->pa_lock);
3237 }
3238 rcu_read_unlock();
3239 size = end - start;
3240
3241 /* XXX: extra loop to check we really don't overlap preallocations */
3242 rcu_read_lock();
3243 list_for_each_rcu(cur, &ei->i_prealloc_list) {
3244 struct ext4_prealloc_space *pa;
3245 unsigned long pa_end;
3246 pa = list_entry(cur, struct ext4_prealloc_space, pa_inode_list);
3247 spin_lock(&pa->pa_lock);
3248 if (pa->pa_deleted == 0) {
3249 pa_end = pa->pa_lstart + pa->pa_len;
3250 BUG_ON(!(start >= pa_end || end <= pa->pa_lstart));
3251 }
3252 spin_unlock(&pa->pa_lock);
3253 }
3254 rcu_read_unlock();
3255
3256 if (start + size <= ac->ac_o_ex.fe_logical &&
3257 start > ac->ac_o_ex.fe_logical) {
3258 printk(KERN_ERR "start %lu, size %lu, fe_logical %lu\n",
3259 (unsigned long) start, (unsigned long) size,
3260 (unsigned long) ac->ac_o_ex.fe_logical);
3261 }
3262 BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
3263 start > ac->ac_o_ex.fe_logical);
3264 BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
3265
3266 /* now prepare goal request */
3267
3268 /* XXX: is it better to align blocks WRT to logical
3269 * placement or satisfy big request as is */
3270 ac->ac_g_ex.fe_logical = start;
3271 ac->ac_g_ex.fe_len = size;
3272
3273 /* define goal start in order to merge */
3274 if (ar->pright && (ar->lright == (start + size))) {
3275 /* merge to the right */
3276 ext4_get_group_no_and_offset(ac->ac_sb, ar->pright - size,
3277 &ac->ac_f_ex.fe_group,
3278 &ac->ac_f_ex.fe_start);
3279 ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
3280 }
3281 if (ar->pleft && (ar->lleft + 1 == start)) {
3282 /* merge to the left */
3283 ext4_get_group_no_and_offset(ac->ac_sb, ar->pleft + 1,
3284 &ac->ac_f_ex.fe_group,
3285 &ac->ac_f_ex.fe_start);
3286 ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
3287 }
3288
3289 mb_debug("goal: %u(was %u) blocks at %u\n", (unsigned) size,
3290 (unsigned) orig_size, (unsigned) start);
3291}
3292
3293static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
3294{
3295 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
3296
3297 if (sbi->s_mb_stats && ac->ac_g_ex.fe_len > 1) {
3298 atomic_inc(&sbi->s_bal_reqs);
3299 atomic_add(ac->ac_b_ex.fe_len, &sbi->s_bal_allocated);
3300 if (ac->ac_o_ex.fe_len >= ac->ac_g_ex.fe_len)
3301 atomic_inc(&sbi->s_bal_success);
3302 atomic_add(ac->ac_found, &sbi->s_bal_ex_scanned);
3303 if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
3304 ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
3305 atomic_inc(&sbi->s_bal_goals);
3306 if (ac->ac_found > sbi->s_mb_max_to_scan)
3307 atomic_inc(&sbi->s_bal_breaks);
3308 }
3309
3310 ext4_mb_store_history(ac);
3311}
3312
3313/*
3314 * use blocks preallocated to inode
3315 */
3316static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
3317 struct ext4_prealloc_space *pa)
3318{
3319 ext4_fsblk_t start;
3320 ext4_fsblk_t end;
3321 int len;
3322
3323 /* found preallocated blocks, use them */
3324 start = pa->pa_pstart + (ac->ac_o_ex.fe_logical - pa->pa_lstart);
3325 end = min(pa->pa_pstart + pa->pa_len, start + ac->ac_o_ex.fe_len);
3326 len = end - start;
3327 ext4_get_group_no_and_offset(ac->ac_sb, start, &ac->ac_b_ex.fe_group,
3328 &ac->ac_b_ex.fe_start);
3329 ac->ac_b_ex.fe_len = len;
3330 ac->ac_status = AC_STATUS_FOUND;
3331 ac->ac_pa = pa;
3332
3333 BUG_ON(start < pa->pa_pstart);
3334 BUG_ON(start + len > pa->pa_pstart + pa->pa_len);
3335 BUG_ON(pa->pa_free < len);
3336 pa->pa_free -= len;
3337
3338 mb_debug("use %llu/%lu from inode pa %p\n", start, len, pa);
3339}
3340
3341/*
3342 * use blocks preallocated to locality group
3343 */
3344static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
3345 struct ext4_prealloc_space *pa)
3346{
3347 unsigned len = ac->ac_o_ex.fe_len;
3348
3349 ext4_get_group_no_and_offset(ac->ac_sb, pa->pa_pstart,
3350 &ac->ac_b_ex.fe_group,
3351 &ac->ac_b_ex.fe_start);
3352 ac->ac_b_ex.fe_len = len;
3353 ac->ac_status = AC_STATUS_FOUND;
3354 ac->ac_pa = pa;
3355
3356 /* we don't correct pa_pstart or pa_plen here to avoid
3357 * possible race when tte group is being loaded concurrently
3358 * instead we correct pa later, after blocks are marked
3359 * in on-disk bitmap -- see ext4_mb_release_context() */
3360 /*
3361 * FIXME!! but the other CPUs can look at this particular
3362 * pa and think that it have enought free blocks if we
3363 * don't update pa_free here right ?
3364 */
3365 mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
3366}
3367
3368/*
3369 * search goal blocks in preallocated space
3370 */
3371static int ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
3372{
3373 struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
3374 struct ext4_locality_group *lg;
3375 struct ext4_prealloc_space *pa;
3376 struct list_head *cur;
3377
3378 /* only data can be preallocated */
3379 if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
3380 return 0;
3381
3382 /* first, try per-file preallocation */
3383 rcu_read_lock();
3384 list_for_each_rcu(cur, &ei->i_prealloc_list) {
3385 pa = list_entry(cur, struct ext4_prealloc_space, pa_inode_list);
3386
3387 /* all fields in this condition don't change,
3388 * so we can skip locking for them */
3389 if (ac->ac_o_ex.fe_logical < pa->pa_lstart ||
3390 ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len)
3391 continue;
3392
3393 /* found preallocated blocks, use them */
3394 spin_lock(&pa->pa_lock);
3395 if (pa->pa_deleted == 0 && pa->pa_free) {
3396 atomic_inc(&pa->pa_count);
3397 ext4_mb_use_inode_pa(ac, pa);
3398 spin_unlock(&pa->pa_lock);
3399 ac->ac_criteria = 10;
3400 rcu_read_unlock();
3401 return 1;
3402 }
3403 spin_unlock(&pa->pa_lock);
3404 }
3405 rcu_read_unlock();
3406
3407 /* can we use group allocation? */
3408 if (!(ac->ac_flags & EXT4_MB_HINT_GROUP_ALLOC))
3409 return 0;
3410
3411 /* inode may have no locality group for some reason */
3412 lg = ac->ac_lg;
3413 if (lg == NULL)
3414 return 0;
3415
3416 rcu_read_lock();
3417 list_for_each_rcu(cur, &lg->lg_prealloc_list) {
3418 pa = list_entry(cur, struct ext4_prealloc_space, pa_inode_list);
3419 spin_lock(&pa->pa_lock);
3420 if (pa->pa_deleted == 0 && pa->pa_free >= ac->ac_o_ex.fe_len) {
3421 atomic_inc(&pa->pa_count);
3422 ext4_mb_use_group_pa(ac, pa);
3423 spin_unlock(&pa->pa_lock);
3424 ac->ac_criteria = 20;
3425 rcu_read_unlock();
3426 return 1;
3427 }
3428 spin_unlock(&pa->pa_lock);
3429 }
3430 rcu_read_unlock();
3431
3432 return 0;
3433}
3434
3435/*
3436 * the function goes through all preallocation in this group and marks them
3437 * used in in-core bitmap. buddy must be generated from this bitmap
3438 * Need to be called with ext4 group lock (ext4_lock_group)
3439 */
3440static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
3441 ext4_group_t group)
3442{
3443 struct ext4_group_info *grp = ext4_get_group_info(sb, group);
3444 struct ext4_prealloc_space *pa;
3445 struct list_head *cur;
3446 ext4_group_t groupnr;
3447 ext4_grpblk_t start;
3448 int preallocated = 0;
3449 int count = 0;
3450 int len;
3451
3452 /* all form of preallocation discards first load group,
3453 * so the only competing code is preallocation use.
3454 * we don't need any locking here
3455 * notice we do NOT ignore preallocations with pa_deleted
3456 * otherwise we could leave used blocks available for
3457 * allocation in buddy when concurrent ext4_mb_put_pa()
3458 * is dropping preallocation
3459 */
3460 list_for_each(cur, &grp->bb_prealloc_list) {
3461 pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list);
3462 spin_lock(&pa->pa_lock);
3463 ext4_get_group_no_and_offset(sb, pa->pa_pstart,
3464 &groupnr, &start);
3465 len = pa->pa_len;
3466 spin_unlock(&pa->pa_lock);
3467 if (unlikely(len == 0))
3468 continue;
3469 BUG_ON(groupnr != group);
3470 mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group),
3471 bitmap, start, len);
3472 preallocated += len;
3473 count++;
3474 }
3475 mb_debug("prellocated %u for group %lu\n", preallocated, group);
3476}
3477
3478static void ext4_mb_pa_callback(struct rcu_head *head)
3479{
3480 struct ext4_prealloc_space *pa;
3481 pa = container_of(head, struct ext4_prealloc_space, u.pa_rcu);
3482 kmem_cache_free(ext4_pspace_cachep, pa);
3483}
3484
3485/*
3486 * drops a reference to preallocated space descriptor
3487 * if this was the last reference and the space is consumed
3488 */
3489static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
3490 struct super_block *sb, struct ext4_prealloc_space *pa)
3491{
3492 unsigned long grp;
3493
3494 if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
3495 return;
3496
3497 /* in this short window concurrent discard can set pa_deleted */
3498 spin_lock(&pa->pa_lock);
3499 if (pa->pa_deleted == 1) {
3500 spin_unlock(&pa->pa_lock);
3501 return;
3502 }
3503
3504 pa->pa_deleted = 1;
3505 spin_unlock(&pa->pa_lock);
3506
3507 /* -1 is to protect from crossing allocation group */
3508 ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL);
3509
3510 /*
3511 * possible race:
3512 *
3513 * P1 (buddy init) P2 (regular allocation)
3514 * find block B in PA
3515 * copy on-disk bitmap to buddy
3516 * mark B in on-disk bitmap
3517 * drop PA from group
3518 * mark all PAs in buddy
3519 *
3520 * thus, P1 initializes buddy with B available. to prevent this
3521 * we make "copy" and "mark all PAs" atomic and serialize "drop PA"
3522 * against that pair
3523 */
3524 ext4_lock_group(sb, grp);
3525 list_del(&pa->pa_group_list);
3526 ext4_unlock_group(sb, grp);
3527
3528 spin_lock(pa->pa_obj_lock);
3529 list_del_rcu(&pa->pa_inode_list);
3530 spin_unlock(pa->pa_obj_lock);
3531
3532 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
3533}
3534
3535/*
3536 * creates new preallocated space for given inode
3537 */
3538static int ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
3539{
3540 struct super_block *sb = ac->ac_sb;
3541 struct ext4_prealloc_space *pa;
3542 struct ext4_group_info *grp;
3543 struct ext4_inode_info *ei;
3544
3545 /* preallocate only when found space is larger then requested */
3546 BUG_ON(ac->ac_o_ex.fe_len >= ac->ac_b_ex.fe_len);
3547 BUG_ON(ac->ac_status != AC_STATUS_FOUND);
3548 BUG_ON(!S_ISREG(ac->ac_inode->i_mode));
3549
3550 pa = kmem_cache_alloc(ext4_pspace_cachep, GFP_NOFS);
3551 if (pa == NULL)
3552 return -ENOMEM;
3553
3554 if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) {
3555 int winl;
3556 int wins;
3557 int win;
3558 int offs;
3559
3560 /* we can't allocate as much as normalizer wants.
3561 * so, found space must get proper lstart
3562 * to cover original request */
3563 BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);
3564 BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len);
3565
3566 /* we're limited by original request in that
3567 * logical block must be covered any way
3568 * winl is window we can move our chunk within */
3569 winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical;
3570
3571 /* also, we should cover whole original request */
3572 wins = ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len;
3573
3574 /* the smallest one defines real window */
3575 win = min(winl, wins);
3576
3577 offs = ac->ac_o_ex.fe_logical % ac->ac_b_ex.fe_len;
3578 if (offs && offs < win)
3579 win = offs;
3580
3581 ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - win;
3582 BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
3583 BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
3584 }
3585
3586 /* preallocation can change ac_b_ex, thus we store actually
3587 * allocated blocks for history */
3588 ac->ac_f_ex = ac->ac_b_ex;
3589
3590 pa->pa_lstart = ac->ac_b_ex.fe_logical;
3591 pa->pa_pstart = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
3592 pa->pa_len = ac->ac_b_ex.fe_len;
3593 pa->pa_free = pa->pa_len;
3594 atomic_set(&pa->pa_count, 1);
3595 spin_lock_init(&pa->pa_lock);
3596 pa->pa_deleted = 0;
3597 pa->pa_linear = 0;
3598
3599 mb_debug("new inode pa %p: %llu/%u for %u\n", pa,
3600 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
3601
3602 ext4_mb_use_inode_pa(ac, pa);
3603 atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
3604
3605 ei = EXT4_I(ac->ac_inode);
3606 grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
3607
3608 pa->pa_obj_lock = &ei->i_prealloc_lock;
3609 pa->pa_inode = ac->ac_inode;
3610
3611 ext4_lock_group(sb, ac->ac_b_ex.fe_group);
3612 list_add(&pa->pa_group_list, &grp->bb_prealloc_list);
3613 ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
3614
3615 spin_lock(pa->pa_obj_lock);
3616 list_add_rcu(&pa->pa_inode_list, &ei->i_prealloc_list);
3617 spin_unlock(pa->pa_obj_lock);
3618
3619 return 0;
3620}
3621
3622/*
3623 * creates new preallocated space for locality group inodes belongs to
3624 */
3625static int ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
3626{
3627 struct super_block *sb = ac->ac_sb;
3628 struct ext4_locality_group *lg;
3629 struct ext4_prealloc_space *pa;
3630 struct ext4_group_info *grp;
3631
3632 /* preallocate only when found space is larger then requested */
3633 BUG_ON(ac->ac_o_ex.fe_len >= ac->ac_b_ex.fe_len);
3634 BUG_ON(ac->ac_status != AC_STATUS_FOUND);
3635 BUG_ON(!S_ISREG(ac->ac_inode->i_mode));
3636
3637 BUG_ON(ext4_pspace_cachep == NULL);
3638 pa = kmem_cache_alloc(ext4_pspace_cachep, GFP_NOFS);
3639 if (pa == NULL)
3640 return -ENOMEM;
3641
3642 /* preallocation can change ac_b_ex, thus we store actually
3643 * allocated blocks for history */
3644 ac->ac_f_ex = ac->ac_b_ex;
3645
3646 pa->pa_pstart = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
3647 pa->pa_lstart = pa->pa_pstart;
3648 pa->pa_len = ac->ac_b_ex.fe_len;
3649 pa->pa_free = pa->pa_len;
3650 atomic_set(&pa->pa_count, 1);
3651 spin_lock_init(&pa->pa_lock);
3652 pa->pa_deleted = 0;
3653 pa->pa_linear = 1;
3654
3655 mb_debug("new group pa %p: %llu/%u for %u\n", pa,
3656 pa->pa_pstart, pa->pa_len, pa->pa_lstart);
3657
3658 ext4_mb_use_group_pa(ac, pa);
3659 atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated);
3660
3661 grp = ext4_get_group_info(sb, ac->ac_b_ex.fe_group);
3662 lg = ac->ac_lg;
3663 BUG_ON(lg == NULL);
3664
3665 pa->pa_obj_lock = &lg->lg_prealloc_lock;
3666 pa->pa_inode = NULL;
3667
3668 ext4_lock_group(sb, ac->ac_b_ex.fe_group);
3669 list_add(&pa->pa_group_list, &grp->bb_prealloc_list);
3670 ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
3671
3672 spin_lock(pa->pa_obj_lock);
3673 list_add_tail_rcu(&pa->pa_inode_list, &lg->lg_prealloc_list);
3674 spin_unlock(pa->pa_obj_lock);
3675
3676 return 0;
3677}
3678
3679static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac)
3680{
3681 int err;
3682
3683 if (ac->ac_flags & EXT4_MB_HINT_GROUP_ALLOC)
3684 err = ext4_mb_new_group_pa(ac);
3685 else
3686 err = ext4_mb_new_inode_pa(ac);
3687 return err;
3688}
3689
3690/*
3691 * finds all unused blocks in on-disk bitmap, frees them in
3692 * in-core bitmap and buddy.
3693 * @pa must be unlinked from inode and group lists, so that
3694 * nobody else can find/use it.
3695 * the caller MUST hold group/inode locks.
3696 * TODO: optimize the case when there are no in-core structures yet
3697 */
3698static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b,
3699 struct buffer_head *bitmap_bh,
3700 struct ext4_prealloc_space *pa)
3701{
3702 struct ext4_allocation_context ac;
3703 struct super_block *sb = e4b->bd_sb;
3704 struct ext4_sb_info *sbi = EXT4_SB(sb);
3705 unsigned long end;
3706 unsigned long next;
3707 ext4_group_t group;
3708 ext4_grpblk_t bit;
3709 sector_t start;
3710 int err = 0;
3711 int free = 0;
3712
3713 BUG_ON(pa->pa_deleted == 0);
3714 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
3715 BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
3716 end = bit + pa->pa_len;
3717
3718 ac.ac_sb = sb;
3719 ac.ac_inode = pa->pa_inode;
3720 ac.ac_op = EXT4_MB_HISTORY_DISCARD;
3721
3722 while (bit < end) {
3723 bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit);
3724 if (bit >= end)
3725 break;
3726 next = ext4_find_next_bit(bitmap_bh->b_data, end, bit);
3727 if (next > end)
3728 next = end;
3729 start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
3730 le32_to_cpu(sbi->s_es->s_first_data_block);
3731 mb_debug(" free preallocated %u/%u in group %u\n",
3732 (unsigned) start, (unsigned) next - bit,
3733 (unsigned) group);
3734 free += next - bit;
3735
3736 ac.ac_b_ex.fe_group = group;
3737 ac.ac_b_ex.fe_start = bit;
3738 ac.ac_b_ex.fe_len = next - bit;
3739 ac.ac_b_ex.fe_logical = 0;
3740 ext4_mb_store_history(&ac);
3741
3742 mb_free_blocks(pa->pa_inode, e4b, bit, next - bit);
3743 bit = next + 1;
3744 }
3745 if (free != pa->pa_free) {
3746 printk(KERN_ERR "pa %p: logic %lu, phys. %lu, len %lu\n",
3747 pa, (unsigned long) pa->pa_lstart,
3748 (unsigned long) pa->pa_pstart,
3749 (unsigned long) pa->pa_len);
3750 printk(KERN_ERR "free %u, pa_free %u\n", free, pa->pa_free);
3751 }
3752 BUG_ON(free != pa->pa_free);
3753 atomic_add(free, &sbi->s_mb_discarded);
3754
3755 return err;
3756}
3757
3758static int ext4_mb_release_group_pa(struct ext4_buddy *e4b,
3759 struct ext4_prealloc_space *pa)
3760{
3761 struct ext4_allocation_context ac;
3762 struct super_block *sb = e4b->bd_sb;
3763 ext4_group_t group;
3764 ext4_grpblk_t bit;
3765
3766 ac.ac_op = EXT4_MB_HISTORY_DISCARD;
3767
3768 BUG_ON(pa->pa_deleted == 0);
3769 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
3770 BUG_ON(group != e4b->bd_group && pa->pa_len != 0);
3771 mb_free_blocks(pa->pa_inode, e4b, bit, pa->pa_len);
3772 atomic_add(pa->pa_len, &EXT4_SB(sb)->s_mb_discarded);
3773
3774 ac.ac_sb = sb;
3775 ac.ac_inode = NULL;
3776 ac.ac_b_ex.fe_group = group;
3777 ac.ac_b_ex.fe_start = bit;
3778 ac.ac_b_ex.fe_len = pa->pa_len;
3779 ac.ac_b_ex.fe_logical = 0;
3780 ext4_mb_store_history(&ac);
3781
3782 return 0;
3783}
3784
3785/*
3786 * releases all preallocations in given group
3787 *
3788 * first, we need to decide discard policy:
3789 * - when do we discard
3790 * 1) ENOSPC
3791 * - how many do we discard
3792 * 1) how many requested
3793 */
3794static int ext4_mb_discard_group_preallocations(struct super_block *sb,
3795 ext4_group_t group, int needed)
3796{
3797 struct ext4_group_info *grp = ext4_get_group_info(sb, group);
3798 struct buffer_head *bitmap_bh = NULL;
3799 struct ext4_prealloc_space *pa, *tmp;
3800 struct list_head list;
3801 struct ext4_buddy e4b;
3802 int err;
3803 int busy = 0;
3804 int free = 0;
3805
3806 mb_debug("discard preallocation for group %lu\n", group);
3807
3808 if (list_empty(&grp->bb_prealloc_list))
3809 return 0;
3810
3811 bitmap_bh = read_block_bitmap(sb, group);
3812 if (bitmap_bh == NULL) {
3813 /* error handling here */
3814 ext4_mb_release_desc(&e4b);
3815 BUG_ON(bitmap_bh == NULL);
3816 }
3817
3818 err = ext4_mb_load_buddy(sb, group, &e4b);
3819 BUG_ON(err != 0); /* error handling here */
3820
3821 if (needed == 0)
3822 needed = EXT4_BLOCKS_PER_GROUP(sb) + 1;
3823
3824 grp = ext4_get_group_info(sb, group);
3825 INIT_LIST_HEAD(&list);
3826
3827repeat:
3828 ext4_lock_group(sb, group);
3829 list_for_each_entry_safe(pa, tmp,
3830 &grp->bb_prealloc_list, pa_group_list) {
3831 spin_lock(&pa->pa_lock);
3832 if (atomic_read(&pa->pa_count)) {
3833 spin_unlock(&pa->pa_lock);
3834 busy = 1;
3835 continue;
3836 }
3837 if (pa->pa_deleted) {
3838 spin_unlock(&pa->pa_lock);
3839 continue;
3840 }
3841
3842 /* seems this one can be freed ... */
3843 pa->pa_deleted = 1;
3844
3845 /* we can trust pa_free ... */
3846 free += pa->pa_free;
3847
3848 spin_unlock(&pa->pa_lock);
3849
3850 list_del(&pa->pa_group_list);
3851 list_add(&pa->u.pa_tmp_list, &list);
3852 }
3853
3854 /* if we still need more blocks and some PAs were used, try again */
3855 if (free < needed && busy) {
3856 busy = 0;
3857 ext4_unlock_group(sb, group);
3858 /*
3859 * Yield the CPU here so that we don't get soft lockup
3860 * in non preempt case.
3861 */
3862 yield();
3863 goto repeat;
3864 }
3865
3866 /* found anything to free? */
3867 if (list_empty(&list)) {
3868 BUG_ON(free != 0);
3869 goto out;
3870 }
3871
3872 /* now free all selected PAs */
3873 list_for_each_entry_safe(pa, tmp, &list, u.pa_tmp_list) {
3874
3875 /* remove from object (inode or locality group) */
3876 spin_lock(pa->pa_obj_lock);
3877 list_del_rcu(&pa->pa_inode_list);
3878 spin_unlock(pa->pa_obj_lock);
3879
3880 if (pa->pa_linear)
3881 ext4_mb_release_group_pa(&e4b, pa);
3882 else
3883 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa);
3884
3885 list_del(&pa->u.pa_tmp_list);
3886 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
3887 }
3888
3889out:
3890 ext4_unlock_group(sb, group);
3891 ext4_mb_release_desc(&e4b);
3892 put_bh(bitmap_bh);
3893 return free;
3894}
3895
3896/*
3897 * releases all non-used preallocated blocks for given inode
3898 *
3899 * It's important to discard preallocations under i_data_sem
3900 * We don't want another block to be served from the prealloc
3901 * space when we are discarding the inode prealloc space.
3902 *
3903 * FIXME!! Make sure it is valid at all the call sites
3904 */
3905void ext4_mb_discard_inode_preallocations(struct inode *inode)
3906{
3907 struct ext4_inode_info *ei = EXT4_I(inode);
3908 struct super_block *sb = inode->i_sb;
3909 struct buffer_head *bitmap_bh = NULL;
3910 struct ext4_prealloc_space *pa, *tmp;
3911 ext4_group_t group = 0;
3912 struct list_head list;
3913 struct ext4_buddy e4b;
3914 int err;
3915
3916 if (!test_opt(sb, MBALLOC) || !S_ISREG(inode->i_mode)) {
3917 /*BUG_ON(!list_empty(&ei->i_prealloc_list));*/
3918 return;
3919 }
3920
3921 mb_debug("discard preallocation for inode %lu\n", inode->i_ino);
3922
3923 INIT_LIST_HEAD(&list);
3924
3925repeat:
3926 /* first, collect all pa's in the inode */
3927 spin_lock(&ei->i_prealloc_lock);
3928 while (!list_empty(&ei->i_prealloc_list)) {
3929 pa = list_entry(ei->i_prealloc_list.next,
3930 struct ext4_prealloc_space, pa_inode_list);
3931 BUG_ON(pa->pa_obj_lock != &ei->i_prealloc_lock);
3932 spin_lock(&pa->pa_lock);
3933 if (atomic_read(&pa->pa_count)) {
3934 /* this shouldn't happen often - nobody should
3935 * use preallocation while we're discarding it */
3936 spin_unlock(&pa->pa_lock);
3937 spin_unlock(&ei->i_prealloc_lock);
3938 printk(KERN_ERR "uh-oh! used pa while discarding\n");
3939 WARN_ON(1);
3940 schedule_timeout_uninterruptible(HZ);
3941 goto repeat;
3942
3943 }
3944 if (pa->pa_deleted == 0) {
3945 pa->pa_deleted = 1;
3946 spin_unlock(&pa->pa_lock);
3947 list_del_rcu(&pa->pa_inode_list);
3948 list_add(&pa->u.pa_tmp_list, &list);
3949 continue;
3950 }
3951
3952 /* someone is deleting pa right now */
3953 spin_unlock(&pa->pa_lock);
3954 spin_unlock(&ei->i_prealloc_lock);
3955
3956 /* we have to wait here because pa_deleted
3957 * doesn't mean pa is already unlinked from
3958 * the list. as we might be called from
3959 * ->clear_inode() the inode will get freed
3960 * and concurrent thread which is unlinking
3961 * pa from inode's list may access already
3962 * freed memory, bad-bad-bad */
3963
3964 /* XXX: if this happens too often, we can
3965 * add a flag to force wait only in case
3966 * of ->clear_inode(), but not in case of
3967 * regular truncate */
3968 schedule_timeout_uninterruptible(HZ);
3969 goto repeat;
3970 }
3971 spin_unlock(&ei->i_prealloc_lock);
3972
3973 list_for_each_entry_safe(pa, tmp, &list, u.pa_tmp_list) {
3974 BUG_ON(pa->pa_linear != 0);
3975 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, NULL);
3976
3977 err = ext4_mb_load_buddy(sb, group, &e4b);
3978 BUG_ON(err != 0); /* error handling here */
3979
3980 bitmap_bh = read_block_bitmap(sb, group);
3981 if (bitmap_bh == NULL) {
3982 /* error handling here */
3983 ext4_mb_release_desc(&e4b);
3984 BUG_ON(bitmap_bh == NULL);
3985 }
3986
3987 ext4_lock_group(sb, group);
3988 list_del(&pa->pa_group_list);
3989 ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa);
3990 ext4_unlock_group(sb, group);
3991
3992 ext4_mb_release_desc(&e4b);
3993 put_bh(bitmap_bh);
3994
3995 list_del(&pa->u.pa_tmp_list);
3996 call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback);
3997 }
3998}
3999
4000/*
4001 * finds all preallocated spaces and return blocks being freed to them
4002 * if preallocated space becomes full (no block is used from the space)
4003 * then the function frees space in buddy
4004 * XXX: at the moment, truncate (which is the only way to free blocks)
4005 * discards all preallocations
4006 */
4007static void ext4_mb_return_to_preallocation(struct inode *inode,
4008 struct ext4_buddy *e4b,
4009 sector_t block, int count)
4010{
4011 BUG_ON(!list_empty(&EXT4_I(inode)->i_prealloc_list));
4012}
4013#ifdef MB_DEBUG
4014static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
4015{
4016 struct super_block *sb = ac->ac_sb;
4017 ext4_group_t i;
4018
4019 printk(KERN_ERR "EXT4-fs: Can't allocate:"
4020 " Allocation context details:\n");
4021 printk(KERN_ERR "EXT4-fs: status %d flags %d\n",
4022 ac->ac_status, ac->ac_flags);
4023 printk(KERN_ERR "EXT4-fs: orig %lu/%lu/%lu@%lu, goal %lu/%lu/%lu@%lu, "
4024 "best %lu/%lu/%lu@%lu cr %d\n",
4025 (unsigned long)ac->ac_o_ex.fe_group,
4026 (unsigned long)ac->ac_o_ex.fe_start,
4027 (unsigned long)ac->ac_o_ex.fe_len,
4028 (unsigned long)ac->ac_o_ex.fe_logical,
4029 (unsigned long)ac->ac_g_ex.fe_group,
4030 (unsigned long)ac->ac_g_ex.fe_start,
4031 (unsigned long)ac->ac_g_ex.fe_len,
4032 (unsigned long)ac->ac_g_ex.fe_logical,
4033 (unsigned long)ac->ac_b_ex.fe_group,
4034 (unsigned long)ac->ac_b_ex.fe_start,
4035 (unsigned long)ac->ac_b_ex.fe_len,
4036 (unsigned long)ac->ac_b_ex.fe_logical,
4037 (int)ac->ac_criteria);
4038 printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned,
4039 ac->ac_found);
4040 printk(KERN_ERR "EXT4-fs: groups: \n");
4041 for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
4042 struct ext4_group_info *grp = ext4_get_group_info(sb, i);
4043 struct ext4_prealloc_space *pa;
4044 ext4_grpblk_t start;
4045 struct list_head *cur;
4046 ext4_lock_group(sb, i);
4047 list_for_each(cur, &grp->bb_prealloc_list) {
4048 pa = list_entry(cur, struct ext4_prealloc_space,
4049 pa_group_list);
4050 spin_lock(&pa->pa_lock);
4051 ext4_get_group_no_and_offset(sb, pa->pa_pstart,
4052 NULL, &start);
4053 spin_unlock(&pa->pa_lock);
4054 printk(KERN_ERR "PA:%lu:%d:%u \n", i,
4055 start, pa->pa_len);
4056 }
4057 ext4_lock_group(sb, i);
4058
4059 if (grp->bb_free == 0)
4060 continue;
4061 printk(KERN_ERR "%lu: %d/%d \n",
4062 i, grp->bb_free, grp->bb_fragments);
4063 }
4064 printk(KERN_ERR "\n");
4065}
4066#else
4067static inline void ext4_mb_show_ac(struct ext4_allocation_context *ac)
4068{
4069 return;
4070}
4071#endif
4072
4073/*
4074 * We use locality group preallocation for small size file. The size of the
4075 * file is determined by the current size or the resulting size after
4076 * allocation which ever is larger
4077 *
4078 * One can tune this size via /proc/fs/ext4/<partition>/stream_req
4079 */
4080static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
4081{
4082 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
4083 int bsbits = ac->ac_sb->s_blocksize_bits;
4084 loff_t size, isize;
4085
4086 if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
4087 return;
4088
4089 size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
4090 isize = i_size_read(ac->ac_inode) >> bsbits;
4091 size = max(size, isize);
4092
4093 /* don't use group allocation for large files */
4094 if (size >= sbi->s_mb_stream_request)
4095 return;
4096
4097 if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
4098 return;
4099
4100 BUG_ON(ac->ac_lg != NULL);
4101 /*
4102 * locality group prealloc space are per cpu. The reason for having
4103 * per cpu locality group is to reduce the contention between block
4104 * request from multiple CPUs.
4105 */
4106 ac->ac_lg = &sbi->s_locality_groups[get_cpu()];
4107 put_cpu();
4108
4109 /* we're going to use group allocation */
4110 ac->ac_flags |= EXT4_MB_HINT_GROUP_ALLOC;
4111
4112 /* serialize all allocations in the group */
4113 mutex_lock(&ac->ac_lg->lg_mutex);
4114}
4115
4116static int ext4_mb_initialize_context(struct ext4_allocation_context *ac,
4117 struct ext4_allocation_request *ar)
4118{
4119 struct super_block *sb = ar->inode->i_sb;
4120 struct ext4_sb_info *sbi = EXT4_SB(sb);
4121 struct ext4_super_block *es = sbi->s_es;
4122 ext4_group_t group;
4123 unsigned long len;
4124 unsigned long goal;
4125 ext4_grpblk_t block;
4126
4127 /* we can't allocate > group size */
4128 len = ar->len;
4129
4130 /* just a dirty hack to filter too big requests */
4131 if (len >= EXT4_BLOCKS_PER_GROUP(sb) - 10)
4132 len = EXT4_BLOCKS_PER_GROUP(sb) - 10;
4133
4134 /* start searching from the goal */
4135 goal = ar->goal;
4136 if (goal < le32_to_cpu(es->s_first_data_block) ||
4137 goal >= ext4_blocks_count(es))
4138 goal = le32_to_cpu(es->s_first_data_block);
4139 ext4_get_group_no_and_offset(sb, goal, &group, &block);
4140
4141 /* set up allocation goals */
4142 ac->ac_b_ex.fe_logical = ar->logical;
4143 ac->ac_b_ex.fe_group = 0;
4144 ac->ac_b_ex.fe_start = 0;
4145 ac->ac_b_ex.fe_len = 0;
4146 ac->ac_status = AC_STATUS_CONTINUE;
4147 ac->ac_groups_scanned = 0;
4148 ac->ac_ex_scanned = 0;
4149 ac->ac_found = 0;
4150 ac->ac_sb = sb;
4151 ac->ac_inode = ar->inode;
4152 ac->ac_o_ex.fe_logical = ar->logical;
4153 ac->ac_o_ex.fe_group = group;
4154 ac->ac_o_ex.fe_start = block;
4155 ac->ac_o_ex.fe_len = len;
4156 ac->ac_g_ex.fe_logical = ar->logical;
4157 ac->ac_g_ex.fe_group = group;
4158 ac->ac_g_ex.fe_start = block;
4159 ac->ac_g_ex.fe_len = len;
4160 ac->ac_f_ex.fe_len = 0;
4161 ac->ac_flags = ar->flags;
4162 ac->ac_2order = 0;
4163 ac->ac_criteria = 0;
4164 ac->ac_pa = NULL;
4165 ac->ac_bitmap_page = NULL;
4166 ac->ac_buddy_page = NULL;
4167 ac->ac_lg = NULL;
4168
4169 /* we have to define context: we'll we work with a file or
4170 * locality group. this is a policy, actually */
4171 ext4_mb_group_or_file(ac);
4172
4173 mb_debug("init ac: %u blocks @ %u, goal %u, flags %x, 2^%d, "
4174 "left: %u/%u, right %u/%u to %swritable\n",
4175 (unsigned) ar->len, (unsigned) ar->logical,
4176 (unsigned) ar->goal, ac->ac_flags, ac->ac_2order,
4177 (unsigned) ar->lleft, (unsigned) ar->pleft,
4178 (unsigned) ar->lright, (unsigned) ar->pright,
4179 atomic_read(&ar->inode->i_writecount) ? "" : "non-");
4180 return 0;
4181
4182}
4183
4184/*
4185 * release all resource we used in allocation
4186 */
4187static int ext4_mb_release_context(struct ext4_allocation_context *ac)
4188{
4189 if (ac->ac_pa) {
4190 if (ac->ac_pa->pa_linear) {
4191 /* see comment in ext4_mb_use_group_pa() */
4192 spin_lock(&ac->ac_pa->pa_lock);
4193 ac->ac_pa->pa_pstart += ac->ac_b_ex.fe_len;
4194 ac->ac_pa->pa_lstart += ac->ac_b_ex.fe_len;
4195 ac->ac_pa->pa_free -= ac->ac_b_ex.fe_len;
4196 ac->ac_pa->pa_len -= ac->ac_b_ex.fe_len;
4197 spin_unlock(&ac->ac_pa->pa_lock);
4198 }
4199 ext4_mb_put_pa(ac, ac->ac_sb, ac->ac_pa);
4200 }
4201 if (ac->ac_bitmap_page)
4202 page_cache_release(ac->ac_bitmap_page);
4203 if (ac->ac_buddy_page)
4204 page_cache_release(ac->ac_buddy_page);
4205 if (ac->ac_flags & EXT4_MB_HINT_GROUP_ALLOC)
4206 mutex_unlock(&ac->ac_lg->lg_mutex);
4207 ext4_mb_collect_stats(ac);
4208 return 0;
4209}
4210
4211static int ext4_mb_discard_preallocations(struct super_block *sb, int needed)
4212{
4213 ext4_group_t i;
4214 int ret;
4215 int freed = 0;
4216
4217 for (i = 0; i < EXT4_SB(sb)->s_groups_count && needed > 0; i++) {
4218 ret = ext4_mb_discard_group_preallocations(sb, i, needed);
4219 freed += ret;
4220 needed -= ret;
4221 }
4222
4223 return freed;
4224}
4225
4226/*
4227 * Main entry point into mballoc to allocate blocks
4228 * it tries to use preallocation first, then falls back
4229 * to usual allocation
4230 */
4231ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
4232 struct ext4_allocation_request *ar, int *errp)
4233{
4234 struct ext4_allocation_context ac;
4235 struct ext4_sb_info *sbi;
4236 struct super_block *sb;
4237 ext4_fsblk_t block = 0;
4238 int freed;
4239 int inquota;
4240
4241 sb = ar->inode->i_sb;
4242 sbi = EXT4_SB(sb);
4243
4244 if (!test_opt(sb, MBALLOC)) {
4245 block = ext4_new_blocks_old(handle, ar->inode, ar->goal,
4246 &(ar->len), errp);
4247 return block;
4248 }
4249
4250 while (ar->len && DQUOT_ALLOC_BLOCK(ar->inode, ar->len)) {
4251 ar->flags |= EXT4_MB_HINT_NOPREALLOC;
4252 ar->len--;
4253 }
4254 if (ar->len == 0) {
4255 *errp = -EDQUOT;
4256 return 0;
4257 }
4258 inquota = ar->len;
4259
4260 ext4_mb_poll_new_transaction(sb, handle);
4261
4262 *errp = ext4_mb_initialize_context(&ac, ar);
4263 if (*errp) {
4264 ar->len = 0;
4265 goto out;
4266 }
4267
4268 ac.ac_op = EXT4_MB_HISTORY_PREALLOC;
4269 if (!ext4_mb_use_preallocated(&ac)) {
4270
4271 ac.ac_op = EXT4_MB_HISTORY_ALLOC;
4272 ext4_mb_normalize_request(&ac, ar);
4273
4274repeat:
4275 /* allocate space in core */
4276 ext4_mb_regular_allocator(&ac);
4277
4278 /* as we've just preallocated more space than
4279 * user requested orinally, we store allocated
4280 * space in a special descriptor */
4281 if (ac.ac_status == AC_STATUS_FOUND &&
4282 ac.ac_o_ex.fe_len < ac.ac_b_ex.fe_len)
4283 ext4_mb_new_preallocation(&ac);
4284 }
4285
4286 if (likely(ac.ac_status == AC_STATUS_FOUND)) {
4287 ext4_mb_mark_diskspace_used(&ac, handle);
4288 *errp = 0;
4289 block = ext4_grp_offs_to_block(sb, &ac.ac_b_ex);
4290 ar->len = ac.ac_b_ex.fe_len;
4291 } else {
4292 freed = ext4_mb_discard_preallocations(sb, ac.ac_o_ex.fe_len);
4293 if (freed)
4294 goto repeat;
4295 *errp = -ENOSPC;
4296 ac.ac_b_ex.fe_len = 0;
4297 ar->len = 0;
4298 ext4_mb_show_ac(&ac);
4299 }
4300
4301 ext4_mb_release_context(&ac);
4302
4303out:
4304 if (ar->len < inquota)
4305 DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len);
4306
4307 return block;
4308}
4309static void ext4_mb_poll_new_transaction(struct super_block *sb,
4310 handle_t *handle)
4311{
4312 struct ext4_sb_info *sbi = EXT4_SB(sb);
4313
4314 if (sbi->s_last_transaction == handle->h_transaction->t_tid)
4315 return;
4316
4317 /* new transaction! time to close last one and free blocks for
4318 * committed transaction. we know that only transaction can be
4319 * active, so previos transaction can be being logged and we
4320 * know that transaction before previous is known to be already
4321 * logged. this means that now we may free blocks freed in all
4322 * transactions before previous one. hope I'm clear enough ... */
4323
4324 spin_lock(&sbi->s_md_lock);
4325 if (sbi->s_last_transaction != handle->h_transaction->t_tid) {
4326 mb_debug("new transaction %lu, old %lu\n",
4327 (unsigned long) handle->h_transaction->t_tid,
4328 (unsigned long) sbi->s_last_transaction);
4329 list_splice_init(&sbi->s_closed_transaction,
4330 &sbi->s_committed_transaction);
4331 list_splice_init(&sbi->s_active_transaction,
4332 &sbi->s_closed_transaction);
4333 sbi->s_last_transaction = handle->h_transaction->t_tid;
4334 }
4335 spin_unlock(&sbi->s_md_lock);
4336
4337 ext4_mb_free_committed_blocks(sb);
4338}
4339
4340static int ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
4341 ext4_group_t group, ext4_grpblk_t block, int count)
4342{
4343 struct ext4_group_info *db = e4b->bd_info;
4344 struct super_block *sb = e4b->bd_sb;
4345 struct ext4_sb_info *sbi = EXT4_SB(sb);
4346 struct ext4_free_metadata *md;
4347 int i;
4348
4349 BUG_ON(e4b->bd_bitmap_page == NULL);
4350 BUG_ON(e4b->bd_buddy_page == NULL);
4351
4352 ext4_lock_group(sb, group);
4353 for (i = 0; i < count; i++) {
4354 md = db->bb_md_cur;
4355 if (md && db->bb_tid != handle->h_transaction->t_tid) {
4356 db->bb_md_cur = NULL;
4357 md = NULL;
4358 }
4359
4360 if (md == NULL) {
4361 ext4_unlock_group(sb, group);
4362 md = kmalloc(sizeof(*md), GFP_NOFS);
4363 if (md == NULL)
4364 return -ENOMEM;
4365 md->num = 0;
4366 md->group = group;
4367
4368 ext4_lock_group(sb, group);
4369 if (db->bb_md_cur == NULL) {
4370 spin_lock(&sbi->s_md_lock);
4371 list_add(&md->list, &sbi->s_active_transaction);
4372 spin_unlock(&sbi->s_md_lock);
4373 /* protect buddy cache from being freed,
4374 * otherwise we'll refresh it from
4375 * on-disk bitmap and lose not-yet-available
4376 * blocks */
4377 page_cache_get(e4b->bd_buddy_page);
4378 page_cache_get(e4b->bd_bitmap_page);
4379 db->bb_md_cur = md;
4380 db->bb_tid = handle->h_transaction->t_tid;
4381 mb_debug("new md 0x%p for group %lu\n",
4382 md, md->group);
4383 } else {
4384 kfree(md);
4385 md = db->bb_md_cur;
4386 }
4387 }
4388
4389 BUG_ON(md->num >= EXT4_BB_MAX_BLOCKS);
4390 md->blocks[md->num] = block + i;
4391 md->num++;
4392 if (md->num == EXT4_BB_MAX_BLOCKS) {
4393 /* no more space, put full container on a sb's list */
4394 db->bb_md_cur = NULL;
4395 }
4396 }
4397 ext4_unlock_group(sb, group);
4398 return 0;
4399}
4400
4401/*
4402 * Main entry point into mballoc to free blocks
4403 */
4404void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
4405 unsigned long block, unsigned long count,
4406 int metadata, unsigned long *freed)
4407{
4408 struct buffer_head *bitmap_bh = 0;
4409 struct super_block *sb = inode->i_sb;
4410 struct ext4_allocation_context ac;
4411 struct ext4_group_desc *gdp;
4412 struct ext4_super_block *es;
4413 unsigned long overflow;
4414 ext4_grpblk_t bit;
4415 struct buffer_head *gd_bh;
4416 ext4_group_t block_group;
4417 struct ext4_sb_info *sbi;
4418 struct ext4_buddy e4b;
4419 int err = 0;
4420 int ret;
4421
4422 *freed = 0;
4423
4424 ext4_mb_poll_new_transaction(sb, handle);
4425
4426 sbi = EXT4_SB(sb);
4427 es = EXT4_SB(sb)->s_es;
4428 if (block < le32_to_cpu(es->s_first_data_block) ||
4429 block + count < block ||
4430 block + count > ext4_blocks_count(es)) {
4431 ext4_error(sb, __FUNCTION__,
4432 "Freeing blocks not in datazone - "
4433 "block = %lu, count = %lu", block, count);
4434 goto error_return;
4435 }
4436
4437 ext4_debug("freeing block %lu\n", block);
4438
4439 ac.ac_op = EXT4_MB_HISTORY_FREE;
4440 ac.ac_inode = inode;
4441 ac.ac_sb = sb;
4442
4443do_more:
4444 overflow = 0;
4445 ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
4446
4447 /*
4448 * Check to see if we are freeing blocks across a group
4449 * boundary.
4450 */
4451 if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) {
4452 overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb);
4453 count -= overflow;
4454 }
4455 bitmap_bh = read_block_bitmap(sb, block_group);
4456 if (!bitmap_bh)
4457 goto error_return;
4458 gdp = ext4_get_group_desc(sb, block_group, &gd_bh);
4459 if (!gdp)
4460 goto error_return;
4461
4462 if (in_range(ext4_block_bitmap(sb, gdp), block, count) ||
4463 in_range(ext4_inode_bitmap(sb, gdp), block, count) ||
4464 in_range(block, ext4_inode_table(sb, gdp),
4465 EXT4_SB(sb)->s_itb_per_group) ||
4466 in_range(block + count - 1, ext4_inode_table(sb, gdp),
4467 EXT4_SB(sb)->s_itb_per_group)) {
4468
4469 ext4_error(sb, __FUNCTION__,
4470 "Freeing blocks in system zone - "
4471 "Block = %lu, count = %lu", block, count);
4472 }
4473
4474 BUFFER_TRACE(bitmap_bh, "getting write access");
4475 err = ext4_journal_get_write_access(handle, bitmap_bh);
4476 if (err)
4477 goto error_return;
4478
4479 /*
4480 * We are about to modify some metadata. Call the journal APIs
4481 * to unshare ->b_data if a currently-committing transaction is
4482 * using it
4483 */
4484 BUFFER_TRACE(gd_bh, "get_write_access");
4485 err = ext4_journal_get_write_access(handle, gd_bh);
4486 if (err)
4487 goto error_return;
4488
4489 err = ext4_mb_load_buddy(sb, block_group, &e4b);
4490 if (err)
4491 goto error_return;
4492
4493#ifdef AGGRESSIVE_CHECK
4494 {
4495 int i;
4496 for (i = 0; i < count; i++)
4497 BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
4498 }
4499#endif
4500 mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data,
4501 bit, count);
4502
4503 /* We dirtied the bitmap block */
4504 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
4505 err = ext4_journal_dirty_metadata(handle, bitmap_bh);
4506
4507 ac.ac_b_ex.fe_group = block_group;
4508 ac.ac_b_ex.fe_start = bit;
4509 ac.ac_b_ex.fe_len = count;
4510 ext4_mb_store_history(&ac);
4511
4512 if (metadata) {
4513 /* blocks being freed are metadata. these blocks shouldn't
4514 * be used until this transaction is committed */
4515 ext4_mb_free_metadata(handle, &e4b, block_group, bit, count);
4516 } else {
4517 ext4_lock_group(sb, block_group);
4518 err = mb_free_blocks(inode, &e4b, bit, count);
4519 ext4_mb_return_to_preallocation(inode, &e4b, block, count);
4520 ext4_unlock_group(sb, block_group);
4521 BUG_ON(err != 0);
4522 }
4523
4524 spin_lock(sb_bgl_lock(sbi, block_group));
4525 gdp->bg_free_blocks_count =
4526 cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count);
4527 gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
4528 spin_unlock(sb_bgl_lock(sbi, block_group));
4529 percpu_counter_add(&sbi->s_freeblocks_counter, count);
4530
4531 ext4_mb_release_desc(&e4b);
4532
4533 *freed += count;
4534
4535 /* And the group descriptor block */
4536 BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
4537 ret = ext4_journal_dirty_metadata(handle, gd_bh);
4538 if (!err)
4539 err = ret;
4540
4541 if (overflow && !err) {
4542 block += count;
4543 count = overflow;
4544 put_bh(bitmap_bh);
4545 goto do_more;
4546 }
4547 sb->s_dirt = 1;
4548error_return:
4549 brelse(bitmap_bh);
4550 ext4_std_error(sb, err);
4551 return;
4552}
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
new file mode 100644
index 000000000000..3ebc2332f52e
--- /dev/null
+++ b/fs/ext4/migrate.c
@@ -0,0 +1,560 @@
1/*
2 * Copyright IBM Corporation, 2007
3 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2.1 of the GNU Lesser General Public License
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/ext4_jbd2.h>
17#include <linux/ext4_fs_extents.h>
18
19/*
20 * The contiguous blocks details which can be
21 * represented by a single extent
22 */
23struct list_blocks_struct {
24 ext4_lblk_t first_block, last_block;
25 ext4_fsblk_t first_pblock, last_pblock;
26};
27
28static int finish_range(handle_t *handle, struct inode *inode,
29 struct list_blocks_struct *lb)
30
31{
32 int retval = 0, needed;
33 struct ext4_extent newext;
34 struct ext4_ext_path *path;
35 if (lb->first_pblock == 0)
36 return 0;
37
38 /* Add the extent to temp inode*/
39 newext.ee_block = cpu_to_le32(lb->first_block);
40 newext.ee_len = cpu_to_le16(lb->last_block - lb->first_block + 1);
41 ext4_ext_store_pblock(&newext, lb->first_pblock);
42 path = ext4_ext_find_extent(inode, lb->first_block, NULL);
43
44 if (IS_ERR(path)) {
45 retval = PTR_ERR(path);
46 goto err_out;
47 }
48
49 /*
50 * Calculate the credit needed to inserting this extent
51 * Since we are doing this in loop we may accumalate extra
52 * credit. But below we try to not accumalate too much
53 * of them by restarting the journal.
54 */
55 needed = ext4_ext_calc_credits_for_insert(inode, path);
56
57 /*
58 * Make sure the credit we accumalated is not really high
59 */
60 if (needed && handle->h_buffer_credits >= EXT4_RESERVE_TRANS_BLOCKS) {
61 retval = ext4_journal_restart(handle, needed);
62 if (retval)
63 goto err_out;
64 }
65 if (needed) {
66 retval = ext4_journal_extend(handle, needed);
67 if (retval != 0) {
68 /*
69 * IF not able to extend the journal restart the journal
70 */
71 retval = ext4_journal_restart(handle, needed);
72 if (retval)
73 goto err_out;
74 }
75 }
76 retval = ext4_ext_insert_extent(handle, inode, path, &newext);
77err_out:
78 lb->first_pblock = 0;
79 return retval;
80}
81
82static int update_extent_range(handle_t *handle, struct inode *inode,
83 ext4_fsblk_t pblock, ext4_lblk_t blk_num,
84 struct list_blocks_struct *lb)
85{
86 int retval;
87 /*
88 * See if we can add on to the existing range (if it exists)
89 */
90 if (lb->first_pblock &&
91 (lb->last_pblock+1 == pblock) &&
92 (lb->last_block+1 == blk_num)) {
93 lb->last_pblock = pblock;
94 lb->last_block = blk_num;
95 return 0;
96 }
97 /*
98 * Start a new range.
99 */
100 retval = finish_range(handle, inode, lb);
101 lb->first_pblock = lb->last_pblock = pblock;
102 lb->first_block = lb->last_block = blk_num;
103
104 return retval;
105}
106
107static int update_ind_extent_range(handle_t *handle, struct inode *inode,
108 ext4_fsblk_t pblock, ext4_lblk_t *blk_nump,
109 struct list_blocks_struct *lb)
110{
111 struct buffer_head *bh;
112 __le32 *i_data;
113 int i, retval = 0;
114 ext4_lblk_t blk_count = *blk_nump;
115 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
116
117 if (!pblock) {
118 /* Only update the file block number */
119 *blk_nump += max_entries;
120 return 0;
121 }
122
123 bh = sb_bread(inode->i_sb, pblock);
124 if (!bh)
125 return -EIO;
126
127 i_data = (__le32 *)bh->b_data;
128 for (i = 0; i < max_entries; i++, blk_count++) {
129 if (i_data[i]) {
130 retval = update_extent_range(handle, inode,
131 le32_to_cpu(i_data[i]),
132 blk_count, lb);
133 if (retval)
134 break;
135 }
136 }
137
138 /* Update the file block number */
139 *blk_nump = blk_count;
140 put_bh(bh);
141 return retval;
142
143}
144
145static int update_dind_extent_range(handle_t *handle, struct inode *inode,
146 ext4_fsblk_t pblock, ext4_lblk_t *blk_nump,
147 struct list_blocks_struct *lb)
148{
149 struct buffer_head *bh;
150 __le32 *i_data;
151 int i, retval = 0;
152 ext4_lblk_t blk_count = *blk_nump;
153 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
154
155 if (!pblock) {
156 /* Only update the file block number */
157 *blk_nump += max_entries * max_entries;
158 return 0;
159 }
160 bh = sb_bread(inode->i_sb, pblock);
161 if (!bh)
162 return -EIO;
163
164 i_data = (__le32 *)bh->b_data;
165 for (i = 0; i < max_entries; i++) {
166 if (i_data[i]) {
167 retval = update_ind_extent_range(handle, inode,
168 le32_to_cpu(i_data[i]),
169 &blk_count, lb);
170 if (retval)
171 break;
172 } else {
173 /* Only update the file block number */
174 blk_count += max_entries;
175 }
176 }
177
178 /* Update the file block number */
179 *blk_nump = blk_count;
180 put_bh(bh);
181 return retval;
182
183}
184
185static int update_tind_extent_range(handle_t *handle, struct inode *inode,
186 ext4_fsblk_t pblock, ext4_lblk_t *blk_nump,
187 struct list_blocks_struct *lb)
188{
189 struct buffer_head *bh;
190 __le32 *i_data;
191 int i, retval = 0;
192 ext4_lblk_t blk_count = *blk_nump;
193 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
194
195 if (!pblock) {
196 /* Only update the file block number */
197 *blk_nump += max_entries * max_entries * max_entries;
198 return 0;
199 }
200 bh = sb_bread(inode->i_sb, pblock);
201 if (!bh)
202 return -EIO;
203
204 i_data = (__le32 *)bh->b_data;
205 for (i = 0; i < max_entries; i++) {
206 if (i_data[i]) {
207 retval = update_dind_extent_range(handle, inode,
208 le32_to_cpu(i_data[i]),
209 &blk_count, lb);
210 if (retval)
211 break;
212 } else
213 /* Only update the file block number */
214 blk_count += max_entries * max_entries;
215 }
216 /* Update the file block number */
217 *blk_nump = blk_count;
218 put_bh(bh);
219 return retval;
220
221}
222
223static int free_dind_blocks(handle_t *handle,
224 struct inode *inode, __le32 i_data)
225{
226 int i;
227 __le32 *tmp_idata;
228 struct buffer_head *bh;
229 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
230
231 bh = sb_bread(inode->i_sb, le32_to_cpu(i_data));
232 if (!bh)
233 return -EIO;
234
235 tmp_idata = (__le32 *)bh->b_data;
236 for (i = 0; i < max_entries; i++) {
237 if (tmp_idata[i])
238 ext4_free_blocks(handle, inode,
239 le32_to_cpu(tmp_idata[i]), 1, 1);
240 }
241 put_bh(bh);
242 ext4_free_blocks(handle, inode, le32_to_cpu(i_data), 1, 1);
243 return 0;
244}
245
246static int free_tind_blocks(handle_t *handle,
247 struct inode *inode, __le32 i_data)
248{
249 int i, retval = 0;
250 __le32 *tmp_idata;
251 struct buffer_head *bh;
252 unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
253
254 bh = sb_bread(inode->i_sb, le32_to_cpu(i_data));
255 if (!bh)
256 return -EIO;
257
258 tmp_idata = (__le32 *)bh->b_data;
259 for (i = 0; i < max_entries; i++) {
260 if (tmp_idata[i]) {
261 retval = free_dind_blocks(handle,
262 inode, tmp_idata[i]);
263 if (retval) {
264 put_bh(bh);
265 return retval;
266 }
267 }
268 }
269 put_bh(bh);
270 ext4_free_blocks(handle, inode, le32_to_cpu(i_data), 1, 1);
271 return 0;
272}
273
274static int free_ind_block(handle_t *handle, struct inode *inode)
275{
276 int retval;
277 struct ext4_inode_info *ei = EXT4_I(inode);
278
279 if (ei->i_data[EXT4_IND_BLOCK])
280 ext4_free_blocks(handle, inode,
281 le32_to_cpu(ei->i_data[EXT4_IND_BLOCK]), 1, 1);
282
283 if (ei->i_data[EXT4_DIND_BLOCK]) {
284 retval = free_dind_blocks(handle, inode,
285 ei->i_data[EXT4_DIND_BLOCK]);
286 if (retval)
287 return retval;
288 }
289
290 if (ei->i_data[EXT4_TIND_BLOCK]) {
291 retval = free_tind_blocks(handle, inode,
292 ei->i_data[EXT4_TIND_BLOCK]);
293 if (retval)
294 return retval;
295 }
296 return 0;
297}
298
299static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
300 struct inode *tmp_inode, int retval)
301{
302 struct ext4_inode_info *ei = EXT4_I(inode);
303 struct ext4_inode_info *tmp_ei = EXT4_I(tmp_inode);
304
305 retval = free_ind_block(handle, inode);
306 if (retval)
307 goto err_out;
308
309 /*
310 * One credit accounted for writing the
311 * i_data field of the original inode
312 */
313 retval = ext4_journal_extend(handle, 1);
314 if (retval != 0) {
315 retval = ext4_journal_restart(handle, 1);
316 if (retval)
317 goto err_out;
318 }
319
320 /*
321 * We have the extent map build with the tmp inode.
322 * Now copy the i_data across
323 */
324 ei->i_flags |= EXT4_EXTENTS_FL;
325 memcpy(ei->i_data, tmp_ei->i_data, sizeof(ei->i_data));
326
327 /*
328 * Update i_blocks with the new blocks that got
329 * allocated while adding extents for extent index
330 * blocks.
331 *
332 * While converting to extents we need not
333 * update the orignal inode i_blocks for extent blocks
334 * via quota APIs. The quota update happened via tmp_inode already.
335 */
336 spin_lock(&inode->i_lock);
337 inode->i_blocks += tmp_inode->i_blocks;
338 spin_unlock(&inode->i_lock);
339
340 ext4_mark_inode_dirty(handle, inode);
341err_out:
342 return retval;
343}
344
345static int free_ext_idx(handle_t *handle, struct inode *inode,
346 struct ext4_extent_idx *ix)
347{
348 int i, retval = 0;
349 ext4_fsblk_t block;
350 struct buffer_head *bh;
351 struct ext4_extent_header *eh;
352
353 block = idx_pblock(ix);
354 bh = sb_bread(inode->i_sb, block);
355 if (!bh)
356 return -EIO;
357
358 eh = (struct ext4_extent_header *)bh->b_data;
359 if (eh->eh_depth != 0) {
360 ix = EXT_FIRST_INDEX(eh);
361 for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
362 retval = free_ext_idx(handle, inode, ix);
363 if (retval)
364 break;
365 }
366 }
367 put_bh(bh);
368 ext4_free_blocks(handle, inode, block, 1, 1);
369 return retval;
370}
371
372/*
373 * Free the extent meta data blocks only
374 */
375static int free_ext_block(handle_t *handle, struct inode *inode)
376{
377 int i, retval = 0;
378 struct ext4_inode_info *ei = EXT4_I(inode);
379 struct ext4_extent_header *eh = (struct ext4_extent_header *)ei->i_data;
380 struct ext4_extent_idx *ix;
381 if (eh->eh_depth == 0)
382 /*
383 * No extra blocks allocated for extent meta data
384 */
385 return 0;
386 ix = EXT_FIRST_INDEX(eh);
387 for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ix++) {
388 retval = free_ext_idx(handle, inode, ix);
389 if (retval)
390 return retval;
391 }
392 return retval;
393
394}
395
396int ext4_ext_migrate(struct inode *inode, struct file *filp,
397 unsigned int cmd, unsigned long arg)
398{
399 handle_t *handle;
400 int retval = 0, i;
401 __le32 *i_data;
402 ext4_lblk_t blk_count = 0;
403 struct ext4_inode_info *ei;
404 struct inode *tmp_inode = NULL;
405 struct list_blocks_struct lb;
406 unsigned long max_entries;
407
408 if (!test_opt(inode->i_sb, EXTENTS))
409 /*
410 * if mounted with noextents we don't allow the migrate
411 */
412 return -EINVAL;
413
414 if ((EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
415 return -EINVAL;
416
417 down_write(&EXT4_I(inode)->i_data_sem);
418 handle = ext4_journal_start(inode,
419 EXT4_DATA_TRANS_BLOCKS(inode->i_sb) +
420 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
421 2 * EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)
422 + 1);
423 if (IS_ERR(handle)) {
424 retval = PTR_ERR(handle);
425 goto err_out;
426 }
427 tmp_inode = ext4_new_inode(handle,
428 inode->i_sb->s_root->d_inode,
429 S_IFREG);
430 if (IS_ERR(tmp_inode)) {
431 retval = -ENOMEM;
432 ext4_journal_stop(handle);
433 tmp_inode = NULL;
434 goto err_out;
435 }
436 i_size_write(tmp_inode, i_size_read(inode));
437 /*
438 * We don't want the inode to be reclaimed
439 * if we got interrupted in between. We have
440 * this tmp inode carrying reference to the
441 * data blocks of the original file. We set
442 * the i_nlink to zero at the last stage after
443 * switching the original file to extent format
444 */
445 tmp_inode->i_nlink = 1;
446
447 ext4_ext_tree_init(handle, tmp_inode);
448 ext4_orphan_add(handle, tmp_inode);
449 ext4_journal_stop(handle);
450
451 ei = EXT4_I(inode);
452 i_data = ei->i_data;
453 memset(&lb, 0, sizeof(lb));
454
455 /* 32 bit block address 4 bytes */
456 max_entries = inode->i_sb->s_blocksize >> 2;
457
458 /*
459 * start with one credit accounted for
460 * superblock modification.
461 *
462 * For the tmp_inode we already have commited the
463 * trascation that created the inode. Later as and
464 * when we add extents we extent the journal
465 */
466 handle = ext4_journal_start(inode, 1);
467 for (i = 0; i < EXT4_NDIR_BLOCKS; i++, blk_count++) {
468 if (i_data[i]) {
469 retval = update_extent_range(handle, tmp_inode,
470 le32_to_cpu(i_data[i]),
471 blk_count, &lb);
472 if (retval)
473 goto err_out;
474 }
475 }
476 if (i_data[EXT4_IND_BLOCK]) {
477 retval = update_ind_extent_range(handle, tmp_inode,
478 le32_to_cpu(i_data[EXT4_IND_BLOCK]),
479 &blk_count, &lb);
480 if (retval)
481 goto err_out;
482 } else
483 blk_count += max_entries;
484 if (i_data[EXT4_DIND_BLOCK]) {
485 retval = update_dind_extent_range(handle, tmp_inode,
486 le32_to_cpu(i_data[EXT4_DIND_BLOCK]),
487 &blk_count, &lb);
488 if (retval)
489 goto err_out;
490 } else
491 blk_count += max_entries * max_entries;
492 if (i_data[EXT4_TIND_BLOCK]) {
493 retval = update_tind_extent_range(handle, tmp_inode,
494 le32_to_cpu(i_data[EXT4_TIND_BLOCK]),
495 &blk_count, &lb);
496 if (retval)
497 goto err_out;
498 }
499 /*
500 * Build the last extent
501 */
502 retval = finish_range(handle, tmp_inode, &lb);
503err_out:
504 /*
505 * We are either freeing extent information or indirect
506 * blocks. During this we touch superblock, group descriptor
507 * and block bitmap. Later we mark the tmp_inode dirty
508 * via ext4_ext_tree_init. So allocate a credit of 4
509 * We may update quota (user and group).
510 *
511 * FIXME!! we may be touching bitmaps in different block groups.
512 */
513 if (ext4_journal_extend(handle,
514 4 + 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb)) != 0)
515 ext4_journal_restart(handle,
516 4 + 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb));
517 if (retval)
518 /*
519 * Failure case delete the extent information with the
520 * tmp_inode
521 */
522 free_ext_block(handle, tmp_inode);
523 else
524 retval = ext4_ext_swap_inode_data(handle, inode,
525 tmp_inode, retval);
526
527 /*
528 * Mark the tmp_inode as of size zero
529 */
530 i_size_write(tmp_inode, 0);
531
532 /*
533 * set the i_blocks count to zero
534 * so that the ext4_delete_inode does the
535 * right job
536 *
537 * We don't need to take the i_lock because
538 * the inode is not visible to user space.
539 */
540 tmp_inode->i_blocks = 0;
541
542 /* Reset the extent details */
543 ext4_ext_tree_init(handle, tmp_inode);
544
545 /*
546 * Set the i_nlink to zero so that
547 * generic_drop_inode really deletes the
548 * inode
549 */
550 tmp_inode->i_nlink = 0;
551
552 ext4_journal_stop(handle);
553
554 up_write(&EXT4_I(inode)->i_data_sem);
555
556 if (tmp_inode)
557 iput(tmp_inode);
558
559 return retval;
560}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 94ee6f315dc1..67b6d8a1ceff 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -51,7 +51,7 @@
51 51
52static struct buffer_head *ext4_append(handle_t *handle, 52static struct buffer_head *ext4_append(handle_t *handle,
53 struct inode *inode, 53 struct inode *inode,
54 u32 *block, int *err) 54 ext4_lblk_t *block, int *err)
55{ 55{
56 struct buffer_head *bh; 56 struct buffer_head *bh;
57 57
@@ -144,8 +144,8 @@ struct dx_map_entry
144 u16 size; 144 u16 size;
145}; 145};
146 146
147static inline unsigned dx_get_block (struct dx_entry *entry); 147static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
148static void dx_set_block (struct dx_entry *entry, unsigned value); 148static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
149static inline unsigned dx_get_hash (struct dx_entry *entry); 149static inline unsigned dx_get_hash (struct dx_entry *entry);
150static void dx_set_hash (struct dx_entry *entry, unsigned value); 150static void dx_set_hash (struct dx_entry *entry, unsigned value);
151static unsigned dx_get_count (struct dx_entry *entries); 151static unsigned dx_get_count (struct dx_entry *entries);
@@ -166,7 +166,8 @@ static void dx_sort_map(struct dx_map_entry *map, unsigned count);
166static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to, 166static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to,
167 struct dx_map_entry *offsets, int count); 167 struct dx_map_entry *offsets, int count);
168static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size); 168static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size);
169static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); 169static void dx_insert_block(struct dx_frame *frame,
170 u32 hash, ext4_lblk_t block);
170static int ext4_htree_next_block(struct inode *dir, __u32 hash, 171static int ext4_htree_next_block(struct inode *dir, __u32 hash,
171 struct dx_frame *frame, 172 struct dx_frame *frame,
172 struct dx_frame *frames, 173 struct dx_frame *frames,
@@ -181,12 +182,12 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
181 * Mask them off for now. 182 * Mask them off for now.
182 */ 183 */
183 184
184static inline unsigned dx_get_block (struct dx_entry *entry) 185static inline ext4_lblk_t dx_get_block(struct dx_entry *entry)
185{ 186{
186 return le32_to_cpu(entry->block) & 0x00ffffff; 187 return le32_to_cpu(entry->block) & 0x00ffffff;
187} 188}
188 189
189static inline void dx_set_block (struct dx_entry *entry, unsigned value) 190static inline void dx_set_block(struct dx_entry *entry, ext4_lblk_t value)
190{ 191{
191 entry->block = cpu_to_le32(value); 192 entry->block = cpu_to_le32(value);
192} 193}
@@ -243,8 +244,8 @@ static void dx_show_index (char * label, struct dx_entry *entries)
243 int i, n = dx_get_count (entries); 244 int i, n = dx_get_count (entries);
244 printk("%s index ", label); 245 printk("%s index ", label);
245 for (i = 0; i < n; i++) { 246 for (i = 0; i < n; i++) {
246 printk("%x->%u ", i? dx_get_hash(entries + i) : 247 printk("%x->%lu ", i? dx_get_hash(entries + i) :
247 0, dx_get_block(entries + i)); 248 0, (unsigned long)dx_get_block(entries + i));
248 } 249 }
249 printk("\n"); 250 printk("\n");
250} 251}
@@ -280,7 +281,7 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_ent
280 space += EXT4_DIR_REC_LEN(de->name_len); 281 space += EXT4_DIR_REC_LEN(de->name_len);
281 names++; 282 names++;
282 } 283 }
283 de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); 284 de = ext4_next_entry(de);
284 } 285 }
285 printk("(%i)\n", names); 286 printk("(%i)\n", names);
286 return (struct stats) { names, space, 1 }; 287 return (struct stats) { names, space, 1 };
@@ -297,7 +298,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
297 printk("%i indexed blocks...\n", count); 298 printk("%i indexed blocks...\n", count);
298 for (i = 0; i < count; i++, entries++) 299 for (i = 0; i < count; i++, entries++)
299 { 300 {
300 u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; 301 ext4_lblk_t block = dx_get_block(entries);
302 ext4_lblk_t hash = i ? dx_get_hash(entries): 0;
301 u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; 303 u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
302 struct stats stats; 304 struct stats stats;
303 printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); 305 printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range);
@@ -551,7 +553,8 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
551 */ 553 */
552static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p) 554static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p)
553{ 555{
554 return (struct ext4_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len)); 556 return (struct ext4_dir_entry_2 *)((char *)p +
557 ext4_rec_len_from_disk(p->rec_len));
555} 558}
556 559
557/* 560/*
@@ -560,7 +563,7 @@ static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *
560 * into the tree. If there is an error it is returned in err. 563 * into the tree. If there is an error it is returned in err.
561 */ 564 */
562static int htree_dirblock_to_tree(struct file *dir_file, 565static int htree_dirblock_to_tree(struct file *dir_file,
563 struct inode *dir, int block, 566 struct inode *dir, ext4_lblk_t block,
564 struct dx_hash_info *hinfo, 567 struct dx_hash_info *hinfo,
565 __u32 start_hash, __u32 start_minor_hash) 568 __u32 start_hash, __u32 start_minor_hash)
566{ 569{
@@ -568,7 +571,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
568 struct ext4_dir_entry_2 *de, *top; 571 struct ext4_dir_entry_2 *de, *top;
569 int err, count = 0; 572 int err, count = 0;
570 573
571 dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); 574 dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
575 (unsigned long)block));
572 if (!(bh = ext4_bread (NULL, dir, block, 0, &err))) 576 if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
573 return err; 577 return err;
574 578
@@ -620,9 +624,9 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
620 struct ext4_dir_entry_2 *de; 624 struct ext4_dir_entry_2 *de;
621 struct dx_frame frames[2], *frame; 625 struct dx_frame frames[2], *frame;
622 struct inode *dir; 626 struct inode *dir;
623 int block, err; 627 ext4_lblk_t block;
624 int count = 0; 628 int count = 0;
625 int ret; 629 int ret, err;
626 __u32 hashval; 630 __u32 hashval;
627 631
628 dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, 632 dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
@@ -720,7 +724,7 @@ static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
720 cond_resched(); 724 cond_resched();
721 } 725 }
722 /* XXX: do we need to check rec_len == 0 case? -Chris */ 726 /* XXX: do we need to check rec_len == 0 case? -Chris */
723 de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); 727 de = ext4_next_entry(de);
724 } 728 }
725 return count; 729 return count;
726} 730}
@@ -752,7 +756,7 @@ static void dx_sort_map (struct dx_map_entry *map, unsigned count)
752 } while(more); 756 } while(more);
753} 757}
754 758
755static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) 759static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
756{ 760{
757 struct dx_entry *entries = frame->entries; 761 struct dx_entry *entries = frame->entries;
758 struct dx_entry *old = frame->at, *new = old + 1; 762 struct dx_entry *old = frame->at, *new = old + 1;
@@ -820,7 +824,7 @@ static inline int search_dirblock(struct buffer_head * bh,
820 return 1; 824 return 1;
821 } 825 }
822 /* prevent looping on a bad block */ 826 /* prevent looping on a bad block */
823 de_len = le16_to_cpu(de->rec_len); 827 de_len = ext4_rec_len_from_disk(de->rec_len);
824 if (de_len <= 0) 828 if (de_len <= 0)
825 return -1; 829 return -1;
826 offset += de_len; 830 offset += de_len;
@@ -847,23 +851,20 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
847 struct super_block * sb; 851 struct super_block * sb;
848 struct buffer_head * bh_use[NAMEI_RA_SIZE]; 852 struct buffer_head * bh_use[NAMEI_RA_SIZE];
849 struct buffer_head * bh, *ret = NULL; 853 struct buffer_head * bh, *ret = NULL;
850 unsigned long start, block, b; 854 ext4_lblk_t start, block, b;
851 int ra_max = 0; /* Number of bh's in the readahead 855 int ra_max = 0; /* Number of bh's in the readahead
852 buffer, bh_use[] */ 856 buffer, bh_use[] */
853 int ra_ptr = 0; /* Current index into readahead 857 int ra_ptr = 0; /* Current index into readahead
854 buffer */ 858 buffer */
855 int num = 0; 859 int num = 0;
856 int nblocks, i, err; 860 ext4_lblk_t nblocks;
861 int i, err;
857 struct inode *dir = dentry->d_parent->d_inode; 862 struct inode *dir = dentry->d_parent->d_inode;
858 int namelen; 863 int namelen;
859 const u8 *name;
860 unsigned blocksize;
861 864
862 *res_dir = NULL; 865 *res_dir = NULL;
863 sb = dir->i_sb; 866 sb = dir->i_sb;
864 blocksize = sb->s_blocksize;
865 namelen = dentry->d_name.len; 867 namelen = dentry->d_name.len;
866 name = dentry->d_name.name;
867 if (namelen > EXT4_NAME_LEN) 868 if (namelen > EXT4_NAME_LEN)
868 return NULL; 869 return NULL;
869 if (is_dx(dir)) { 870 if (is_dx(dir)) {
@@ -914,7 +915,8 @@ restart:
914 if (!buffer_uptodate(bh)) { 915 if (!buffer_uptodate(bh)) {
915 /* read error, skip block & hope for the best */ 916 /* read error, skip block & hope for the best */
916 ext4_error(sb, __FUNCTION__, "reading directory #%lu " 917 ext4_error(sb, __FUNCTION__, "reading directory #%lu "
917 "offset %lu", dir->i_ino, block); 918 "offset %lu", dir->i_ino,
919 (unsigned long)block);
918 brelse(bh); 920 brelse(bh);
919 goto next; 921 goto next;
920 } 922 }
@@ -961,7 +963,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
961 struct dx_frame frames[2], *frame; 963 struct dx_frame frames[2], *frame;
962 struct ext4_dir_entry_2 *de, *top; 964 struct ext4_dir_entry_2 *de, *top;
963 struct buffer_head *bh; 965 struct buffer_head *bh;
964 unsigned long block; 966 ext4_lblk_t block;
965 int retval; 967 int retval;
966 int namelen = dentry->d_name.len; 968 int namelen = dentry->d_name.len;
967 const u8 *name = dentry->d_name.name; 969 const u8 *name = dentry->d_name.name;
@@ -1128,7 +1130,7 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
1128 rec_len = EXT4_DIR_REC_LEN(de->name_len); 1130 rec_len = EXT4_DIR_REC_LEN(de->name_len);
1129 memcpy (to, de, rec_len); 1131 memcpy (to, de, rec_len);
1130 ((struct ext4_dir_entry_2 *) to)->rec_len = 1132 ((struct ext4_dir_entry_2 *) to)->rec_len =
1131 cpu_to_le16(rec_len); 1133 ext4_rec_len_to_disk(rec_len);
1132 de->inode = 0; 1134 de->inode = 0;
1133 map++; 1135 map++;
1134 to += rec_len; 1136 to += rec_len;
@@ -1147,13 +1149,12 @@ static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size)
1147 1149
1148 prev = to = de; 1150 prev = to = de;
1149 while ((char*)de < base + size) { 1151 while ((char*)de < base + size) {
1150 next = (struct ext4_dir_entry_2 *) ((char *) de + 1152 next = ext4_next_entry(de);
1151 le16_to_cpu(de->rec_len));
1152 if (de->inode && de->name_len) { 1153 if (de->inode && de->name_len) {
1153 rec_len = EXT4_DIR_REC_LEN(de->name_len); 1154 rec_len = EXT4_DIR_REC_LEN(de->name_len);
1154 if (de > to) 1155 if (de > to)
1155 memmove(to, de, rec_len); 1156 memmove(to, de, rec_len);
1156 to->rec_len = cpu_to_le16(rec_len); 1157 to->rec_len = ext4_rec_len_to_disk(rec_len);
1157 prev = to; 1158 prev = to;
1158 to = (struct ext4_dir_entry_2 *) (((char *) to) + rec_len); 1159 to = (struct ext4_dir_entry_2 *) (((char *) to) + rec_len);
1159 } 1160 }
@@ -1174,7 +1175,7 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1174 unsigned blocksize = dir->i_sb->s_blocksize; 1175 unsigned blocksize = dir->i_sb->s_blocksize;
1175 unsigned count, continued; 1176 unsigned count, continued;
1176 struct buffer_head *bh2; 1177 struct buffer_head *bh2;
1177 u32 newblock; 1178 ext4_lblk_t newblock;
1178 u32 hash2; 1179 u32 hash2;
1179 struct dx_map_entry *map; 1180 struct dx_map_entry *map;
1180 char *data1 = (*bh)->b_data, *data2; 1181 char *data1 = (*bh)->b_data, *data2;
@@ -1221,14 +1222,15 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1221 split = count - move; 1222 split = count - move;
1222 hash2 = map[split].hash; 1223 hash2 = map[split].hash;
1223 continued = hash2 == map[split - 1].hash; 1224 continued = hash2 == map[split - 1].hash;
1224 dxtrace(printk("Split block %i at %x, %i/%i\n", 1225 dxtrace(printk(KERN_INFO "Split block %lu at %x, %i/%i\n",
1225 dx_get_block(frame->at), hash2, split, count-split)); 1226 (unsigned long)dx_get_block(frame->at),
1227 hash2, split, count-split));
1226 1228
1227 /* Fancy dance to stay within two buffers */ 1229 /* Fancy dance to stay within two buffers */
1228 de2 = dx_move_dirents(data1, data2, map + split, count - split); 1230 de2 = dx_move_dirents(data1, data2, map + split, count - split);
1229 de = dx_pack_dirents(data1,blocksize); 1231 de = dx_pack_dirents(data1,blocksize);
1230 de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); 1232 de->rec_len = ext4_rec_len_to_disk(data1 + blocksize - (char *) de);
1231 de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); 1233 de2->rec_len = ext4_rec_len_to_disk(data2 + blocksize - (char *) de2);
1232 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1)); 1234 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1));
1233 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1)); 1235 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1));
1234 1236
@@ -1297,7 +1299,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1297 return -EEXIST; 1299 return -EEXIST;
1298 } 1300 }
1299 nlen = EXT4_DIR_REC_LEN(de->name_len); 1301 nlen = EXT4_DIR_REC_LEN(de->name_len);
1300 rlen = le16_to_cpu(de->rec_len); 1302 rlen = ext4_rec_len_from_disk(de->rec_len);
1301 if ((de->inode? rlen - nlen: rlen) >= reclen) 1303 if ((de->inode? rlen - nlen: rlen) >= reclen)
1302 break; 1304 break;
1303 de = (struct ext4_dir_entry_2 *)((char *)de + rlen); 1305 de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
@@ -1316,11 +1318,11 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1316 1318
1317 /* By now the buffer is marked for journaling */ 1319 /* By now the buffer is marked for journaling */
1318 nlen = EXT4_DIR_REC_LEN(de->name_len); 1320 nlen = EXT4_DIR_REC_LEN(de->name_len);
1319 rlen = le16_to_cpu(de->rec_len); 1321 rlen = ext4_rec_len_from_disk(de->rec_len);
1320 if (de->inode) { 1322 if (de->inode) {
1321 struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen); 1323 struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen);
1322 de1->rec_len = cpu_to_le16(rlen - nlen); 1324 de1->rec_len = ext4_rec_len_to_disk(rlen - nlen);
1323 de->rec_len = cpu_to_le16(nlen); 1325 de->rec_len = ext4_rec_len_to_disk(nlen);
1324 de = de1; 1326 de = de1;
1325 } 1327 }
1326 de->file_type = EXT4_FT_UNKNOWN; 1328 de->file_type = EXT4_FT_UNKNOWN;
@@ -1374,7 +1376,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1374 int retval; 1376 int retval;
1375 unsigned blocksize; 1377 unsigned blocksize;
1376 struct dx_hash_info hinfo; 1378 struct dx_hash_info hinfo;
1377 u32 block; 1379 ext4_lblk_t block;
1378 struct fake_dirent *fde; 1380 struct fake_dirent *fde;
1379 1381
1380 blocksize = dir->i_sb->s_blocksize; 1382 blocksize = dir->i_sb->s_blocksize;
@@ -1397,17 +1399,18 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1397 1399
1398 /* The 0th block becomes the root, move the dirents out */ 1400 /* The 0th block becomes the root, move the dirents out */
1399 fde = &root->dotdot; 1401 fde = &root->dotdot;
1400 de = (struct ext4_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len)); 1402 de = (struct ext4_dir_entry_2 *)((char *)fde +
1403 ext4_rec_len_from_disk(fde->rec_len));
1401 len = ((char *) root) + blocksize - (char *) de; 1404 len = ((char *) root) + blocksize - (char *) de;
1402 memcpy (data1, de, len); 1405 memcpy (data1, de, len);
1403 de = (struct ext4_dir_entry_2 *) data1; 1406 de = (struct ext4_dir_entry_2 *) data1;
1404 top = data1 + len; 1407 top = data1 + len;
1405 while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top) 1408 while ((char *)(de2 = ext4_next_entry(de)) < top)
1406 de = de2; 1409 de = de2;
1407 de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); 1410 de->rec_len = ext4_rec_len_to_disk(data1 + blocksize - (char *) de);
1408 /* Initialize the root; the dot dirents already exist */ 1411 /* Initialize the root; the dot dirents already exist */
1409 de = (struct ext4_dir_entry_2 *) (&root->dotdot); 1412 de = (struct ext4_dir_entry_2 *) (&root->dotdot);
1410 de->rec_len = cpu_to_le16(blocksize - EXT4_DIR_REC_LEN(2)); 1413 de->rec_len = ext4_rec_len_to_disk(blocksize - EXT4_DIR_REC_LEN(2));
1411 memset (&root->info, 0, sizeof(root->info)); 1414 memset (&root->info, 0, sizeof(root->info));
1412 root->info.info_length = sizeof(root->info); 1415 root->info.info_length = sizeof(root->info);
1413 root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; 1416 root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
@@ -1454,7 +1457,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
1454 int retval; 1457 int retval;
1455 int dx_fallback=0; 1458 int dx_fallback=0;
1456 unsigned blocksize; 1459 unsigned blocksize;
1457 u32 block, blocks; 1460 ext4_lblk_t block, blocks;
1458 1461
1459 sb = dir->i_sb; 1462 sb = dir->i_sb;
1460 blocksize = sb->s_blocksize; 1463 blocksize = sb->s_blocksize;
@@ -1487,7 +1490,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
1487 return retval; 1490 return retval;
1488 de = (struct ext4_dir_entry_2 *) bh->b_data; 1491 de = (struct ext4_dir_entry_2 *) bh->b_data;
1489 de->inode = 0; 1492 de->inode = 0;
1490 de->rec_len = cpu_to_le16(blocksize); 1493 de->rec_len = ext4_rec_len_to_disk(blocksize);
1491 return add_dirent_to_buf(handle, dentry, inode, de, bh); 1494 return add_dirent_to_buf(handle, dentry, inode, de, bh);
1492} 1495}
1493 1496
@@ -1531,7 +1534,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1531 dx_get_count(entries), dx_get_limit(entries))); 1534 dx_get_count(entries), dx_get_limit(entries)));
1532 /* Need to split index? */ 1535 /* Need to split index? */
1533 if (dx_get_count(entries) == dx_get_limit(entries)) { 1536 if (dx_get_count(entries) == dx_get_limit(entries)) {
1534 u32 newblock; 1537 ext4_lblk_t newblock;
1535 unsigned icount = dx_get_count(entries); 1538 unsigned icount = dx_get_count(entries);
1536 int levels = frame - frames; 1539 int levels = frame - frames;
1537 struct dx_entry *entries2; 1540 struct dx_entry *entries2;
@@ -1550,7 +1553,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1550 goto cleanup; 1553 goto cleanup;
1551 node2 = (struct dx_node *)(bh2->b_data); 1554 node2 = (struct dx_node *)(bh2->b_data);
1552 entries2 = node2->entries; 1555 entries2 = node2->entries;
1553 node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); 1556 node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize);
1554 node2->fake.inode = 0; 1557 node2->fake.inode = 0;
1555 BUFFER_TRACE(frame->bh, "get_write_access"); 1558 BUFFER_TRACE(frame->bh, "get_write_access");
1556 err = ext4_journal_get_write_access(handle, frame->bh); 1559 err = ext4_journal_get_write_access(handle, frame->bh);
@@ -1648,9 +1651,9 @@ static int ext4_delete_entry (handle_t *handle,
1648 BUFFER_TRACE(bh, "get_write_access"); 1651 BUFFER_TRACE(bh, "get_write_access");
1649 ext4_journal_get_write_access(handle, bh); 1652 ext4_journal_get_write_access(handle, bh);
1650 if (pde) 1653 if (pde)
1651 pde->rec_len = 1654 pde->rec_len = ext4_rec_len_to_disk(
1652 cpu_to_le16(le16_to_cpu(pde->rec_len) + 1655 ext4_rec_len_from_disk(pde->rec_len) +
1653 le16_to_cpu(de->rec_len)); 1656 ext4_rec_len_from_disk(de->rec_len));
1654 else 1657 else
1655 de->inode = 0; 1658 de->inode = 0;
1656 dir->i_version++; 1659 dir->i_version++;
@@ -1658,10 +1661,9 @@ static int ext4_delete_entry (handle_t *handle,
1658 ext4_journal_dirty_metadata(handle, bh); 1661 ext4_journal_dirty_metadata(handle, bh);
1659 return 0; 1662 return 0;
1660 } 1663 }
1661 i += le16_to_cpu(de->rec_len); 1664 i += ext4_rec_len_from_disk(de->rec_len);
1662 pde = de; 1665 pde = de;
1663 de = (struct ext4_dir_entry_2 *) 1666 de = ext4_next_entry(de);
1664 ((char *) de + le16_to_cpu(de->rec_len));
1665 } 1667 }
1666 return -ENOENT; 1668 return -ENOENT;
1667} 1669}
@@ -1824,13 +1826,13 @@ retry:
1824 de = (struct ext4_dir_entry_2 *) dir_block->b_data; 1826 de = (struct ext4_dir_entry_2 *) dir_block->b_data;
1825 de->inode = cpu_to_le32(inode->i_ino); 1827 de->inode = cpu_to_le32(inode->i_ino);
1826 de->name_len = 1; 1828 de->name_len = 1;
1827 de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de->name_len)); 1829 de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len));
1828 strcpy (de->name, "."); 1830 strcpy (de->name, ".");
1829 ext4_set_de_type(dir->i_sb, de, S_IFDIR); 1831 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
1830 de = (struct ext4_dir_entry_2 *) 1832 de = ext4_next_entry(de);
1831 ((char *) de + le16_to_cpu(de->rec_len));
1832 de->inode = cpu_to_le32(dir->i_ino); 1833 de->inode = cpu_to_le32(dir->i_ino);
1833 de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT4_DIR_REC_LEN(1)); 1834 de->rec_len = ext4_rec_len_to_disk(inode->i_sb->s_blocksize -
1835 EXT4_DIR_REC_LEN(1));
1834 de->name_len = 2; 1836 de->name_len = 2;
1835 strcpy (de->name, ".."); 1837 strcpy (de->name, "..");
1836 ext4_set_de_type(dir->i_sb, de, S_IFDIR); 1838 ext4_set_de_type(dir->i_sb, de, S_IFDIR);
@@ -1882,8 +1884,7 @@ static int empty_dir (struct inode * inode)
1882 return 1; 1884 return 1;
1883 } 1885 }
1884 de = (struct ext4_dir_entry_2 *) bh->b_data; 1886 de = (struct ext4_dir_entry_2 *) bh->b_data;
1885 de1 = (struct ext4_dir_entry_2 *) 1887 de1 = ext4_next_entry(de);
1886 ((char *) de + le16_to_cpu(de->rec_len));
1887 if (le32_to_cpu(de->inode) != inode->i_ino || 1888 if (le32_to_cpu(de->inode) != inode->i_ino ||
1888 !le32_to_cpu(de1->inode) || 1889 !le32_to_cpu(de1->inode) ||
1889 strcmp (".", de->name) || 1890 strcmp (".", de->name) ||
@@ -1894,9 +1895,9 @@ static int empty_dir (struct inode * inode)
1894 brelse (bh); 1895 brelse (bh);
1895 return 1; 1896 return 1;
1896 } 1897 }
1897 offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len); 1898 offset = ext4_rec_len_from_disk(de->rec_len) +
1898 de = (struct ext4_dir_entry_2 *) 1899 ext4_rec_len_from_disk(de1->rec_len);
1899 ((char *) de1 + le16_to_cpu(de1->rec_len)); 1900 de = ext4_next_entry(de1);
1900 while (offset < inode->i_size ) { 1901 while (offset < inode->i_size ) {
1901 if (!bh || 1902 if (!bh ||
1902 (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { 1903 (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
@@ -1925,9 +1926,8 @@ static int empty_dir (struct inode * inode)
1925 brelse (bh); 1926 brelse (bh);
1926 return 0; 1927 return 0;
1927 } 1928 }
1928 offset += le16_to_cpu(de->rec_len); 1929 offset += ext4_rec_len_from_disk(de->rec_len);
1929 de = (struct ext4_dir_entry_2 *) 1930 de = ext4_next_entry(de);
1930 ((char *) de + le16_to_cpu(de->rec_len));
1931 } 1931 }
1932 brelse (bh); 1932 brelse (bh);
1933 return 1; 1933 return 1;
@@ -2282,8 +2282,7 @@ retry:
2282} 2282}
2283 2283
2284#define PARENT_INO(buffer) \ 2284#define PARENT_INO(buffer) \
2285 ((struct ext4_dir_entry_2 *) ((char *) buffer + \ 2285 (ext4_next_entry((struct ext4_dir_entry_2 *)(buffer))->inode)
2286 le16_to_cpu(((struct ext4_dir_entry_2 *) buffer)->rec_len)))->inode
2287 2286
2288/* 2287/*
2289 * Anybody can rename anything with this: the permission checks are left to the 2288 * Anybody can rename anything with this: the permission checks are left to the
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index bd8a52bb3999..4fbba60816f4 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -28,7 +28,7 @@ static int verify_group_input(struct super_block *sb,
28 struct ext4_super_block *es = sbi->s_es; 28 struct ext4_super_block *es = sbi->s_es;
29 ext4_fsblk_t start = ext4_blocks_count(es); 29 ext4_fsblk_t start = ext4_blocks_count(es);
30 ext4_fsblk_t end = start + input->blocks_count; 30 ext4_fsblk_t end = start + input->blocks_count;
31 unsigned group = input->group; 31 ext4_group_t group = input->group;
32 ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group; 32 ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
33 unsigned overhead = ext4_bg_has_super(sb, group) ? 33 unsigned overhead = ext4_bg_has_super(sb, group) ?
34 (1 + ext4_bg_num_gdb(sb, group) + 34 (1 + ext4_bg_num_gdb(sb, group) +
@@ -206,7 +206,7 @@ static int setup_new_group_blocks(struct super_block *sb,
206 } 206 }
207 207
208 if (ext4_bg_has_super(sb, input->group)) { 208 if (ext4_bg_has_super(sb, input->group)) {
209 ext4_debug("mark backup superblock %#04lx (+0)\n", start); 209 ext4_debug("mark backup superblock %#04llx (+0)\n", start);
210 ext4_set_bit(0, bh->b_data); 210 ext4_set_bit(0, bh->b_data);
211 } 211 }
212 212
@@ -215,7 +215,7 @@ static int setup_new_group_blocks(struct super_block *sb,
215 i < gdblocks; i++, block++, bit++) { 215 i < gdblocks; i++, block++, bit++) {
216 struct buffer_head *gdb; 216 struct buffer_head *gdb;
217 217
218 ext4_debug("update backup group %#04lx (+%d)\n", block, bit); 218 ext4_debug("update backup group %#04llx (+%d)\n", block, bit);
219 219
220 if ((err = extend_or_restart_transaction(handle, 1, bh))) 220 if ((err = extend_or_restart_transaction(handle, 1, bh)))
221 goto exit_bh; 221 goto exit_bh;
@@ -243,7 +243,7 @@ static int setup_new_group_blocks(struct super_block *sb,
243 i < reserved_gdb; i++, block++, bit++) { 243 i < reserved_gdb; i++, block++, bit++) {
244 struct buffer_head *gdb; 244 struct buffer_head *gdb;
245 245
246 ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit); 246 ext4_debug("clear reserved block %#04llx (+%d)\n", block, bit);
247 247
248 if ((err = extend_or_restart_transaction(handle, 1, bh))) 248 if ((err = extend_or_restart_transaction(handle, 1, bh)))
249 goto exit_bh; 249 goto exit_bh;
@@ -256,10 +256,10 @@ static int setup_new_group_blocks(struct super_block *sb,
256 ext4_set_bit(bit, bh->b_data); 256 ext4_set_bit(bit, bh->b_data);
257 brelse(gdb); 257 brelse(gdb);
258 } 258 }
259 ext4_debug("mark block bitmap %#04x (+%ld)\n", input->block_bitmap, 259 ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap,
260 input->block_bitmap - start); 260 input->block_bitmap - start);
261 ext4_set_bit(input->block_bitmap - start, bh->b_data); 261 ext4_set_bit(input->block_bitmap - start, bh->b_data);
262 ext4_debug("mark inode bitmap %#04x (+%ld)\n", input->inode_bitmap, 262 ext4_debug("mark inode bitmap %#04llx (+%llu)\n", input->inode_bitmap,
263 input->inode_bitmap - start); 263 input->inode_bitmap - start);
264 ext4_set_bit(input->inode_bitmap - start, bh->b_data); 264 ext4_set_bit(input->inode_bitmap - start, bh->b_data);
265 265
@@ -268,7 +268,7 @@ static int setup_new_group_blocks(struct super_block *sb,
268 i < sbi->s_itb_per_group; i++, bit++, block++) { 268 i < sbi->s_itb_per_group; i++, bit++, block++) {
269 struct buffer_head *it; 269 struct buffer_head *it;
270 270
271 ext4_debug("clear inode block %#04lx (+%d)\n", block, bit); 271 ext4_debug("clear inode block %#04llx (+%d)\n", block, bit);
272 272
273 if ((err = extend_or_restart_transaction(handle, 1, bh))) 273 if ((err = extend_or_restart_transaction(handle, 1, bh)))
274 goto exit_bh; 274 goto exit_bh;
@@ -291,7 +291,7 @@ static int setup_new_group_blocks(struct super_block *sb,
291 brelse(bh); 291 brelse(bh);
292 292
293 /* Mark unused entries in inode bitmap used */ 293 /* Mark unused entries in inode bitmap used */
294 ext4_debug("clear inode bitmap %#04x (+%ld)\n", 294 ext4_debug("clear inode bitmap %#04llx (+%llu)\n",
295 input->inode_bitmap, input->inode_bitmap - start); 295 input->inode_bitmap, input->inode_bitmap - start);
296 if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) { 296 if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) {
297 err = PTR_ERR(bh); 297 err = PTR_ERR(bh);
@@ -357,7 +357,7 @@ static int verify_reserved_gdb(struct super_block *sb,
357 struct buffer_head *primary) 357 struct buffer_head *primary)
358{ 358{
359 const ext4_fsblk_t blk = primary->b_blocknr; 359 const ext4_fsblk_t blk = primary->b_blocknr;
360 const unsigned long end = EXT4_SB(sb)->s_groups_count; 360 const ext4_group_t end = EXT4_SB(sb)->s_groups_count;
361 unsigned three = 1; 361 unsigned three = 1;
362 unsigned five = 5; 362 unsigned five = 5;
363 unsigned seven = 7; 363 unsigned seven = 7;
@@ -656,12 +656,12 @@ static void update_backups(struct super_block *sb,
656 int blk_off, char *data, int size) 656 int blk_off, char *data, int size)
657{ 657{
658 struct ext4_sb_info *sbi = EXT4_SB(sb); 658 struct ext4_sb_info *sbi = EXT4_SB(sb);
659 const unsigned long last = sbi->s_groups_count; 659 const ext4_group_t last = sbi->s_groups_count;
660 const int bpg = EXT4_BLOCKS_PER_GROUP(sb); 660 const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
661 unsigned three = 1; 661 unsigned three = 1;
662 unsigned five = 5; 662 unsigned five = 5;
663 unsigned seven = 7; 663 unsigned seven = 7;
664 unsigned group; 664 ext4_group_t group;
665 int rest = sb->s_blocksize - size; 665 int rest = sb->s_blocksize - size;
666 handle_t *handle; 666 handle_t *handle;
667 int err = 0, err2; 667 int err = 0, err2;
@@ -716,7 +716,7 @@ static void update_backups(struct super_block *sb,
716exit_err: 716exit_err:
717 if (err) { 717 if (err) {
718 ext4_warning(sb, __FUNCTION__, 718 ext4_warning(sb, __FUNCTION__,
719 "can't update backup for group %d (err %d), " 719 "can't update backup for group %lu (err %d), "
720 "forcing fsck on next reboot", group, err); 720 "forcing fsck on next reboot", group, err);
721 sbi->s_mount_state &= ~EXT4_VALID_FS; 721 sbi->s_mount_state &= ~EXT4_VALID_FS;
722 sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS); 722 sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
@@ -952,7 +952,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
952 ext4_fsblk_t n_blocks_count) 952 ext4_fsblk_t n_blocks_count)
953{ 953{
954 ext4_fsblk_t o_blocks_count; 954 ext4_fsblk_t o_blocks_count;
955 unsigned long o_groups_count; 955 ext4_group_t o_groups_count;
956 ext4_grpblk_t last; 956 ext4_grpblk_t last;
957 ext4_grpblk_t add; 957 ext4_grpblk_t add;
958 struct buffer_head * bh; 958 struct buffer_head * bh;
@@ -1054,7 +1054,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
1054 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); 1054 ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
1055 sb->s_dirt = 1; 1055 sb->s_dirt = 1;
1056 unlock_super(sb); 1056 unlock_super(sb);
1057 ext4_debug("freeing blocks %lu through %llu\n", o_blocks_count, 1057 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
1058 o_blocks_count + add); 1058 o_blocks_count + add);
1059 ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); 1059 ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks);
1060 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, 1060 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1ca0f546c466..055a0cd0168e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -373,6 +373,66 @@ void ext4_update_dynamic_rev(struct super_block *sb)
373 */ 373 */
374} 374}
375 375
376int ext4_update_compat_feature(handle_t *handle,
377 struct super_block *sb, __u32 compat)
378{
379 int err = 0;
380 if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) {
381 err = ext4_journal_get_write_access(handle,
382 EXT4_SB(sb)->s_sbh);
383 if (err)
384 return err;
385 EXT4_SET_COMPAT_FEATURE(sb, compat);
386 sb->s_dirt = 1;
387 handle->h_sync = 1;
388 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
389 "call ext4_journal_dirty_met adata");
390 err = ext4_journal_dirty_metadata(handle,
391 EXT4_SB(sb)->s_sbh);
392 }
393 return err;
394}
395
396int ext4_update_rocompat_feature(handle_t *handle,
397 struct super_block *sb, __u32 rocompat)
398{
399 int err = 0;
400 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) {
401 err = ext4_journal_get_write_access(handle,
402 EXT4_SB(sb)->s_sbh);
403 if (err)
404 return err;
405 EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat);
406 sb->s_dirt = 1;
407 handle->h_sync = 1;
408 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
409 "call ext4_journal_dirty_met adata");
410 err = ext4_journal_dirty_metadata(handle,
411 EXT4_SB(sb)->s_sbh);
412 }
413 return err;
414}
415
416int ext4_update_incompat_feature(handle_t *handle,
417 struct super_block *sb, __u32 incompat)
418{
419 int err = 0;
420 if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) {
421 err = ext4_journal_get_write_access(handle,
422 EXT4_SB(sb)->s_sbh);
423 if (err)
424 return err;
425 EXT4_SET_INCOMPAT_FEATURE(sb, incompat);
426 sb->s_dirt = 1;
427 handle->h_sync = 1;
428 BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
429 "call ext4_journal_dirty_met adata");
430 err = ext4_journal_dirty_metadata(handle,
431 EXT4_SB(sb)->s_sbh);
432 }
433 return err;
434}
435
376/* 436/*
377 * Open the external journal device 437 * Open the external journal device
378 */ 438 */
@@ -443,6 +503,7 @@ static void ext4_put_super (struct super_block * sb)
443 struct ext4_super_block *es = sbi->s_es; 503 struct ext4_super_block *es = sbi->s_es;
444 int i; 504 int i;
445 505
506 ext4_mb_release(sb);
446 ext4_ext_release(sb); 507 ext4_ext_release(sb);
447 ext4_xattr_put_super(sb); 508 ext4_xattr_put_super(sb);
448 jbd2_journal_destroy(sbi->s_journal); 509 jbd2_journal_destroy(sbi->s_journal);
@@ -509,6 +570,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
509 ei->i_block_alloc_info = NULL; 570 ei->i_block_alloc_info = NULL;
510 ei->vfs_inode.i_version = 1; 571 ei->vfs_inode.i_version = 1;
511 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache)); 572 memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
573 INIT_LIST_HEAD(&ei->i_prealloc_list);
574 spin_lock_init(&ei->i_prealloc_lock);
512 return &ei->vfs_inode; 575 return &ei->vfs_inode;
513} 576}
514 577
@@ -533,7 +596,7 @@ static void init_once(struct kmem_cache *cachep, void *foo)
533#ifdef CONFIG_EXT4DEV_FS_XATTR 596#ifdef CONFIG_EXT4DEV_FS_XATTR
534 init_rwsem(&ei->xattr_sem); 597 init_rwsem(&ei->xattr_sem);
535#endif 598#endif
536 mutex_init(&ei->truncate_mutex); 599 init_rwsem(&ei->i_data_sem);
537 inode_init_once(&ei->vfs_inode); 600 inode_init_once(&ei->vfs_inode);
538} 601}
539 602
@@ -605,18 +668,20 @@ static inline void ext4_show_quota_options(struct seq_file *seq, struct super_bl
605 */ 668 */
606static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) 669static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
607{ 670{
671 int def_errors;
672 unsigned long def_mount_opts;
608 struct super_block *sb = vfs->mnt_sb; 673 struct super_block *sb = vfs->mnt_sb;
609 struct ext4_sb_info *sbi = EXT4_SB(sb); 674 struct ext4_sb_info *sbi = EXT4_SB(sb);
610 struct ext4_super_block *es = sbi->s_es; 675 struct ext4_super_block *es = sbi->s_es;
611 unsigned long def_mount_opts;
612 676
613 def_mount_opts = le32_to_cpu(es->s_default_mount_opts); 677 def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
678 def_errors = le16_to_cpu(es->s_errors);
614 679
615 if (sbi->s_sb_block != 1) 680 if (sbi->s_sb_block != 1)
616 seq_printf(seq, ",sb=%llu", sbi->s_sb_block); 681 seq_printf(seq, ",sb=%llu", sbi->s_sb_block);
617 if (test_opt(sb, MINIX_DF)) 682 if (test_opt(sb, MINIX_DF))
618 seq_puts(seq, ",minixdf"); 683 seq_puts(seq, ",minixdf");
619 if (test_opt(sb, GRPID)) 684 if (test_opt(sb, GRPID) && !(def_mount_opts & EXT4_DEFM_BSDGROUPS))
620 seq_puts(seq, ",grpid"); 685 seq_puts(seq, ",grpid");
621 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS)) 686 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))
622 seq_puts(seq, ",nogrpid"); 687 seq_puts(seq, ",nogrpid");
@@ -628,34 +693,33 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
628 le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) { 693 le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {
629 seq_printf(seq, ",resgid=%u", sbi->s_resgid); 694 seq_printf(seq, ",resgid=%u", sbi->s_resgid);
630 } 695 }
631 if (test_opt(sb, ERRORS_CONT)) { 696 if (test_opt(sb, ERRORS_RO)) {
632 int def_errors = le16_to_cpu(es->s_errors);
633
634 if (def_errors == EXT4_ERRORS_PANIC || 697 if (def_errors == EXT4_ERRORS_PANIC ||
635 def_errors == EXT4_ERRORS_RO) { 698 def_errors == EXT4_ERRORS_CONTINUE) {
636 seq_puts(seq, ",errors=continue"); 699 seq_puts(seq, ",errors=remount-ro");
637 } 700 }
638 } 701 }
639 if (test_opt(sb, ERRORS_RO)) 702 if (test_opt(sb, ERRORS_CONT) && def_errors != EXT4_ERRORS_CONTINUE)
640 seq_puts(seq, ",errors=remount-ro"); 703 seq_puts(seq, ",errors=continue");
641 if (test_opt(sb, ERRORS_PANIC)) 704 if (test_opt(sb, ERRORS_PANIC) && def_errors != EXT4_ERRORS_PANIC)
642 seq_puts(seq, ",errors=panic"); 705 seq_puts(seq, ",errors=panic");
643 if (test_opt(sb, NO_UID32)) 706 if (test_opt(sb, NO_UID32) && !(def_mount_opts & EXT4_DEFM_UID16))
644 seq_puts(seq, ",nouid32"); 707 seq_puts(seq, ",nouid32");
645 if (test_opt(sb, DEBUG)) 708 if (test_opt(sb, DEBUG) && !(def_mount_opts & EXT4_DEFM_DEBUG))
646 seq_puts(seq, ",debug"); 709 seq_puts(seq, ",debug");
647 if (test_opt(sb, OLDALLOC)) 710 if (test_opt(sb, OLDALLOC))
648 seq_puts(seq, ",oldalloc"); 711 seq_puts(seq, ",oldalloc");
649#ifdef CONFIG_EXT4_FS_XATTR 712#ifdef CONFIG_EXT4DEV_FS_XATTR
650 if (test_opt(sb, XATTR_USER)) 713 if (test_opt(sb, XATTR_USER) &&
714 !(def_mount_opts & EXT4_DEFM_XATTR_USER))
651 seq_puts(seq, ",user_xattr"); 715 seq_puts(seq, ",user_xattr");
652 if (!test_opt(sb, XATTR_USER) && 716 if (!test_opt(sb, XATTR_USER) &&
653 (def_mount_opts & EXT4_DEFM_XATTR_USER)) { 717 (def_mount_opts & EXT4_DEFM_XATTR_USER)) {
654 seq_puts(seq, ",nouser_xattr"); 718 seq_puts(seq, ",nouser_xattr");
655 } 719 }
656#endif 720#endif
657#ifdef CONFIG_EXT4_FS_POSIX_ACL 721#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
658 if (test_opt(sb, POSIX_ACL)) 722 if (test_opt(sb, POSIX_ACL) && !(def_mount_opts & EXT4_DEFM_ACL))
659 seq_puts(seq, ",acl"); 723 seq_puts(seq, ",acl");
660 if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL)) 724 if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
661 seq_puts(seq, ",noacl"); 725 seq_puts(seq, ",noacl");
@@ -672,7 +736,17 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
672 seq_puts(seq, ",nobh"); 736 seq_puts(seq, ",nobh");
673 if (!test_opt(sb, EXTENTS)) 737 if (!test_opt(sb, EXTENTS))
674 seq_puts(seq, ",noextents"); 738 seq_puts(seq, ",noextents");
739 if (!test_opt(sb, MBALLOC))
740 seq_puts(seq, ",nomballoc");
741 if (test_opt(sb, I_VERSION))
742 seq_puts(seq, ",i_version");
675 743
744 if (sbi->s_stripe)
745 seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
746 /*
747 * journal mode get enabled in different ways
748 * So just print the value even if we didn't specify it
749 */
676 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) 750 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
677 seq_puts(seq, ",data=journal"); 751 seq_puts(seq, ",data=journal");
678 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) 752 else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
@@ -681,7 +755,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
681 seq_puts(seq, ",data=writeback"); 755 seq_puts(seq, ",data=writeback");
682 756
683 ext4_show_quota_options(seq, sb); 757 ext4_show_quota_options(seq, sb);
684
685 return 0; 758 return 0;
686} 759}
687 760
@@ -809,11 +882,13 @@ enum {
809 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 882 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
810 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh, 883 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
811 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, 884 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
885 Opt_journal_checksum, Opt_journal_async_commit,
812 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 886 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
813 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 887 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
814 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 888 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
815 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, 889 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
816 Opt_grpquota, Opt_extents, Opt_noextents, 890 Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
891 Opt_mballoc, Opt_nomballoc, Opt_stripe,
817}; 892};
818 893
819static match_table_t tokens = { 894static match_table_t tokens = {
@@ -848,6 +923,8 @@ static match_table_t tokens = {
848 {Opt_journal_update, "journal=update"}, 923 {Opt_journal_update, "journal=update"},
849 {Opt_journal_inum, "journal=%u"}, 924 {Opt_journal_inum, "journal=%u"},
850 {Opt_journal_dev, "journal_dev=%u"}, 925 {Opt_journal_dev, "journal_dev=%u"},
926 {Opt_journal_checksum, "journal_checksum"},
927 {Opt_journal_async_commit, "journal_async_commit"},
851 {Opt_abort, "abort"}, 928 {Opt_abort, "abort"},
852 {Opt_data_journal, "data=journal"}, 929 {Opt_data_journal, "data=journal"},
853 {Opt_data_ordered, "data=ordered"}, 930 {Opt_data_ordered, "data=ordered"},
@@ -865,6 +942,10 @@ static match_table_t tokens = {
865 {Opt_barrier, "barrier=%u"}, 942 {Opt_barrier, "barrier=%u"},
866 {Opt_extents, "extents"}, 943 {Opt_extents, "extents"},
867 {Opt_noextents, "noextents"}, 944 {Opt_noextents, "noextents"},
945 {Opt_i_version, "i_version"},
946 {Opt_mballoc, "mballoc"},
947 {Opt_nomballoc, "nomballoc"},
948 {Opt_stripe, "stripe=%u"},
868 {Opt_err, NULL}, 949 {Opt_err, NULL},
869 {Opt_resize, "resize"}, 950 {Opt_resize, "resize"},
870}; 951};
@@ -1035,6 +1116,13 @@ static int parse_options (char *options, struct super_block *sb,
1035 return 0; 1116 return 0;
1036 *journal_devnum = option; 1117 *journal_devnum = option;
1037 break; 1118 break;
1119 case Opt_journal_checksum:
1120 set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
1121 break;
1122 case Opt_journal_async_commit:
1123 set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
1124 set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
1125 break;
1038 case Opt_noload: 1126 case Opt_noload:
1039 set_opt (sbi->s_mount_opt, NOLOAD); 1127 set_opt (sbi->s_mount_opt, NOLOAD);
1040 break; 1128 break;
@@ -1203,6 +1291,23 @@ clear_qf_name:
1203 case Opt_noextents: 1291 case Opt_noextents:
1204 clear_opt (sbi->s_mount_opt, EXTENTS); 1292 clear_opt (sbi->s_mount_opt, EXTENTS);
1205 break; 1293 break;
1294 case Opt_i_version:
1295 set_opt(sbi->s_mount_opt, I_VERSION);
1296 sb->s_flags |= MS_I_VERSION;
1297 break;
1298 case Opt_mballoc:
1299 set_opt(sbi->s_mount_opt, MBALLOC);
1300 break;
1301 case Opt_nomballoc:
1302 clear_opt(sbi->s_mount_opt, MBALLOC);
1303 break;
1304 case Opt_stripe:
1305 if (match_int(&args[0], &option))
1306 return 0;
1307 if (option < 0)
1308 return 0;
1309 sbi->s_stripe = option;
1310 break;
1206 default: 1311 default:
1207 printk (KERN_ERR 1312 printk (KERN_ERR
1208 "EXT4-fs: Unrecognized mount option \"%s\" " 1313 "EXT4-fs: Unrecognized mount option \"%s\" "
@@ -1364,7 +1469,7 @@ static int ext4_check_descriptors (struct super_block * sb)
1364 struct ext4_group_desc * gdp = NULL; 1469 struct ext4_group_desc * gdp = NULL;
1365 int desc_block = 0; 1470 int desc_block = 0;
1366 int flexbg_flag = 0; 1471 int flexbg_flag = 0;
1367 int i; 1472 ext4_group_t i;
1368 1473
1369 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) 1474 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
1370 flexbg_flag = 1; 1475 flexbg_flag = 1;
@@ -1386,7 +1491,7 @@ static int ext4_check_descriptors (struct super_block * sb)
1386 if (block_bitmap < first_block || block_bitmap > last_block) 1491 if (block_bitmap < first_block || block_bitmap > last_block)
1387 { 1492 {
1388 ext4_error (sb, "ext4_check_descriptors", 1493 ext4_error (sb, "ext4_check_descriptors",
1389 "Block bitmap for group %d" 1494 "Block bitmap for group %lu"
1390 " not in group (block %llu)!", 1495 " not in group (block %llu)!",
1391 i, block_bitmap); 1496 i, block_bitmap);
1392 return 0; 1497 return 0;
@@ -1395,7 +1500,7 @@ static int ext4_check_descriptors (struct super_block * sb)
1395 if (inode_bitmap < first_block || inode_bitmap > last_block) 1500 if (inode_bitmap < first_block || inode_bitmap > last_block)
1396 { 1501 {
1397 ext4_error (sb, "ext4_check_descriptors", 1502 ext4_error (sb, "ext4_check_descriptors",
1398 "Inode bitmap for group %d" 1503 "Inode bitmap for group %lu"
1399 " not in group (block %llu)!", 1504 " not in group (block %llu)!",
1400 i, inode_bitmap); 1505 i, inode_bitmap);
1401 return 0; 1506 return 0;
@@ -1405,17 +1510,16 @@ static int ext4_check_descriptors (struct super_block * sb)
1405 inode_table + sbi->s_itb_per_group - 1 > last_block) 1510 inode_table + sbi->s_itb_per_group - 1 > last_block)
1406 { 1511 {
1407 ext4_error (sb, "ext4_check_descriptors", 1512 ext4_error (sb, "ext4_check_descriptors",
1408 "Inode table for group %d" 1513 "Inode table for group %lu"
1409 " not in group (block %llu)!", 1514 " not in group (block %llu)!",
1410 i, inode_table); 1515 i, inode_table);
1411 return 0; 1516 return 0;
1412 } 1517 }
1413 if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { 1518 if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
1414 ext4_error(sb, __FUNCTION__, 1519 ext4_error(sb, __FUNCTION__,
1415 "Checksum for group %d failed (%u!=%u)\n", i, 1520 "Checksum for group %lu failed (%u!=%u)\n",
1416 le16_to_cpu(ext4_group_desc_csum(sbi, i, 1521 i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
1417 gdp)), 1522 gdp)), le16_to_cpu(gdp->bg_checksum));
1418 le16_to_cpu(gdp->bg_checksum));
1419 return 0; 1523 return 0;
1420 } 1524 }
1421 if (!flexbg_flag) 1525 if (!flexbg_flag)
@@ -1429,7 +1533,6 @@ static int ext4_check_descriptors (struct super_block * sb)
1429 return 1; 1533 return 1;
1430} 1534}
1431 1535
1432
1433/* ext4_orphan_cleanup() walks a singly-linked list of inodes (starting at 1536/* ext4_orphan_cleanup() walks a singly-linked list of inodes (starting at
1434 * the superblock) which were deleted from all directories, but held open by 1537 * the superblock) which were deleted from all directories, but held open by
1435 * a process at the time of a crash. We walk the list and try to delete these 1538 * a process at the time of a crash. We walk the list and try to delete these
@@ -1542,20 +1645,95 @@ static void ext4_orphan_cleanup (struct super_block * sb,
1542#endif 1645#endif
1543 sb->s_flags = s_flags; /* Restore MS_RDONLY status */ 1646 sb->s_flags = s_flags; /* Restore MS_RDONLY status */
1544} 1647}
1648/*
1649 * Maximal extent format file size.
1650 * Resulting logical blkno at s_maxbytes must fit in our on-disk
1651 * extent format containers, within a sector_t, and within i_blocks
1652 * in the vfs. ext4 inode has 48 bits of i_block in fsblock units,
1653 * so that won't be a limiting factor.
1654 *
1655 * Note, this does *not* consider any metadata overhead for vfs i_blocks.
1656 */
1657static loff_t ext4_max_size(int blkbits)
1658{
1659 loff_t res;
1660 loff_t upper_limit = MAX_LFS_FILESIZE;
1661
1662 /* small i_blocks in vfs inode? */
1663 if (sizeof(blkcnt_t) < sizeof(u64)) {
1664 /*
1665 * CONFIG_LSF is not enabled implies the inode
1666 * i_block represent total blocks in 512 bytes
1667 * 32 == size of vfs inode i_blocks * 8
1668 */
1669 upper_limit = (1LL << 32) - 1;
1670
1671 /* total blocks in file system block size */
1672 upper_limit >>= (blkbits - 9);
1673 upper_limit <<= blkbits;
1674 }
1675
1676 /* 32-bit extent-start container, ee_block */
1677 res = 1LL << 32;
1678 res <<= blkbits;
1679 res -= 1;
1680
1681 /* Sanity check against vm- & vfs- imposed limits */
1682 if (res > upper_limit)
1683 res = upper_limit;
1684
1685 return res;
1686}
1545 1687
1546/* 1688/*
1547 * Maximal file size. There is a direct, and {,double-,triple-}indirect 1689 * Maximal bitmap file size. There is a direct, and {,double-,triple-}indirect
1548 * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks. 1690 * block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
1549 * We need to be 1 filesystem block less than the 2^32 sector limit. 1691 * We need to be 1 filesystem block less than the 2^48 sector limit.
1550 */ 1692 */
1551static loff_t ext4_max_size(int bits) 1693static loff_t ext4_max_bitmap_size(int bits)
1552{ 1694{
1553 loff_t res = EXT4_NDIR_BLOCKS; 1695 loff_t res = EXT4_NDIR_BLOCKS;
1554 /* This constant is calculated to be the largest file size for a 1696 int meta_blocks;
1555 * dense, 4k-blocksize file such that the total number of 1697 loff_t upper_limit;
1698 /* This is calculated to be the largest file size for a
1699 * dense, bitmapped file such that the total number of
1556 * sectors in the file, including data and all indirect blocks, 1700 * sectors in the file, including data and all indirect blocks,
1557 * does not exceed 2^32. */ 1701 * does not exceed 2^48 -1
1558 const loff_t upper_limit = 0x1ff7fffd000LL; 1702 * __u32 i_blocks_lo and _u16 i_blocks_high representing the
1703 * total number of 512 bytes blocks of the file
1704 */
1705
1706 if (sizeof(blkcnt_t) < sizeof(u64)) {
1707 /*
1708 * CONFIG_LSF is not enabled implies the inode
1709 * i_block represent total blocks in 512 bytes
1710 * 32 == size of vfs inode i_blocks * 8
1711 */
1712 upper_limit = (1LL << 32) - 1;
1713
1714 /* total blocks in file system block size */
1715 upper_limit >>= (bits - 9);
1716
1717 } else {
1718 /*
1719 * We use 48 bit ext4_inode i_blocks
1720 * With EXT4_HUGE_FILE_FL set the i_blocks
1721 * represent total number of blocks in
1722 * file system block size
1723 */
1724 upper_limit = (1LL << 48) - 1;
1725
1726 }
1727
1728 /* indirect blocks */
1729 meta_blocks = 1;
1730 /* double indirect blocks */
1731 meta_blocks += 1 + (1LL << (bits-2));
1732 /* tripple indirect blocks */
1733 meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2)));
1734
1735 upper_limit -= meta_blocks;
1736 upper_limit <<= bits;
1559 1737
1560 res += 1LL << (bits-2); 1738 res += 1LL << (bits-2);
1561 res += 1LL << (2*(bits-2)); 1739 res += 1LL << (2*(bits-2));
@@ -1563,6 +1741,10 @@ static loff_t ext4_max_size(int bits)
1563 res <<= bits; 1741 res <<= bits;
1564 if (res > upper_limit) 1742 if (res > upper_limit)
1565 res = upper_limit; 1743 res = upper_limit;
1744
1745 if (res > MAX_LFS_FILESIZE)
1746 res = MAX_LFS_FILESIZE;
1747
1566 return res; 1748 return res;
1567} 1749}
1568 1750
@@ -1570,7 +1752,7 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb,
1570 ext4_fsblk_t logical_sb_block, int nr) 1752 ext4_fsblk_t logical_sb_block, int nr)
1571{ 1753{
1572 struct ext4_sb_info *sbi = EXT4_SB(sb); 1754 struct ext4_sb_info *sbi = EXT4_SB(sb);
1573 unsigned long bg, first_meta_bg; 1755 ext4_group_t bg, first_meta_bg;
1574 int has_super = 0; 1756 int has_super = 0;
1575 1757
1576 first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg); 1758 first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
@@ -1584,8 +1766,39 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb,
1584 return (has_super + ext4_group_first_block_no(sb, bg)); 1766 return (has_super + ext4_group_first_block_no(sb, bg));
1585} 1767}
1586 1768
1769/**
1770 * ext4_get_stripe_size: Get the stripe size.
1771 * @sbi: In memory super block info
1772 *
1773 * If we have specified it via mount option, then
1774 * use the mount option value. If the value specified at mount time is
1775 * greater than the blocks per group use the super block value.
1776 * If the super block value is greater than blocks per group return 0.
1777 * Allocator needs it be less than blocks per group.
1778 *
1779 */
1780static unsigned long ext4_get_stripe_size(struct ext4_sb_info *sbi)
1781{
1782 unsigned long stride = le16_to_cpu(sbi->s_es->s_raid_stride);
1783 unsigned long stripe_width =
1784 le32_to_cpu(sbi->s_es->s_raid_stripe_width);
1785
1786 if (sbi->s_stripe && sbi->s_stripe <= sbi->s_blocks_per_group)
1787 return sbi->s_stripe;
1788
1789 if (stripe_width <= sbi->s_blocks_per_group)
1790 return stripe_width;
1791
1792 if (stride <= sbi->s_blocks_per_group)
1793 return stride;
1794
1795 return 0;
1796}
1587 1797
1588static int ext4_fill_super (struct super_block *sb, void *data, int silent) 1798static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1799 __releases(kernel_sem)
1800 __acquires(kernel_sem)
1801
1589{ 1802{
1590 struct buffer_head * bh; 1803 struct buffer_head * bh;
1591 struct ext4_super_block *es = NULL; 1804 struct ext4_super_block *es = NULL;
@@ -1599,7 +1812,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1599 unsigned long def_mount_opts; 1812 unsigned long def_mount_opts;
1600 struct inode *root; 1813 struct inode *root;
1601 int blocksize; 1814 int blocksize;
1602 int hblock;
1603 int db_count; 1815 int db_count;
1604 int i; 1816 int i;
1605 int needs_recovery; 1817 int needs_recovery;
@@ -1624,6 +1836,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1624 goto out_fail; 1836 goto out_fail;
1625 } 1837 }
1626 1838
1839 if (!sb_set_blocksize(sb, blocksize)) {
1840 printk(KERN_ERR "EXT4-fs: bad blocksize %d.\n", blocksize);
1841 goto out_fail;
1842 }
1843
1627 /* 1844 /*
1628 * The ext4 superblock will not be buffer aligned for other than 1kB 1845 * The ext4 superblock will not be buffer aligned for other than 1kB
1629 * block sizes. We need to calculate the offset from buffer start. 1846 * block sizes. We need to calculate the offset from buffer start.
@@ -1674,10 +1891,10 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1674 1891
1675 if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) 1892 if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC)
1676 set_opt(sbi->s_mount_opt, ERRORS_PANIC); 1893 set_opt(sbi->s_mount_opt, ERRORS_PANIC);
1677 else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_RO) 1894 else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE)
1678 set_opt(sbi->s_mount_opt, ERRORS_RO);
1679 else
1680 set_opt(sbi->s_mount_opt, ERRORS_CONT); 1895 set_opt(sbi->s_mount_opt, ERRORS_CONT);
1896 else
1897 set_opt(sbi->s_mount_opt, ERRORS_RO);
1681 1898
1682 sbi->s_resuid = le16_to_cpu(es->s_def_resuid); 1899 sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
1683 sbi->s_resgid = le16_to_cpu(es->s_def_resgid); 1900 sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
@@ -1689,6 +1906,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1689 * User -o noextents to turn it off 1906 * User -o noextents to turn it off
1690 */ 1907 */
1691 set_opt(sbi->s_mount_opt, EXTENTS); 1908 set_opt(sbi->s_mount_opt, EXTENTS);
1909 /*
1910 * turn on mballoc feature by default in ext4 filesystem
1911 * User -o nomballoc to turn it off
1912 */
1913 set_opt(sbi->s_mount_opt, MBALLOC);
1692 1914
1693 if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum, 1915 if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
1694 NULL, 0)) 1916 NULL, 0))
@@ -1723,6 +1945,19 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1723 sb->s_id, le32_to_cpu(features)); 1945 sb->s_id, le32_to_cpu(features));
1724 goto failed_mount; 1946 goto failed_mount;
1725 } 1947 }
1948 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
1949 /*
1950 * Large file size enabled file system can only be
1951 * mount if kernel is build with CONFIG_LSF
1952 */
1953 if (sizeof(root->i_blocks) < sizeof(u64) &&
1954 !(sb->s_flags & MS_RDONLY)) {
1955 printk(KERN_ERR "EXT4-fs: %s: Filesystem with huge "
1956 "files cannot be mounted read-write "
1957 "without CONFIG_LSF.\n", sb->s_id);
1958 goto failed_mount;
1959 }
1960 }
1726 blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); 1961 blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
1727 1962
1728 if (blocksize < EXT4_MIN_BLOCK_SIZE || 1963 if (blocksize < EXT4_MIN_BLOCK_SIZE ||
@@ -1733,20 +1968,16 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1733 goto failed_mount; 1968 goto failed_mount;
1734 } 1969 }
1735 1970
1736 hblock = bdev_hardsect_size(sb->s_bdev);
1737 if (sb->s_blocksize != blocksize) { 1971 if (sb->s_blocksize != blocksize) {
1738 /* 1972
1739 * Make sure the blocksize for the filesystem is larger 1973 /* Validate the filesystem blocksize */
1740 * than the hardware sectorsize for the machine. 1974 if (!sb_set_blocksize(sb, blocksize)) {
1741 */ 1975 printk(KERN_ERR "EXT4-fs: bad block size %d.\n",
1742 if (blocksize < hblock) { 1976 blocksize);
1743 printk(KERN_ERR "EXT4-fs: blocksize %d too small for "
1744 "device blocksize %d.\n", blocksize, hblock);
1745 goto failed_mount; 1977 goto failed_mount;
1746 } 1978 }
1747 1979
1748 brelse (bh); 1980 brelse (bh);
1749 sb_set_blocksize(sb, blocksize);
1750 logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; 1981 logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
1751 offset = do_div(logical_sb_block, blocksize); 1982 offset = do_div(logical_sb_block, blocksize);
1752 bh = sb_bread(sb, logical_sb_block); 1983 bh = sb_bread(sb, logical_sb_block);
@@ -1764,6 +1995,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1764 } 1995 }
1765 } 1996 }
1766 1997
1998 sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits);
1767 sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits); 1999 sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits);
1768 2000
1769 if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) { 2001 if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
@@ -1838,6 +2070,17 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1838 2070
1839 if (EXT4_BLOCKS_PER_GROUP(sb) == 0) 2071 if (EXT4_BLOCKS_PER_GROUP(sb) == 0)
1840 goto cantfind_ext4; 2072 goto cantfind_ext4;
2073
2074 /* ensure blocks_count calculation below doesn't sign-extend */
2075 if (ext4_blocks_count(es) + EXT4_BLOCKS_PER_GROUP(sb) <
2076 le32_to_cpu(es->s_first_data_block) + 1) {
2077 printk(KERN_WARNING "EXT4-fs: bad geometry: block count %llu, "
2078 "first data block %u, blocks per group %lu\n",
2079 ext4_blocks_count(es),
2080 le32_to_cpu(es->s_first_data_block),
2081 EXT4_BLOCKS_PER_GROUP(sb));
2082 goto failed_mount;
2083 }
1841 blocks_count = (ext4_blocks_count(es) - 2084 blocks_count = (ext4_blocks_count(es) -
1842 le32_to_cpu(es->s_first_data_block) + 2085 le32_to_cpu(es->s_first_data_block) +
1843 EXT4_BLOCKS_PER_GROUP(sb) - 1); 2086 EXT4_BLOCKS_PER_GROUP(sb) - 1);
@@ -1900,6 +2143,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1900 sbi->s_rsv_window_head.rsv_goal_size = 0; 2143 sbi->s_rsv_window_head.rsv_goal_size = 0;
1901 ext4_rsv_window_add(sb, &sbi->s_rsv_window_head); 2144 ext4_rsv_window_add(sb, &sbi->s_rsv_window_head);
1902 2145
2146 sbi->s_stripe = ext4_get_stripe_size(sbi);
2147
1903 /* 2148 /*
1904 * set up enough so that it can read an inode 2149 * set up enough so that it can read an inode
1905 */ 2150 */
@@ -1944,6 +2189,21 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
1944 goto failed_mount4; 2189 goto failed_mount4;
1945 } 2190 }
1946 2191
2192 if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
2193 jbd2_journal_set_features(sbi->s_journal,
2194 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
2195 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2196 } else if (test_opt(sb, JOURNAL_CHECKSUM)) {
2197 jbd2_journal_set_features(sbi->s_journal,
2198 JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
2199 jbd2_journal_clear_features(sbi->s_journal, 0, 0,
2200 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2201 } else {
2202 jbd2_journal_clear_features(sbi->s_journal,
2203 JBD2_FEATURE_COMPAT_CHECKSUM, 0,
2204 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
2205 }
2206
1947 /* We have now updated the journal if required, so we can 2207 /* We have now updated the journal if required, so we can
1948 * validate the data journaling mode. */ 2208 * validate the data journaling mode. */
1949 switch (test_opt(sb, DATA_FLAGS)) { 2209 switch (test_opt(sb, DATA_FLAGS)) {
@@ -2044,6 +2304,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
2044 "writeback"); 2304 "writeback");
2045 2305
2046 ext4_ext_init(sb); 2306 ext4_ext_init(sb);
2307 ext4_mb_init(sb, needs_recovery);
2047 2308
2048 lock_kernel(); 2309 lock_kernel();
2049 return 0; 2310 return 0;
@@ -2673,7 +2934,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
2673 if (test_opt(sb, MINIX_DF)) { 2934 if (test_opt(sb, MINIX_DF)) {
2674 sbi->s_overhead_last = 0; 2935 sbi->s_overhead_last = 0;
2675 } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { 2936 } else if (sbi->s_blocks_last != ext4_blocks_count(es)) {
2676 unsigned long ngroups = sbi->s_groups_count, i; 2937 ext4_group_t ngroups = sbi->s_groups_count, i;
2677 ext4_fsblk_t overhead = 0; 2938 ext4_fsblk_t overhead = 0;
2678 smp_rmb(); 2939 smp_rmb();
2679 2940
@@ -2909,7 +3170,7 @@ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
2909 size_t len, loff_t off) 3170 size_t len, loff_t off)
2910{ 3171{
2911 struct inode *inode = sb_dqopt(sb)->files[type]; 3172 struct inode *inode = sb_dqopt(sb)->files[type];
2912 sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); 3173 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
2913 int err = 0; 3174 int err = 0;
2914 int offset = off & (sb->s_blocksize - 1); 3175 int offset = off & (sb->s_blocksize - 1);
2915 int tocopy; 3176 int tocopy;
@@ -2947,7 +3208,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
2947 const char *data, size_t len, loff_t off) 3208 const char *data, size_t len, loff_t off)
2948{ 3209{
2949 struct inode *inode = sb_dqopt(sb)->files[type]; 3210 struct inode *inode = sb_dqopt(sb)->files[type];
2950 sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); 3211 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
2951 int err = 0; 3212 int err = 0;
2952 int offset = off & (sb->s_blocksize - 1); 3213 int offset = off & (sb->s_blocksize - 1);
2953 int tocopy; 3214 int tocopy;
@@ -3002,7 +3263,6 @@ out:
3002 i_size_write(inode, off+len-towrite); 3263 i_size_write(inode, off+len-towrite);
3003 EXT4_I(inode)->i_disksize = inode->i_size; 3264 EXT4_I(inode)->i_disksize = inode->i_size;
3004 } 3265 }
3005 inode->i_version++;
3006 inode->i_mtime = inode->i_ctime = CURRENT_TIME; 3266 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
3007 ext4_mark_inode_dirty(handle, inode); 3267 ext4_mark_inode_dirty(handle, inode);
3008 mutex_unlock(&inode->i_mutex); 3268 mutex_unlock(&inode->i_mutex);
@@ -3027,9 +3287,15 @@ static struct file_system_type ext4dev_fs_type = {
3027 3287
3028static int __init init_ext4_fs(void) 3288static int __init init_ext4_fs(void)
3029{ 3289{
3030 int err = init_ext4_xattr(); 3290 int err;
3291
3292 err = init_ext4_mballoc();
3031 if (err) 3293 if (err)
3032 return err; 3294 return err;
3295
3296 err = init_ext4_xattr();
3297 if (err)
3298 goto out2;
3033 err = init_inodecache(); 3299 err = init_inodecache();
3034 if (err) 3300 if (err)
3035 goto out1; 3301 goto out1;
@@ -3041,6 +3307,8 @@ out:
3041 destroy_inodecache(); 3307 destroy_inodecache();
3042out1: 3308out1:
3043 exit_ext4_xattr(); 3309 exit_ext4_xattr();
3310out2:
3311 exit_ext4_mballoc();
3044 return err; 3312 return err;
3045} 3313}
3046 3314
@@ -3049,6 +3317,7 @@ static void __exit exit_ext4_fs(void)
3049 unregister_filesystem(&ext4dev_fs_type); 3317 unregister_filesystem(&ext4dev_fs_type);
3050 destroy_inodecache(); 3318 destroy_inodecache();
3051 exit_ext4_xattr(); 3319 exit_ext4_xattr();
3320 exit_ext4_mballoc();
3052} 3321}
3053 3322
3054MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); 3323MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 86387302c2a9..d7962139c010 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -480,7 +480,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
480 ea_bdebug(bh, "refcount now=0; freeing"); 480 ea_bdebug(bh, "refcount now=0; freeing");
481 if (ce) 481 if (ce)
482 mb_cache_entry_free(ce); 482 mb_cache_entry_free(ce);
483 ext4_free_blocks(handle, inode, bh->b_blocknr, 1); 483 ext4_free_blocks(handle, inode, bh->b_blocknr, 1, 1);
484 get_bh(bh); 484 get_bh(bh);
485 ext4_forget(handle, 1, inode, bh, bh->b_blocknr); 485 ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
486 } else { 486 } else {
@@ -821,7 +821,7 @@ inserted:
821 new_bh = sb_getblk(sb, block); 821 new_bh = sb_getblk(sb, block);
822 if (!new_bh) { 822 if (!new_bh) {
823getblk_failed: 823getblk_failed:
824 ext4_free_blocks(handle, inode, block, 1); 824 ext4_free_blocks(handle, inode, block, 1, 1);
825 error = -EIO; 825 error = -EIO;
826 goto cleanup; 826 goto cleanup;
827 } 827 }
diff --git a/fs/inode.c b/fs/inode.c
index ed35383d0b6c..276ffd6b6fdd 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1276,6 +1276,11 @@ void file_update_time(struct file *file)
1276 sync_it = 1; 1276 sync_it = 1;
1277 } 1277 }
1278 1278
1279 if (IS_I_VERSION(inode)) {
1280 inode_inc_iversion(inode);
1281 sync_it = 1;
1282 }
1283
1279 if (sync_it) 1284 if (sync_it)
1280 mark_inode_dirty_sync(inode); 1285 mark_inode_dirty_sync(inode);
1281} 1286}
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 3fccde7ba008..1b7f282c1ae9 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -232,7 +232,8 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
232 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it 232 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
233 */ 233 */
234static int __process_buffer(journal_t *journal, struct journal_head *jh, 234static int __process_buffer(journal_t *journal, struct journal_head *jh,
235 struct buffer_head **bhs, int *batch_count) 235 struct buffer_head **bhs, int *batch_count,
236 transaction_t *transaction)
236{ 237{
237 struct buffer_head *bh = jh2bh(jh); 238 struct buffer_head *bh = jh2bh(jh);
238 int ret = 0; 239 int ret = 0;
@@ -250,6 +251,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
250 transaction_t *t = jh->b_transaction; 251 transaction_t *t = jh->b_transaction;
251 tid_t tid = t->t_tid; 252 tid_t tid = t->t_tid;
252 253
254 transaction->t_chp_stats.cs_forced_to_close++;
253 spin_unlock(&journal->j_list_lock); 255 spin_unlock(&journal->j_list_lock);
254 jbd_unlock_bh_state(bh); 256 jbd_unlock_bh_state(bh);
255 jbd2_log_start_commit(journal, tid); 257 jbd2_log_start_commit(journal, tid);
@@ -279,6 +281,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
279 bhs[*batch_count] = bh; 281 bhs[*batch_count] = bh;
280 __buffer_relink_io(jh); 282 __buffer_relink_io(jh);
281 jbd_unlock_bh_state(bh); 283 jbd_unlock_bh_state(bh);
284 transaction->t_chp_stats.cs_written++;
282 (*batch_count)++; 285 (*batch_count)++;
283 if (*batch_count == NR_BATCH) { 286 if (*batch_count == NR_BATCH) {
284 spin_unlock(&journal->j_list_lock); 287 spin_unlock(&journal->j_list_lock);
@@ -322,6 +325,8 @@ int jbd2_log_do_checkpoint(journal_t *journal)
322 if (!journal->j_checkpoint_transactions) 325 if (!journal->j_checkpoint_transactions)
323 goto out; 326 goto out;
324 transaction = journal->j_checkpoint_transactions; 327 transaction = journal->j_checkpoint_transactions;
328 if (transaction->t_chp_stats.cs_chp_time == 0)
329 transaction->t_chp_stats.cs_chp_time = jiffies;
325 this_tid = transaction->t_tid; 330 this_tid = transaction->t_tid;
326restart: 331restart:
327 /* 332 /*
@@ -346,7 +351,8 @@ restart:
346 retry = 1; 351 retry = 1;
347 break; 352 break;
348 } 353 }
349 retry = __process_buffer(journal, jh, bhs,&batch_count); 354 retry = __process_buffer(journal, jh, bhs, &batch_count,
355 transaction);
350 if (!retry && lock_need_resched(&journal->j_list_lock)){ 356 if (!retry && lock_need_resched(&journal->j_list_lock)){
351 spin_unlock(&journal->j_list_lock); 357 spin_unlock(&journal->j_list_lock);
352 retry = 1; 358 retry = 1;
@@ -602,15 +608,15 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
602 608
603 /* 609 /*
604 * There is one special case to worry about: if we have just pulled the 610 * There is one special case to worry about: if we have just pulled the
605 * buffer off a committing transaction's forget list, then even if the 611 * buffer off a running or committing transaction's checkpoing list,
606 * checkpoint list is empty, the transaction obviously cannot be 612 * then even if the checkpoint list is empty, the transaction obviously
607 * dropped! 613 * cannot be dropped!
608 * 614 *
609 * The locking here around j_committing_transaction is a bit sleazy. 615 * The locking here around t_state is a bit sleazy.
610 * See the comment at the end of jbd2_journal_commit_transaction(). 616 * See the comment at the end of jbd2_journal_commit_transaction().
611 */ 617 */
612 if (transaction == journal->j_committing_transaction) { 618 if (transaction->t_state != T_FINISHED) {
613 JBUFFER_TRACE(jh, "belongs to committing transaction"); 619 JBUFFER_TRACE(jh, "belongs to running/committing transaction");
614 goto out; 620 goto out;
615 } 621 }
616 622
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 6986f334c643..da8d0eb3b7b9 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -20,6 +20,8 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/pagemap.h> 22#include <linux/pagemap.h>
23#include <linux/jiffies.h>
24#include <linux/crc32.h>
23 25
24/* 26/*
25 * Default IO end handler for temporary BJ_IO buffer_heads. 27 * Default IO end handler for temporary BJ_IO buffer_heads.
@@ -92,19 +94,23 @@ static int inverted_lock(journal_t *journal, struct buffer_head *bh)
92 return 1; 94 return 1;
93} 95}
94 96
95/* Done it all: now write the commit record. We should have 97/*
98 * Done it all: now submit the commit record. We should have
96 * cleaned up our previous buffers by now, so if we are in abort 99 * cleaned up our previous buffers by now, so if we are in abort
97 * mode we can now just skip the rest of the journal write 100 * mode we can now just skip the rest of the journal write
98 * entirely. 101 * entirely.
99 * 102 *
100 * Returns 1 if the journal needs to be aborted or 0 on success 103 * Returns 1 if the journal needs to be aborted or 0 on success
101 */ 104 */
102static int journal_write_commit_record(journal_t *journal, 105static int journal_submit_commit_record(journal_t *journal,
103 transaction_t *commit_transaction) 106 transaction_t *commit_transaction,
107 struct buffer_head **cbh,
108 __u32 crc32_sum)
104{ 109{
105 struct journal_head *descriptor; 110 struct journal_head *descriptor;
111 struct commit_header *tmp;
106 struct buffer_head *bh; 112 struct buffer_head *bh;
107 int i, ret; 113 int ret;
108 int barrier_done = 0; 114 int barrier_done = 0;
109 115
110 if (is_journal_aborted(journal)) 116 if (is_journal_aborted(journal))
@@ -116,21 +122,33 @@ static int journal_write_commit_record(journal_t *journal,
116 122
117 bh = jh2bh(descriptor); 123 bh = jh2bh(descriptor);
118 124
119 /* AKPM: buglet - add `i' to tmp! */ 125 tmp = (struct commit_header *)bh->b_data;
120 for (i = 0; i < bh->b_size; i += 512) { 126 tmp->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER);
121 journal_header_t *tmp = (journal_header_t*)bh->b_data; 127 tmp->h_blocktype = cpu_to_be32(JBD2_COMMIT_BLOCK);
122 tmp->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); 128 tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid);
123 tmp->h_blocktype = cpu_to_be32(JBD2_COMMIT_BLOCK); 129
124 tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid); 130 if (JBD2_HAS_COMPAT_FEATURE(journal,
131 JBD2_FEATURE_COMPAT_CHECKSUM)) {
132 tmp->h_chksum_type = JBD2_CRC32_CHKSUM;
133 tmp->h_chksum_size = JBD2_CRC32_CHKSUM_SIZE;
134 tmp->h_chksum[0] = cpu_to_be32(crc32_sum);
125 } 135 }
126 136
127 JBUFFER_TRACE(descriptor, "write commit block"); 137 JBUFFER_TRACE(descriptor, "submit commit block");
138 lock_buffer(bh);
139
128 set_buffer_dirty(bh); 140 set_buffer_dirty(bh);
129 if (journal->j_flags & JBD2_BARRIER) { 141 set_buffer_uptodate(bh);
142 bh->b_end_io = journal_end_buffer_io_sync;
143
144 if (journal->j_flags & JBD2_BARRIER &&
145 !JBD2_HAS_COMPAT_FEATURE(journal,
146 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
130 set_buffer_ordered(bh); 147 set_buffer_ordered(bh);
131 barrier_done = 1; 148 barrier_done = 1;
132 } 149 }
133 ret = sync_dirty_buffer(bh); 150 ret = submit_bh(WRITE, bh);
151
134 /* is it possible for another commit to fail at roughly 152 /* is it possible for another commit to fail at roughly
135 * the same time as this one? If so, we don't want to 153 * the same time as this one? If so, we don't want to
136 * trust the barrier flag in the super, but instead want 154 * trust the barrier flag in the super, but instead want
@@ -151,14 +169,72 @@ static int journal_write_commit_record(journal_t *journal,
151 clear_buffer_ordered(bh); 169 clear_buffer_ordered(bh);
152 set_buffer_uptodate(bh); 170 set_buffer_uptodate(bh);
153 set_buffer_dirty(bh); 171 set_buffer_dirty(bh);
154 ret = sync_dirty_buffer(bh); 172 ret = submit_bh(WRITE, bh);
155 } 173 }
156 put_bh(bh); /* One for getblk() */ 174 *cbh = bh;
157 jbd2_journal_put_journal_head(descriptor); 175 return ret;
176}
177
178/*
179 * This function along with journal_submit_commit_record
180 * allows to write the commit record asynchronously.
181 */
182static int journal_wait_on_commit_record(struct buffer_head *bh)
183{
184 int ret = 0;
185
186 clear_buffer_dirty(bh);
187 wait_on_buffer(bh);
188
189 if (unlikely(!buffer_uptodate(bh)))
190 ret = -EIO;
191 put_bh(bh); /* One for getblk() */
192 jbd2_journal_put_journal_head(bh2jh(bh));
158 193
159 return (ret == -EIO); 194 return ret;
160} 195}
161 196
197/*
198 * Wait for all submitted IO to complete.
199 */
200static int journal_wait_on_locked_list(journal_t *journal,
201 transaction_t *commit_transaction)
202{
203 int ret = 0;
204 struct journal_head *jh;
205
206 while (commit_transaction->t_locked_list) {
207 struct buffer_head *bh;
208
209 jh = commit_transaction->t_locked_list->b_tprev;
210 bh = jh2bh(jh);
211 get_bh(bh);
212 if (buffer_locked(bh)) {
213 spin_unlock(&journal->j_list_lock);
214 wait_on_buffer(bh);
215 if (unlikely(!buffer_uptodate(bh)))
216 ret = -EIO;
217 spin_lock(&journal->j_list_lock);
218 }
219 if (!inverted_lock(journal, bh)) {
220 put_bh(bh);
221 spin_lock(&journal->j_list_lock);
222 continue;
223 }
224 if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
225 __jbd2_journal_unfile_buffer(jh);
226 jbd_unlock_bh_state(bh);
227 jbd2_journal_remove_journal_head(bh);
228 put_bh(bh);
229 } else {
230 jbd_unlock_bh_state(bh);
231 }
232 put_bh(bh);
233 cond_resched_lock(&journal->j_list_lock);
234 }
235 return ret;
236 }
237
162static void journal_do_submit_data(struct buffer_head **wbuf, int bufs) 238static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
163{ 239{
164 int i; 240 int i;
@@ -274,7 +350,21 @@ write_out_data:
274 journal_do_submit_data(wbuf, bufs); 350 journal_do_submit_data(wbuf, bufs);
275} 351}
276 352
277static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag, 353static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh)
354{
355 struct page *page = bh->b_page;
356 char *addr;
357 __u32 checksum;
358
359 addr = kmap_atomic(page, KM_USER0);
360 checksum = crc32_be(crc32_sum,
361 (void *)(addr + offset_in_page(bh->b_data)), bh->b_size);
362 kunmap_atomic(addr, KM_USER0);
363
364 return checksum;
365}
366
367static void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
278 unsigned long long block) 368 unsigned long long block)
279{ 369{
280 tag->t_blocknr = cpu_to_be32(block & (u32)~0); 370 tag->t_blocknr = cpu_to_be32(block & (u32)~0);
@@ -290,6 +380,7 @@ static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
290 */ 380 */
291void jbd2_journal_commit_transaction(journal_t *journal) 381void jbd2_journal_commit_transaction(journal_t *journal)
292{ 382{
383 struct transaction_stats_s stats;
293 transaction_t *commit_transaction; 384 transaction_t *commit_transaction;
294 struct journal_head *jh, *new_jh, *descriptor; 385 struct journal_head *jh, *new_jh, *descriptor;
295 struct buffer_head **wbuf = journal->j_wbuf; 386 struct buffer_head **wbuf = journal->j_wbuf;
@@ -305,6 +396,8 @@ void jbd2_journal_commit_transaction(journal_t *journal)
305 int tag_flag; 396 int tag_flag;
306 int i; 397 int i;
307 int tag_bytes = journal_tag_bytes(journal); 398 int tag_bytes = journal_tag_bytes(journal);
399 struct buffer_head *cbh = NULL; /* For transactional checksums */
400 __u32 crc32_sum = ~0;
308 401
309 /* 402 /*
310 * First job: lock down the current transaction and wait for 403 * First job: lock down the current transaction and wait for
@@ -337,6 +430,11 @@ void jbd2_journal_commit_transaction(journal_t *journal)
337 spin_lock(&journal->j_state_lock); 430 spin_lock(&journal->j_state_lock);
338 commit_transaction->t_state = T_LOCKED; 431 commit_transaction->t_state = T_LOCKED;
339 432
433 stats.u.run.rs_wait = commit_transaction->t_max_wait;
434 stats.u.run.rs_locked = jiffies;
435 stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
436 stats.u.run.rs_locked);
437
340 spin_lock(&commit_transaction->t_handle_lock); 438 spin_lock(&commit_transaction->t_handle_lock);
341 while (commit_transaction->t_updates) { 439 while (commit_transaction->t_updates) {
342 DEFINE_WAIT(wait); 440 DEFINE_WAIT(wait);
@@ -407,6 +505,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
407 */ 505 */
408 jbd2_journal_switch_revoke_table(journal); 506 jbd2_journal_switch_revoke_table(journal);
409 507
508 stats.u.run.rs_flushing = jiffies;
509 stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked,
510 stats.u.run.rs_flushing);
511
410 commit_transaction->t_state = T_FLUSH; 512 commit_transaction->t_state = T_FLUSH;
411 journal->j_committing_transaction = commit_transaction; 513 journal->j_committing_transaction = commit_transaction;
412 journal->j_running_transaction = NULL; 514 journal->j_running_transaction = NULL;
@@ -440,38 +542,15 @@ void jbd2_journal_commit_transaction(journal_t *journal)
440 journal_submit_data_buffers(journal, commit_transaction); 542 journal_submit_data_buffers(journal, commit_transaction);
441 543
442 /* 544 /*
443 * Wait for all previously submitted IO to complete. 545 * Wait for all previously submitted IO to complete if commit
546 * record is to be written synchronously.
444 */ 547 */
445 spin_lock(&journal->j_list_lock); 548 spin_lock(&journal->j_list_lock);
446 while (commit_transaction->t_locked_list) { 549 if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
447 struct buffer_head *bh; 550 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT))
551 err = journal_wait_on_locked_list(journal,
552 commit_transaction);
448 553
449 jh = commit_transaction->t_locked_list->b_tprev;
450 bh = jh2bh(jh);
451 get_bh(bh);
452 if (buffer_locked(bh)) {
453 spin_unlock(&journal->j_list_lock);
454 wait_on_buffer(bh);
455 if (unlikely(!buffer_uptodate(bh)))
456 err = -EIO;
457 spin_lock(&journal->j_list_lock);
458 }
459 if (!inverted_lock(journal, bh)) {
460 put_bh(bh);
461 spin_lock(&journal->j_list_lock);
462 continue;
463 }
464 if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
465 __jbd2_journal_unfile_buffer(jh);
466 jbd_unlock_bh_state(bh);
467 jbd2_journal_remove_journal_head(bh);
468 put_bh(bh);
469 } else {
470 jbd_unlock_bh_state(bh);
471 }
472 put_bh(bh);
473 cond_resched_lock(&journal->j_list_lock);
474 }
475 spin_unlock(&journal->j_list_lock); 554 spin_unlock(&journal->j_list_lock);
476 555
477 if (err) 556 if (err)
@@ -498,6 +577,12 @@ void jbd2_journal_commit_transaction(journal_t *journal)
498 */ 577 */
499 commit_transaction->t_state = T_COMMIT; 578 commit_transaction->t_state = T_COMMIT;
500 579
580 stats.u.run.rs_logging = jiffies;
581 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing,
582 stats.u.run.rs_logging);
583 stats.u.run.rs_blocks = commit_transaction->t_outstanding_credits;
584 stats.u.run.rs_blocks_logged = 0;
585
501 descriptor = NULL; 586 descriptor = NULL;
502 bufs = 0; 587 bufs = 0;
503 while (commit_transaction->t_buffers) { 588 while (commit_transaction->t_buffers) {
@@ -639,6 +724,15 @@ void jbd2_journal_commit_transaction(journal_t *journal)
639start_journal_io: 724start_journal_io:
640 for (i = 0; i < bufs; i++) { 725 for (i = 0; i < bufs; i++) {
641 struct buffer_head *bh = wbuf[i]; 726 struct buffer_head *bh = wbuf[i];
727 /*
728 * Compute checksum.
729 */
730 if (JBD2_HAS_COMPAT_FEATURE(journal,
731 JBD2_FEATURE_COMPAT_CHECKSUM)) {
732 crc32_sum =
733 jbd2_checksum_data(crc32_sum, bh);
734 }
735
642 lock_buffer(bh); 736 lock_buffer(bh);
643 clear_buffer_dirty(bh); 737 clear_buffer_dirty(bh);
644 set_buffer_uptodate(bh); 738 set_buffer_uptodate(bh);
@@ -646,6 +740,7 @@ start_journal_io:
646 submit_bh(WRITE, bh); 740 submit_bh(WRITE, bh);
647 } 741 }
648 cond_resched(); 742 cond_resched();
743 stats.u.run.rs_blocks_logged += bufs;
649 744
650 /* Force a new descriptor to be generated next 745 /* Force a new descriptor to be generated next
651 time round the loop. */ 746 time round the loop. */
@@ -654,6 +749,23 @@ start_journal_io:
654 } 749 }
655 } 750 }
656 751
752 /* Done it all: now write the commit record asynchronously. */
753
754 if (JBD2_HAS_INCOMPAT_FEATURE(journal,
755 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
756 err = journal_submit_commit_record(journal, commit_transaction,
757 &cbh, crc32_sum);
758 if (err)
759 __jbd2_journal_abort_hard(journal);
760
761 spin_lock(&journal->j_list_lock);
762 err = journal_wait_on_locked_list(journal,
763 commit_transaction);
764 spin_unlock(&journal->j_list_lock);
765 if (err)
766 __jbd2_journal_abort_hard(journal);
767 }
768
657 /* Lo and behold: we have just managed to send a transaction to 769 /* Lo and behold: we have just managed to send a transaction to
658 the log. Before we can commit it, wait for the IO so far to 770 the log. Before we can commit it, wait for the IO so far to
659 complete. Control buffers being written are on the 771 complete. Control buffers being written are on the
@@ -753,8 +865,14 @@ wait_for_iobuf:
753 865
754 jbd_debug(3, "JBD: commit phase 6\n"); 866 jbd_debug(3, "JBD: commit phase 6\n");
755 867
756 if (journal_write_commit_record(journal, commit_transaction)) 868 if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
757 err = -EIO; 869 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
870 err = journal_submit_commit_record(journal, commit_transaction,
871 &cbh, crc32_sum);
872 if (err)
873 __jbd2_journal_abort_hard(journal);
874 }
875 err = journal_wait_on_commit_record(cbh);
758 876
759 if (err) 877 if (err)
760 jbd2_journal_abort(journal, err); 878 jbd2_journal_abort(journal, err);
@@ -816,6 +934,7 @@ restart_loop:
816 cp_transaction = jh->b_cp_transaction; 934 cp_transaction = jh->b_cp_transaction;
817 if (cp_transaction) { 935 if (cp_transaction) {
818 JBUFFER_TRACE(jh, "remove from old cp transaction"); 936 JBUFFER_TRACE(jh, "remove from old cp transaction");
937 cp_transaction->t_chp_stats.cs_dropped++;
819 __jbd2_journal_remove_checkpoint(jh); 938 __jbd2_journal_remove_checkpoint(jh);
820 } 939 }
821 940
@@ -867,10 +986,10 @@ restart_loop:
867 } 986 }
868 spin_unlock(&journal->j_list_lock); 987 spin_unlock(&journal->j_list_lock);
869 /* 988 /*
870 * This is a bit sleazy. We borrow j_list_lock to protect 989 * This is a bit sleazy. We use j_list_lock to protect transition
871 * journal->j_committing_transaction in __jbd2_journal_remove_checkpoint. 990 * of a transaction into T_FINISHED state and calling
872 * Really, __jbd2_journal_remove_checkpoint should be using j_state_lock but 991 * __jbd2_journal_drop_transaction(). Otherwise we could race with
873 * it's a bit hassle to hold that across __jbd2_journal_remove_checkpoint 992 * other checkpointing code processing the transaction...
874 */ 993 */
875 spin_lock(&journal->j_state_lock); 994 spin_lock(&journal->j_state_lock);
876 spin_lock(&journal->j_list_lock); 995 spin_lock(&journal->j_list_lock);
@@ -890,6 +1009,36 @@ restart_loop:
890 1009
891 J_ASSERT(commit_transaction->t_state == T_COMMIT); 1010 J_ASSERT(commit_transaction->t_state == T_COMMIT);
892 1011
1012 commit_transaction->t_start = jiffies;
1013 stats.u.run.rs_logging = jbd2_time_diff(stats.u.run.rs_logging,
1014 commit_transaction->t_start);
1015
1016 /*
1017 * File the transaction for history
1018 */
1019 stats.ts_type = JBD2_STATS_RUN;
1020 stats.ts_tid = commit_transaction->t_tid;
1021 stats.u.run.rs_handle_count = commit_transaction->t_handle_count;
1022 spin_lock(&journal->j_history_lock);
1023 memcpy(journal->j_history + journal->j_history_cur, &stats,
1024 sizeof(stats));
1025 if (++journal->j_history_cur == journal->j_history_max)
1026 journal->j_history_cur = 0;
1027
1028 /*
1029 * Calculate overall stats
1030 */
1031 journal->j_stats.ts_tid++;
1032 journal->j_stats.u.run.rs_wait += stats.u.run.rs_wait;
1033 journal->j_stats.u.run.rs_running += stats.u.run.rs_running;
1034 journal->j_stats.u.run.rs_locked += stats.u.run.rs_locked;
1035 journal->j_stats.u.run.rs_flushing += stats.u.run.rs_flushing;
1036 journal->j_stats.u.run.rs_logging += stats.u.run.rs_logging;
1037 journal->j_stats.u.run.rs_handle_count += stats.u.run.rs_handle_count;
1038 journal->j_stats.u.run.rs_blocks += stats.u.run.rs_blocks;
1039 journal->j_stats.u.run.rs_blocks_logged += stats.u.run.rs_blocks_logged;
1040 spin_unlock(&journal->j_history_lock);
1041
893 commit_transaction->t_state = T_FINISHED; 1042 commit_transaction->t_state = T_FINISHED;
894 J_ASSERT(commit_transaction == journal->j_committing_transaction); 1043 J_ASSERT(commit_transaction == journal->j_committing_transaction);
895 journal->j_commit_sequence = commit_transaction->t_tid; 1044 journal->j_commit_sequence = commit_transaction->t_tid;
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 6ddc5531587c..96ba846992e9 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -36,6 +36,7 @@
36#include <linux/poison.h> 36#include <linux/poison.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/debugfs.h> 38#include <linux/debugfs.h>
39#include <linux/seq_file.h>
39 40
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
41#include <asm/page.h> 42#include <asm/page.h>
@@ -640,6 +641,312 @@ struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal)
640 return jbd2_journal_add_journal_head(bh); 641 return jbd2_journal_add_journal_head(bh);
641} 642}
642 643
644struct jbd2_stats_proc_session {
645 journal_t *journal;
646 struct transaction_stats_s *stats;
647 int start;
648 int max;
649};
650
651static void *jbd2_history_skip_empty(struct jbd2_stats_proc_session *s,
652 struct transaction_stats_s *ts,
653 int first)
654{
655 if (ts == s->stats + s->max)
656 ts = s->stats;
657 if (!first && ts == s->stats + s->start)
658 return NULL;
659 while (ts->ts_type == 0) {
660 ts++;
661 if (ts == s->stats + s->max)
662 ts = s->stats;
663 if (ts == s->stats + s->start)
664 return NULL;
665 }
666 return ts;
667
668}
669
670static void *jbd2_seq_history_start(struct seq_file *seq, loff_t *pos)
671{
672 struct jbd2_stats_proc_session *s = seq->private;
673 struct transaction_stats_s *ts;
674 int l = *pos;
675
676 if (l == 0)
677 return SEQ_START_TOKEN;
678 ts = jbd2_history_skip_empty(s, s->stats + s->start, 1);
679 if (!ts)
680 return NULL;
681 l--;
682 while (l) {
683 ts = jbd2_history_skip_empty(s, ++ts, 0);
684 if (!ts)
685 break;
686 l--;
687 }
688 return ts;
689}
690
691static void *jbd2_seq_history_next(struct seq_file *seq, void *v, loff_t *pos)
692{
693 struct jbd2_stats_proc_session *s = seq->private;
694 struct transaction_stats_s *ts = v;
695
696 ++*pos;
697 if (v == SEQ_START_TOKEN)
698 return jbd2_history_skip_empty(s, s->stats + s->start, 1);
699 else
700 return jbd2_history_skip_empty(s, ++ts, 0);
701}
702
703static int jbd2_seq_history_show(struct seq_file *seq, void *v)
704{
705 struct transaction_stats_s *ts = v;
706 if (v == SEQ_START_TOKEN) {
707 seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s "
708 "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid",
709 "wait", "run", "lock", "flush", "log", "hndls",
710 "block", "inlog", "ctime", "write", "drop",
711 "close");
712 return 0;
713 }
714 if (ts->ts_type == JBD2_STATS_RUN)
715 seq_printf(seq, "%-4s %-5lu %-5u %-5u %-5u %-5u %-5u "
716 "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid,
717 jiffies_to_msecs(ts->u.run.rs_wait),
718 jiffies_to_msecs(ts->u.run.rs_running),
719 jiffies_to_msecs(ts->u.run.rs_locked),
720 jiffies_to_msecs(ts->u.run.rs_flushing),
721 jiffies_to_msecs(ts->u.run.rs_logging),
722 ts->u.run.rs_handle_count,
723 ts->u.run.rs_blocks,
724 ts->u.run.rs_blocks_logged);
725 else if (ts->ts_type == JBD2_STATS_CHECKPOINT)
726 seq_printf(seq, "%-4s %-5lu %48s %-5u %-5lu %-5lu %-5lu\n",
727 "C", ts->ts_tid, " ",
728 jiffies_to_msecs(ts->u.chp.cs_chp_time),
729 ts->u.chp.cs_written, ts->u.chp.cs_dropped,
730 ts->u.chp.cs_forced_to_close);
731 else
732 J_ASSERT(0);
733 return 0;
734}
735
736static void jbd2_seq_history_stop(struct seq_file *seq, void *v)
737{
738}
739
740static struct seq_operations jbd2_seq_history_ops = {
741 .start = jbd2_seq_history_start,
742 .next = jbd2_seq_history_next,
743 .stop = jbd2_seq_history_stop,
744 .show = jbd2_seq_history_show,
745};
746
747static int jbd2_seq_history_open(struct inode *inode, struct file *file)
748{
749 journal_t *journal = PDE(inode)->data;
750 struct jbd2_stats_proc_session *s;
751 int rc, size;
752
753 s = kmalloc(sizeof(*s), GFP_KERNEL);
754 if (s == NULL)
755 return -ENOMEM;
756 size = sizeof(struct transaction_stats_s) * journal->j_history_max;
757 s->stats = kmalloc(size, GFP_KERNEL);
758 if (s->stats == NULL) {
759 kfree(s);
760 return -ENOMEM;
761 }
762 spin_lock(&journal->j_history_lock);
763 memcpy(s->stats, journal->j_history, size);
764 s->max = journal->j_history_max;
765 s->start = journal->j_history_cur % s->max;
766 spin_unlock(&journal->j_history_lock);
767
768 rc = seq_open(file, &jbd2_seq_history_ops);
769 if (rc == 0) {
770 struct seq_file *m = file->private_data;
771 m->private = s;
772 } else {
773 kfree(s->stats);
774 kfree(s);
775 }
776 return rc;
777
778}
779
780static int jbd2_seq_history_release(struct inode *inode, struct file *file)
781{
782 struct seq_file *seq = file->private_data;
783 struct jbd2_stats_proc_session *s = seq->private;
784
785 kfree(s->stats);
786 kfree(s);
787 return seq_release(inode, file);
788}
789
790static struct file_operations jbd2_seq_history_fops = {
791 .owner = THIS_MODULE,
792 .open = jbd2_seq_history_open,
793 .read = seq_read,
794 .llseek = seq_lseek,
795 .release = jbd2_seq_history_release,
796};
797
798static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos)
799{
800 return *pos ? NULL : SEQ_START_TOKEN;
801}
802
803static void *jbd2_seq_info_next(struct seq_file *seq, void *v, loff_t *pos)
804{
805 return NULL;
806}
807
808static int jbd2_seq_info_show(struct seq_file *seq, void *v)
809{
810 struct jbd2_stats_proc_session *s = seq->private;
811
812 if (v != SEQ_START_TOKEN)
813 return 0;
814 seq_printf(seq, "%lu transaction, each upto %u blocks\n",
815 s->stats->ts_tid,
816 s->journal->j_max_transaction_buffers);
817 if (s->stats->ts_tid == 0)
818 return 0;
819 seq_printf(seq, "average: \n %ums waiting for transaction\n",
820 jiffies_to_msecs(s->stats->u.run.rs_wait / s->stats->ts_tid));
821 seq_printf(seq, " %ums running transaction\n",
822 jiffies_to_msecs(s->stats->u.run.rs_running / s->stats->ts_tid));
823 seq_printf(seq, " %ums transaction was being locked\n",
824 jiffies_to_msecs(s->stats->u.run.rs_locked / s->stats->ts_tid));
825 seq_printf(seq, " %ums flushing data (in ordered mode)\n",
826 jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid));
827 seq_printf(seq, " %ums logging transaction\n",
828 jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid));
829 seq_printf(seq, " %lu handles per transaction\n",
830 s->stats->u.run.rs_handle_count / s->stats->ts_tid);
831 seq_printf(seq, " %lu blocks per transaction\n",
832 s->stats->u.run.rs_blocks / s->stats->ts_tid);
833 seq_printf(seq, " %lu logged blocks per transaction\n",
834 s->stats->u.run.rs_blocks_logged / s->stats->ts_tid);
835 return 0;
836}
837
838static void jbd2_seq_info_stop(struct seq_file *seq, void *v)
839{
840}
841
842static struct seq_operations jbd2_seq_info_ops = {
843 .start = jbd2_seq_info_start,
844 .next = jbd2_seq_info_next,
845 .stop = jbd2_seq_info_stop,
846 .show = jbd2_seq_info_show,
847};
848
849static int jbd2_seq_info_open(struct inode *inode, struct file *file)
850{
851 journal_t *journal = PDE(inode)->data;
852 struct jbd2_stats_proc_session *s;
853 int rc, size;
854
855 s = kmalloc(sizeof(*s), GFP_KERNEL);
856 if (s == NULL)
857 return -ENOMEM;
858 size = sizeof(struct transaction_stats_s);
859 s->stats = kmalloc(size, GFP_KERNEL);
860 if (s->stats == NULL) {
861 kfree(s);
862 return -ENOMEM;
863 }
864 spin_lock(&journal->j_history_lock);
865 memcpy(s->stats, &journal->j_stats, size);
866 s->journal = journal;
867 spin_unlock(&journal->j_history_lock);
868
869 rc = seq_open(file, &jbd2_seq_info_ops);
870 if (rc == 0) {
871 struct seq_file *m = file->private_data;
872 m->private = s;
873 } else {
874 kfree(s->stats);
875 kfree(s);
876 }
877 return rc;
878
879}
880
881static int jbd2_seq_info_release(struct inode *inode, struct file *file)
882{
883 struct seq_file *seq = file->private_data;
884 struct jbd2_stats_proc_session *s = seq->private;
885 kfree(s->stats);
886 kfree(s);
887 return seq_release(inode, file);
888}
889
890static struct file_operations jbd2_seq_info_fops = {
891 .owner = THIS_MODULE,
892 .open = jbd2_seq_info_open,
893 .read = seq_read,
894 .llseek = seq_lseek,
895 .release = jbd2_seq_info_release,
896};
897
898static struct proc_dir_entry *proc_jbd2_stats;
899
900static void jbd2_stats_proc_init(journal_t *journal)
901{
902 char name[BDEVNAME_SIZE];
903
904 snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
905 journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats);
906 if (journal->j_proc_entry) {
907 struct proc_dir_entry *p;
908 p = create_proc_entry("history", S_IRUGO,
909 journal->j_proc_entry);
910 if (p) {
911 p->proc_fops = &jbd2_seq_history_fops;
912 p->data = journal;
913 p = create_proc_entry("info", S_IRUGO,
914 journal->j_proc_entry);
915 if (p) {
916 p->proc_fops = &jbd2_seq_info_fops;
917 p->data = journal;
918 }
919 }
920 }
921}
922
923static void jbd2_stats_proc_exit(journal_t *journal)
924{
925 char name[BDEVNAME_SIZE];
926
927 snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name));
928 remove_proc_entry("info", journal->j_proc_entry);
929 remove_proc_entry("history", journal->j_proc_entry);
930 remove_proc_entry(name, proc_jbd2_stats);
931}
932
933static void journal_init_stats(journal_t *journal)
934{
935 int size;
936
937 if (!proc_jbd2_stats)
938 return;
939
940 journal->j_history_max = 100;
941 size = sizeof(struct transaction_stats_s) * journal->j_history_max;
942 journal->j_history = kzalloc(size, GFP_KERNEL);
943 if (!journal->j_history) {
944 journal->j_history_max = 0;
945 return;
946 }
947 spin_lock_init(&journal->j_history_lock);
948}
949
643/* 950/*
644 * Management for journal control blocks: functions to create and 951 * Management for journal control blocks: functions to create and
645 * destroy journal_t structures, and to initialise and read existing 952 * destroy journal_t structures, and to initialise and read existing
@@ -681,6 +988,9 @@ static journal_t * journal_init_common (void)
681 kfree(journal); 988 kfree(journal);
682 goto fail; 989 goto fail;
683 } 990 }
991
992 journal_init_stats(journal);
993
684 return journal; 994 return journal;
685fail: 995fail:
686 return NULL; 996 return NULL;
@@ -735,6 +1045,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev,
735 journal->j_fs_dev = fs_dev; 1045 journal->j_fs_dev = fs_dev;
736 journal->j_blk_offset = start; 1046 journal->j_blk_offset = start;
737 journal->j_maxlen = len; 1047 journal->j_maxlen = len;
1048 jbd2_stats_proc_init(journal);
738 1049
739 bh = __getblk(journal->j_dev, start, journal->j_blocksize); 1050 bh = __getblk(journal->j_dev, start, journal->j_blocksize);
740 J_ASSERT(bh != NULL); 1051 J_ASSERT(bh != NULL);
@@ -773,6 +1084,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
773 1084
774 journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits; 1085 journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits;
775 journal->j_blocksize = inode->i_sb->s_blocksize; 1086 journal->j_blocksize = inode->i_sb->s_blocksize;
1087 jbd2_stats_proc_init(journal);
776 1088
777 /* journal descriptor can store up to n blocks -bzzz */ 1089 /* journal descriptor can store up to n blocks -bzzz */
778 n = journal->j_blocksize / sizeof(journal_block_tag_t); 1090 n = journal->j_blocksize / sizeof(journal_block_tag_t);
@@ -1153,6 +1465,8 @@ void jbd2_journal_destroy(journal_t *journal)
1153 brelse(journal->j_sb_buffer); 1465 brelse(journal->j_sb_buffer);
1154 } 1466 }
1155 1467
1468 if (journal->j_proc_entry)
1469 jbd2_stats_proc_exit(journal);
1156 if (journal->j_inode) 1470 if (journal->j_inode)
1157 iput(journal->j_inode); 1471 iput(journal->j_inode);
1158 if (journal->j_revoke) 1472 if (journal->j_revoke)
@@ -1264,6 +1578,32 @@ int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
1264 return 1; 1578 return 1;
1265} 1579}
1266 1580
1581/*
1582 * jbd2_journal_clear_features () - Clear a given journal feature in the
1583 * superblock
1584 * @journal: Journal to act on.
1585 * @compat: bitmask of compatible features
1586 * @ro: bitmask of features that force read-only mount
1587 * @incompat: bitmask of incompatible features
1588 *
1589 * Clear a given journal feature as present on the
1590 * superblock.
1591 */
1592void jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
1593 unsigned long ro, unsigned long incompat)
1594{
1595 journal_superblock_t *sb;
1596
1597 jbd_debug(1, "Clear features 0x%lx/0x%lx/0x%lx\n",
1598 compat, ro, incompat);
1599
1600 sb = journal->j_superblock;
1601
1602 sb->s_feature_compat &= ~cpu_to_be32(compat);
1603 sb->s_feature_ro_compat &= ~cpu_to_be32(ro);
1604 sb->s_feature_incompat &= ~cpu_to_be32(incompat);
1605}
1606EXPORT_SYMBOL(jbd2_journal_clear_features);
1267 1607
1268/** 1608/**
1269 * int jbd2_journal_update_format () - Update on-disk journal structure. 1609 * int jbd2_journal_update_format () - Update on-disk journal structure.
@@ -1633,7 +1973,7 @@ static int journal_init_jbd2_journal_head_cache(void)
1633 jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", 1973 jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
1634 sizeof(struct journal_head), 1974 sizeof(struct journal_head),
1635 0, /* offset */ 1975 0, /* offset */
1636 0, /* flags */ 1976 SLAB_TEMPORARY, /* flags */
1637 NULL); /* ctor */ 1977 NULL); /* ctor */
1638 retval = 0; 1978 retval = 0;
1639 if (jbd2_journal_head_cache == 0) { 1979 if (jbd2_journal_head_cache == 0) {
@@ -1900,6 +2240,28 @@ static void __exit jbd2_remove_debugfs_entry(void)
1900 2240
1901#endif 2241#endif
1902 2242
2243#ifdef CONFIG_PROC_FS
2244
2245#define JBD2_STATS_PROC_NAME "fs/jbd2"
2246
2247static void __init jbd2_create_jbd_stats_proc_entry(void)
2248{
2249 proc_jbd2_stats = proc_mkdir(JBD2_STATS_PROC_NAME, NULL);
2250}
2251
2252static void __exit jbd2_remove_jbd_stats_proc_entry(void)
2253{
2254 if (proc_jbd2_stats)
2255 remove_proc_entry(JBD2_STATS_PROC_NAME, NULL);
2256}
2257
2258#else
2259
2260#define jbd2_create_jbd_stats_proc_entry() do {} while (0)
2261#define jbd2_remove_jbd_stats_proc_entry() do {} while (0)
2262
2263#endif
2264
1903struct kmem_cache *jbd2_handle_cache; 2265struct kmem_cache *jbd2_handle_cache;
1904 2266
1905static int __init journal_init_handle_cache(void) 2267static int __init journal_init_handle_cache(void)
@@ -1907,7 +2269,7 @@ static int __init journal_init_handle_cache(void)
1907 jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle", 2269 jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle",
1908 sizeof(handle_t), 2270 sizeof(handle_t),
1909 0, /* offset */ 2271 0, /* offset */
1910 0, /* flags */ 2272 SLAB_TEMPORARY, /* flags */
1911 NULL); /* ctor */ 2273 NULL); /* ctor */
1912 if (jbd2_handle_cache == NULL) { 2274 if (jbd2_handle_cache == NULL) {
1913 printk(KERN_EMERG "JBD: failed to create handle cache\n"); 2275 printk(KERN_EMERG "JBD: failed to create handle cache\n");
@@ -1955,6 +2317,7 @@ static int __init journal_init(void)
1955 if (ret != 0) 2317 if (ret != 0)
1956 jbd2_journal_destroy_caches(); 2318 jbd2_journal_destroy_caches();
1957 jbd2_create_debugfs_entry(); 2319 jbd2_create_debugfs_entry();
2320 jbd2_create_jbd_stats_proc_entry();
1958 return ret; 2321 return ret;
1959} 2322}
1960 2323
@@ -1966,6 +2329,7 @@ static void __exit journal_exit(void)
1966 printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); 2329 printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
1967#endif 2330#endif
1968 jbd2_remove_debugfs_entry(); 2331 jbd2_remove_debugfs_entry();
2332 jbd2_remove_jbd_stats_proc_entry();
1969 jbd2_journal_destroy_caches(); 2333 jbd2_journal_destroy_caches();
1970} 2334}
1971 2335
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index d0ce627539ef..921680663fa2 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -21,6 +21,7 @@
21#include <linux/jbd2.h> 21#include <linux/jbd2.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/crc32.h>
24#endif 25#endif
25 26
26/* 27/*
@@ -316,6 +317,37 @@ static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag
316 return block; 317 return block;
317} 318}
318 319
320/*
321 * calc_chksums calculates the checksums for the blocks described in the
322 * descriptor block.
323 */
324static int calc_chksums(journal_t *journal, struct buffer_head *bh,
325 unsigned long *next_log_block, __u32 *crc32_sum)
326{
327 int i, num_blks, err;
328 unsigned long io_block;
329 struct buffer_head *obh;
330
331 num_blks = count_tags(journal, bh);
332 /* Calculate checksum of the descriptor block. */
333 *crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size);
334
335 for (i = 0; i < num_blks; i++) {
336 io_block = (*next_log_block)++;
337 wrap(journal, *next_log_block);
338 err = jread(&obh, journal, io_block);
339 if (err) {
340 printk(KERN_ERR "JBD: IO error %d recovering block "
341 "%lu in log\n", err, io_block);
342 return 1;
343 } else {
344 *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,
345 obh->b_size);
346 }
347 }
348 return 0;
349}
350
319static int do_one_pass(journal_t *journal, 351static int do_one_pass(journal_t *journal,
320 struct recovery_info *info, enum passtype pass) 352 struct recovery_info *info, enum passtype pass)
321{ 353{
@@ -328,6 +360,7 @@ static int do_one_pass(journal_t *journal,
328 unsigned int sequence; 360 unsigned int sequence;
329 int blocktype; 361 int blocktype;
330 int tag_bytes = journal_tag_bytes(journal); 362 int tag_bytes = journal_tag_bytes(journal);
363 __u32 crc32_sum = ~0; /* Transactional Checksums */
331 364
332 /* Precompute the maximum metadata descriptors in a descriptor block */ 365 /* Precompute the maximum metadata descriptors in a descriptor block */
333 int MAX_BLOCKS_PER_DESC; 366 int MAX_BLOCKS_PER_DESC;
@@ -419,12 +452,26 @@ static int do_one_pass(journal_t *journal,
419 switch(blocktype) { 452 switch(blocktype) {
420 case JBD2_DESCRIPTOR_BLOCK: 453 case JBD2_DESCRIPTOR_BLOCK:
421 /* If it is a valid descriptor block, replay it 454 /* If it is a valid descriptor block, replay it
422 * in pass REPLAY; otherwise, just skip over the 455 * in pass REPLAY; if journal_checksums enabled, then
423 * blocks it describes. */ 456 * calculate checksums in PASS_SCAN, otherwise,
457 * just skip over the blocks it describes. */
424 if (pass != PASS_REPLAY) { 458 if (pass != PASS_REPLAY) {
459 if (pass == PASS_SCAN &&
460 JBD2_HAS_COMPAT_FEATURE(journal,
461 JBD2_FEATURE_COMPAT_CHECKSUM) &&
462 !info->end_transaction) {
463 if (calc_chksums(journal, bh,
464 &next_log_block,
465 &crc32_sum)) {
466 put_bh(bh);
467 break;
468 }
469 put_bh(bh);
470 continue;
471 }
425 next_log_block += count_tags(journal, bh); 472 next_log_block += count_tags(journal, bh);
426 wrap(journal, next_log_block); 473 wrap(journal, next_log_block);
427 brelse(bh); 474 put_bh(bh);
428 continue; 475 continue;
429 } 476 }
430 477
@@ -516,9 +563,96 @@ static int do_one_pass(journal_t *journal,
516 continue; 563 continue;
517 564
518 case JBD2_COMMIT_BLOCK: 565 case JBD2_COMMIT_BLOCK:
519 /* Found an expected commit block: not much to 566 /* How to differentiate between interrupted commit
520 * do other than move on to the next sequence 567 * and journal corruption ?
568 *
569 * {nth transaction}
570 * Checksum Verification Failed
571 * |
572 * ____________________
573 * | |
574 * async_commit sync_commit
575 * | |
576 * | GO TO NEXT "Journal Corruption"
577 * | TRANSACTION
578 * |
579 * {(n+1)th transanction}
580 * |
581 * _______|______________
582 * | |
583 * Commit block found Commit block not found
584 * | |
585 * "Journal Corruption" |
586 * _____________|_________
587 * | |
588 * nth trans corrupt OR nth trans
589 * and (n+1)th interrupted interrupted
590 * before commit block
591 * could reach the disk.
592 * (Cannot find the difference in above
593 * mentioned conditions. Hence assume
594 * "Interrupted Commit".)
595 */
596
597 /* Found an expected commit block: if checksums
598 * are present verify them in PASS_SCAN; else not
599 * much to do other than move on to the next sequence
521 * number. */ 600 * number. */
601 if (pass == PASS_SCAN &&
602 JBD2_HAS_COMPAT_FEATURE(journal,
603 JBD2_FEATURE_COMPAT_CHECKSUM)) {
604 int chksum_err, chksum_seen;
605 struct commit_header *cbh =
606 (struct commit_header *)bh->b_data;
607 unsigned found_chksum =
608 be32_to_cpu(cbh->h_chksum[0]);
609
610 chksum_err = chksum_seen = 0;
611
612 if (info->end_transaction) {
613 printk(KERN_ERR "JBD: Transaction %u "
614 "found to be corrupt.\n",
615 next_commit_ID - 1);
616 brelse(bh);
617 break;
618 }
619
620 if (crc32_sum == found_chksum &&
621 cbh->h_chksum_type == JBD2_CRC32_CHKSUM &&
622 cbh->h_chksum_size ==
623 JBD2_CRC32_CHKSUM_SIZE)
624 chksum_seen = 1;
625 else if (!(cbh->h_chksum_type == 0 &&
626 cbh->h_chksum_size == 0 &&
627 found_chksum == 0 &&
628 !chksum_seen))
629 /*
630 * If fs is mounted using an old kernel and then
631 * kernel with journal_chksum is used then we
632 * get a situation where the journal flag has
633 * checksum flag set but checksums are not
634 * present i.e chksum = 0, in the individual
635 * commit blocks.
636 * Hence to avoid checksum failures, in this
637 * situation, this extra check is added.
638 */
639 chksum_err = 1;
640
641 if (chksum_err) {
642 info->end_transaction = next_commit_ID;
643
644 if (!JBD2_HAS_COMPAT_FEATURE(journal,
645 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){
646 printk(KERN_ERR
647 "JBD: Transaction %u "
648 "found to be corrupt.\n",
649 next_commit_ID);
650 brelse(bh);
651 break;
652 }
653 }
654 crc32_sum = ~0;
655 }
522 brelse(bh); 656 brelse(bh);
523 next_commit_ID++; 657 next_commit_ID++;
524 continue; 658 continue;
@@ -554,9 +688,10 @@ static int do_one_pass(journal_t *journal,
554 * transaction marks the end of the valid log. 688 * transaction marks the end of the valid log.
555 */ 689 */
556 690
557 if (pass == PASS_SCAN) 691 if (pass == PASS_SCAN) {
558 info->end_transaction = next_commit_ID; 692 if (!info->end_transaction)
559 else { 693 info->end_transaction = next_commit_ID;
694 } else {
560 /* It's really bad news if different passes end up at 695 /* It's really bad news if different passes end up at
561 * different places (but possible due to IO errors). */ 696 * different places (but possible due to IO errors). */
562 if (info->end_transaction != next_commit_ID) { 697 if (info->end_transaction != next_commit_ID) {
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index 3595fd432d5b..df36f42e19e1 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -171,13 +171,15 @@ int __init jbd2_journal_init_revoke_caches(void)
171{ 171{
172 jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record", 172 jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record",
173 sizeof(struct jbd2_revoke_record_s), 173 sizeof(struct jbd2_revoke_record_s),
174 0, SLAB_HWCACHE_ALIGN, NULL); 174 0,
175 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
176 NULL);
175 if (jbd2_revoke_record_cache == 0) 177 if (jbd2_revoke_record_cache == 0)
176 return -ENOMEM; 178 return -ENOMEM;
177 179
178 jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table", 180 jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table",
179 sizeof(struct jbd2_revoke_table_s), 181 sizeof(struct jbd2_revoke_table_s),
180 0, 0, NULL); 182 0, SLAB_TEMPORARY, NULL);
181 if (jbd2_revoke_table_cache == 0) { 183 if (jbd2_revoke_table_cache == 0) {
182 kmem_cache_destroy(jbd2_revoke_record_cache); 184 kmem_cache_destroy(jbd2_revoke_record_cache);
183 jbd2_revoke_record_cache = NULL; 185 jbd2_revoke_record_cache = NULL;
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index b1fcf2b3dca3..b9b0b6f899b9 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -54,11 +54,13 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
54 spin_lock_init(&transaction->t_handle_lock); 54 spin_lock_init(&transaction->t_handle_lock);
55 55
56 /* Set up the commit timer for the new transaction. */ 56 /* Set up the commit timer for the new transaction. */
57 journal->j_commit_timer.expires = transaction->t_expires; 57 journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
58 add_timer(&journal->j_commit_timer); 58 add_timer(&journal->j_commit_timer);
59 59
60 J_ASSERT(journal->j_running_transaction == NULL); 60 J_ASSERT(journal->j_running_transaction == NULL);
61 journal->j_running_transaction = transaction; 61 journal->j_running_transaction = transaction;
62 transaction->t_max_wait = 0;
63 transaction->t_start = jiffies;
62 64
63 return transaction; 65 return transaction;
64} 66}
@@ -85,6 +87,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
85 int nblocks = handle->h_buffer_credits; 87 int nblocks = handle->h_buffer_credits;
86 transaction_t *new_transaction = NULL; 88 transaction_t *new_transaction = NULL;
87 int ret = 0; 89 int ret = 0;
90 unsigned long ts = jiffies;
88 91
89 if (nblocks > journal->j_max_transaction_buffers) { 92 if (nblocks > journal->j_max_transaction_buffers) {
90 printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n", 93 printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
@@ -217,6 +220,12 @@ repeat_locked:
217 /* OK, account for the buffers that this operation expects to 220 /* OK, account for the buffers that this operation expects to
218 * use and add the handle to the running transaction. */ 221 * use and add the handle to the running transaction. */
219 222
223 if (time_after(transaction->t_start, ts)) {
224 ts = jbd2_time_diff(ts, transaction->t_start);
225 if (ts > transaction->t_max_wait)
226 transaction->t_max_wait = ts;
227 }
228
220 handle->h_transaction = transaction; 229 handle->h_transaction = transaction;
221 transaction->t_outstanding_credits += nblocks; 230 transaction->t_outstanding_credits += nblocks;
222 transaction->t_updates++; 231 transaction->t_updates++;
@@ -232,6 +241,8 @@ out:
232 return ret; 241 return ret;
233} 242}
234 243
244static struct lock_class_key jbd2_handle_key;
245
235/* Allocate a new handle. This should probably be in a slab... */ 246/* Allocate a new handle. This should probably be in a slab... */
236static handle_t *new_handle(int nblocks) 247static handle_t *new_handle(int nblocks)
237{ 248{
@@ -242,6 +253,9 @@ static handle_t *new_handle(int nblocks)
242 handle->h_buffer_credits = nblocks; 253 handle->h_buffer_credits = nblocks;
243 handle->h_ref = 1; 254 handle->h_ref = 1;
244 255
256 lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle",
257 &jbd2_handle_key, 0);
258
245 return handle; 259 return handle;
246} 260}
247 261
@@ -284,7 +298,11 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
284 jbd2_free_handle(handle); 298 jbd2_free_handle(handle);
285 current->journal_info = NULL; 299 current->journal_info = NULL;
286 handle = ERR_PTR(err); 300 handle = ERR_PTR(err);
301 goto out;
287 } 302 }
303
304 lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_);
305out:
288 return handle; 306 return handle;
289} 307}
290 308
@@ -1164,7 +1182,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
1164 } 1182 }
1165 1183
1166 /* That test should have eliminated the following case: */ 1184 /* That test should have eliminated the following case: */
1167 J_ASSERT_JH(jh, jh->b_frozen_data == 0); 1185 J_ASSERT_JH(jh, jh->b_frozen_data == NULL);
1168 1186
1169 JBUFFER_TRACE(jh, "file as BJ_Metadata"); 1187 JBUFFER_TRACE(jh, "file as BJ_Metadata");
1170 spin_lock(&journal->j_list_lock); 1188 spin_lock(&journal->j_list_lock);
@@ -1410,6 +1428,8 @@ int jbd2_journal_stop(handle_t *handle)
1410 spin_unlock(&journal->j_state_lock); 1428 spin_unlock(&journal->j_state_lock);
1411 } 1429 }
1412 1430
1431 lock_release(&handle->h_lockdep_map, 1, _THIS_IP_);
1432
1413 jbd2_free_handle(handle); 1433 jbd2_free_handle(handle);
1414 return err; 1434 return err;
1415} 1435}
@@ -1512,7 +1532,7 @@ void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
1512 1532
1513 J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); 1533 J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
1514 if (jh->b_jlist != BJ_None) 1534 if (jh->b_jlist != BJ_None)
1515 J_ASSERT_JH(jh, transaction != 0); 1535 J_ASSERT_JH(jh, transaction != NULL);
1516 1536
1517 switch (jh->b_jlist) { 1537 switch (jh->b_jlist) {
1518 case BJ_None: 1538 case BJ_None:
@@ -1581,11 +1601,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
1581 if (buffer_locked(bh) || buffer_dirty(bh)) 1601 if (buffer_locked(bh) || buffer_dirty(bh))
1582 goto out; 1602 goto out;
1583 1603
1584 if (jh->b_next_transaction != 0) 1604 if (jh->b_next_transaction != NULL)
1585 goto out; 1605 goto out;
1586 1606
1587 spin_lock(&journal->j_list_lock); 1607 spin_lock(&journal->j_list_lock);
1588 if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) { 1608 if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) {
1589 if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { 1609 if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
1590 /* A written-back ordered data buffer */ 1610 /* A written-back ordered data buffer */
1591 JBUFFER_TRACE(jh, "release data"); 1611 JBUFFER_TRACE(jh, "release data");
@@ -1593,7 +1613,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
1593 jbd2_journal_remove_journal_head(bh); 1613 jbd2_journal_remove_journal_head(bh);
1594 __brelse(bh); 1614 __brelse(bh);
1595 } 1615 }
1596 } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) { 1616 } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
1597 /* written-back checkpointed metadata buffer */ 1617 /* written-back checkpointed metadata buffer */
1598 if (jh->b_jlist == BJ_None) { 1618 if (jh->b_jlist == BJ_None) {
1599 JBUFFER_TRACE(jh, "remove from checkpoint list"); 1619 JBUFFER_TRACE(jh, "remove from checkpoint list");
@@ -1953,7 +1973,7 @@ void __jbd2_journal_file_buffer(struct journal_head *jh,
1953 1973
1954 J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); 1974 J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
1955 J_ASSERT_JH(jh, jh->b_transaction == transaction || 1975 J_ASSERT_JH(jh, jh->b_transaction == transaction ||
1956 jh->b_transaction == 0); 1976 jh->b_transaction == NULL);
1957 1977
1958 if (jh->b_transaction && jh->b_jlist == jlist) 1978 if (jh->b_transaction && jh->b_jlist == jlist)
1959 return; 1979 return;
diff --git a/fs/ocfs2/cluster/sys.c b/fs/ocfs2/cluster/sys.c
index a4b07730b2e1..0c095ce7723d 100644
--- a/fs/ocfs2/cluster/sys.c
+++ b/fs/ocfs2/cluster/sys.c
@@ -64,7 +64,7 @@ int o2cb_sys_init(void)
64{ 64{
65 int ret; 65 int ret;
66 66
67 o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); 67 o2cb_kset = kset_create_and_add("o2cb", NULL, NULL);
68 if (!o2cb_kset) 68 if (!o2cb_kset)
69 return -ENOMEM; 69 return -ENOMEM;
70 70
diff --git a/fs/read_write.c b/fs/read_write.c
index c4d3d17923f1..1c177f29e1b7 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -446,6 +446,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
446 } 446 }
447 return seg; 447 return seg;
448} 448}
449EXPORT_SYMBOL(iov_shorten);
449 450
450ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, 451ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
451 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) 452 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile
index 6673ee82cb4c..4faf8c4722c3 100644
--- a/fs/smbfs/Makefile
+++ b/fs/smbfs/Makefile
@@ -16,23 +16,3 @@ EXTRA_CFLAGS += -DSMBFS_PARANOIA
16#EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP 16#EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP
17#EXTRA_CFLAGS += -Werror 17#EXTRA_CFLAGS += -Werror
18 18
19#
20# Maintainer rules
21#
22
23# getopt.c not included. It is intentionally separate
24SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c smbiod.c request.c \
25 symlink.c
26
27proto:
28 -rm -f proto.h
29 @echo > proto2.h "/*"
30 @echo >> proto2.h " * Autogenerated with cproto on: " `date`
31 @echo >> proto2.h " */"
32 @echo >> proto2.h ""
33 @echo >> proto2.h "struct smb_request;"
34 @echo >> proto2.h "struct sock;"
35 @echo >> proto2.h "struct statfs;"
36 @echo >> proto2.h ""
37 cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
38 mv proto2.h proto.h
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 47a6b086eee2..5c60bfc1a84d 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -310,6 +310,8 @@ static inline int constant_fls(int x)
310 _find_first_zero_bit_le(p,sz) 310 _find_first_zero_bit_le(p,sz)
311#define ext2_find_next_zero_bit(p,sz,off) \ 311#define ext2_find_next_zero_bit(p,sz,off) \
312 _find_next_zero_bit_le(p,sz,off) 312 _find_next_zero_bit_le(p,sz,off)
313#define ext2_find_next_bit(p, sz, off) \
314 _find_next_bit_le(p, sz, off)
313 315
314/* 316/*
315 * Minix is defined to use little-endian byte ordering. 317 * Minix is defined to use little-endian byte ordering.
diff --git a/include/asm-avr32/setup.h b/include/asm-avr32/setup.h
index b0828d43e110..ea3070ff13a5 100644
--- a/include/asm-avr32/setup.h
+++ b/include/asm-avr32/setup.h
@@ -110,7 +110,7 @@ struct tagtable {
110 int (*parse)(struct tag *); 110 int (*parse)(struct tag *);
111}; 111};
112 112
113#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) 113#define __tag __used __attribute__((__section__(".taglist.init")))
114#define __tagtable(tag, fn) \ 114#define __tagtable(tag, fn) \
115 static struct tagtable __tagtable_##fn __tag = { tag, fn } 115 static struct tagtable __tagtable_##fn __tag = { tag, fn }
116 116
diff --git a/include/asm-generic/bitops/ext2-non-atomic.h b/include/asm-generic/bitops/ext2-non-atomic.h
index 1697404afa05..63cf822431a2 100644
--- a/include/asm-generic/bitops/ext2-non-atomic.h
+++ b/include/asm-generic/bitops/ext2-non-atomic.h
@@ -14,5 +14,7 @@
14 generic_find_first_zero_le_bit((unsigned long *)(addr), (size)) 14 generic_find_first_zero_le_bit((unsigned long *)(addr), (size))
15#define ext2_find_next_zero_bit(addr, size, off) \ 15#define ext2_find_next_zero_bit(addr, size, off) \
16 generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) 16 generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
17#define ext2_find_next_bit(addr, size, off) \
18 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
17 19
18#endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */ 20#endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */
diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h
index b9c7e5d2d2ad..80e3bf13b2b9 100644
--- a/include/asm-generic/bitops/le.h
+++ b/include/asm-generic/bitops/le.h
@@ -20,6 +20,8 @@
20#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr) 20#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr)
21 21
22#define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset) 22#define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset)
23#define generic_find_next_le_bit(addr, size, offset) \
24 find_next_bit(addr, size, offset)
23 25
24#elif defined(__BIG_ENDIAN) 26#elif defined(__BIG_ENDIAN)
25 27
@@ -42,6 +44,8 @@
42 44
43extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, 45extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
44 unsigned long size, unsigned long offset); 46 unsigned long size, unsigned long offset);
47extern unsigned long generic_find_next_le_bit(const unsigned long *addr,
48 unsigned long size, unsigned long offset);
45 49
46#else 50#else
47#error "Please fix <asm/byteorder.h>" 51#error "Please fix <asm/byteorder.h>"
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9f584cc5c5fb..76df771be585 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -9,10 +9,46 @@
9/* Align . to a 8 byte boundary equals to maximum function alignment. */ 9/* Align . to a 8 byte boundary equals to maximum function alignment. */
10#define ALIGN_FUNCTION() . = ALIGN(8) 10#define ALIGN_FUNCTION() . = ALIGN(8)
11 11
12/* The actual configuration determine if the init/exit sections
13 * are handled as text/data or they can be discarded (which
14 * often happens at runtime)
15 */
16#ifdef CONFIG_HOTPLUG
17#define DEV_KEEP(sec) *(.dev##sec)
18#define DEV_DISCARD(sec)
19#else
20#define DEV_KEEP(sec)
21#define DEV_DISCARD(sec) *(.dev##sec)
22#endif
23
24#ifdef CONFIG_HOTPLUG_CPU
25#define CPU_KEEP(sec) *(.cpu##sec)
26#define CPU_DISCARD(sec)
27#else
28#define CPU_KEEP(sec)
29#define CPU_DISCARD(sec) *(.cpu##sec)
30#endif
31
32#if defined(CONFIG_MEMORY_HOTPLUG)
33#define MEM_KEEP(sec) *(.mem##sec)
34#define MEM_DISCARD(sec)
35#else
36#define MEM_KEEP(sec)
37#define MEM_DISCARD(sec) *(.mem##sec)
38#endif
39
40
12/* .data section */ 41/* .data section */
13#define DATA_DATA \ 42#define DATA_DATA \
14 *(.data) \ 43 *(.data) \
15 *(.data.init.refok) \ 44 *(.data.init.refok) \
45 *(.ref.data) \
46 DEV_KEEP(init.data) \
47 DEV_KEEP(exit.data) \
48 CPU_KEEP(init.data) \
49 CPU_KEEP(exit.data) \
50 MEM_KEEP(init.data) \
51 MEM_KEEP(exit.data) \
16 . = ALIGN(8); \ 52 . = ALIGN(8); \
17 VMLINUX_SYMBOL(__start___markers) = .; \ 53 VMLINUX_SYMBOL(__start___markers) = .; \
18 *(__markers) \ 54 *(__markers) \
@@ -132,6 +168,17 @@
132 *(__ksymtab_strings) \ 168 *(__ksymtab_strings) \
133 } \ 169 } \
134 \ 170 \
171 /* __*init sections */ \
172 __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \
173 *(.ref.rodata) \
174 DEV_KEEP(init.rodata) \
175 DEV_KEEP(exit.rodata) \
176 CPU_KEEP(init.rodata) \
177 CPU_KEEP(exit.rodata) \
178 MEM_KEEP(init.rodata) \
179 MEM_KEEP(exit.rodata) \
180 } \
181 \
135 /* Built-in module parameters. */ \ 182 /* Built-in module parameters. */ \
136 __param : AT(ADDR(__param) - LOAD_OFFSET) { \ 183 __param : AT(ADDR(__param) - LOAD_OFFSET) { \
137 VMLINUX_SYMBOL(__start___param) = .; \ 184 VMLINUX_SYMBOL(__start___param) = .; \
@@ -139,7 +186,6 @@
139 VMLINUX_SYMBOL(__stop___param) = .; \ 186 VMLINUX_SYMBOL(__stop___param) = .; \
140 VMLINUX_SYMBOL(__end_rodata) = .; \ 187 VMLINUX_SYMBOL(__end_rodata) = .; \
141 } \ 188 } \
142 \
143 . = ALIGN((align)); 189 . = ALIGN((align));
144 190
145/* RODATA provided for backward compatibility. 191/* RODATA provided for backward compatibility.
@@ -158,8 +204,16 @@
158#define TEXT_TEXT \ 204#define TEXT_TEXT \
159 ALIGN_FUNCTION(); \ 205 ALIGN_FUNCTION(); \
160 *(.text) \ 206 *(.text) \
207 *(.ref.text) \
161 *(.text.init.refok) \ 208 *(.text.init.refok) \
162 *(.exit.text.refok) 209 *(.exit.text.refok) \
210 DEV_KEEP(init.text) \
211 DEV_KEEP(exit.text) \
212 CPU_KEEP(init.text) \
213 CPU_KEEP(exit.text) \
214 MEM_KEEP(init.text) \
215 MEM_KEEP(exit.text)
216
163 217
164/* sched.text is aling to function alignment to secure we have same 218/* sched.text is aling to function alignment to secure we have same
165 * address even at second ld pass when generating System.map */ 219 * address even at second ld pass when generating System.map */
@@ -183,6 +237,37 @@
183 *(.kprobes.text) \ 237 *(.kprobes.text) \
184 VMLINUX_SYMBOL(__kprobes_text_end) = .; 238 VMLINUX_SYMBOL(__kprobes_text_end) = .;
185 239
240/* init and exit section handling */
241#define INIT_DATA \
242 *(.init.data) \
243 DEV_DISCARD(init.data) \
244 DEV_DISCARD(init.rodata) \
245 CPU_DISCARD(init.data) \
246 CPU_DISCARD(init.rodata) \
247 MEM_DISCARD(init.data) \
248 MEM_DISCARD(init.rodata)
249
250#define INIT_TEXT \
251 *(.init.text) \
252 DEV_DISCARD(init.text) \
253 CPU_DISCARD(init.text) \
254 MEM_DISCARD(init.text)
255
256#define EXIT_DATA \
257 *(.exit.data) \
258 DEV_DISCARD(exit.data) \
259 DEV_DISCARD(exit.rodata) \
260 CPU_DISCARD(exit.data) \
261 CPU_DISCARD(exit.rodata) \
262 MEM_DISCARD(exit.data) \
263 MEM_DISCARD(exit.rodata)
264
265#define EXIT_TEXT \
266 *(.exit.text) \
267 DEV_DISCARD(exit.text) \
268 CPU_DISCARD(exit.text) \
269 MEM_DISCARD(exit.text)
270
186 /* DWARF debug sections. 271 /* DWARF debug sections.
187 Symbols in the DWARF debugging sections are relative to 272 Symbols in the DWARF debugging sections are relative to
188 the beginning of the section so we begin them at 0. */ 273 the beginning of the section so we begin them at 0. */
diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h
index e58d3298fa10..5b6665c754c9 100644
--- a/include/asm-ia64/gcc_intrin.h
+++ b/include/asm-ia64/gcc_intrin.h
@@ -24,7 +24,7 @@
24extern void ia64_bad_param_for_setreg (void); 24extern void ia64_bad_param_for_setreg (void);
25extern void ia64_bad_param_for_getreg (void); 25extern void ia64_bad_param_for_getreg (void);
26 26
27register unsigned long ia64_r13 asm ("r13") __attribute_used__; 27register unsigned long ia64_r13 asm ("r13") __used;
28 28
29#define ia64_setreg(regnum, val) \ 29#define ia64_setreg(regnum, val) \
30({ \ 30({ \
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index 2976b5d68e96..83d1f286230b 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -410,6 +410,8 @@ static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
410 res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); 410 res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
411 return (p - addr) * 32 + res; 411 return (p - addr) * 32 + res;
412} 412}
413#define ext2_find_next_bit(addr, size, off) \
414 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
413 415
414#endif /* __KERNEL__ */ 416#endif /* __KERNEL__ */
415 417
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index f8dfb7ba2e25..f43afe1fc3b3 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -294,6 +294,8 @@ found_middle:
294 return result + ffz(__swab32(tmp)); 294 return result + ffz(__swab32(tmp));
295} 295}
296 296
297#define ext2_find_next_bit(addr, size, off) \
298 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
297#include <asm-generic/bitops/minix.h> 299#include <asm-generic/bitops/minix.h>
298 300
299#endif /* __KERNEL__ */ 301#endif /* __KERNEL__ */
diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h
index 0bb7a93b7a5e..569f80aacbd2 100644
--- a/include/asm-mips/addrspace.h
+++ b/include/asm-mips/addrspace.h
@@ -127,7 +127,7 @@
127#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p)) 127#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p))
128#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) 128#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
129#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \ 129#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \
130 ((cm)<<59) | (a)) 130 (_CONST64_(cm) << 59) | (a))
131 131
132/* 132/*
133 * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting 133 * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h
index 12e17581b823..608cfcfbb3ea 100644
--- a/include/asm-mips/asm.h
+++ b/include/asm-mips/asm.h
@@ -398,4 +398,12 @@ symbol = value
398 398
399#define SSNOP sll zero, zero, 1 399#define SSNOP sll zero, zero, 1
400 400
401#ifdef CONFIG_SGI_IP28
402/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
403#include <asm/cacheops.h>
404#define R10KCBARRIER(addr) cache Cache_Barrier, addr;
405#else
406#define R10KCBARRIER(addr)
407#endif
408
401#endif /* __ASM_ASM_H */ 409#endif /* __ASM_ASM_H */
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index b2dd9b33de8f..e031bdff9920 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -48,22 +48,11 @@
48#define MACH_DS5900 10 /* DECsystem 5900 */ 48#define MACH_DS5900 10 /* DECsystem 5900 */
49 49
50/* 50/*
51 * Valid machtype for group ARC
52 */
53#define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */
54#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */
55
56/*
57 * Valid machtype for group SNI_RM 51 * Valid machtype for group SNI_RM
58 */ 52 */
59#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ 53#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */
60 54
61/* 55/*
62 * Valid machtype for group ACN
63 */
64#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */
65
66/*
67 * Valid machtype for group SGI 56 * Valid machtype for group SGI
68 */ 57 */
69#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */ 58#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */
@@ -73,44 +62,6 @@
73#define MACH_SGI_IP30 4 /* Octane, Octane2 */ 62#define MACH_SGI_IP30 4 /* Octane, Octane2 */
74 63
75/* 64/*
76 * Valid machtype for group COBALT
77 */
78#define MACH_COBALT_27 0 /* Proto "27" hardware */
79
80/*
81 * Valid machtype for group BAGET
82 */
83#define MACH_BAGET201 0 /* BT23-201 */
84#define MACH_BAGET202 1 /* BT23-202 */
85
86/*
87 * Cosine boards.
88 */
89#define MACH_COSINE_ORION 0
90
91/*
92 * Valid machtype for group MOMENCO
93 */
94#define MACH_MOMENCO_OCELOT 0
95#define MACH_MOMENCO_OCELOT_G 1 /* no more supported (may 2007) */
96#define MACH_MOMENCO_OCELOT_C 2 /* no more supported (jun 2007) */
97#define MACH_MOMENCO_JAGUAR_ATX 3 /* no more supported (may 2007) */
98#define MACH_MOMENCO_OCELOT_3 4
99
100/*
101 * Valid machtype for group PHILIPS
102 */
103#define MACH_PHILIPS_NINO 0 /* Nino */
104#define MACH_PHILIPS_VELO 1 /* Velo */
105#define MACH_PHILIPS_JBS 2 /* JBS */
106#define MACH_PHILIPS_STB810 3 /* STB810 */
107
108/*
109 * Valid machtype for group SIBYTE
110 */
111#define MACH_SWARM 0
112
113/*
114 * Valid machtypes for group Toshiba 65 * Valid machtypes for group Toshiba
115 */ 66 */
116#define MACH_PALLAS 0 67#define MACH_PALLAS 0
@@ -122,64 +73,17 @@
122#define MACH_TOSHIBA_RBTX4938 6 73#define MACH_TOSHIBA_RBTX4938 6
123 74
124/* 75/*
125 * Valid machtype for group Alchemy
126 */
127#define MACH_PB1000 0 /* Au1000-based eval board */
128#define MACH_PB1100 1 /* Au1100-based eval board */
129#define MACH_PB1500 2 /* Au1500-based eval board */
130#define MACH_DB1000 3 /* Au1000-based eval board */
131#define MACH_DB1100 4 /* Au1100-based eval board */
132#define MACH_DB1500 5 /* Au1500-based eval board */
133#define MACH_XXS1500 6 /* Au1500-based eval board */
134#define MACH_MTX1 7 /* 4G MTX-1 Au1500-based board */
135#define MACH_PB1550 8 /* Au1550-based eval board */
136#define MACH_DB1550 9 /* Au1550-based eval board */
137#define MACH_PB1200 10 /* Au1200-based eval board */
138#define MACH_DB1200 11 /* Au1200-based eval board */
139
140/*
141 * Valid machtype for group NEC_VR41XX
142 *
143 * Various NEC-based devices.
144 *
145 * FIXME: MACH_GROUPs should be by _MANUFACTURER_ of * the device, not by
146 * technical properties, so no new additions to this group.
147 */
148#define MACH_NEC_OSPREY 0 /* Osprey eval board */
149#define MACH_NEC_EAGLE 1 /* NEC Eagle/Hawk board */
150#define MACH_ZAO_CAPCELLA 2 /* ZAO Networks Capcella */
151#define MACH_VICTOR_MPC30X 3 /* Victor MP-C303/304 */
152#define MACH_IBM_WORKPAD 4 /* IBM WorkPad z50 */
153#define MACH_CASIO_E55 5 /* CASIO CASSIOPEIA E-10/15/55/65 */
154#define MACH_TANBAC_TB0226 6 /* TANBAC TB0226 (Mbase) */
155#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */
156#define MACH_NEC_CMBVR4133 8 /* CMB VR4133 Board */
157
158#define MACH_HP_LASERJET 1
159
160/*
161 * Valid machtype for group LASAT 76 * Valid machtype for group LASAT
162 */ 77 */
163#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ 78#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */
164#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ 79#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */
165 80
166/* 81/*
167 * Valid machtype for group TITAN
168 */
169#define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */
170#define MACH_TITAN_EXCITE 2 /* Basler eXcite */
171
172/*
173 * Valid machtype for group NEC EMMA2RH 82 * Valid machtype for group NEC EMMA2RH
174 */ 83 */
175#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ 84#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */
176 85
177/* 86/*
178 * Valid machtype for group LEMOTE
179 */
180#define MACH_LEMOTE_FULONG 0
181
182/*
183 * Valid machtype for group PMC-MSP 87 * Valid machtype for group PMC-MSP
184 */ 88 */
185#define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */ 89#define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */
@@ -190,16 +94,9 @@
190#define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */ 94#define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */
191#define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */ 95#define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */
192 96
193#define MACH_WRPPMC 1
194
195/*
196 * Valid machtype for group Broadcom
197 */
198#define MACH_GROUP_BRCM 23 /* Broadcom */
199#define MACH_BCM47XX 1 /* Broadcom BCM47XX */
200
201#define CL_SIZE COMMAND_LINE_SIZE 97#define CL_SIZE COMMAND_LINE_SIZE
202 98
99extern char *system_type;
203const char *get_system_type(void); 100const char *get_system_type(void);
204 101
205extern unsigned long mips_machtype; 102extern unsigned long mips_machtype;
diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h
index 0d7f9c1f5546..9dc10df32078 100644
--- a/include/asm-mips/bugs.h
+++ b/include/asm-mips/bugs.h
@@ -1,19 +1,34 @@
1/* 1/*
2 * This is included by init/main.c to check for architecture-dependent bugs. 2 * This is included by init/main.c to check for architecture-dependent bugs.
3 * 3 *
4 * Copyright (C) 2007 Maciej W. Rozycki
5 *
4 * Needs: 6 * Needs:
5 * void check_bugs(void); 7 * void check_bugs(void);
6 */ 8 */
7#ifndef _ASM_BUGS_H 9#ifndef _ASM_BUGS_H
8#define _ASM_BUGS_H 10#define _ASM_BUGS_H
9 11
12#include <linux/bug.h>
10#include <linux/delay.h> 13#include <linux/delay.h>
14
11#include <asm/cpu.h> 15#include <asm/cpu.h>
12#include <asm/cpu-info.h> 16#include <asm/cpu-info.h>
13 17
18extern int daddiu_bug;
19
20extern void check_bugs64_early(void);
21
14extern void check_bugs32(void); 22extern void check_bugs32(void);
15extern void check_bugs64(void); 23extern void check_bugs64(void);
16 24
25static inline void check_bugs_early(void)
26{
27#ifdef CONFIG_64BIT
28 check_bugs64_early();
29#endif
30}
31
17static inline void check_bugs(void) 32static inline void check_bugs(void)
18{ 33{
19 unsigned int cpu = smp_processor_id(); 34 unsigned int cpu = smp_processor_id();
@@ -25,4 +40,14 @@ static inline void check_bugs(void)
25#endif 40#endif
26} 41}
27 42
43static inline int r4k_daddiu_bug(void)
44{
45#ifdef CONFIG_64BIT
46 WARN_ON(daddiu_bug < 0);
47 return daddiu_bug != 0;
48#else
49 return 0;
50#endif
51}
52
28#endif /* _ASM_BUGS_H */ 53#endif /* _ASM_BUGS_H */
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index ed5c02c6afbb..0c5a358863f3 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -55,6 +55,7 @@ struct cpuinfo_mips {
55 struct cache_desc scache; /* Secondary cache */ 55 struct cache_desc scache; /* Secondary cache */
56 struct cache_desc tcache; /* Tertiary/split secondary cache */ 56 struct cache_desc tcache; /* Tertiary/split secondary cache */
57 int srsets; /* Shadow register sets */ 57 int srsets; /* Shadow register sets */
58 int core; /* physical core number */
58#if defined(CONFIG_MIPS_MT_SMTC) 59#if defined(CONFIG_MIPS_MT_SMTC)
59 /* 60 /*
60 * In the MIPS MT "SMTC" model, each TC is considered 61 * In the MIPS MT "SMTC" model, each TC is considered
@@ -63,8 +64,10 @@ struct cpuinfo_mips {
63 * to all TCs within the same VPE. 64 * to all TCs within the same VPE.
64 */ 65 */
65 int vpe_id; /* Virtual Processor number */ 66 int vpe_id; /* Virtual Processor number */
66 int tc_id; /* Thread Context number */
67#endif /* CONFIG_MIPS_MT */ 67#endif /* CONFIG_MIPS_MT */
68#ifdef CONFIG_MIPS_MT_SMTC
69 int tc_id; /* Thread Context number */
70#endif
68 void *data; /* Additional data */ 71 void *data; /* Additional data */
69} __attribute__((aligned(SMP_CACHE_BYTES))); 72} __attribute__((aligned(SMP_CACHE_BYTES)));
70 73
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index 54fc18a4e5a8..bf5bbc78a9f7 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -195,8 +195,8 @@ enum cpu_type_enum {
195 * MIPS32 class processors 195 * MIPS32 class processors
196 */ 196 */
197 CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_74K, CPU_AU1000, 197 CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_74K, CPU_AU1000,
198 CPU_AU1100, CPU_AU1200, CPU_AU1500, CPU_AU1550, CPU_PR4450, 198 CPU_AU1100, CPU_AU1200, CPU_AU1210, CPU_AU1250, CPU_AU1500, CPU_AU1550,
199 CPU_BCM3302, CPU_BCM4710, 199 CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
200 200
201 /* 201 /*
202 * MIPS64 class processors 202 * MIPS64 class processors
diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
index fab32131e9b4..b0bccd2c4ed5 100644
--- a/include/asm-mips/delay.h
+++ b/include/asm-mips/delay.h
@@ -6,13 +6,16 @@
6 * Copyright (C) 1994 by Waldorf Electronics 6 * Copyright (C) 1994 by Waldorf Electronics
7 * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle 7 * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 * Copyright (C) 2007 Maciej W. Rozycki
9 */ 10 */
10#ifndef _ASM_DELAY_H 11#ifndef _ASM_DELAY_H
11#define _ASM_DELAY_H 12#define _ASM_DELAY_H
12 13
13#include <linux/param.h> 14#include <linux/param.h>
14#include <linux/smp.h> 15#include <linux/smp.h>
16
15#include <asm/compiler.h> 17#include <asm/compiler.h>
18#include <asm/war.h>
16 19
17static inline void __delay(unsigned long loops) 20static inline void __delay(unsigned long loops)
18{ 21{
@@ -25,7 +28,7 @@ static inline void __delay(unsigned long loops)
25 " .set reorder \n" 28 " .set reorder \n"
26 : "=r" (loops) 29 : "=r" (loops)
27 : "0" (loops)); 30 : "0" (loops));
28 else if (sizeof(long) == 8) 31 else if (sizeof(long) == 8 && !DADDI_WAR)
29 __asm__ __volatile__ ( 32 __asm__ __volatile__ (
30 " .set noreorder \n" 33 " .set noreorder \n"
31 " .align 3 \n" 34 " .align 3 \n"
@@ -34,6 +37,15 @@ static inline void __delay(unsigned long loops)
34 " .set reorder \n" 37 " .set reorder \n"
35 : "=r" (loops) 38 : "=r" (loops)
36 : "0" (loops)); 39 : "0" (loops));
40 else if (sizeof(long) == 8 && DADDI_WAR)
41 __asm__ __volatile__ (
42 " .set noreorder \n"
43 " .align 3 \n"
44 "1: bnez %0, 1b \n"
45 " dsubu %0, %2 \n"
46 " .set reorder \n"
47 : "=r" (loops)
48 : "0" (loops), "r" (1));
37} 49}
38 50
39 51
@@ -50,7 +62,7 @@ static inline void __delay(unsigned long loops)
50 62
51static inline void __udelay(unsigned long usecs, unsigned long lpj) 63static inline void __udelay(unsigned long usecs, unsigned long lpj)
52{ 64{
53 unsigned long lo; 65 unsigned long hi, lo;
54 66
55 /* 67 /*
56 * The rates of 128 is rounded wrongly by the catchall case 68 * The rates of 128 is rounded wrongly by the catchall case
@@ -70,11 +82,16 @@ static inline void __udelay(unsigned long usecs, unsigned long lpj)
70 : "=h" (usecs), "=l" (lo) 82 : "=h" (usecs), "=l" (lo)
71 : "r" (usecs), "r" (lpj) 83 : "r" (usecs), "r" (lpj)
72 : GCC_REG_ACCUM); 84 : GCC_REG_ACCUM);
73 else if (sizeof(long) == 8) 85 else if (sizeof(long) == 8 && !R4000_WAR)
74 __asm__("dmultu\t%2, %3" 86 __asm__("dmultu\t%2, %3"
75 : "=h" (usecs), "=l" (lo) 87 : "=h" (usecs), "=l" (lo)
76 : "r" (usecs), "r" (lpj) 88 : "r" (usecs), "r" (lpj)
77 : GCC_REG_ACCUM); 89 : GCC_REG_ACCUM);
90 else if (sizeof(long) == 8 && R4000_WAR)
91 __asm__("dmultu\t%3, %4\n\tmfhi\t%0"
92 : "=r" (usecs), "=h" (hi), "=l" (lo)
93 : "r" (usecs), "r" (lpj)
94 : GCC_REG_ACCUM);
78 95
79 __delay(usecs); 96 __delay(usecs);
80} 97}
diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h
index d6a6c21f16db..1353c81065d1 100644
--- a/include/asm-mips/dma.h
+++ b/include/asm-mips/dma.h
@@ -84,10 +84,9 @@
84 * Deskstations or Acer PICA but not the much more versatile DMA logic used 84 * Deskstations or Acer PICA but not the much more versatile DMA logic used
85 * for the local devices on Acer PICA or Magnums. 85 * for the local devices on Acer PICA or Magnums.
86 */ 86 */
87#ifdef CONFIG_SGI_IP22 87#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28)
88/* Horrible hack to have a correct DMA window on IP22 */ 88/* don't care; ISA bus master won't work, ISA slave DMA supports 32bit addr */
89#include <asm/sgi/mc.h> 89#define MAX_DMA_ADDRESS PAGE_OFFSET
90#define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000)
91#else 90#else
92#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) 91#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
93#endif 92#endif
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
index f27b96cfac2e..9cc8522a394f 100644
--- a/include/asm-mips/fixmap.h
+++ b/include/asm-mips/fixmap.h
@@ -60,16 +60,6 @@ enum fixed_addresses {
60 __end_of_fixed_addresses 60 __end_of_fixed_addresses
61}; 61};
62 62
63extern void __set_fixmap(enum fixed_addresses idx,
64 unsigned long phys, pgprot_t flags);
65
66#define set_fixmap(idx, phys) \
67 __set_fixmap(idx, phys, PAGE_KERNEL)
68/*
69 * Some hardware wants to get fixmapped without caching.
70 */
71#define set_fixmap_nocache(idx, phys) \
72 __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
73/* 63/*
74 * used by vmalloc.c. 64 * used by vmalloc.c.
75 * 65 *
diff --git a/include/asm-mips/fw/cfe/cfe_api.h b/include/asm-mips/fw/cfe/cfe_api.h
index 1003e7156bfc..0995575db320 100644
--- a/include/asm-mips/fw/cfe/cfe_api.h
+++ b/include/asm-mips/fw/cfe/cfe_api.h
@@ -15,49 +15,27 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18 18/*
19/* ********************************************************************* 19 * Broadcom Common Firmware Environment (CFE)
20 * 20 *
21 * Broadcom Common Firmware Environment (CFE) 21 * This file contains declarations for doing callbacks to
22 * 22 * cfe from an application. It should be the only header
23 * Device function prototypes File: cfe_api.h 23 * needed by the application to use this library
24 * 24 *
25 * This file contains declarations for doing callbacks to 25 * Authors: Mitch Lichtenberg, Chris Demetriou
26 * cfe from an application. It should be the only header 26 */
27 * needed by the application to use this library
28 *
29 * Authors: Mitch Lichtenberg, Chris Demetriou
30 *
31 ********************************************************************* */
32
33#ifndef CFE_API_H 27#ifndef CFE_API_H
34#define CFE_API_H 28#define CFE_API_H
35 29
36/*
37 * Apply customizations here for different OSes. These need to:
38 * * typedef uint64_t, int64_t, intptr_t, uintptr_t.
39 * * define cfe_strlen() if use of an existing function is desired.
40 * * define CFE_API_IMPL_NAMESPACE if API functions are to use
41 * names in the implementation namespace.
42 * Also, optionally, if the build environment does not do so automatically,
43 * CFE_API_* can be defined here as desired.
44 */
45/* Begin customization. */
46#include <linux/types.h> 30#include <linux/types.h>
47#include <linux/string.h> 31#include <linux/string.h>
48 32
49typedef long intptr_t; 33typedef long intptr_t;
50 34
51#define cfe_strlen strlen
52 35
53#define CFE_API_ALL 36/*
54#define CFE_API_STRLEN_CUSTOM 37 * Constants
55/* End customization. */ 38 */
56
57
58/* *********************************************************************
59 * Constants
60 ********************************************************************* */
61 39
62/* Seal indicating CFE's presence, passed to user program. */ 40/* Seal indicating CFE's presence, passed to user program. */
63#define CFE_EPTSEAL 0x43464531 41#define CFE_EPTSEAL 0x43464531
@@ -109,54 +87,13 @@ typedef struct {
109 87
110 88
111/* 89/*
112 * cfe_strlen is handled specially: If already defined, it has been
113 * overridden in this environment with a standard strlen-like function.
114 */
115#ifdef cfe_strlen
116# define CFE_API_STRLEN_CUSTOM
117#else
118# ifdef CFE_API_IMPL_NAMESPACE
119# define cfe_strlen(a) __cfe_strlen(a)
120# endif
121int cfe_strlen(char *name);
122#endif
123
124/*
125 * Defines and prototypes for functions which take no arguments. 90 * Defines and prototypes for functions which take no arguments.
126 */ 91 */
127#ifdef CFE_API_IMPL_NAMESPACE
128int64_t __cfe_getticks(void);
129#define cfe_getticks() __cfe_getticks()
130#else
131int64_t cfe_getticks(void); 92int64_t cfe_getticks(void);
132#endif
133 93
134/* 94/*
135 * Defines and prototypes for the rest of the functions. 95 * Defines and prototypes for the rest of the functions.
136 */ 96 */
137#ifdef CFE_API_IMPL_NAMESPACE
138#define cfe_close(a) __cfe_close(a)
139#define cfe_cpu_start(a, b, c, d, e) __cfe_cpu_start(a, b, c, d, e)
140#define cfe_cpu_stop(a) __cfe_cpu_stop(a)
141#define cfe_enumenv(a, b, d, e, f) __cfe_enumenv(a, b, d, e, f)
142#define cfe_enummem(a, b, c, d, e) __cfe_enummem(a, b, c, d, e)
143#define cfe_exit(a, b) __cfe_exit(a, b)
144#define cfe_flushcache(a) __cfe_cacheflush(a)
145#define cfe_getdevinfo(a) __cfe_getdevinfo(a)
146#define cfe_getenv(a, b, c) __cfe_getenv(a, b, c)
147#define cfe_getfwinfo(a) __cfe_getfwinfo(a)
148#define cfe_getstdhandle(a) __cfe_getstdhandle(a)
149#define cfe_init(a, b) __cfe_init(a, b)
150#define cfe_inpstat(a) __cfe_inpstat(a)
151#define cfe_ioctl(a, b, c, d, e, f) __cfe_ioctl(a, b, c, d, e, f)
152#define cfe_open(a) __cfe_open(a)
153#define cfe_read(a, b, c) __cfe_read(a, b, c)
154#define cfe_readblk(a, b, c, d) __cfe_readblk(a, b, c, d)
155#define cfe_setenv(a, b) __cfe_setenv(a, b)
156#define cfe_write(a, b, c) __cfe_write(a, b, c)
157#define cfe_writeblk(a, b, c, d) __cfe_writeblk(a, b, c, d)
158#endif /* CFE_API_IMPL_NAMESPACE */
159
160int cfe_close(int handle); 97int cfe_close(int handle);
161int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1); 98int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1);
162int cfe_cpu_stop(int cpu); 99int cfe_cpu_stop(int cpu);
diff --git a/include/asm-mips/fw/cfe/cfe_error.h b/include/asm-mips/fw/cfe/cfe_error.h
index 975f00002cbe..b80374636279 100644
--- a/include/asm-mips/fw/cfe/cfe_error.h
+++ b/include/asm-mips/fw/cfe/cfe_error.h
@@ -16,18 +16,13 @@
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18 18
19/* ********************************************************************* 19/*
20 * 20 * Broadcom Common Firmware Environment (CFE)
21 * Broadcom Common Firmware Environment (CFE) 21 *
22 * 22 * CFE's global error code list is here.
23 * Error codes File: cfe_error.h 23 *
24 * 24 * Author: Mitch Lichtenberg
25 * CFE's global error code list is here. 25 */
26 *
27 * Author: Mitch Lichtenberg
28 *
29 ********************************************************************* */
30
31 26
32#define CFE_OK 0 27#define CFE_OK 0
33#define CFE_ERR -1 /* generic error */ 28#define CFE_ERR -1 /* generic error */
diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h
index a79e7caf3a86..5b9fce73f11d 100644
--- a/include/asm-mips/mach-cobalt/cobalt.h
+++ b/include/asm-mips/mach-cobalt/cobalt.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Lowlevel hardware stuff for the MIPS based Cobalt microservers. 2 * The Cobalt board ID information.
3 * 3 *
4 * This file is subject to the terms and conditions of the GNU General Public 4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
@@ -12,9 +12,6 @@
12#ifndef __ASM_COBALT_H 12#ifndef __ASM_COBALT_H
13#define __ASM_COBALT_H 13#define __ASM_COBALT_H
14 14
15/*
16 * The Cobalt board ID information.
17 */
18extern int cobalt_board_id; 15extern int cobalt_board_id;
19 16
20#define COBALT_BRD_ID_QUBE1 0x3 17#define COBALT_BRD_ID_QUBE1 0x3
@@ -22,14 +19,4 @@ extern int cobalt_board_id;
22#define COBALT_BRD_ID_QUBE2 0x5 19#define COBALT_BRD_ID_QUBE2 0x5
23#define COBALT_BRD_ID_RAQ2 0x6 20#define COBALT_BRD_ID_RAQ2 0x6
24 21
25#define COBALT_KEY_PORT ((~*(volatile unsigned int *) CKSEG1ADDR(0x1d000000) >> 24) & COBALT_KEY_MASK)
26# define COBALT_KEY_CLEAR (1 << 1)
27# define COBALT_KEY_LEFT (1 << 2)
28# define COBALT_KEY_UP (1 << 3)
29# define COBALT_KEY_DOWN (1 << 4)
30# define COBALT_KEY_RIGHT (1 << 5)
31# define COBALT_KEY_ENTER (1 << 6)
32# define COBALT_KEY_SELECT (1 << 7)
33# define COBALT_KEY_MASK 0xfe
34
35#endif /* __ASM_COBALT_H */ 22#endif /* __ASM_COBALT_H */
diff --git a/include/asm-mips/mach-ip28/cpu-feature-overrides.h b/include/asm-mips/mach-ip28/cpu-feature-overrides.h
new file mode 100644
index 000000000000..9a53b326f848
--- /dev/null
+++ b/include/asm-mips/mach-ip28/cpu-feature-overrides.h
@@ -0,0 +1,50 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Ralf Baechle
7 * 6/2004 pf
8 */
9#ifndef __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
10#define __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
11
12/*
13 * IP28 only comes with R10000 family processors all using the same config
14 */
15#define cpu_has_watch 1
16#define cpu_has_mips16 0
17#define cpu_has_divec 0
18#define cpu_has_vce 0
19#define cpu_has_cache_cdex_p 0
20#define cpu_has_cache_cdex_s 0
21#define cpu_has_prefetch 1
22#define cpu_has_mcheck 0
23#define cpu_has_ejtag 0
24
25#define cpu_has_llsc 1
26#define cpu_has_vtag_icache 0
27#define cpu_has_dc_aliases 0 /* see probe_pcache() */
28#define cpu_has_ic_fills_f_dc 0
29#define cpu_has_dsp 0
30#define cpu_icache_snoops_remote_store 1
31#define cpu_has_mipsmt 0
32#define cpu_has_userlocal 0
33
34#define cpu_has_nofpuex 0
35#define cpu_has_64bits 1
36
37#define cpu_has_4kex 1
38#define cpu_has_4k_cache 1
39
40#define cpu_has_inclusive_pcaches 1
41
42#define cpu_dcache_line_size() 32
43#define cpu_icache_line_size() 64
44
45#define cpu_has_mips32r1 0
46#define cpu_has_mips32r2 0
47#define cpu_has_mips64r1 0
48#define cpu_has_mips64r2 0
49
50#endif /* __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip28/ds1286.h b/include/asm-mips/mach-ip28/ds1286.h
new file mode 100644
index 000000000000..471bb9a33e0f
--- /dev/null
+++ b/include/asm-mips/mach-ip28/ds1286.h
@@ -0,0 +1,4 @@
1#ifndef __ASM_MACH_IP28_DS1286_H
2#define __ASM_MACH_IP28_DS1286_H
3#include <asm/mach-ip22/ds1286.h>
4#endif /* __ASM_MACH_IP28_DS1286_H */
diff --git a/include/asm-mips/mach-ip28/spaces.h b/include/asm-mips/mach-ip28/spaces.h
new file mode 100644
index 000000000000..05aabb27e5e7
--- /dev/null
+++ b/include/asm-mips/mach-ip28/spaces.h
@@ -0,0 +1,22 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
7 * Copyright (C) 2000, 2002 Maciej W. Rozycki
8 * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
9 * 2004 pf
10 */
11#ifndef _ASM_MACH_IP28_SPACES_H
12#define _ASM_MACH_IP28_SPACES_H
13
14#define CAC_BASE 0xa800000000000000
15
16#define HIGHMEM_START (~0UL)
17
18#define PHYS_OFFSET _AC(0x20000000, UL)
19
20#include <asm/mach-generic/spaces.h>
21
22#endif /* _ASM_MACH_IP28_SPACES_H */
diff --git a/include/asm-mips/mach-qemu/war.h b/include/asm-mips/mach-ip28/war.h
index 0eaf0c548a47..a1baafab486a 100644
--- a/include/asm-mips/mach-qemu/war.h
+++ b/include/asm-mips/mach-ip28/war.h
@@ -5,8 +5,8 @@
5 * 5 *
6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> 6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
7 */ 7 */
8#ifndef __ASM_MIPS_MACH_QEMU_WAR_H 8#ifndef __ASM_MIPS_MACH_IP28_WAR_H
9#define __ASM_MIPS_MACH_QEMU_WAR_H 9#define __ASM_MIPS_MACH_IP28_WAR_H
10 10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0 11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0 12#define R4600_V1_HIT_CACHEOP_WAR 0
@@ -19,7 +19,7 @@
19#define TX49XX_ICACHE_INDEX_INV_WAR 0 19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define RM9000_CDEX_SMP_WAR 0 20#define RM9000_CDEX_SMP_WAR 0
21#define ICACHE_REFILLS_WORKAROUND_WAR 0 21#define ICACHE_REFILLS_WORKAROUND_WAR 0
22#define R10000_LLSC_WAR 0 22#define R10000_LLSC_WAR 1
23#define MIPS34K_MISSED_ITLB_WAR 0 23#define MIPS34K_MISSED_ITLB_WAR 0
24 24
25#endif /* __ASM_MIPS_MACH_QEMU_WAR_H */ 25#endif /* __ASM_MIPS_MACH_IP28_WAR_H */
diff --git a/include/asm-mips/mach-qemu/cpu-feature-overrides.h b/include/asm-mips/mach-qemu/cpu-feature-overrides.h
deleted file mode 100644
index d2daaed235d5..000000000000
--- a/include/asm-mips/mach-qemu/cpu-feature-overrides.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003, 07 Ralf Baechle
7 */
8#ifndef __ASM_MACH_QEMU_CPU_FEATURE_OVERRIDES_H
9#define __ASM_MACH_QEMU_CPU_FEATURE_OVERRIDES_H
10
11/*
12 * QEMU only comes with a hazard-free MIPS32 processor, so things are easy.
13 */
14#define cpu_has_mips16 0
15#define cpu_has_divec 0
16#define cpu_has_cache_cdex_p 0
17#define cpu_has_prefetch 0
18#define cpu_has_mcheck 0
19#define cpu_has_ejtag 0
20
21#define cpu_has_llsc 1
22#define cpu_has_vtag_icache 0
23#define cpu_has_dc_aliases 0
24#define cpu_has_ic_fills_f_dc 0
25
26#define cpu_has_dsp 0
27#define cpu_has_mipsmt 0
28
29#define cpu_has_nofpuex 0
30#define cpu_has_64bits 0
31
32#endif /* __ASM_MACH_QEMU_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h
index d58977483534..1c39d339521e 100644
--- a/include/asm-mips/mips-boards/generic.h
+++ b/include/asm-mips/mips-boards/generic.h
@@ -97,10 +97,16 @@ extern int mips_revision_corid;
97 97
98extern int mips_revision_sconid; 98extern int mips_revision_sconid;
99 99
100extern void mips_reboot_setup(void);
101
100#ifdef CONFIG_PCI 102#ifdef CONFIG_PCI
101extern void mips_pcibios_init(void); 103extern void mips_pcibios_init(void);
102#else 104#else
103#define mips_pcibios_init() do { } while (0) 105#define mips_pcibios_init() do { } while (0)
104#endif 106#endif
105 107
108#ifdef CONFIG_KGDB
109extern void kgdb_config(void);
110#endif
111
106#endif /* __ASM_MIPS_BOARDS_GENERIC_H */ 112#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
diff --git a/include/asm-mips/mipsprom.h b/include/asm-mips/mipsprom.h
index ce7cff7f1e8e..146d41b67adc 100644
--- a/include/asm-mips/mipsprom.h
+++ b/include/asm-mips/mipsprom.h
@@ -71,4 +71,6 @@
71#define PROM_NV_GET 53 /* XXX */ 71#define PROM_NV_GET 53 /* XXX */
72#define PROM_NV_SET 54 /* XXX */ 72#define PROM_NV_SET 54 /* XXX */
73 73
74extern char *prom_getenv(char *);
75
74#endif /* __ASM_MIPS_PROM_H */ 76#endif /* __ASM_MIPS_PROM_H */
diff --git a/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
index 0b56f55206c6..603eb737b4a8 100644
--- a/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
+++ b/include/asm-mips/pmc-sierra/msp71xx/msp_regs.h
@@ -585,11 +585,7 @@
585 * UART defines * 585 * UART defines *
586 *************************************************************************** 586 ***************************************************************************
587 */ 587 */
588#ifndef CONFIG_MSP_FPGA
589#define MSP_BASE_BAUD 25000000 588#define MSP_BASE_BAUD 25000000
590#else
591#define MSP_BASE_BAUD 6000000
592#endif
593#define MSP_UART_REG_LEN 0x20 589#define MSP_UART_REG_LEN 0x20
594 590
595/* 591/*
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h
index 2b8466ffd3ca..4c140db36786 100644
--- a/include/asm-mips/r4kcache.h
+++ b/include/asm-mips/r4kcache.h
@@ -403,6 +403,13 @@ __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
403__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) 403__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
404__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) 404__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
405 405
406__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
407__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
408__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
409__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
410__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
411__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
412
406/* build blast_xxx_range, protected_blast_xxx_range */ 413/* build blast_xxx_range, protected_blast_xxx_range */
407#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ 414#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
408static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ 415static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
diff --git a/include/asm-mips/sgi/ioc.h b/include/asm-mips/sgi/ioc.h
index f3e3dc9bb732..343ed15f8dc4 100644
--- a/include/asm-mips/sgi/ioc.h
+++ b/include/asm-mips/sgi/ioc.h
@@ -138,8 +138,8 @@ struct sgioc_regs {
138 u8 _sysid[3]; 138 u8 _sysid[3];
139 volatile u8 sysid; 139 volatile u8 sysid;
140#define SGIOC_SYSID_FULLHOUSE 0x01 140#define SGIOC_SYSID_FULLHOUSE 0x01
141#define SGIOC_SYSID_BOARDREV(x) ((x & 0xe0) > 5) 141#define SGIOC_SYSID_BOARDREV(x) (((x) & 0x1e) >> 1)
142#define SGIOC_SYSID_CHIPREV(x) ((x & 0x1e) > 1) 142#define SGIOC_SYSID_CHIPREV(x) (((x) & 0xe0) >> 5)
143 u32 _unused2; 143 u32 _unused2;
144 u8 _read[3]; 144 u8 _read[3];
145 volatile u8 read; 145 volatile u8 read;
diff --git a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h
index da198a1c8c81..25372ae0e814 100644
--- a/include/asm-mips/sibyte/board.h
+++ b/include/asm-mips/sibyte/board.h
@@ -19,10 +19,8 @@
19#ifndef _SIBYTE_BOARD_H 19#ifndef _SIBYTE_BOARD_H
20#define _SIBYTE_BOARD_H 20#define _SIBYTE_BOARD_H
21 21
22#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \ 22#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_CRHONE) || \
23 defined(CONFIG_SIBYTE_PT1120) || defined(CONFIG_SIBYTE_PT1125) || \ 23 defined(CONFIG_SIBYTE_CRHINE) || defined(CONFIG_SIBYTE_LITTLESUR)
24 defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) || \
25 defined(CONFIG_SIBYTE_LITTLESUR)
26#include <asm/sibyte/swarm.h> 24#include <asm/sibyte/swarm.h>
27#endif 25#endif
28 26
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index 0dad844a3b5b..80c1a052662a 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -48,12 +48,10 @@ extern unsigned int zbbus_mhz;
48extern void sb1250_time_init(void); 48extern void sb1250_time_init(void);
49extern void sb1250_mask_irq(int cpu, int irq); 49extern void sb1250_mask_irq(int cpu, int irq);
50extern void sb1250_unmask_irq(int cpu, int irq); 50extern void sb1250_unmask_irq(int cpu, int irq);
51extern void sb1250_smp_finish(void);
52 51
53extern void bcm1480_time_init(void); 52extern void bcm1480_time_init(void);
54extern void bcm1480_mask_irq(int cpu, int irq); 53extern void bcm1480_mask_irq(int cpu, int irq);
55extern void bcm1480_unmask_irq(int cpu, int irq); 54extern void bcm1480_unmask_irq(int cpu, int irq);
56extern void bcm1480_smp_finish(void);
57 55
58#define AT_spin \ 56#define AT_spin \
59 __asm__ __volatile__ ( \ 57 __asm__ __volatile__ ( \
diff --git a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h
index 540865fa7ec3..114d9d29ca9d 100644
--- a/include/asm-mips/sibyte/swarm.h
+++ b/include/asm-mips/sibyte/swarm.h
@@ -26,24 +26,6 @@
26#define SIBYTE_HAVE_PCMCIA 1 26#define SIBYTE_HAVE_PCMCIA 1
27#define SIBYTE_HAVE_IDE 1 27#define SIBYTE_HAVE_IDE 1
28#endif 28#endif
29#ifdef CONFIG_SIBYTE_PTSWARM
30#define SIBYTE_BOARD_NAME "PTSWARM"
31#define SIBYTE_HAVE_PCMCIA 1
32#define SIBYTE_HAVE_IDE 1
33#define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
34#endif
35#ifdef CONFIG_SIBYTE_PT1120
36#define SIBYTE_BOARD_NAME "PT1120"
37#define SIBYTE_HAVE_PCMCIA 1
38#define SIBYTE_HAVE_IDE 1
39#define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
40#endif
41#ifdef CONFIG_SIBYTE_PT1125
42#define SIBYTE_BOARD_NAME "PT1125"
43#define SIBYTE_HAVE_PCMCIA 1
44#define SIBYTE_HAVE_IDE 1
45#define SIBYTE_DEFAULT_CONSOLE "ttyS0,115200"
46#endif
47#ifdef CONFIG_SIBYTE_LITTLESUR 29#ifdef CONFIG_SIBYTE_LITTLESUR
48#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)" 30#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)"
49#define SIBYTE_HAVE_PCMCIA 0 31#define SIBYTE_HAVE_PCMCIA 0
diff --git a/include/asm-mips/smp-ops.h b/include/asm-mips/smp-ops.h
new file mode 100644
index 000000000000..b17fdfb5d818
--- /dev/null
+++ b/include/asm-mips/smp-ops.h
@@ -0,0 +1,56 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General
3 * Public License. See the file "COPYING" in the main directory of this
4 * archive for more details.
5 *
6 * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
7 * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
8 * Copyright (C) 2000, 2001, 2002 Ralf Baechle
9 * Copyright (C) 2000, 2001 Broadcom Corporation
10 */
11#ifndef __ASM_SMP_OPS_H
12#define __ASM_SMP_OPS_H
13
14#ifdef CONFIG_SMP
15
16#include <linux/cpumask.h>
17
18struct plat_smp_ops {
19 void (*send_ipi_single)(int cpu, unsigned int action);
20 void (*send_ipi_mask)(cpumask_t mask, unsigned int action);
21 void (*init_secondary)(void);
22 void (*smp_finish)(void);
23 void (*cpus_done)(void);
24 void (*boot_secondary)(int cpu, struct task_struct *idle);
25 void (*smp_setup)(void);
26 void (*prepare_cpus)(unsigned int max_cpus);
27};
28
29extern void register_smp_ops(struct plat_smp_ops *ops);
30
31static inline void plat_smp_setup(void)
32{
33 extern struct plat_smp_ops *mp_ops; /* private */
34
35 mp_ops->smp_setup();
36}
37
38#else /* !CONFIG_SMP */
39
40struct plat_smp_ops;
41
42static inline void plat_smp_setup(void)
43{
44 /* UP, nothing to do ... */
45}
46
47static inline void register_smp_ops(struct plat_smp_ops *ops)
48{
49}
50
51#endif /* !CONFIG_SMP */
52
53extern struct plat_smp_ops up_smp_ops;
54extern struct plat_smp_ops vsmp_smp_ops;
55
56#endif /* __ASM_SMP_OPS_H */
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
index dc770025a9b0..84fef1aeec0c 100644
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -11,14 +11,16 @@
11#ifndef __ASM_SMP_H 11#ifndef __ASM_SMP_H
12#define __ASM_SMP_H 12#define __ASM_SMP_H
13 13
14
15#ifdef CONFIG_SMP
16
17#include <linux/bitops.h> 14#include <linux/bitops.h>
18#include <linux/linkage.h> 15#include <linux/linkage.h>
19#include <linux/threads.h> 16#include <linux/threads.h>
20#include <linux/cpumask.h> 17#include <linux/cpumask.h>
18
21#include <asm/atomic.h> 19#include <asm/atomic.h>
20#include <asm/smp-ops.h>
21
22extern int smp_num_siblings;
23extern cpumask_t cpu_sibling_map[];
22 24
23#define raw_smp_processor_id() (current_thread_info()->cpu) 25#define raw_smp_processor_id() (current_thread_info()->cpu)
24 26
@@ -49,56 +51,6 @@ extern struct call_data_struct *call_data;
49extern cpumask_t phys_cpu_present_map; 51extern cpumask_t phys_cpu_present_map;
50#define cpu_possible_map phys_cpu_present_map 52#define cpu_possible_map phys_cpu_present_map
51 53
52/*
53 * These are defined by the board-specific code.
54 */
55
56/*
57 * Cause the function described by call_data to be executed on the passed
58 * cpu. When the function has finished, increment the finished field of
59 * call_data.
60 */
61extern void core_send_ipi(int cpu, unsigned int action);
62
63static inline void core_send_ipi_mask(cpumask_t mask, unsigned int action)
64{
65 unsigned int i;
66
67 for_each_cpu_mask(i, mask)
68 core_send_ipi(i, action);
69}
70
71
72/*
73 * Firmware CPU startup hook
74 */
75extern void prom_boot_secondary(int cpu, struct task_struct *idle);
76
77/*
78 * After we've done initial boot, this function is called to allow the
79 * board code to clean up state, if needed
80 */
81extern void prom_init_secondary(void);
82
83/*
84 * Populate cpu_possible_map before smp_init, called from setup_arch.
85 */
86extern void plat_smp_setup(void);
87
88/*
89 * Called in smp_prepare_cpus.
90 */
91extern void plat_prepare_cpus(unsigned int max_cpus);
92
93/*
94 * Last chance for the board code to finish SMP initialization before
95 * the CPU is "online".
96 */
97extern void prom_smp_finish(void);
98
99/* Hook for after all CPUs are online */
100extern void prom_cpus_done(void);
101
102extern void asmlinkage smp_bootstrap(void); 54extern void asmlinkage smp_bootstrap(void);
103 55
104/* 56/*
@@ -108,11 +60,11 @@ extern void asmlinkage smp_bootstrap(void);
108 */ 60 */
109static inline void smp_send_reschedule(int cpu) 61static inline void smp_send_reschedule(int cpu)
110{ 62{
111 core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); 63 extern struct plat_smp_ops *mp_ops; /* private */
64
65 mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF);
112} 66}
113 67
114extern asmlinkage void smp_call_function_interrupt(void); 68extern asmlinkage void smp_call_function_interrupt(void);
115 69
116#endif /* CONFIG_SMP */
117
118#endif /* __ASM_SMP_H */ 70#endif /* __ASM_SMP_H */
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index af081457f847..e716447e5e03 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -35,23 +35,23 @@ extern unsigned int sni_brd_type;
35#define SNI_CPU_M8050 0x0b 35#define SNI_CPU_M8050 0x0b
36#define SNI_CPU_M8053 0x0d 36#define SNI_CPU_M8053 0x0d
37 37
38#define SNI_PORT_BASE 0xb4000000 38#define SNI_PORT_BASE CKSEG1ADDR(0xb4000000)
39 39
40#ifndef __MIPSEL__ 40#ifndef __MIPSEL__
41/* 41/*
42 * ASIC PCI registers for big endian configuration. 42 * ASIC PCI registers for big endian configuration.
43 */ 43 */
44#define PCIMT_UCONF 0xbfff0004 44#define PCIMT_UCONF CKSEG1ADDR(0xbfff0004)
45#define PCIMT_IOADTIMEOUT2 0xbfff000c 45#define PCIMT_IOADTIMEOUT2 CKSEG1ADDR(0xbfff000c)
46#define PCIMT_IOMEMCONF 0xbfff0014 46#define PCIMT_IOMEMCONF CKSEG1ADDR(0xbfff0014)
47#define PCIMT_IOMMU 0xbfff001c 47#define PCIMT_IOMMU CKSEG1ADDR(0xbfff001c)
48#define PCIMT_IOADTIMEOUT1 0xbfff0024 48#define PCIMT_IOADTIMEOUT1 CKSEG1ADDR(0xbfff0024)
49#define PCIMT_DMAACCESS 0xbfff002c 49#define PCIMT_DMAACCESS CKSEG1ADDR(0xbfff002c)
50#define PCIMT_DMAHIT 0xbfff0034 50#define PCIMT_DMAHIT CKSEG1ADDR(0xbfff0034)
51#define PCIMT_ERRSTATUS 0xbfff003c 51#define PCIMT_ERRSTATUS CKSEG1ADDR(0xbfff003c)
52#define PCIMT_ERRADDR 0xbfff0044 52#define PCIMT_ERRADDR CKSEG1ADDR(0xbfff0044)
53#define PCIMT_SYNDROME 0xbfff004c 53#define PCIMT_SYNDROME CKSEG1ADDR(0xbfff004c)
54#define PCIMT_ITPEND 0xbfff0054 54#define PCIMT_ITPEND CKSEG1ADDR(0xbfff0054)
55#define IT_INT2 0x01 55#define IT_INT2 0x01
56#define IT_INTD 0x02 56#define IT_INTD 0x02
57#define IT_INTC 0x04 57#define IT_INTC 0x04
@@ -60,32 +60,32 @@ extern unsigned int sni_brd_type;
60#define IT_EISA 0x20 60#define IT_EISA 0x20
61#define IT_SCSI 0x40 61#define IT_SCSI 0x40
62#define IT_ETH 0x80 62#define IT_ETH 0x80
63#define PCIMT_IRQSEL 0xbfff005c 63#define PCIMT_IRQSEL CKSEG1ADDR(0xbfff005c)
64#define PCIMT_TESTMEM 0xbfff0064 64#define PCIMT_TESTMEM CKSEG1ADDR(0xbfff0064)
65#define PCIMT_ECCREG 0xbfff006c 65#define PCIMT_ECCREG CKSEG1ADDR(0xbfff006c)
66#define PCIMT_CONFIG_ADDRESS 0xbfff0074 66#define PCIMT_CONFIG_ADDRESS CKSEG1ADDR(0xbfff0074)
67#define PCIMT_ASIC_ID 0xbfff007c /* read */ 67#define PCIMT_ASIC_ID CKSEG1ADDR(0xbfff007c) /* read */
68#define PCIMT_SOFT_RESET 0xbfff007c /* write */ 68#define PCIMT_SOFT_RESET CKSEG1ADDR(0xbfff007c) /* write */
69#define PCIMT_PIA_OE 0xbfff0084 69#define PCIMT_PIA_OE CKSEG1ADDR(0xbfff0084)
70#define PCIMT_PIA_DATAOUT 0xbfff008c 70#define PCIMT_PIA_DATAOUT CKSEG1ADDR(0xbfff008c)
71#define PCIMT_PIA_DATAIN 0xbfff0094 71#define PCIMT_PIA_DATAIN CKSEG1ADDR(0xbfff0094)
72#define PCIMT_CACHECONF 0xbfff009c 72#define PCIMT_CACHECONF CKSEG1ADDR(0xbfff009c)
73#define PCIMT_INVSPACE 0xbfff00a4 73#define PCIMT_INVSPACE CKSEG1ADDR(0xbfff00a4)
74#else 74#else
75/* 75/*
76 * ASIC PCI registers for little endian configuration. 76 * ASIC PCI registers for little endian configuration.
77 */ 77 */
78#define PCIMT_UCONF 0xbfff0000 78#define PCIMT_UCONF CKSEG1ADDR(0xbfff0000)
79#define PCIMT_IOADTIMEOUT2 0xbfff0008 79#define PCIMT_IOADTIMEOUT2 CKSEG1ADDR(0xbfff0008)
80#define PCIMT_IOMEMCONF 0xbfff0010 80#define PCIMT_IOMEMCONF CKSEG1ADDR(0xbfff0010)
81#define PCIMT_IOMMU 0xbfff0018 81#define PCIMT_IOMMU CKSEG1ADDR(0xbfff0018)
82#define PCIMT_IOADTIMEOUT1 0xbfff0020 82#define PCIMT_IOADTIMEOUT1 CKSEG1ADDR(0xbfff0020)
83#define PCIMT_DMAACCESS 0xbfff0028 83#define PCIMT_DMAACCESS CKSEG1ADDR(0xbfff0028)
84#define PCIMT_DMAHIT 0xbfff0030 84#define PCIMT_DMAHIT CKSEG1ADDR(0xbfff0030)
85#define PCIMT_ERRSTATUS 0xbfff0038 85#define PCIMT_ERRSTATUS CKSEG1ADDR(0xbfff0038)
86#define PCIMT_ERRADDR 0xbfff0040 86#define PCIMT_ERRADDR CKSEG1ADDR(0xbfff0040)
87#define PCIMT_SYNDROME 0xbfff0048 87#define PCIMT_SYNDROME CKSEG1ADDR(0xbfff0048)
88#define PCIMT_ITPEND 0xbfff0050 88#define PCIMT_ITPEND CKSEG1ADDR(0xbfff0050)
89#define IT_INT2 0x01 89#define IT_INT2 0x01
90#define IT_INTD 0x02 90#define IT_INTD 0x02
91#define IT_INTC 0x04 91#define IT_INTC 0x04
@@ -94,20 +94,20 @@ extern unsigned int sni_brd_type;
94#define IT_EISA 0x20 94#define IT_EISA 0x20
95#define IT_SCSI 0x40 95#define IT_SCSI 0x40
96#define IT_ETH 0x80 96#define IT_ETH 0x80
97#define PCIMT_IRQSEL 0xbfff0058 97#define PCIMT_IRQSEL CKSEG1ADDR(0xbfff0058)
98#define PCIMT_TESTMEM 0xbfff0060 98#define PCIMT_TESTMEM CKSEG1ADDR(0xbfff0060)
99#define PCIMT_ECCREG 0xbfff0068 99#define PCIMT_ECCREG CKSEG1ADDR(0xbfff0068)
100#define PCIMT_CONFIG_ADDRESS 0xbfff0070 100#define PCIMT_CONFIG_ADDRESS CKSEG1ADDR(0xbfff0070)
101#define PCIMT_ASIC_ID 0xbfff0078 /* read */ 101#define PCIMT_ASIC_ID CKSEG1ADDR(0xbfff0078) /* read */
102#define PCIMT_SOFT_RESET 0xbfff0078 /* write */ 102#define PCIMT_SOFT_RESET CKSEG1ADDR(0xbfff0078) /* write */
103#define PCIMT_PIA_OE 0xbfff0080 103#define PCIMT_PIA_OE CKSEG1ADDR(0xbfff0080)
104#define PCIMT_PIA_DATAOUT 0xbfff0088 104#define PCIMT_PIA_DATAOUT CKSEG1ADDR(0xbfff0088)
105#define PCIMT_PIA_DATAIN 0xbfff0090 105#define PCIMT_PIA_DATAIN CKSEG1ADDR(0xbfff0090)
106#define PCIMT_CACHECONF 0xbfff0098 106#define PCIMT_CACHECONF CKSEG1ADDR(0xbfff0098)
107#define PCIMT_INVSPACE 0xbfff00a0 107#define PCIMT_INVSPACE CKSEG1ADDR(0xbfff00a0)
108#endif 108#endif
109 109
110#define PCIMT_PCI_CONF 0xbfff0100 110#define PCIMT_PCI_CONF CKSEG1ADDR(0xbfff0100)
111 111
112/* 112/*
113 * Data port for the PCI bus in IO space 113 * Data port for the PCI bus in IO space
@@ -117,34 +117,34 @@ extern unsigned int sni_brd_type;
117/* 117/*
118 * Board specific registers 118 * Board specific registers
119 */ 119 */
120#define PCIMT_CSMSR 0xbfd00000 120#define PCIMT_CSMSR CKSEG1ADDR(0xbfd00000)
121#define PCIMT_CSSWITCH 0xbfd10000 121#define PCIMT_CSSWITCH CKSEG1ADDR(0xbfd10000)
122#define PCIMT_CSITPEND 0xbfd20000 122#define PCIMT_CSITPEND CKSEG1ADDR(0xbfd20000)
123#define PCIMT_AUTO_PO_EN 0xbfd30000 123#define PCIMT_AUTO_PO_EN CKSEG1ADDR(0xbfd30000)
124#define PCIMT_CLR_TEMP 0xbfd40000 124#define PCIMT_CLR_TEMP CKSEG1ADDR(0xbfd40000)
125#define PCIMT_AUTO_PO_DIS 0xbfd50000 125#define PCIMT_AUTO_PO_DIS CKSEG1ADDR(0xbfd50000)
126#define PCIMT_EXMSR 0xbfd60000 126#define PCIMT_EXMSR CKSEG1ADDR(0xbfd60000)
127#define PCIMT_UNUSED1 0xbfd70000 127#define PCIMT_UNUSED1 CKSEG1ADDR(0xbfd70000)
128#define PCIMT_CSWCSM 0xbfd80000 128#define PCIMT_CSWCSM CKSEG1ADDR(0xbfd80000)
129#define PCIMT_UNUSED2 0xbfd90000 129#define PCIMT_UNUSED2 CKSEG1ADDR(0xbfd90000)
130#define PCIMT_CSLED 0xbfda0000 130#define PCIMT_CSLED CKSEG1ADDR(0xbfda0000)
131#define PCIMT_CSMAPISA 0xbfdb0000 131#define PCIMT_CSMAPISA CKSEG1ADDR(0xbfdb0000)
132#define PCIMT_CSRSTBP 0xbfdc0000 132#define PCIMT_CSRSTBP CKSEG1ADDR(0xbfdc0000)
133#define PCIMT_CLRPOFF 0xbfdd0000 133#define PCIMT_CLRPOFF CKSEG1ADDR(0xbfdd0000)
134#define PCIMT_CSTIMER 0xbfde0000 134#define PCIMT_CSTIMER CKSEG1ADDR(0xbfde0000)
135#define PCIMT_PWDN 0xbfdf0000 135#define PCIMT_PWDN CKSEG1ADDR(0xbfdf0000)
136 136
137/* 137/*
138 * A20R based boards 138 * A20R based boards
139 */ 139 */
140#define A20R_PT_CLOCK_BASE 0xbc040000 140#define A20R_PT_CLOCK_BASE CKSEG1ADDR(0xbc040000)
141#define A20R_PT_TIM0_ACK 0xbc050000 141#define A20R_PT_TIM0_ACK CKSEG1ADDR(0xbc050000)
142#define A20R_PT_TIM1_ACK 0xbc060000 142#define A20R_PT_TIM1_ACK CKSEG1ADDR(0xbc060000)
143 143
144#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE 144#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE
145#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5) 145#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5)
146 146
147#define SNI_PCIT_INT_REG 0xbfff000c 147#define SNI_PCIT_INT_REG CKSEG1ADDR(0xbfff000c)
148 148
149#define SNI_PCIT_INT_START 24 149#define SNI_PCIT_INT_START 24
150#define SNI_PCIT_INT_END 30 150#define SNI_PCIT_INT_END 30
@@ -186,10 +186,30 @@ extern unsigned int sni_brd_type;
186/* 186/*
187 * Base address for the mapped 16mb EISA bus segment. 187 * Base address for the mapped 16mb EISA bus segment.
188 */ 188 */
189#define PCIMT_EISA_BASE 0xb0000000 189#define PCIMT_EISA_BASE CKSEG1ADDR(0xb0000000)
190 190
191/* PCI EISA Interrupt acknowledge */ 191/* PCI EISA Interrupt acknowledge */
192#define PCIMT_INT_ACKNOWLEDGE 0xba000000 192#define PCIMT_INT_ACKNOWLEDGE CKSEG1ADDR(0xba000000)
193
194/*
195 * SNI ID PROM
196 *
197 * SNI_IDPROM_MEMSIZE Memsize in 16MB quantities
198 * SNI_IDPROM_BRDTYPE Board Type
199 * SNI_IDPROM_CPUTYPE CPU Type on RM400
200 */
201#ifdef CONFIG_CPU_BIG_ENDIAN
202#define __SNI_END 0
203#endif
204#ifdef CONFIG_CPU_LITTLE_ENDIAN
205#define __SNI_END 3
206#endif
207#define SNI_IDPROM_BASE CKSEG1ADDR(0x1ff00000)
208#define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE + (0x28 ^ __SNI_END))
209#define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE + (0x29 ^ __SNI_END))
210#define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE + (0x30 ^ __SNI_END))
211
212#define SNI_IDPROM_SIZE 0x1000
193 213
194/* board specific init functions */ 214/* board specific init functions */
195extern void sni_a20r_init(void); 215extern void sni_a20r_init(void);
@@ -207,6 +227,9 @@ extern void sni_pcimt_irq_init(void);
207/* timer inits */ 227/* timer inits */
208extern void sni_cpu_time_init(void); 228extern void sni_cpu_time_init(void);
209 229
230/* eisa init for RM200/400 */
231extern int sni_eisa_root_init(void);
232
210/* common irq stuff */ 233/* common irq stuff */
211extern void (*sni_hwint)(void); 234extern void (*sni_hwint)(void);
212extern struct irqaction sni_isa_irq; 235extern struct irqaction sni_isa_irq;
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index fb41a8d76392..051e1af0bb95 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -6,6 +6,7 @@
6 * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle 6 * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
7 * Copyright (C) 1994, 1995, 1996 Paul M. Antoine. 7 * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
8 * Copyright (C) 1999 Silicon Graphics, Inc. 8 * Copyright (C) 1999 Silicon Graphics, Inc.
9 * Copyright (C) 2007 Maciej W. Rozycki
9 */ 10 */
10#ifndef _ASM_STACKFRAME_H 11#ifndef _ASM_STACKFRAME_H
11#define _ASM_STACKFRAME_H 12#define _ASM_STACKFRAME_H
@@ -145,8 +146,16 @@
145 .set reorder 146 .set reorder
146 /* Called from user mode, new stack. */ 147 /* Called from user mode, new stack. */
147 get_saved_sp 148 get_saved_sp
149#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
1488: move k0, sp 1508: move k0, sp
149 PTR_SUBU sp, k1, PT_SIZE 151 PTR_SUBU sp, k1, PT_SIZE
152#else
153 .set at=k0
1548: PTR_SUBU k1, PT_SIZE
155 .set noat
156 move k0, sp
157 move sp, k1
158#endif
150 LONG_S k0, PT_R29(sp) 159 LONG_S k0, PT_R29(sp)
151 LONG_S $3, PT_R3(sp) 160 LONG_S $3, PT_R3(sp)
152 /* 161 /*
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 7717934f94c3..a8fd16e1981f 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -31,20 +31,13 @@ extern int rtc_mips_set_time(unsigned long);
31extern int rtc_mips_set_mmss(unsigned long); 31extern int rtc_mips_set_mmss(unsigned long);
32 32
33/* 33/*
34 * Timer interrupt functions.
35 * mips_timer_state is needed for high precision timer calibration.
36 */
37extern int (*mips_timer_state)(void);
38
39/*
40 * board specific routines required by time_init(). 34 * board specific routines required by time_init().
41 */ 35 */
42extern void plat_time_init(void); 36extern void plat_time_init(void);
43 37
44/* 38/*
45 * mips_hpt_frequency - must be set if you intend to use an R4k-compatible 39 * mips_hpt_frequency - must be set if you intend to use an R4k-compatible
46 * counter as a timer interrupt source; otherwise it can be set up 40 * counter as a timer interrupt source.
47 * automagically with an aid of mips_timer_state.
48 */ 41 */
49extern unsigned int mips_hpt_frequency; 42extern unsigned int mips_hpt_frequency;
50 43
diff --git a/include/asm-mips/topology.h b/include/asm-mips/topology.h
index 0440fb9f2180..259145e07e97 100644
--- a/include/asm-mips/topology.h
+++ b/include/asm-mips/topology.h
@@ -1 +1,17 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 by Ralf Baechle
7 */
8#ifndef __ASM_TOPOLOGY_H
9#define __ASM_TOPOLOGY_H
10
1#include <topology.h> 11#include <topology.h>
12
13#ifdef CONFIG_SMP
14#define smt_capable() (smp_num_siblings > 1)
15#endif
16
17#endif /* __ASM_TOPOLOGY_H */
diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h
index 3f1e470192e3..0be77df70f2b 100644
--- a/include/asm-mips/tx4927/tx4927_pci.h
+++ b/include/asm-mips/tx4927/tx4927_pci.h
@@ -9,6 +9,7 @@
9#define __ASM_TX4927_TX4927_PCI_H 9#define __ASM_TX4927_TX4927_PCI_H
10 10
11#define TX4927_CCFG_TOE 0x00004000 11#define TX4927_CCFG_TOE 0x00004000
12#define TX4927_CCFG_WR 0x00008000
12#define TX4927_CCFG_TINTDIS 0x01000000 13#define TX4927_CCFG_TINTDIS 0x01000000
13 14
14#define TX4927_PCIMEM 0x08000000 15#define TX4927_PCIMEM 0x08000000
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h
index c30c718994c9..66523d610950 100644
--- a/include/asm-mips/uaccess.h
+++ b/include/asm-mips/uaccess.h
@@ -5,6 +5,7 @@
5 * 5 *
6 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle 6 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2007 Maciej W. Rozycki
8 */ 9 */
9#ifndef _ASM_UACCESS_H 10#ifndef _ASM_UACCESS_H
10#define _ASM_UACCESS_H 11#define _ASM_UACCESS_H
@@ -387,6 +388,12 @@ extern void __put_user_unknown(void);
387 "jal\t" #destination "\n\t" 388 "jal\t" #destination "\n\t"
388#endif 389#endif
389 390
391#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
392#define DADDI_SCRATCH "$0"
393#else
394#define DADDI_SCRATCH "$3"
395#endif
396
390extern size_t __copy_user(void *__to, const void *__from, size_t __n); 397extern size_t __copy_user(void *__to, const void *__from, size_t __n);
391 398
392#define __invoke_copy_to_user(to, from, n) \ 399#define __invoke_copy_to_user(to, from, n) \
@@ -403,7 +410,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
403 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ 410 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
404 : \ 411 : \
405 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ 412 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
406 "memory"); \ 413 DADDI_SCRATCH, "memory"); \
407 __cu_len_r; \ 414 __cu_len_r; \
408}) 415})
409 416
@@ -512,7 +519,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
512 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ 519 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
513 : \ 520 : \
514 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ 521 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
515 "memory"); \ 522 DADDI_SCRATCH, "memory"); \
516 __cu_len_r; \ 523 __cu_len_r; \
517}) 524})
518 525
@@ -535,7 +542,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
535 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ 542 : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
536 : \ 543 : \
537 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ 544 : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
538 "memory"); \ 545 DADDI_SCRATCH, "memory"); \
539 __cu_len_r; \ 546 __cu_len_r; \
540}) 547})
541 548
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index d2808edfd4e9..22361d5e3bf0 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -4,6 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle 6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle
7 * Copyright (C) 2007 Maciej W. Rozycki
7 */ 8 */
8#ifndef _ASM_WAR_H 9#ifndef _ASM_WAR_H
9#define _ASM_WAR_H 10#define _ASM_WAR_H
@@ -11,6 +12,67 @@
11#include <war.h> 12#include <war.h>
12 13
13/* 14/*
15 * Work around certain R4000 CPU errata (as implemented by GCC):
16 *
17 * - A double-word or a variable shift may give an incorrect result
18 * if executed immediately after starting an integer division:
19 * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
20 * erratum #28
21 * "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
22 * #19
23 *
24 * - A double-word or a variable shift may give an incorrect result
25 * if executed while an integer multiplication is in progress:
26 * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
27 * errata #16 & #28
28 *
29 * - An integer division may give an incorrect result if started in
30 * a delay slot of a taken branch or a jump:
31 * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
32 * erratum #52
33 */
34#ifdef CONFIG_CPU_R4000_WORKAROUNDS
35#define R4000_WAR 1
36#else
37#define R4000_WAR 0
38#endif
39
40/*
41 * Work around certain R4400 CPU errata (as implemented by GCC):
42 *
43 * - A double-word or a variable shift may give an incorrect result
44 * if executed immediately after starting an integer division:
45 * "MIPS R4400MC Errata, Processor Revision 1.0", erratum #10
46 * "MIPS R4400MC Errata, Processor Revision 2.0 & 3.0", erratum #4
47 */
48#ifdef CONFIG_CPU_R4400_WORKAROUNDS
49#define R4400_WAR 1
50#else
51#define R4400_WAR 0
52#endif
53
54/*
55 * Work around the "daddi" and "daddiu" CPU errata:
56 *
57 * - The `daddi' instruction fails to trap on overflow.
58 * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
59 * erratum #23
60 *
61 * - The `daddiu' instruction can produce an incorrect result.
62 * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
63 * erratum #41
64 * "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
65 * #15
66 * "MIPS R4400PC/SC Errata, Processor Revision 1.0", erratum #7
67 * "MIPS R4400MC Errata, Processor Revision 1.0", erratum #5
68 */
69#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
70#define DADDI_WAR 1
71#else
72#define DADDI_WAR 0
73#endif
74
75/*
14 * Another R4600 erratum. Due to the lack of errata information the exact 76 * Another R4600 erratum. Due to the lack of errata information the exact
15 * technical details aren't known. I've experimentally found that disabling 77 * technical details aren't known. I've experimentally found that disabling
16 * interrupts during indexed I-cache flushes seems to be sufficient to deal 78 * interrupts during indexed I-cache flushes seems to be sufficient to deal
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 733b4af7f4f1..220d9a781ab9 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -359,6 +359,8 @@ static __inline__ int test_le_bit(unsigned long nr,
359unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, 359unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
360 unsigned long size, unsigned long offset); 360 unsigned long size, unsigned long offset);
361 361
362unsigned long generic_find_next_le_bit(const unsigned long *addr,
363 unsigned long size, unsigned long offset);
362/* Bitmap functions for the ext2 filesystem */ 364/* Bitmap functions for the ext2 filesystem */
363 365
364#define ext2_set_bit(nr,addr) \ 366#define ext2_set_bit(nr,addr) \
@@ -378,6 +380,8 @@ unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
378#define ext2_find_next_zero_bit(addr, size, off) \ 380#define ext2_find_next_zero_bit(addr, size, off) \
379 generic_find_next_zero_le_bit((unsigned long*)addr, size, off) 381 generic_find_next_zero_le_bit((unsigned long*)addr, size, off)
380 382
383#define ext2_find_next_bit(addr, size, off) \
384 generic_find_next_le_bit((unsigned long *)addr, size, off)
381/* Bitmap functions for the minix filesystem. */ 385/* Bitmap functions for the minix filesystem. */
382 386
383#define minix_test_and_set_bit(nr,addr) \ 387#define minix_test_and_set_bit(nr,addr) \
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 34d9a6357c38..dba6fecad0be 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -772,6 +772,8 @@ static inline int sched_find_first_bit(unsigned long *b)
772 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 772 test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
773#define ext2_test_bit(nr, addr) \ 773#define ext2_test_bit(nr, addr) \
774 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) 774 test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)
775#define ext2_find_next_bit(addr, size, off) \
776 generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
775 777
776#ifndef __s390x__ 778#ifndef __s390x__
777 779
diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h
index ddb18ad23303..b2e4124070ae 100644
--- a/include/asm-sh/machvec.h
+++ b/include/asm-sh/machvec.h
@@ -65,6 +65,6 @@ extern struct sh_machine_vector sh_mv;
65#define get_system_type() sh_mv.mv_name 65#define get_system_type() sh_mv.mv_name
66 66
67#define __initmv \ 67#define __initmv \
68 __attribute_used__ __attribute__((__section__ (".machvec.init"))) 68 __used __section(.machvec.init)
69 69
70#endif /* _ASM_SH_MACHVEC_H */ 70#endif /* _ASM_SH_MACHVEC_H */
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index c6577d3dc46d..c50e5d35fe84 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -68,7 +68,7 @@ struct thread_info {
68#define init_stack (init_thread_union.stack) 68#define init_stack (init_thread_union.stack)
69 69
70/* how to get the current stack pointer from C */ 70/* how to get the current stack pointer from C */
71register unsigned long current_stack_pointer asm("r15") __attribute_used__; 71register unsigned long current_stack_pointer asm("r15") __used;
72 72
73/* how to get the thread information struct from C */ 73/* how to get the thread information struct from C */
74static inline struct thread_info *current_thread_info(void) 74static inline struct thread_info *current_thread_info(void)
diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h
index ef58fd2a6eb0..a516e9192f11 100644
--- a/include/asm-x86/thread_info_32.h
+++ b/include/asm-x86/thread_info_32.h
@@ -85,7 +85,7 @@ struct thread_info {
85 85
86 86
87/* how to get the current stack pointer from C */ 87/* how to get the current stack pointer from C */
88register unsigned long current_stack_pointer asm("esp") __attribute_used__; 88register unsigned long current_stack_pointer asm("esp") __used;
89 89
90/* how to get the thread information struct from C */ 90/* how to get the thread information struct from C */
91static inline struct thread_info *current_thread_info(void) 91static inline struct thread_info *current_thread_info(void)
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index bc33a5c87d64..27b9350052b4 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -35,7 +35,6 @@ header-y += atmsap.h
35header-y += atmsvc.h 35header-y += atmsvc.h
36header-y += atm_zatm.h 36header-y += atm_zatm.h
37header-y += auto_fs4.h 37header-y += auto_fs4.h
38header-y += auxvec.h
39header-y += ax25.h 38header-y += ax25.h
40header-y += b1lli.h 39header-y += b1lli.h
41header-y += baycom.h 40header-y += baycom.h
@@ -75,7 +74,7 @@ header-y += gen_stats.h
75header-y += gigaset_dev.h 74header-y += gigaset_dev.h
76header-y += hdsmart.h 75header-y += hdsmart.h
77header-y += hysdn_if.h 76header-y += hysdn_if.h
78header-y += i2c-dev.h 77header-y += i2o-dev.h
79header-y += i8k.h 78header-y += i8k.h
80header-y += if_arcnet.h 79header-y += if_arcnet.h
81header-y += if_bonding.h 80header-y += if_bonding.h
@@ -160,7 +159,6 @@ header-y += veth.h
160header-y += video_decoder.h 159header-y += video_decoder.h
161header-y += video_encoder.h 160header-y += video_encoder.h
162header-y += videotext.h 161header-y += videotext.h
163header-y += vt.h
164header-y += x25.h 162header-y += x25.h
165 163
166unifdef-y += acct.h 164unifdef-y += acct.h
@@ -175,6 +173,7 @@ unifdef-y += atm.h
175unifdef-y += atm_tcp.h 173unifdef-y += atm_tcp.h
176unifdef-y += audit.h 174unifdef-y += audit.h
177unifdef-y += auto_fs.h 175unifdef-y += auto_fs.h
176unifdef-y += auxvec.h
178unifdef-y += binfmts.h 177unifdef-y += binfmts.h
179unifdef-y += capability.h 178unifdef-y += capability.h
180unifdef-y += capi.h 179unifdef-y += capi.h
@@ -216,7 +215,7 @@ unifdef-y += hdreg.h
216unifdef-y += hiddev.h 215unifdef-y += hiddev.h
217unifdef-y += hpet.h 216unifdef-y += hpet.h
218unifdef-y += i2c.h 217unifdef-y += i2c.h
219unifdef-y += i2o-dev.h 218unifdef-y += i2c-dev.h
220unifdef-y += icmp.h 219unifdef-y += icmp.h
221unifdef-y += icmpv6.h 220unifdef-y += icmpv6.h
222unifdef-y += if_addr.h 221unifdef-y += if_addr.h
@@ -350,6 +349,7 @@ unifdef-y += videodev.h
350unifdef-y += virtio_config.h 349unifdef-y += virtio_config.h
351unifdef-y += virtio_blk.h 350unifdef-y += virtio_blk.h
352unifdef-y += virtio_net.h 351unifdef-y += virtio_net.h
352unifdef-y += vt.h
353unifdef-y += wait.h 353unifdef-y += wait.h
354unifdef-y += wanrouter.h 354unifdef-y += wanrouter.h
355unifdef-y += watchdog.h 355unifdef-y += watchdog.h
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index da0d83fbadc0..e98801f06dcc 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -192,6 +192,8 @@ int sync_dirty_buffer(struct buffer_head *bh);
192int submit_bh(int, struct buffer_head *); 192int submit_bh(int, struct buffer_head *);
193void write_boundary_block(struct block_device *bdev, 193void write_boundary_block(struct block_device *bdev,
194 sector_t bblock, unsigned blocksize); 194 sector_t bblock, unsigned blocksize);
195int bh_uptodate_or_lock(struct buffer_head *bh);
196int bh_submit_read(struct buffer_head *bh);
195 197
196extern int buffer_heads_over_limit; 198extern int buffer_heads_over_limit;
197 199
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index 2d8c0f48f55e..e5eb795f78a1 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -7,10 +7,8 @@
7 7
8#if __GNUC_MINOR__ >= 3 8#if __GNUC_MINOR__ >= 3
9# define __used __attribute__((__used__)) 9# define __used __attribute__((__used__))
10# define __attribute_used__ __used /* deprecated */
11#else 10#else
12# define __used __attribute__((__unused__)) 11# define __used __attribute__((__unused__))
13# define __attribute_used__ __used /* deprecated */
14#endif 12#endif
15 13
16#if __GNUC_MINOR__ >= 4 14#if __GNUC_MINOR__ >= 4
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index ee7ca5de970c..0ab3a3232330 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -15,7 +15,6 @@
15#endif 15#endif
16 16
17#define __used __attribute__((__used__)) 17#define __used __attribute__((__used__))
18#define __attribute_used__ __used /* deprecated */
19#define __must_check __attribute__((warn_unused_result)) 18#define __must_check __attribute__((warn_unused_result))
20#define __compiler_offsetof(a,b) __builtin_offsetof(a,b) 19#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
21#define __always_inline inline __attribute__((always_inline)) 20#define __always_inline inline __attribute__((always_inline))
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index c68b67b86ef1..d0e17e1657dc 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -126,10 +126,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
126 * Mark functions that are referenced only in inline assembly as __used so 126 * Mark functions that are referenced only in inline assembly as __used so
127 * the code is emitted even though it appears to be unreferenced. 127 * the code is emitted even though it appears to be unreferenced.
128 */ 128 */
129#ifndef __attribute_used__
130# define __attribute_used__ /* deprecated */
131#endif
132
133#ifndef __used 129#ifndef __used
134# define __used /* unimplemented */ 130# define __used /* unimplemented */
135#endif 131#endif
@@ -175,4 +171,9 @@ extern void __chk_io_ptr(const volatile void __iomem *);
175#define __cold 171#define __cold
176#endif 172#endif
177 173
174/* Simple shorthand for a section definition */
175#ifndef __section
176# define __section(S) __attribute__ ((__section__(#S)))
177#endif
178
178#endif /* __LINUX_COMPILER_H */ 179#endif /* __LINUX_COMPILER_H */
diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h
index e831759b2fb5..278e3ef05336 100644
--- a/include/linux/elfnote.h
+++ b/include/linux/elfnote.h
@@ -76,7 +76,7 @@
76 typeof(desc) _desc \ 76 typeof(desc) _desc \
77 __attribute__((aligned(sizeof(Elf##size##_Word)))); \ 77 __attribute__((aligned(sizeof(Elf##size##_Word)))); \
78 } _ELFNOTE_PASTE(_note_, unique) \ 78 } _ELFNOTE_PASTE(_note_, unique) \
79 __attribute_used__ \ 79 __used \
80 __attribute__((section(".note." name), \ 80 __attribute__((section(".note." name), \
81 aligned(sizeof(Elf##size##_Word)), \ 81 aligned(sizeof(Elf##size##_Word)), \
82 unused)) = { \ 82 unused)) = { \
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
index 97dd409d5f4a..1852313fc7c7 100644
--- a/include/linux/ext4_fs.h
+++ b/include/linux/ext4_fs.h
@@ -20,6 +20,8 @@
20#include <linux/blkdev.h> 20#include <linux/blkdev.h>
21#include <linux/magic.h> 21#include <linux/magic.h>
22 22
23#include <linux/ext4_fs_i.h>
24
23/* 25/*
24 * The second extended filesystem constants/structures 26 * The second extended filesystem constants/structures
25 */ 27 */
@@ -51,6 +53,50 @@
51#define ext4_debug(f, a...) do {} while (0) 53#define ext4_debug(f, a...) do {} while (0)
52#endif 54#endif
53 55
56#define EXT4_MULTIBLOCK_ALLOCATOR 1
57
58/* prefer goal again. length */
59#define EXT4_MB_HINT_MERGE 1
60/* blocks already reserved */
61#define EXT4_MB_HINT_RESERVED 2
62/* metadata is being allocated */
63#define EXT4_MB_HINT_METADATA 4
64/* first blocks in the file */
65#define EXT4_MB_HINT_FIRST 8
66/* search for the best chunk */
67#define EXT4_MB_HINT_BEST 16
68/* data is being allocated */
69#define EXT4_MB_HINT_DATA 32
70/* don't preallocate (for tails) */
71#define EXT4_MB_HINT_NOPREALLOC 64
72/* allocate for locality group */
73#define EXT4_MB_HINT_GROUP_ALLOC 128
74/* allocate goal blocks or none */
75#define EXT4_MB_HINT_GOAL_ONLY 256
76/* goal is meaningful */
77#define EXT4_MB_HINT_TRY_GOAL 512
78
79struct ext4_allocation_request {
80 /* target inode for block we're allocating */
81 struct inode *inode;
82 /* logical block in target inode */
83 ext4_lblk_t logical;
84 /* phys. target (a hint) */
85 ext4_fsblk_t goal;
86 /* the closest logical allocated block to the left */
87 ext4_lblk_t lleft;
88 /* phys. block for ^^^ */
89 ext4_fsblk_t pleft;
90 /* the closest logical allocated block to the right */
91 ext4_lblk_t lright;
92 /* phys. block for ^^^ */
93 ext4_fsblk_t pright;
94 /* how many blocks we want to allocate */
95 unsigned long len;
96 /* flags. see above EXT4_MB_HINT_* */
97 unsigned long flags;
98};
99
54/* 100/*
55 * Special inodes numbers 101 * Special inodes numbers
56 */ 102 */
@@ -73,8 +119,8 @@
73 * Macro-instructions used to manage several block sizes 119 * Macro-instructions used to manage several block sizes
74 */ 120 */
75#define EXT4_MIN_BLOCK_SIZE 1024 121#define EXT4_MIN_BLOCK_SIZE 1024
76#define EXT4_MAX_BLOCK_SIZE 4096 122#define EXT4_MAX_BLOCK_SIZE 65536
77#define EXT4_MIN_BLOCK_LOG_SIZE 10 123#define EXT4_MIN_BLOCK_LOG_SIZE 10
78#ifdef __KERNEL__ 124#ifdef __KERNEL__
79# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) 125# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize)
80#else 126#else
@@ -118,6 +164,11 @@ struct ext4_group_desc
118 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ 164 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
119 __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ 165 __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
120 __le32 bg_inode_table_hi; /* Inodes table block MSB */ 166 __le32 bg_inode_table_hi; /* Inodes table block MSB */
167 __le16 bg_free_blocks_count_hi;/* Free blocks count MSB */
168 __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
169 __le16 bg_used_dirs_count_hi; /* Directories count MSB */
170 __le16 bg_itable_unused_hi; /* Unused inodes count MSB */
171 __u32 bg_reserved2[3];
121}; 172};
122 173
123#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ 174#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
@@ -178,8 +229,9 @@ struct ext4_group_desc
178#define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */ 229#define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */
179#define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ 230#define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
180#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ 231#define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
181#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ 232#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
182#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ 233#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
234#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
183 235
184#define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ 236#define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
185#define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ 237#define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
@@ -237,6 +289,7 @@ struct ext4_new_group_data {
237#endif 289#endif
238#define EXT4_IOC_GETRSVSZ _IOR('f', 5, long) 290#define EXT4_IOC_GETRSVSZ _IOR('f', 5, long)
239#define EXT4_IOC_SETRSVSZ _IOW('f', 6, long) 291#define EXT4_IOC_SETRSVSZ _IOW('f', 6, long)
292#define EXT4_IOC_MIGRATE _IO('f', 7)
240 293
241/* 294/*
242 * ioctl commands in 32 bit emulation 295 * ioctl commands in 32 bit emulation
@@ -275,18 +328,18 @@ struct ext4_mount_options {
275struct ext4_inode { 328struct ext4_inode {
276 __le16 i_mode; /* File mode */ 329 __le16 i_mode; /* File mode */
277 __le16 i_uid; /* Low 16 bits of Owner Uid */ 330 __le16 i_uid; /* Low 16 bits of Owner Uid */
278 __le32 i_size; /* Size in bytes */ 331 __le32 i_size_lo; /* Size in bytes */
279 __le32 i_atime; /* Access time */ 332 __le32 i_atime; /* Access time */
280 __le32 i_ctime; /* Inode Change time */ 333 __le32 i_ctime; /* Inode Change time */
281 __le32 i_mtime; /* Modification time */ 334 __le32 i_mtime; /* Modification time */
282 __le32 i_dtime; /* Deletion Time */ 335 __le32 i_dtime; /* Deletion Time */
283 __le16 i_gid; /* Low 16 bits of Group Id */ 336 __le16 i_gid; /* Low 16 bits of Group Id */
284 __le16 i_links_count; /* Links count */ 337 __le16 i_links_count; /* Links count */
285 __le32 i_blocks; /* Blocks count */ 338 __le32 i_blocks_lo; /* Blocks count */
286 __le32 i_flags; /* File flags */ 339 __le32 i_flags; /* File flags */
287 union { 340 union {
288 struct { 341 struct {
289 __u32 l_i_reserved1; 342 __le32 l_i_version;
290 } linux1; 343 } linux1;
291 struct { 344 struct {
292 __u32 h_i_translator; 345 __u32 h_i_translator;
@@ -297,12 +350,12 @@ struct ext4_inode {
297 } osd1; /* OS dependent 1 */ 350 } osd1; /* OS dependent 1 */
298 __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ 351 __le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
299 __le32 i_generation; /* File version (for NFS) */ 352 __le32 i_generation; /* File version (for NFS) */
300 __le32 i_file_acl; /* File ACL */ 353 __le32 i_file_acl_lo; /* File ACL */
301 __le32 i_dir_acl; /* Directory ACL */ 354 __le32 i_size_high;
302 __le32 i_obso_faddr; /* Obsoleted fragment address */ 355 __le32 i_obso_faddr; /* Obsoleted fragment address */
303 union { 356 union {
304 struct { 357 struct {
305 __le16 l_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ 358 __le16 l_i_blocks_high; /* were l_i_reserved1 */
306 __le16 l_i_file_acl_high; 359 __le16 l_i_file_acl_high;
307 __le16 l_i_uid_high; /* these 2 fields */ 360 __le16 l_i_uid_high; /* these 2 fields */
308 __le16 l_i_gid_high; /* were reserved2[0] */ 361 __le16 l_i_gid_high; /* were reserved2[0] */
@@ -328,9 +381,9 @@ struct ext4_inode {
328 __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ 381 __le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
329 __le32 i_crtime; /* File Creation time */ 382 __le32 i_crtime; /* File Creation time */
330 __le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */ 383 __le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
384 __le32 i_version_hi; /* high 32 bits for 64-bit version */
331}; 385};
332 386
333#define i_size_high i_dir_acl
334 387
335#define EXT4_EPOCH_BITS 2 388#define EXT4_EPOCH_BITS 2
336#define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1) 389#define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
@@ -402,9 +455,12 @@ do { \
402 raw_inode->xtime ## _extra); \ 455 raw_inode->xtime ## _extra); \
403} while (0) 456} while (0)
404 457
458#define i_disk_version osd1.linux1.l_i_version
459
405#if defined(__KERNEL__) || defined(__linux__) 460#if defined(__KERNEL__) || defined(__linux__)
406#define i_reserved1 osd1.linux1.l_i_reserved1 461#define i_reserved1 osd1.linux1.l_i_reserved1
407#define i_file_acl_high osd2.linux2.l_i_file_acl_high 462#define i_file_acl_high osd2.linux2.l_i_file_acl_high
463#define i_blocks_high osd2.linux2.l_i_blocks_high
408#define i_uid_low i_uid 464#define i_uid_low i_uid
409#define i_gid_low i_gid 465#define i_gid_low i_gid
410#define i_uid_high osd2.linux2.l_i_uid_high 466#define i_uid_high osd2.linux2.l_i_uid_high
@@ -461,7 +517,10 @@ do { \
461#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ 517#define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
462#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ 518#define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
463#define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */ 519#define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */
464 520#define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */
521#define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */
522#define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */
523#define EXT4_MOUNT_MBALLOC 0x4000000 /* Buddy allocation support */
465/* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ 524/* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
466#ifndef _LINUX_EXT2_FS_H 525#ifndef _LINUX_EXT2_FS_H
467#define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt 526#define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt
@@ -481,6 +540,7 @@ do { \
481#define ext4_test_bit ext2_test_bit 540#define ext4_test_bit ext2_test_bit
482#define ext4_find_first_zero_bit ext2_find_first_zero_bit 541#define ext4_find_first_zero_bit ext2_find_first_zero_bit
483#define ext4_find_next_zero_bit ext2_find_next_zero_bit 542#define ext4_find_next_zero_bit ext2_find_next_zero_bit
543#define ext4_find_next_bit ext2_find_next_bit
484 544
485/* 545/*
486 * Maximal mount counts between two filesystem checks 546 * Maximal mount counts between two filesystem checks
@@ -671,6 +731,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
671#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 731#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
672#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 732#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
673#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 733#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
734#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
674#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 735#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
675#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 736#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
676#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 737#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
@@ -682,6 +743,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
682#define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 743#define EXT4_FEATURE_INCOMPAT_META_BG 0x0010
683#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ 744#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
684#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 745#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
746#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
685#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 747#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
686 748
687#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR 749#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
@@ -696,7 +758,8 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
696 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ 758 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
697 EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ 759 EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
698 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ 760 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
699 EXT4_FEATURE_RO_COMPAT_BTREE_DIR) 761 EXT4_FEATURE_RO_COMPAT_BTREE_DIR |\
762 EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
700 763
701/* 764/*
702 * Default values for user and/or group using reserved blocks 765 * Default values for user and/or group using reserved blocks
@@ -767,6 +830,26 @@ struct ext4_dir_entry_2 {
767#define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1) 830#define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1)
768#define EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \ 831#define EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \
769 ~EXT4_DIR_ROUND) 832 ~EXT4_DIR_ROUND)
833#define EXT4_MAX_REC_LEN ((1<<16)-1)
834
835static inline unsigned ext4_rec_len_from_disk(__le16 dlen)
836{
837 unsigned len = le16_to_cpu(dlen);
838
839 if (len == EXT4_MAX_REC_LEN)
840 return 1 << 16;
841 return len;
842}
843
844static inline __le16 ext4_rec_len_to_disk(unsigned len)
845{
846 if (len == (1 << 16))
847 return cpu_to_le16(EXT4_MAX_REC_LEN);
848 else if (len > (1 << 16))
849 BUG();
850 return cpu_to_le16(len);
851}
852
770/* 853/*
771 * Hash Tree Directory indexing 854 * Hash Tree Directory indexing
772 * (c) Daniel Phillips, 2001 855 * (c) Daniel Phillips, 2001
@@ -810,7 +893,7 @@ struct ext4_iloc
810{ 893{
811 struct buffer_head *bh; 894 struct buffer_head *bh;
812 unsigned long offset; 895 unsigned long offset;
813 unsigned long block_group; 896 ext4_group_t block_group;
814}; 897};
815 898
816static inline struct ext4_inode *ext4_raw_inode(struct ext4_iloc *iloc) 899static inline struct ext4_inode *ext4_raw_inode(struct ext4_iloc *iloc)
@@ -835,7 +918,7 @@ struct dir_private_info {
835 918
836/* calculate the first block number of the group */ 919/* calculate the first block number of the group */
837static inline ext4_fsblk_t 920static inline ext4_fsblk_t
838ext4_group_first_block_no(struct super_block *sb, unsigned long group_no) 921ext4_group_first_block_no(struct super_block *sb, ext4_group_t group_no)
839{ 922{
840 return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) + 923 return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
841 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); 924 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
@@ -866,21 +949,24 @@ extern unsigned int ext4_block_group(struct super_block *sb,
866 ext4_fsblk_t blocknr); 949 ext4_fsblk_t blocknr);
867extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, 950extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb,
868 ext4_fsblk_t blocknr); 951 ext4_fsblk_t blocknr);
869extern int ext4_bg_has_super(struct super_block *sb, int group); 952extern int ext4_bg_has_super(struct super_block *sb, ext4_group_t group);
870extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group); 953extern unsigned long ext4_bg_num_gdb(struct super_block *sb,
954 ext4_group_t group);
871extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode, 955extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
872 ext4_fsblk_t goal, int *errp); 956 ext4_fsblk_t goal, int *errp);
873extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, 957extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode,
874 ext4_fsblk_t goal, unsigned long *count, int *errp); 958 ext4_fsblk_t goal, unsigned long *count, int *errp);
959extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode,
960 ext4_fsblk_t goal, unsigned long *count, int *errp);
875extern void ext4_free_blocks (handle_t *handle, struct inode *inode, 961extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
876 ext4_fsblk_t block, unsigned long count); 962 ext4_fsblk_t block, unsigned long count, int metadata);
877extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, 963extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb,
878 ext4_fsblk_t block, unsigned long count, 964 ext4_fsblk_t block, unsigned long count,
879 unsigned long *pdquot_freed_blocks); 965 unsigned long *pdquot_freed_blocks);
880extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *); 966extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *);
881extern void ext4_check_blocks_bitmap (struct super_block *); 967extern void ext4_check_blocks_bitmap (struct super_block *);
882extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, 968extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
883 unsigned int block_group, 969 ext4_group_t block_group,
884 struct buffer_head ** bh); 970 struct buffer_head ** bh);
885extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); 971extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
886extern void ext4_init_block_alloc_info(struct inode *); 972extern void ext4_init_block_alloc_info(struct inode *);
@@ -911,15 +997,32 @@ extern unsigned long ext4_count_dirs (struct super_block *);
911extern void ext4_check_inodes_bitmap (struct super_block *); 997extern void ext4_check_inodes_bitmap (struct super_block *);
912extern unsigned long ext4_count_free (struct buffer_head *, unsigned); 998extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
913 999
1000/* mballoc.c */
1001extern long ext4_mb_stats;
1002extern long ext4_mb_max_to_scan;
1003extern int ext4_mb_init(struct super_block *, int);
1004extern int ext4_mb_release(struct super_block *);
1005extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
1006 struct ext4_allocation_request *, int *);
1007extern int ext4_mb_reserve_blocks(struct super_block *, int);
1008extern void ext4_mb_discard_inode_preallocations(struct inode *);
1009extern int __init init_ext4_mballoc(void);
1010extern void exit_ext4_mballoc(void);
1011extern void ext4_mb_free_blocks(handle_t *, struct inode *,
1012 unsigned long, unsigned long, int, unsigned long *);
1013
914 1014
915/* inode.c */ 1015/* inode.c */
916int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, 1016int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
917 struct buffer_head *bh, ext4_fsblk_t blocknr); 1017 struct buffer_head *bh, ext4_fsblk_t blocknr);
918struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *); 1018struct buffer_head *ext4_getblk(handle_t *, struct inode *,
919struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *); 1019 ext4_lblk_t, int, int *);
1020struct buffer_head *ext4_bread(handle_t *, struct inode *,
1021 ext4_lblk_t, int, int *);
920int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, 1022int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
921 sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, 1023 ext4_lblk_t iblock, unsigned long maxblocks,
922 int create, int extend_disksize); 1024 struct buffer_head *bh_result,
1025 int create, int extend_disksize);
923 1026
924extern void ext4_read_inode (struct inode *); 1027extern void ext4_read_inode (struct inode *);
925extern int ext4_write_inode (struct inode *, int); 1028extern int ext4_write_inode (struct inode *, int);
@@ -943,6 +1046,9 @@ extern int ext4_ioctl (struct inode *, struct file *, unsigned int,
943 unsigned long); 1046 unsigned long);
944extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long); 1047extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
945 1048
1049/* migrate.c */
1050extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int,
1051 unsigned long);
946/* namei.c */ 1052/* namei.c */
947extern int ext4_orphan_add(handle_t *, struct inode *); 1053extern int ext4_orphan_add(handle_t *, struct inode *);
948extern int ext4_orphan_del(handle_t *, struct inode *); 1054extern int ext4_orphan_del(handle_t *, struct inode *);
@@ -965,6 +1071,12 @@ extern void ext4_abort (struct super_block *, const char *, const char *, ...)
965extern void ext4_warning (struct super_block *, const char *, const char *, ...) 1071extern void ext4_warning (struct super_block *, const char *, const char *, ...)
966 __attribute__ ((format (printf, 3, 4))); 1072 __attribute__ ((format (printf, 3, 4)));
967extern void ext4_update_dynamic_rev (struct super_block *sb); 1073extern void ext4_update_dynamic_rev (struct super_block *sb);
1074extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb,
1075 __u32 compat);
1076extern int ext4_update_rocompat_feature(handle_t *handle,
1077 struct super_block *sb, __u32 rocompat);
1078extern int ext4_update_incompat_feature(handle_t *handle,
1079 struct super_block *sb, __u32 incompat);
968extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, 1080extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
969 struct ext4_group_desc *bg); 1081 struct ext4_group_desc *bg);
970extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, 1082extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
@@ -1017,6 +1129,29 @@ static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
1017 es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); 1129 es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
1018} 1130}
1019 1131
1132static inline loff_t ext4_isize(struct ext4_inode *raw_inode)
1133{
1134 return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) |
1135 le32_to_cpu(raw_inode->i_size_lo);
1136}
1137
1138static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size)
1139{
1140 raw_inode->i_size_lo = cpu_to_le32(i_size);
1141 raw_inode->i_size_high = cpu_to_le32(i_size >> 32);
1142}
1143
1144static inline
1145struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
1146 ext4_group_t group)
1147{
1148 struct ext4_group_info ***grp_info;
1149 long indexv, indexh;
1150 grp_info = EXT4_SB(sb)->s_group_info;
1151 indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
1152 indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
1153 return grp_info[indexv][indexh];
1154}
1020 1155
1021 1156
1022#define ext4_std_error(sb, errno) \ 1157#define ext4_std_error(sb, errno) \
@@ -1048,7 +1183,7 @@ extern const struct inode_operations ext4_fast_symlink_inode_operations;
1048extern int ext4_ext_tree_init(handle_t *handle, struct inode *); 1183extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
1049extern int ext4_ext_writepage_trans_blocks(struct inode *, int); 1184extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
1050extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 1185extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
1051 ext4_fsblk_t iblock, 1186 ext4_lblk_t iblock,
1052 unsigned long max_blocks, struct buffer_head *bh_result, 1187 unsigned long max_blocks, struct buffer_head *bh_result,
1053 int create, int extend_disksize); 1188 int create, int extend_disksize);
1054extern void ext4_ext_truncate(struct inode *, struct page *); 1189extern void ext4_ext_truncate(struct inode *, struct page *);
@@ -1056,19 +1191,10 @@ extern void ext4_ext_init(struct super_block *);
1056extern void ext4_ext_release(struct super_block *); 1191extern void ext4_ext_release(struct super_block *);
1057extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, 1192extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
1058 loff_t len); 1193 loff_t len);
1059static inline int 1194extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode,
1060ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, 1195 sector_t block, unsigned long max_blocks,
1061 unsigned long max_blocks, struct buffer_head *bh, 1196 struct buffer_head *bh, int create,
1062 int create, int extend_disksize) 1197 int extend_disksize);
1063{
1064 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
1065 return ext4_ext_get_blocks(handle, inode, block, max_blocks,
1066 bh, create, extend_disksize);
1067 return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh,
1068 create, extend_disksize);
1069}
1070
1071
1072#endif /* __KERNEL__ */ 1198#endif /* __KERNEL__ */
1073 1199
1074#endif /* _LINUX_EXT4_FS_H */ 1200#endif /* _LINUX_EXT4_FS_H */
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index d2045a26195d..697da4bce6c5 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -124,20 +124,6 @@ struct ext4_ext_path {
124#define EXT4_EXT_CACHE_GAP 1 124#define EXT4_EXT_CACHE_GAP 1
125#define EXT4_EXT_CACHE_EXTENT 2 125#define EXT4_EXT_CACHE_EXTENT 2
126 126
127/*
128 * to be called by ext4_ext_walk_space()
129 * negative retcode - error
130 * positive retcode - signal for ext4_ext_walk_space(), see below
131 * callback must return valid extent (passed or newly created)
132 */
133typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
134 struct ext4_ext_cache *,
135 void *);
136
137#define EXT_CONTINUE 0
138#define EXT_BREAK 1
139#define EXT_REPEAT 2
140
141 127
142#define EXT_MAX_BLOCK 0xffffffff 128#define EXT_MAX_BLOCK 0xffffffff
143 129
@@ -226,6 +212,8 @@ static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
226 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN)); 212 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
227} 213}
228 214
215extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
216extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t);
229extern int ext4_extent_tree_init(handle_t *, struct inode *); 217extern int ext4_extent_tree_init(handle_t *, struct inode *);
230extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *); 218extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *);
231extern int ext4_ext_try_to_merge(struct inode *inode, 219extern int ext4_ext_try_to_merge(struct inode *inode,
@@ -233,8 +221,11 @@ extern int ext4_ext_try_to_merge(struct inode *inode,
233 struct ext4_extent *); 221 struct ext4_extent *);
234extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *); 222extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
235extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *); 223extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
236extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *); 224extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
237extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *); 225 struct ext4_ext_path *);
238 226extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *,
227 ext4_lblk_t *, ext4_fsblk_t *);
228extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *,
229 ext4_lblk_t *, ext4_fsblk_t *);
239#endif /* _LINUX_EXT4_EXTENTS */ 230#endif /* _LINUX_EXT4_EXTENTS */
240 231
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h
index 86ddfe2089f3..d5508d3cf290 100644
--- a/include/linux/ext4_fs_i.h
+++ b/include/linux/ext4_fs_i.h
@@ -27,6 +27,12 @@ typedef int ext4_grpblk_t;
27/* data type for filesystem-wide blocks number */ 27/* data type for filesystem-wide blocks number */
28typedef unsigned long long ext4_fsblk_t; 28typedef unsigned long long ext4_fsblk_t;
29 29
30/* data type for file logical block number */
31typedef __u32 ext4_lblk_t;
32
33/* data type for block group number */
34typedef unsigned long ext4_group_t;
35
30struct ext4_reserve_window { 36struct ext4_reserve_window {
31 ext4_fsblk_t _rsv_start; /* First byte reserved */ 37 ext4_fsblk_t _rsv_start; /* First byte reserved */
32 ext4_fsblk_t _rsv_end; /* Last byte reserved or 0 */ 38 ext4_fsblk_t _rsv_end; /* Last byte reserved or 0 */
@@ -48,7 +54,7 @@ struct ext4_block_alloc_info {
48 * most-recently-allocated block in this file. 54 * most-recently-allocated block in this file.
49 * We use this for detecting linearly ascending allocation requests. 55 * We use this for detecting linearly ascending allocation requests.
50 */ 56 */
51 __u32 last_alloc_logical_block; 57 ext4_lblk_t last_alloc_logical_block;
52 /* 58 /*
53 * Was i_next_alloc_goal in ext4_inode_info 59 * Was i_next_alloc_goal in ext4_inode_info
54 * is the *physical* companion to i_next_alloc_block. 60 * is the *physical* companion to i_next_alloc_block.
@@ -67,7 +73,7 @@ struct ext4_block_alloc_info {
67 */ 73 */
68struct ext4_ext_cache { 74struct ext4_ext_cache {
69 ext4_fsblk_t ec_start; 75 ext4_fsblk_t ec_start;
70 __u32 ec_block; 76 ext4_lblk_t ec_block;
71 __u32 ec_len; /* must be 32bit to return holes */ 77 __u32 ec_len; /* must be 32bit to return holes */
72 __u32 ec_type; 78 __u32 ec_type;
73}; 79};
@@ -79,7 +85,6 @@ struct ext4_inode_info {
79 __le32 i_data[15]; /* unconverted */ 85 __le32 i_data[15]; /* unconverted */
80 __u32 i_flags; 86 __u32 i_flags;
81 ext4_fsblk_t i_file_acl; 87 ext4_fsblk_t i_file_acl;
82 __u32 i_dir_acl;
83 __u32 i_dtime; 88 __u32 i_dtime;
84 89
85 /* 90 /*
@@ -89,13 +94,13 @@ struct ext4_inode_info {
89 * place a file's data blocks near its inode block, and new inodes 94 * place a file's data blocks near its inode block, and new inodes
90 * near to their parent directory's inode. 95 * near to their parent directory's inode.
91 */ 96 */
92 __u32 i_block_group; 97 ext4_group_t i_block_group;
93 __u32 i_state; /* Dynamic state flags for ext4 */ 98 __u32 i_state; /* Dynamic state flags for ext4 */
94 99
95 /* block reservation info */ 100 /* block reservation info */
96 struct ext4_block_alloc_info *i_block_alloc_info; 101 struct ext4_block_alloc_info *i_block_alloc_info;
97 102
98 __u32 i_dir_start_lookup; 103 ext4_lblk_t i_dir_start_lookup;
99#ifdef CONFIG_EXT4DEV_FS_XATTR 104#ifdef CONFIG_EXT4DEV_FS_XATTR
100 /* 105 /*
101 * Extended attributes can be read independently of the main file 106 * Extended attributes can be read independently of the main file
@@ -134,16 +139,16 @@ struct ext4_inode_info {
134 __u16 i_extra_isize; 139 __u16 i_extra_isize;
135 140
136 /* 141 /*
137 * truncate_mutex is for serialising ext4_truncate() against 142 * i_data_sem is for serialising ext4_truncate() against
138 * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's 143 * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's
139 * data tree are chopped off during truncate. We can't do that in 144 * data tree are chopped off during truncate. We can't do that in
140 * ext4 because whenever we perform intermediate commits during 145 * ext4 because whenever we perform intermediate commits during
141 * truncate, the inode and all the metadata blocks *must* be in a 146 * truncate, the inode and all the metadata blocks *must* be in a
142 * consistent state which allows truncation of the orphans to restart 147 * consistent state which allows truncation of the orphans to restart
143 * during recovery. Hence we must fix the get_block-vs-truncate race 148 * during recovery. Hence we must fix the get_block-vs-truncate race
144 * by other means, so we have truncate_mutex. 149 * by other means, so we have i_data_sem.
145 */ 150 */
146 struct mutex truncate_mutex; 151 struct rw_semaphore i_data_sem;
147 struct inode vfs_inode; 152 struct inode vfs_inode;
148 153
149 unsigned long i_ext_generation; 154 unsigned long i_ext_generation;
@@ -153,6 +158,10 @@ struct ext4_inode_info {
153 * struct timespec i_{a,c,m}time in the generic inode. 158 * struct timespec i_{a,c,m}time in the generic inode.
154 */ 159 */
155 struct timespec i_crtime; 160 struct timespec i_crtime;
161
162 /* mballoc */
163 struct list_head i_prealloc_list;
164 spinlock_t i_prealloc_lock;
156}; 165};
157 166
158#endif /* _LINUX_EXT4_FS_I */ 167#endif /* _LINUX_EXT4_FS_I */
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h
index b40e827cd495..abaae2c8cccf 100644
--- a/include/linux/ext4_fs_sb.h
+++ b/include/linux/ext4_fs_sb.h
@@ -35,9 +35,10 @@ struct ext4_sb_info {
35 unsigned long s_itb_per_group; /* Number of inode table blocks per group */ 35 unsigned long s_itb_per_group; /* Number of inode table blocks per group */
36 unsigned long s_gdb_count; /* Number of group descriptor blocks */ 36 unsigned long s_gdb_count; /* Number of group descriptor blocks */
37 unsigned long s_desc_per_block; /* Number of group descriptors per block */ 37 unsigned long s_desc_per_block; /* Number of group descriptors per block */
38 unsigned long s_groups_count; /* Number of groups in the fs */ 38 ext4_group_t s_groups_count; /* Number of groups in the fs */
39 unsigned long s_overhead_last; /* Last calculated overhead */ 39 unsigned long s_overhead_last; /* Last calculated overhead */
40 unsigned long s_blocks_last; /* Last seen block count */ 40 unsigned long s_blocks_last; /* Last seen block count */
41 loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */
41 struct buffer_head * s_sbh; /* Buffer containing the super block */ 42 struct buffer_head * s_sbh; /* Buffer containing the super block */
42 struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */ 43 struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
43 struct buffer_head ** s_group_desc; 44 struct buffer_head ** s_group_desc;
@@ -90,6 +91,58 @@ struct ext4_sb_info {
90 unsigned long s_ext_blocks; 91 unsigned long s_ext_blocks;
91 unsigned long s_ext_extents; 92 unsigned long s_ext_extents;
92#endif 93#endif
94
95 /* for buddy allocator */
96 struct ext4_group_info ***s_group_info;
97 struct inode *s_buddy_cache;
98 long s_blocks_reserved;
99 spinlock_t s_reserve_lock;
100 struct list_head s_active_transaction;
101 struct list_head s_closed_transaction;
102 struct list_head s_committed_transaction;
103 spinlock_t s_md_lock;
104 tid_t s_last_transaction;
105 unsigned short *s_mb_offsets, *s_mb_maxs;
106
107 /* tunables */
108 unsigned long s_stripe;
109 unsigned long s_mb_stream_request;
110 unsigned long s_mb_max_to_scan;
111 unsigned long s_mb_min_to_scan;
112 unsigned long s_mb_stats;
113 unsigned long s_mb_order2_reqs;
114 unsigned long s_mb_group_prealloc;
115 /* where last allocation was done - for stream allocation */
116 unsigned long s_mb_last_group;
117 unsigned long s_mb_last_start;
118
119 /* history to debug policy */
120 struct ext4_mb_history *s_mb_history;
121 int s_mb_history_cur;
122 int s_mb_history_max;
123 int s_mb_history_num;
124 struct proc_dir_entry *s_mb_proc;
125 spinlock_t s_mb_history_lock;
126 int s_mb_history_filter;
127
128 /* stats for buddy allocator */
129 spinlock_t s_mb_pa_lock;
130 atomic_t s_bal_reqs; /* number of reqs with len > 1 */
131 atomic_t s_bal_success; /* we found long enough chunks */
132 atomic_t s_bal_allocated; /* in blocks */
133 atomic_t s_bal_ex_scanned; /* total extents scanned */
134 atomic_t s_bal_goals; /* goal hits */
135 atomic_t s_bal_breaks; /* too long searches */
136 atomic_t s_bal_2orders; /* 2^order hits */
137 spinlock_t s_bal_lock;
138 unsigned long s_mb_buddies_generated;
139 unsigned long long s_mb_generation_time;
140 atomic_t s_mb_lost_chunks;
141 atomic_t s_mb_preallocated;
142 atomic_t s_mb_discarded;
143
144 /* locality groups */
145 struct ext4_locality_group *s_locality_groups;
93}; 146};
94 147
95#endif /* _LINUX_EXT4_FS_SB */ 148#endif /* _LINUX_EXT4_FS_SB */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 21398a5d688d..a516b6716870 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -124,6 +124,7 @@ extern int dir_notify_enable;
124#define MS_SHARED (1<<20) /* change to shared */ 124#define MS_SHARED (1<<20) /* change to shared */
125#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ 125#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
126#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ 126#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
127#define MS_I_VERSION (1<<23) /* Update inode I_version field */
127#define MS_ACTIVE (1<<30) 128#define MS_ACTIVE (1<<30)
128#define MS_NOUSER (1<<31) 129#define MS_NOUSER (1<<31)
129 130
@@ -173,6 +174,7 @@ extern int dir_notify_enable;
173 ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) 174 ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
174#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) 175#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
175#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) 176#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME)
177#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION)
176 178
177#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) 179#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
178#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) 180#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
@@ -599,7 +601,7 @@ struct inode {
599 uid_t i_uid; 601 uid_t i_uid;
600 gid_t i_gid; 602 gid_t i_gid;
601 dev_t i_rdev; 603 dev_t i_rdev;
602 unsigned long i_version; 604 u64 i_version;
603 loff_t i_size; 605 loff_t i_size;
604#ifdef __NEED_I_SIZE_ORDERED 606#ifdef __NEED_I_SIZE_ORDERED
605 seqcount_t i_size_seqcount; 607 seqcount_t i_size_seqcount;
@@ -1394,6 +1396,21 @@ static inline void inode_dec_link_count(struct inode *inode)
1394 mark_inode_dirty(inode); 1396 mark_inode_dirty(inode);
1395} 1397}
1396 1398
1399/**
1400 * inode_inc_iversion - increments i_version
1401 * @inode: inode that need to be updated
1402 *
1403 * Every time the inode is modified, the i_version field will be incremented.
1404 * The filesystem has to be mounted with i_version flag
1405 */
1406
1407static inline void inode_inc_iversion(struct inode *inode)
1408{
1409 spin_lock(&inode->i_lock);
1410 inode->i_version++;
1411 spin_unlock(&inode->i_lock);
1412}
1413
1397extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry); 1414extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry);
1398static inline void file_accessed(struct file *file) 1415static inline void file_accessed(struct file *file)
1399{ 1416{
diff --git a/include/linux/init.h b/include/linux/init.h
index 5141381a7527..2efbda016741 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -40,10 +40,10 @@
40 40
41/* These are for everybody (although not all archs will actually 41/* These are for everybody (although not all archs will actually
42 discard it in modules) */ 42 discard it in modules) */
43#define __init __attribute__ ((__section__ (".init.text"))) __cold 43#define __init __section(.init.text) __cold
44#define __initdata __attribute__ ((__section__ (".init.data"))) 44#define __initdata __section(.init.data)
45#define __exitdata __attribute__ ((__section__(".exit.data"))) 45#define __exitdata __section(.exit.data)
46#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) 46#define __exit_call __used __section(.exitcall.exit)
47 47
48/* modpost check for section mismatches during the kernel build. 48/* modpost check for section mismatches during the kernel build.
49 * A section mismatch happens when there are references from a 49 * A section mismatch happens when there are references from a
@@ -52,25 +52,81 @@
52 * when early init has completed so all such references are potential bugs. 52 * when early init has completed so all such references are potential bugs.
53 * For exit sections the same issue exists. 53 * For exit sections the same issue exists.
54 * The following markers are used for the cases where the reference to 54 * The following markers are used for the cases where the reference to
55 * the init/exit section (code or data) is valid and will teach modpost 55 * the *init / *exit section (code or data) is valid and will teach
56 * not to issue a warning. 56 * modpost not to issue a warning.
57 * The markers follow same syntax rules as __init / __initdata. */ 57 * The markers follow same syntax rules as __init / __initdata. */
58#define __init_refok noinline __attribute__ ((__section__ (".text.init.refok"))) 58#define __ref __section(.ref.text) noinline
59#define __initdata_refok __attribute__ ((__section__ (".data.init.refok"))) 59#define __refdata __section(.ref.data)
60#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok"))) 60#define __refconst __section(.ref.rodata)
61
62/* backward compatibility note
63 * A few places hardcode the old section names:
64 * .text.init.refok
65 * .data.init.refok
66 * .exit.text.refok
67 * They should be converted to use the defines from this file
68 */
69
70/* compatibility defines */
71#define __init_refok __ref
72#define __initdata_refok __refdata
73#define __exit_refok __ref
74
61 75
62#ifdef MODULE 76#ifdef MODULE
63#define __exit __attribute__ ((__section__(".exit.text"))) __cold 77#define __exitused
64#else 78#else
65#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text"))) __cold 79#define __exitused __used
66#endif 80#endif
67 81
82#define __exit __section(.exit.text) __exitused __cold
83
84/* Used for HOTPLUG */
85#define __devinit __section(.devinit.text) __cold
86#define __devinitdata __section(.devinit.data)
87#define __devinitconst __section(.devinit.rodata)
88#define __devexit __section(.devexit.text) __exitused __cold
89#define __devexitdata __section(.devexit.data)
90#define __devexitconst __section(.devexit.rodata)
91
92/* Used for HOTPLUG_CPU */
93#define __cpuinit __section(.cpuinit.text) __cold
94#define __cpuinitdata __section(.cpuinit.data)
95#define __cpuinitconst __section(.cpuinit.rodata)
96#define __cpuexit __section(.cpuexit.text) __exitused __cold
97#define __cpuexitdata __section(.cpuexit.data)
98#define __cpuexitconst __section(.cpuexit.rodata)
99
100/* Used for MEMORY_HOTPLUG */
101#define __meminit __section(.meminit.text) __cold
102#define __meminitdata __section(.meminit.data)
103#define __meminitconst __section(.meminit.rodata)
104#define __memexit __section(.memexit.text) __exitused __cold
105#define __memexitdata __section(.memexit.data)
106#define __memexitconst __section(.memexit.rodata)
107
68/* For assembly routines */ 108/* For assembly routines */
69#define __INIT .section ".init.text","ax" 109#define __INIT .section ".init.text","ax"
70#define __INIT_REFOK .section ".text.init.refok","ax"
71#define __FINIT .previous 110#define __FINIT .previous
111
72#define __INITDATA .section ".init.data","aw" 112#define __INITDATA .section ".init.data","aw"
73#define __INITDATA_REFOK .section ".data.init.refok","aw" 113
114#define __DEVINIT .section ".devinit.text", "ax"
115#define __DEVINITDATA .section ".devinit.data", "aw"
116
117#define __CPUINIT .section ".cpuinit.text", "ax"
118#define __CPUINITDATA .section ".cpuinit.data", "aw"
119
120#define __MEMINIT .section ".meminit.text", "ax"
121#define __MEMINITDATA .section ".meminit.data", "aw"
122
123/* silence warnings when references are OK */
124#define __REF .section ".ref.text", "ax"
125#define __REFDATA .section ".ref.data", "aw"
126#define __REFCONST .section ".ref.rodata", "aw"
127/* backward compatibility */
128#define __INIT_REFOK .section __REF
129#define __INITDATA_REFOK .section __REFDATA
74 130
75#ifndef __ASSEMBLY__ 131#ifndef __ASSEMBLY__
76/* 132/*
@@ -108,7 +164,7 @@ void prepare_namespace(void);
108 */ 164 */
109 165
110#define __define_initcall(level,fn,id) \ 166#define __define_initcall(level,fn,id) \
111 static initcall_t __initcall_##fn##id __attribute_used__ \ 167 static initcall_t __initcall_##fn##id __used \
112 __attribute__((__section__(".initcall" level ".init"))) = fn 168 __attribute__((__section__(".initcall" level ".init"))) = fn
113 169
114/* 170/*
@@ -142,11 +198,11 @@ void prepare_namespace(void);
142 198
143#define console_initcall(fn) \ 199#define console_initcall(fn) \
144 static initcall_t __initcall_##fn \ 200 static initcall_t __initcall_##fn \
145 __attribute_used__ __attribute__((__section__(".con_initcall.init")))=fn 201 __used __section(.con_initcall.init) = fn
146 202
147#define security_initcall(fn) \ 203#define security_initcall(fn) \
148 static initcall_t __initcall_##fn \ 204 static initcall_t __initcall_##fn \
149 __attribute_used__ __attribute__((__section__(".security_initcall.init"))) = fn 205 __used __section(.security_initcall.init) = fn
150 206
151struct obs_kernel_param { 207struct obs_kernel_param {
152 const char *str; 208 const char *str;
@@ -163,8 +219,7 @@ struct obs_kernel_param {
163#define __setup_param(str, unique_id, fn, early) \ 219#define __setup_param(str, unique_id, fn, early) \
164 static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \ 220 static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
165 static struct obs_kernel_param __setup_##unique_id \ 221 static struct obs_kernel_param __setup_##unique_id \
166 __attribute_used__ \ 222 __used __section(.init.setup) \
167 __attribute__((__section__(".init.setup"))) \
168 __attribute__((aligned((sizeof(long))))) \ 223 __attribute__((aligned((sizeof(long))))) \
169 = { __setup_str_##unique_id, fn, early } 224 = { __setup_str_##unique_id, fn, early }
170 225
@@ -242,7 +297,7 @@ void __init parse_early_param(void);
242#endif 297#endif
243 298
244/* Data marked not to be saved by software suspend */ 299/* Data marked not to be saved by software suspend */
245#define __nosavedata __attribute__ ((__section__ (".data.nosave"))) 300#define __nosavedata __section(.data.nosave)
246 301
247/* This means "can be init if no module support, otherwise module load 302/* This means "can be init if no module support, otherwise module load
248 may call it." */ 303 may call it." */
@@ -254,43 +309,6 @@ void __init parse_early_param(void);
254#define __initdata_or_module __initdata 309#define __initdata_or_module __initdata
255#endif /*CONFIG_MODULES*/ 310#endif /*CONFIG_MODULES*/
256 311
257#ifdef CONFIG_HOTPLUG
258#define __devinit
259#define __devinitdata
260#define __devexit
261#define __devexitdata
262#else
263#define __devinit __init
264#define __devinitdata __initdata
265#define __devexit __exit
266#define __devexitdata __exitdata
267#endif
268
269#ifdef CONFIG_HOTPLUG_CPU
270#define __cpuinit
271#define __cpuinitdata
272#define __cpuexit
273#define __cpuexitdata
274#else
275#define __cpuinit __init
276#define __cpuinitdata __initdata
277#define __cpuexit __exit
278#define __cpuexitdata __exitdata
279#endif
280
281#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
282 || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
283#define __meminit
284#define __meminitdata
285#define __memexit
286#define __memexitdata
287#else
288#define __meminit __init
289#define __meminitdata __initdata
290#define __memexit __exit
291#define __memexitdata __exitdata
292#endif
293
294/* Functions marked as __devexit may be discarded at kernel link time, depending 312/* Functions marked as __devexit may be discarded at kernel link time, depending
295 on config options. Newer versions of binutils detect references from 313 on config options. Newer versions of binutils detect references from
296 retained sections to discarded sections and flag an error. Pointers to 314 retained sections to discarded sections and flag an error. Pointers to
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 06ef11457051..2cbf6fdb1799 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -149,6 +149,28 @@ typedef struct journal_header_s
149 __be32 h_sequence; 149 __be32 h_sequence;
150} journal_header_t; 150} journal_header_t;
151 151
152/*
153 * Checksum types.
154 */
155#define JBD2_CRC32_CHKSUM 1
156#define JBD2_MD5_CHKSUM 2
157#define JBD2_SHA1_CHKSUM 3
158
159#define JBD2_CRC32_CHKSUM_SIZE 4
160
161#define JBD2_CHECKSUM_BYTES (32 / sizeof(u32))
162/*
163 * Commit block header for storing transactional checksums:
164 */
165struct commit_header {
166 __be32 h_magic;
167 __be32 h_blocktype;
168 __be32 h_sequence;
169 unsigned char h_chksum_type;
170 unsigned char h_chksum_size;
171 unsigned char h_padding[2];
172 __be32 h_chksum[JBD2_CHECKSUM_BYTES];
173};
152 174
153/* 175/*
154 * The block tag: used to describe a single buffer in the journal. 176 * The block tag: used to describe a single buffer in the journal.
@@ -242,31 +264,25 @@ typedef struct journal_superblock_s
242 ((j)->j_format_version >= 2 && \ 264 ((j)->j_format_version >= 2 && \
243 ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) 265 ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
244 266
245#define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 267#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001
246#define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 268
269#define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001
270#define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002
271#define JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004
247 272
248/* Features known to this kernel version: */ 273/* Features known to this kernel version: */
249#define JBD2_KNOWN_COMPAT_FEATURES 0 274#define JBD2_KNOWN_COMPAT_FEATURES JBD2_FEATURE_COMPAT_CHECKSUM
250#define JBD2_KNOWN_ROCOMPAT_FEATURES 0 275#define JBD2_KNOWN_ROCOMPAT_FEATURES 0
251#define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | \ 276#define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | \
252 JBD2_FEATURE_INCOMPAT_64BIT) 277 JBD2_FEATURE_INCOMPAT_64BIT | \
278 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)
253 279
254#ifdef __KERNEL__ 280#ifdef __KERNEL__
255 281
256#include <linux/fs.h> 282#include <linux/fs.h>
257#include <linux/sched.h> 283#include <linux/sched.h>
258 284
259#define JBD2_ASSERTIONS 285#define J_ASSERT(assert) BUG_ON(!(assert))
260#ifdef JBD2_ASSERTIONS
261#define J_ASSERT(assert) \
262do { \
263 if (!(assert)) { \
264 printk (KERN_EMERG \
265 "Assertion failure in %s() at %s:%d: \"%s\"\n", \
266 __FUNCTION__, __FILE__, __LINE__, # assert); \
267 BUG(); \
268 } \
269} while (0)
270 286
271#if defined(CONFIG_BUFFER_DEBUG) 287#if defined(CONFIG_BUFFER_DEBUG)
272void buffer_assertion_failure(struct buffer_head *bh); 288void buffer_assertion_failure(struct buffer_head *bh);
@@ -282,10 +298,6 @@ void buffer_assertion_failure(struct buffer_head *bh);
282#define J_ASSERT_JH(jh, expr) J_ASSERT(expr) 298#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
283#endif 299#endif
284 300
285#else
286#define J_ASSERT(assert) do { } while (0)
287#endif /* JBD2_ASSERTIONS */
288
289#if defined(JBD2_PARANOID_IOFAIL) 301#if defined(JBD2_PARANOID_IOFAIL)
290#define J_EXPECT(expr, why...) J_ASSERT(expr) 302#define J_EXPECT(expr, why...) J_ASSERT(expr)
291#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) 303#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr)
@@ -406,9 +418,23 @@ struct handle_s
406 unsigned int h_sync: 1; /* sync-on-close */ 418 unsigned int h_sync: 1; /* sync-on-close */
407 unsigned int h_jdata: 1; /* force data journaling */ 419 unsigned int h_jdata: 1; /* force data journaling */
408 unsigned int h_aborted: 1; /* fatal error on handle */ 420 unsigned int h_aborted: 1; /* fatal error on handle */
421
422#ifdef CONFIG_DEBUG_LOCK_ALLOC
423 struct lockdep_map h_lockdep_map;
424#endif
409}; 425};
410 426
411 427
428/*
429 * Some stats for checkpoint phase
430 */
431struct transaction_chp_stats_s {
432 unsigned long cs_chp_time;
433 unsigned long cs_forced_to_close;
434 unsigned long cs_written;
435 unsigned long cs_dropped;
436};
437
412/* The transaction_t type is the guts of the journaling mechanism. It 438/* The transaction_t type is the guts of the journaling mechanism. It
413 * tracks a compound transaction through its various states: 439 * tracks a compound transaction through its various states:
414 * 440 *
@@ -456,6 +482,8 @@ struct transaction_s
456 /* 482 /*
457 * Transaction's current state 483 * Transaction's current state
458 * [no locking - only kjournald2 alters this] 484 * [no locking - only kjournald2 alters this]
485 * [j_list_lock] guards transition of a transaction into T_FINISHED
486 * state and subsequent call of __jbd2_journal_drop_transaction()
459 * FIXME: needs barriers 487 * FIXME: needs barriers
460 * KLUDGE: [use j_state_lock] 488 * KLUDGE: [use j_state_lock]
461 */ 489 */
@@ -544,6 +572,21 @@ struct transaction_s
544 spinlock_t t_handle_lock; 572 spinlock_t t_handle_lock;
545 573
546 /* 574 /*
575 * Longest time some handle had to wait for running transaction
576 */
577 unsigned long t_max_wait;
578
579 /*
580 * When transaction started
581 */
582 unsigned long t_start;
583
584 /*
585 * Checkpointing stats [j_checkpoint_sem]
586 */
587 struct transaction_chp_stats_s t_chp_stats;
588
589 /*
547 * Number of outstanding updates running on this transaction 590 * Number of outstanding updates running on this transaction
548 * [t_handle_lock] 591 * [t_handle_lock]
549 */ 592 */
@@ -574,6 +617,39 @@ struct transaction_s
574 617
575}; 618};
576 619
620struct transaction_run_stats_s {
621 unsigned long rs_wait;
622 unsigned long rs_running;
623 unsigned long rs_locked;
624 unsigned long rs_flushing;
625 unsigned long rs_logging;
626
627 unsigned long rs_handle_count;
628 unsigned long rs_blocks;
629 unsigned long rs_blocks_logged;
630};
631
632struct transaction_stats_s {
633 int ts_type;
634 unsigned long ts_tid;
635 union {
636 struct transaction_run_stats_s run;
637 struct transaction_chp_stats_s chp;
638 } u;
639};
640
641#define JBD2_STATS_RUN 1
642#define JBD2_STATS_CHECKPOINT 2
643
644static inline unsigned long
645jbd2_time_diff(unsigned long start, unsigned long end)
646{
647 if (end >= start)
648 return end - start;
649
650 return end + (MAX_JIFFY_OFFSET - start);
651}
652
577/** 653/**
578 * struct journal_s - The journal_s type is the concrete type associated with 654 * struct journal_s - The journal_s type is the concrete type associated with
579 * journal_t. 655 * journal_t.
@@ -635,6 +711,12 @@ struct transaction_s
635 * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the 711 * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
636 * number that will fit in j_blocksize 712 * number that will fit in j_blocksize
637 * @j_last_sync_writer: most recent pid which did a synchronous write 713 * @j_last_sync_writer: most recent pid which did a synchronous write
714 * @j_history: Buffer storing the transactions statistics history
715 * @j_history_max: Maximum number of transactions in the statistics history
716 * @j_history_cur: Current number of transactions in the statistics history
717 * @j_history_lock: Protect the transactions statistics history
718 * @j_proc_entry: procfs entry for the jbd statistics directory
719 * @j_stats: Overall statistics
638 * @j_private: An opaque pointer to fs-private information. 720 * @j_private: An opaque pointer to fs-private information.
639 */ 721 */
640 722
@@ -827,6 +909,19 @@ struct journal_s
827 pid_t j_last_sync_writer; 909 pid_t j_last_sync_writer;
828 910
829 /* 911 /*
912 * Journal statistics
913 */
914 struct transaction_stats_s *j_history;
915 int j_history_max;
916 int j_history_cur;
917 /*
918 * Protect the transactions statistics history
919 */
920 spinlock_t j_history_lock;
921 struct proc_dir_entry *j_proc_entry;
922 struct transaction_stats_s j_stats;
923
924 /*
830 * An opaque pointer to fs-private information. ext3 puts its 925 * An opaque pointer to fs-private information. ext3 puts its
831 * superblock pointer here 926 * superblock pointer here
832 */ 927 */
@@ -932,6 +1027,8 @@ extern int jbd2_journal_check_available_features
932 (journal_t *, unsigned long, unsigned long, unsigned long); 1027 (journal_t *, unsigned long, unsigned long, unsigned long);
933extern int jbd2_journal_set_features 1028extern int jbd2_journal_set_features
934 (journal_t *, unsigned long, unsigned long, unsigned long); 1029 (journal_t *, unsigned long, unsigned long, unsigned long);
1030extern void jbd2_journal_clear_features
1031 (journal_t *, unsigned long, unsigned long, unsigned long);
935extern int jbd2_journal_create (journal_t *); 1032extern int jbd2_journal_create (journal_t *);
936extern int jbd2_journal_load (journal_t *journal); 1033extern int jbd2_journal_load (journal_t *journal);
937extern void jbd2_journal_destroy (journal_t *); 1034extern void jbd2_journal_destroy (journal_t *);
diff --git a/include/linux/module.h b/include/linux/module.h
index c97bdb7eb957..ac481e2094fd 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -178,7 +178,7 @@ void *__symbol_get_gpl(const char *symbol);
178#define __CRC_SYMBOL(sym, sec) \ 178#define __CRC_SYMBOL(sym, sec) \
179 extern void *__crc_##sym __attribute__((weak)); \ 179 extern void *__crc_##sym __attribute__((weak)); \
180 static const unsigned long __kcrctab_##sym \ 180 static const unsigned long __kcrctab_##sym \
181 __attribute_used__ \ 181 __used \
182 __attribute__((section("__kcrctab" sec), unused)) \ 182 __attribute__((section("__kcrctab" sec), unused)) \
183 = (unsigned long) &__crc_##sym; 183 = (unsigned long) &__crc_##sym;
184#else 184#else
@@ -193,7 +193,7 @@ void *__symbol_get_gpl(const char *symbol);
193 __attribute__((section("__ksymtab_strings"))) \ 193 __attribute__((section("__ksymtab_strings"))) \
194 = MODULE_SYMBOL_PREFIX #sym; \ 194 = MODULE_SYMBOL_PREFIX #sym; \
195 static const struct kernel_symbol __ksymtab_##sym \ 195 static const struct kernel_symbol __ksymtab_##sym \
196 __attribute_used__ \ 196 __used \
197 __attribute__((section("__ksymtab" sec), unused)) \ 197 __attribute__((section("__ksymtab" sec), unused)) \
198 = { (unsigned long)&sym, __kstrtab_##sym } 198 = { (unsigned long)&sym, __kstrtab_##sym }
199 199
@@ -446,11 +446,14 @@ static inline void __module_get(struct module *module)
446 __mod ? __mod->name : "kernel"; \ 446 __mod ? __mod->name : "kernel"; \
447}) 447})
448 448
449/* For kallsyms to ask for address resolution. NULL means not found. */ 449/* For kallsyms to ask for address resolution. namebuf should be at
450const char *module_address_lookup(unsigned long addr, 450 * least KSYM_NAME_LEN long: a pointer to namebuf is returned if
451 unsigned long *symbolsize, 451 * found, otherwise NULL. */
452 unsigned long *offset, 452char *module_address_lookup(unsigned long addr,
453 char **modname); 453 unsigned long *symbolsize,
454 unsigned long *offset,
455 char **modname,
456 char *namebuf);
454int lookup_module_symbol_name(unsigned long addr, char *symname); 457int lookup_module_symbol_name(unsigned long addr, char *symname);
455int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); 458int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
456 459
@@ -516,10 +519,11 @@ static inline void module_put(struct module *module)
516#define module_name(mod) "kernel" 519#define module_name(mod) "kernel"
517 520
518/* For kallsyms to ask for address resolution. NULL means not found. */ 521/* For kallsyms to ask for address resolution. NULL means not found. */
519static inline const char *module_address_lookup(unsigned long addr, 522static inline char *module_address_lookup(unsigned long addr,
520 unsigned long *symbolsize, 523 unsigned long *symbolsize,
521 unsigned long *offset, 524 unsigned long *offset,
522 char **modname) 525 char **modname,
526 char *namebuf)
523{ 527{
524 return NULL; 528 return NULL;
525} 529}
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 13410b20600f..8126e55c5bdc 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -18,7 +18,7 @@
18#define __module_cat(a,b) ___module_cat(a,b) 18#define __module_cat(a,b) ___module_cat(a,b)
19#define __MODULE_INFO(tag, name, info) \ 19#define __MODULE_INFO(tag, name, info) \
20static const char __module_cat(name,__LINE__)[] \ 20static const char __module_cat(name,__LINE__)[] \
21 __attribute_used__ \ 21 __used \
22 __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info 22 __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
23#else /* !MODULE */ 23#else /* !MODULE */
24#define __MODULE_INFO(tag, name, info) 24#define __MODULE_INFO(tag, name, info)
@@ -72,7 +72,7 @@ struct kparam_array
72 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ 72 BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
73 static const char __param_str_##name[] = prefix #name; \ 73 static const char __param_str_##name[] = prefix #name; \
74 static struct kernel_param const __param_##name \ 74 static struct kernel_param const __param_##name \
75 __attribute_used__ \ 75 __used \
76 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ 76 __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
77 = { __param_str_##name, perm, set, get, { arg } } 77 = { __param_str_##name, perm, set, get, { arg } }
78 78
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0dd93bb62fbe..ae1006322f80 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -867,7 +867,7 @@ enum pci_fixup_pass {
867 867
868/* Anonymous variables would be nice... */ 868/* Anonymous variables would be nice... */
869#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \ 869#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \
870 static const struct pci_fixup __pci_fixup_##name __attribute_used__ \ 870 static const struct pci_fixup __pci_fixup_##name __used \
871 __attribute__((__section__(#section))) = { vendor, device, hook }; 871 __attribute__((__section__(#section))) = { vendor, device, hook };
872#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ 872#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
873 DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ 873 DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
diff --git a/init/Kconfig b/init/Kconfig
index 288444b4cd8a..0d0bbf218f1f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1,3 +1,11 @@
1config ARCH
2 string
3 option env="ARCH"
4
5config KERNELVERSION
6 string
7 option env="KERNELVERSION"
8
1config DEFCONFIG_LIST 9config DEFCONFIG_LIST
2 string 10 string
3 depends on !UML 11 depends on !UML
diff --git a/kernel/extable.c b/kernel/extable.c
index 7fe262855317..a26cb2e17023 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -46,7 +46,8 @@ int core_kernel_text(unsigned long addr)
46 addr <= (unsigned long)_etext) 46 addr <= (unsigned long)_etext)
47 return 1; 47 return 1;
48 48
49 if (addr >= (unsigned long)_sinittext && 49 if (system_state == SYSTEM_BOOTING &&
50 addr >= (unsigned long)_sinittext &&
50 addr <= (unsigned long)_einittext) 51 addr <= (unsigned long)_einittext)
51 return 1; 52 return 1;
52 return 0; 53 return 0;
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 2fc25810509e..7dadc71ce516 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -233,10 +233,11 @@ static unsigned long get_symbol_pos(unsigned long addr,
233int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize, 233int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
234 unsigned long *offset) 234 unsigned long *offset)
235{ 235{
236 char namebuf[KSYM_NAME_LEN];
236 if (is_ksym_addr(addr)) 237 if (is_ksym_addr(addr))
237 return !!get_symbol_pos(addr, symbolsize, offset); 238 return !!get_symbol_pos(addr, symbolsize, offset);
238 239
239 return !!module_address_lookup(addr, symbolsize, offset, NULL); 240 return !!module_address_lookup(addr, symbolsize, offset, NULL, namebuf);
240} 241}
241 242
242/* 243/*
@@ -251,8 +252,6 @@ const char *kallsyms_lookup(unsigned long addr,
251 unsigned long *offset, 252 unsigned long *offset,
252 char **modname, char *namebuf) 253 char **modname, char *namebuf)
253{ 254{
254 const char *msym;
255
256 namebuf[KSYM_NAME_LEN - 1] = 0; 255 namebuf[KSYM_NAME_LEN - 1] = 0;
257 namebuf[0] = 0; 256 namebuf[0] = 0;
258 257
@@ -268,10 +267,8 @@ const char *kallsyms_lookup(unsigned long addr,
268 } 267 }
269 268
270 /* see if it's in a module */ 269 /* see if it's in a module */
271 msym = module_address_lookup(addr, symbolsize, offset, modname); 270 return module_address_lookup(addr, symbolsize, offset, modname,
272 if (msym) 271 namebuf);
273 return strncpy(namebuf, msym, KSYM_NAME_LEN - 1);
274
275 return NULL; 272 return NULL;
276} 273}
277 274
diff --git a/kernel/module.c b/kernel/module.c
index 1bb4c5e0d56e..f6a4e721fd49 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -65,6 +65,9 @@
65static DEFINE_MUTEX(module_mutex); 65static DEFINE_MUTEX(module_mutex);
66static LIST_HEAD(modules); 66static LIST_HEAD(modules);
67 67
68/* Waiting for a module to finish initializing? */
69static DECLARE_WAIT_QUEUE_HEAD(module_wq);
70
68static BLOCKING_NOTIFIER_HEAD(module_notify_list); 71static BLOCKING_NOTIFIER_HEAD(module_notify_list);
69 72
70int register_module_notifier(struct notifier_block * nb) 73int register_module_notifier(struct notifier_block * nb)
@@ -84,8 +87,11 @@ EXPORT_SYMBOL(unregister_module_notifier);
84static inline int strong_try_module_get(struct module *mod) 87static inline int strong_try_module_get(struct module *mod)
85{ 88{
86 if (mod && mod->state == MODULE_STATE_COMING) 89 if (mod && mod->state == MODULE_STATE_COMING)
90 return -EBUSY;
91 if (try_module_get(mod))
87 return 0; 92 return 0;
88 return try_module_get(mod); 93 else
94 return -ENOENT;
89} 95}
90 96
91static inline void add_taint_module(struct module *mod, unsigned flag) 97static inline void add_taint_module(struct module *mod, unsigned flag)
@@ -539,11 +545,21 @@ static int already_uses(struct module *a, struct module *b)
539static int use_module(struct module *a, struct module *b) 545static int use_module(struct module *a, struct module *b)
540{ 546{
541 struct module_use *use; 547 struct module_use *use;
542 int no_warn; 548 int no_warn, err;
543 549
544 if (b == NULL || already_uses(a, b)) return 1; 550 if (b == NULL || already_uses(a, b)) return 1;
545 551
546 if (!strong_try_module_get(b)) 552 /* If we're interrupted or time out, we fail. */
553 if (wait_event_interruptible_timeout(
554 module_wq, (err = strong_try_module_get(b)) != -EBUSY,
555 30 * HZ) <= 0) {
556 printk("%s: gave up waiting for init of module %s.\n",
557 a->name, b->name);
558 return 0;
559 }
560
561 /* If strong_try_module_get() returned a different error, we fail. */
562 if (err)
547 return 0; 563 return 0;
548 564
549 DEBUGP("Allocating new usage for %s.\n", a->name); 565 DEBUGP("Allocating new usage for %s.\n", a->name);
@@ -722,7 +738,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
722 mutex_lock(&module_mutex); 738 mutex_lock(&module_mutex);
723 } 739 }
724 /* Store the name of the last unloaded module for diagnostic purposes */ 740 /* Store the name of the last unloaded module for diagnostic purposes */
725 sprintf(last_unloaded_module, mod->name); 741 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
726 free_module(mod); 742 free_module(mod);
727 743
728 out: 744 out:
@@ -816,7 +832,7 @@ static inline void module_unload_free(struct module *mod)
816 832
817static inline int use_module(struct module *a, struct module *b) 833static inline int use_module(struct module *a, struct module *b)
818{ 834{
819 return strong_try_module_get(b); 835 return strong_try_module_get(b) == 0;
820} 836}
821 837
822static inline void module_unload_init(struct module *mod) 838static inline void module_unload_init(struct module *mod)
@@ -1214,6 +1230,7 @@ void module_remove_modinfo_attrs(struct module *mod)
1214int mod_sysfs_init(struct module *mod) 1230int mod_sysfs_init(struct module *mod)
1215{ 1231{
1216 int err; 1232 int err;
1233 struct kobject *kobj;
1217 1234
1218 if (!module_sysfs_initialized) { 1235 if (!module_sysfs_initialized) {
1219 printk(KERN_ERR "%s: module sysfs not initialized\n", 1236 printk(KERN_ERR "%s: module sysfs not initialized\n",
@@ -1221,6 +1238,15 @@ int mod_sysfs_init(struct module *mod)
1221 err = -EINVAL; 1238 err = -EINVAL;
1222 goto out; 1239 goto out;
1223 } 1240 }
1241
1242 kobj = kset_find_obj(module_kset, mod->name);
1243 if (kobj) {
1244 printk(KERN_ERR "%s: module is already loaded\n", mod->name);
1245 kobject_put(kobj);
1246 err = -EINVAL;
1247 goto out;
1248 }
1249
1224 mod->mkobj.mod = mod; 1250 mod->mkobj.mod = mod;
1225 1251
1226 memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); 1252 memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
@@ -1278,6 +1304,17 @@ static void mod_kobject_remove(struct module *mod)
1278} 1304}
1279 1305
1280/* 1306/*
1307 * link the module with the whole machine is stopped with interrupts off
1308 * - this defends against kallsyms not taking locks
1309 */
1310static int __link_module(void *_mod)
1311{
1312 struct module *mod = _mod;
1313 list_add(&mod->list, &modules);
1314 return 0;
1315}
1316
1317/*
1281 * unlink the module with the whole machine is stopped with interrupts off 1318 * unlink the module with the whole machine is stopped with interrupts off
1282 * - this defends against kallsyms not taking locks 1319 * - this defends against kallsyms not taking locks
1283 */ 1320 */
@@ -1326,7 +1363,7 @@ void *__symbol_get(const char *symbol)
1326 1363
1327 preempt_disable(); 1364 preempt_disable();
1328 value = __find_symbol(symbol, &owner, &crc, 1); 1365 value = __find_symbol(symbol, &owner, &crc, 1);
1329 if (value && !strong_try_module_get(owner)) 1366 if (value && strong_try_module_get(owner) != 0)
1330 value = 0; 1367 value = 0;
1331 preempt_enable(); 1368 preempt_enable();
1332 1369
@@ -1889,7 +1926,7 @@ static struct module *load_module(void __user *umod,
1889 set_license(mod, get_modinfo(sechdrs, infoindex, "license")); 1926 set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
1890 1927
1891 if (strcmp(mod->name, "ndiswrapper") == 0) 1928 if (strcmp(mod->name, "ndiswrapper") == 0)
1892 add_taint(TAINT_PROPRIETARY_MODULE); 1929 add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
1893 if (strcmp(mod->name, "driverloader") == 0) 1930 if (strcmp(mod->name, "driverloader") == 0)
1894 add_taint_module(mod, TAINT_PROPRIETARY_MODULE); 1931 add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
1895 1932
@@ -2019,6 +2056,11 @@ static struct module *load_module(void __user *umod,
2019 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", 2056 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
2020 mod->name); 2057 mod->name);
2021 2058
2059 /* Now sew it into the lists so we can get lockdep and oops
2060 * info during argument parsing. Noone should access us, since
2061 * strong_try_module_get() will fail. */
2062 stop_machine_run(__link_module, mod, NR_CPUS);
2063
2022 /* Size of section 0 is 0, so this works well if no params */ 2064 /* Size of section 0 is 0, so this works well if no params */
2023 err = parse_args(mod->name, mod->args, 2065 err = parse_args(mod->name, mod->args,
2024 (struct kernel_param *) 2066 (struct kernel_param *)
@@ -2027,7 +2069,7 @@ static struct module *load_module(void __user *umod,
2027 / sizeof(struct kernel_param), 2069 / sizeof(struct kernel_param),
2028 NULL); 2070 NULL);
2029 if (err < 0) 2071 if (err < 0)
2030 goto arch_cleanup; 2072 goto unlink;
2031 2073
2032 err = mod_sysfs_setup(mod, 2074 err = mod_sysfs_setup(mod,
2033 (struct kernel_param *) 2075 (struct kernel_param *)
@@ -2035,7 +2077,7 @@ static struct module *load_module(void __user *umod,
2035 sechdrs[setupindex].sh_size 2077 sechdrs[setupindex].sh_size
2036 / sizeof(struct kernel_param)); 2078 / sizeof(struct kernel_param));
2037 if (err < 0) 2079 if (err < 0)
2038 goto arch_cleanup; 2080 goto unlink;
2039 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 2081 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2040 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 2082 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2041 2083
@@ -2050,7 +2092,8 @@ static struct module *load_module(void __user *umod,
2050 /* Done! */ 2092 /* Done! */
2051 return mod; 2093 return mod;
2052 2094
2053 arch_cleanup: 2095 unlink:
2096 stop_machine_run(__unlink_module, mod, NR_CPUS);
2054 module_arch_cleanup(mod); 2097 module_arch_cleanup(mod);
2055 cleanup: 2098 cleanup:
2056 kobject_del(&mod->mkobj.kobj); 2099 kobject_del(&mod->mkobj.kobj);
@@ -2075,17 +2118,6 @@ static struct module *load_module(void __user *umod,
2075 goto free_hdr; 2118 goto free_hdr;
2076} 2119}
2077 2120
2078/*
2079 * link the module with the whole machine is stopped with interrupts off
2080 * - this defends against kallsyms not taking locks
2081 */
2082static int __link_module(void *_mod)
2083{
2084 struct module *mod = _mod;
2085 list_add(&mod->list, &modules);
2086 return 0;
2087}
2088
2089/* This is where the real work happens */ 2121/* This is where the real work happens */
2090asmlinkage long 2122asmlinkage long
2091sys_init_module(void __user *umod, 2123sys_init_module(void __user *umod,
@@ -2110,10 +2142,6 @@ sys_init_module(void __user *umod,
2110 return PTR_ERR(mod); 2142 return PTR_ERR(mod);
2111 } 2143 }
2112 2144
2113 /* Now sew it into the lists. They won't access us, since
2114 strong_try_module_get() will fail. */
2115 stop_machine_run(__link_module, mod, NR_CPUS);
2116
2117 /* Drop lock so they can recurse */ 2145 /* Drop lock so they can recurse */
2118 mutex_unlock(&module_mutex); 2146 mutex_unlock(&module_mutex);
2119 2147
@@ -2132,6 +2160,7 @@ sys_init_module(void __user *umod,
2132 mutex_lock(&module_mutex); 2160 mutex_lock(&module_mutex);
2133 free_module(mod); 2161 free_module(mod);
2134 mutex_unlock(&module_mutex); 2162 mutex_unlock(&module_mutex);
2163 wake_up(&module_wq);
2135 return ret; 2164 return ret;
2136 } 2165 }
2137 2166
@@ -2146,6 +2175,7 @@ sys_init_module(void __user *umod,
2146 mod->init_size = 0; 2175 mod->init_size = 0;
2147 mod->init_text_size = 0; 2176 mod->init_text_size = 0;
2148 mutex_unlock(&module_mutex); 2177 mutex_unlock(&module_mutex);
2178 wake_up(&module_wq);
2149 2179
2150 return 0; 2180 return 0;
2151} 2181}
@@ -2210,14 +2240,13 @@ static const char *get_ksymbol(struct module *mod,
2210 return mod->strtab + mod->symtab[best].st_name; 2240 return mod->strtab + mod->symtab[best].st_name;
2211} 2241}
2212 2242
2213/* For kallsyms to ask for address resolution. NULL means not found. 2243/* For kallsyms to ask for address resolution. NULL means not found. Careful
2214 We don't lock, as this is used for oops resolution and races are a 2244 * not to lock to avoid deadlock on oopses, simply disable preemption. */
2215 lesser concern. */ 2245char *module_address_lookup(unsigned long addr,
2216/* FIXME: Risky: returns a pointer into a module w/o lock */ 2246 unsigned long *size,
2217const char *module_address_lookup(unsigned long addr, 2247 unsigned long *offset,
2218 unsigned long *size, 2248 char **modname,
2219 unsigned long *offset, 2249 char *namebuf)
2220 char **modname)
2221{ 2250{
2222 struct module *mod; 2251 struct module *mod;
2223 const char *ret = NULL; 2252 const char *ret = NULL;
@@ -2232,8 +2261,13 @@ const char *module_address_lookup(unsigned long addr,
2232 break; 2261 break;
2233 } 2262 }
2234 } 2263 }
2264 /* Make a copy in here where it's safe */
2265 if (ret) {
2266 strncpy(namebuf, ret, KSYM_NAME_LEN - 1);
2267 ret = namebuf;
2268 }
2235 preempt_enable(); 2269 preempt_enable();
2236 return ret; 2270 return (char *)ret;
2237} 2271}
2238 2272
2239int lookup_module_symbol_name(unsigned long addr, char *symname) 2273int lookup_module_symbol_name(unsigned long addr, char *symname)
diff --git a/kernel/params.c b/kernel/params.c
index 67f65ee7211d..42fe5e6126c0 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -376,8 +376,6 @@ int param_get_string(char *buffer, struct kernel_param *kp)
376 376
377extern struct kernel_param __start___param[], __stop___param[]; 377extern struct kernel_param __start___param[], __stop___param[];
378 378
379#define MAX_KBUILD_MODNAME KOBJ_NAME_LEN
380
381struct param_attribute 379struct param_attribute
382{ 380{
383 struct module_attribute mattr; 381 struct module_attribute mattr;
@@ -587,7 +585,7 @@ static void __init param_sysfs_builtin(void)
587{ 585{
588 struct kernel_param *kp, *kp_begin = NULL; 586 struct kernel_param *kp, *kp_begin = NULL;
589 unsigned int i, name_len, count = 0; 587 unsigned int i, name_len, count = 0;
590 char modname[MAX_KBUILD_MODNAME + 1] = ""; 588 char modname[MODULE_NAME_LEN + 1] = "";
591 589
592 for (i=0; i < __stop___param - __start___param; i++) { 590 for (i=0; i < __stop___param - __start___param; i++) {
593 char *dot; 591 char *dot;
@@ -595,12 +593,12 @@ static void __init param_sysfs_builtin(void)
595 593
596 kp = &__start___param[i]; 594 kp = &__start___param[i];
597 max_name_len = 595 max_name_len =
598 min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name)); 596 min_t(size_t, MODULE_NAME_LEN, strlen(kp->name));
599 597
600 dot = memchr(kp->name, '.', max_name_len); 598 dot = memchr(kp->name, '.', max_name_len);
601 if (!dot) { 599 if (!dot) {
602 DEBUGP("couldn't find period in first %d characters " 600 DEBUGP("couldn't find period in first %d characters "
603 "of %s\n", MAX_KBUILD_MODNAME, kp->name); 601 "of %s\n", MODULE_NAME_LEN, kp->name);
604 continue; 602 continue;
605 } 603 }
606 name_len = dot - kp->name; 604 name_len = dot - kp->name;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 14fb355e3caa..c4ecb2994ba3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -79,6 +79,38 @@ config HEADERS_CHECK
79 exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in 79 exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in
80 your build tree), to make sure they're suitable. 80 your build tree), to make sure they're suitable.
81 81
82config DEBUG_SECTION_MISMATCH
83 bool "Enable full Section mismatch analysis"
84 default n
85 help
86 The section mismatch analysis checks if there are illegal
87 references from one section to another section.
88 Linux will during link or during runtime drop some sections
89 and any use of code/data previously in these sections will
90 most likely result in an oops.
91 In the code functions and variables are annotated with
92 __init, __devinit etc. (see full list in include/linux/init.h)
93 which result in the code/data being placed in specific sections.
94 The section mismatch anaylsis are always done after a full
95 kernel build but enabling this options will in addition
96 do the following:
97 - Add the option -fno-inline-functions-called-once to gcc
98 When inlining a function annotated __init in a non-init
99 function we would loose the section information and thus
100 the analysis would not catch the illegal reference.
101 This options tell gcc to inline less but will also
102 result in a larger kernel.
103 - Run the section mismatch analysis for each module/built-in.o
104 When we run the section mismatch analysis on vmlinux.o we
105 looses valueable information about where the mismatch was
106 introduced.
107 Running the analysis for each module/built-in.o file
108 will tell where the mismatch happens much closer to the
109 source. The drawback is that we will report the same
110 mismatch at least twice.
111 - Enable verbose reporting from modpost to help solving
112 the section mismatches reported.
113
82config DEBUG_KERNEL 114config DEBUG_KERNEL
83 bool "Kernel debugging" 115 bool "Kernel debugging"
84 help 116 help
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index bda0d71a2514..78ccd73a8841 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -178,4 +178,47 @@ found_middle_swap:
178 178
179EXPORT_SYMBOL(generic_find_next_zero_le_bit); 179EXPORT_SYMBOL(generic_find_next_zero_le_bit);
180 180
181unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
182 long size, unsigned long offset)
183{
184 const unsigned long *p = addr + BITOP_WORD(offset);
185 unsigned long result = offset & ~(BITS_PER_LONG - 1);
186 unsigned long tmp;
187
188 if (offset >= size)
189 return size;
190 size -= result;
191 offset &= (BITS_PER_LONG - 1UL);
192 if (offset) {
193 tmp = ext2_swabp(p++);
194 tmp &= (~0UL << offset);
195 if (size < BITS_PER_LONG)
196 goto found_first;
197 if (tmp)
198 goto found_middle;
199 size -= BITS_PER_LONG;
200 result += BITS_PER_LONG;
201 }
202
203 while (size & ~(BITS_PER_LONG - 1)) {
204 tmp = *(p++);
205 if (tmp)
206 goto found_middle_swap;
207 result += BITS_PER_LONG;
208 size -= BITS_PER_LONG;
209 }
210 if (!size)
211 return result;
212 tmp = ext2_swabp(p);
213found_first:
214 tmp &= (~0UL >> (BITS_PER_LONG - size));
215 if (tmp == 0UL) /* Are any bits set? */
216 return result + size; /* Nope. */
217found_middle:
218 return result + __ffs(tmp);
219
220found_middle_swap:
221 return result + __ffs(ext2_swab(tmp));
222}
223EXPORT_SYMBOL(generic_find_next_le_bit);
181#endif /* __BIG_ENDIAN */ 224#endif /* __BIG_ENDIAN */
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index de9836eee8bb..67fb4530a6ff 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -83,10 +83,12 @@ ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),)
83builtin-target := $(obj)/built-in.o 83builtin-target := $(obj)/built-in.o
84endif 84endif
85 85
86modorder-target := $(obj)/modules.order
87
86# We keep a list of all modules in $(MODVERDIR) 88# We keep a list of all modules in $(MODVERDIR)
87 89
88__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ 90__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
89 $(if $(KBUILD_MODULES),$(obj-m)) \ 91 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
90 $(subdir-ym) $(always) 92 $(subdir-ym) $(always)
91 @: 93 @:
92 94
@@ -101,6 +103,10 @@ ifneq ($(KBUILD_CHECKSRC),0)
101 endif 103 endif
102endif 104endif
103 105
106# Do section mismatch analysis for each module/built-in.o
107ifdef CONFIG_DEBUG_SECTION_MISMATCH
108 cmd_secanalysis = ; scripts/mod/modpost $@
109endif
104 110
105# Compile C sources (.c) 111# Compile C sources (.c)
106# --------------------------------------------------------------------------- 112# ---------------------------------------------------------------------------
@@ -266,7 +272,8 @@ ifdef builtin-target
266quiet_cmd_link_o_target = LD $@ 272quiet_cmd_link_o_target = LD $@
267# If the list of objects to link is empty, just create an empty built-in.o 273# If the list of objects to link is empty, just create an empty built-in.o
268cmd_link_o_target = $(if $(strip $(obj-y)),\ 274cmd_link_o_target = $(if $(strip $(obj-y)),\
269 $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\ 275 $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
276 $(cmd_secanalysis),\
270 rm -f $@; $(AR) rcs $@) 277 rm -f $@; $(AR) rcs $@)
271 278
272$(builtin-target): $(obj-y) FORCE 279$(builtin-target): $(obj-y) FORCE
@@ -276,6 +283,19 @@ targets += $(builtin-target)
276endif # builtin-target 283endif # builtin-target
277 284
278# 285#
286# Rule to create modules.order file
287#
288# Create commands to either record .ko file or cat modules.order from
289# a subdirectory
290modorder-cmds = \
291 $(foreach m, $(modorder), \
292 $(if $(filter %/modules.order, $m), \
293 cat $m;, echo kernel/$m;))
294
295$(modorder-target): $(subdir-ym) FORCE
296 $(Q)(cat /dev/null; $(modorder-cmds)) > $@
297
298#
279# Rule to compile a set of .o files into one .a file 299# Rule to compile a set of .o files into one .a file
280# 300#
281ifdef lib-target 301ifdef lib-target
@@ -301,7 +321,7 @@ $($(subst $(obj)/,,$(@:.o=-objs))) \
301$($(subst $(obj)/,,$(@:.o=-y)))), $^) 321$($(subst $(obj)/,,$(@:.o=-y)))), $^)
302 322
303quiet_cmd_link_multi-y = LD $@ 323quiet_cmd_link_multi-y = LD $@
304cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) 324cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
305 325
306quiet_cmd_link_multi-m = LD [M] $@ 326quiet_cmd_link_multi-m = LD [M] $@
307cmd_link_multi-m = $(cmd_link_multi-y) 327cmd_link_multi-m = $(cmd_link_multi-y)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 3c5e88bfecf1..8e440233c27d 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -25,6 +25,11 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
25# o if we encounter foo/ in $(obj-m), remove it from $(obj-m) 25# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
26# and add the directory to the list of dirs to descend into: $(subdir-m) 26# and add the directory to the list of dirs to descend into: $(subdir-m)
27 27
28# Determine modorder.
29# Unfortunately, we don't have information about ordering between -y
30# and -m subdirs. Just put -y's first.
31modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
32
28__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) 33__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
29subdir-y += $(__subdir-y) 34subdir-y += $(__subdir-y)
30__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) 35__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
@@ -64,6 +69,7 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)
64extra-y := $(addprefix $(obj)/,$(extra-y)) 69extra-y := $(addprefix $(obj)/,$(extra-y))
65always := $(addprefix $(obj)/,$(always)) 70always := $(addprefix $(obj)/,$(always))
66targets := $(addprefix $(obj)/,$(targets)) 71targets := $(addprefix $(obj)/,$(targets))
72modorder := $(addprefix $(obj)/,$(modorder))
67obj-y := $(addprefix $(obj)/,$(obj-y)) 73obj-y := $(addprefix $(obj)/,$(obj-y))
68obj-m := $(addprefix $(obj)/,$(obj-m)) 74obj-m := $(addprefix $(obj)/,$(obj-m))
69lib-y := $(addprefix $(obj)/,$(lib-y)) 75lib-y := $(addprefix $(obj)/,$(lib-y))
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index f0ff248f5e6f..efa5d940e632 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -21,7 +21,7 @@ quiet_cmd_modules_install = INSTALL $@
21 21
22# Modules built outside the kernel source tree go into extra by default 22# Modules built outside the kernel source tree go into extra by default
23INSTALL_MOD_DIR ?= extra 23INSTALL_MOD_DIR ?= extra
24ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(KBUILD_EXTMOD),,$(@D)) 24ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D))
25 25
26modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) 26modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
27 27
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index d988f5d21e3d..65e707e1ffc3 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -62,6 +62,7 @@ modpost = scripts/mod/modpost \
62 $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ 62 $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
63 $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ 63 $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
64 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ 64 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
65 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
65 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) 66 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
66 67
67quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules 68quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 0e4bd5459df4..35bdc68b6e66 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -30,6 +30,7 @@
30 * !Ifilename 30 * !Ifilename
31 * !Dfilename 31 * !Dfilename
32 * !Ffilename 32 * !Ffilename
33 * !Pfilename
33 * 34 *
34 */ 35 */
35 36
@@ -57,6 +58,7 @@ FILEONLY *symbolsonly;
57typedef void FILELINE(char * file, char * line); 58typedef void FILELINE(char * file, char * line);
58FILELINE * singlefunctions; 59FILELINE * singlefunctions;
59FILELINE * entity_system; 60FILELINE * entity_system;
61FILELINE * docsection;
60 62
61#define MAXLINESZ 2048 63#define MAXLINESZ 2048
62#define MAXFILES 250 64#define MAXFILES 250
@@ -65,6 +67,7 @@ FILELINE * entity_system;
65#define DOCBOOK "-docbook" 67#define DOCBOOK "-docbook"
66#define FUNCTION "-function" 68#define FUNCTION "-function"
67#define NOFUNCTION "-nofunction" 69#define NOFUNCTION "-nofunction"
70#define NODOCSECTIONS "-no-doc-sections"
68 71
69char *srctree; 72char *srctree;
70 73
@@ -231,13 +234,14 @@ void docfunctions(char * filename, char * type)
231 234
232 for (i=0; i <= symfilecnt; i++) 235 for (i=0; i <= symfilecnt; i++)
233 symcnt += symfilelist[i].symbolcnt; 236 symcnt += symfilelist[i].symbolcnt;
234 vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*)); 237 vec = malloc((2 + 2 * symcnt + 3) * sizeof(char *));
235 if (vec == NULL) { 238 if (vec == NULL) {
236 perror("docproc: "); 239 perror("docproc: ");
237 exit(1); 240 exit(1);
238 } 241 }
239 vec[idx++] = KERNELDOC; 242 vec[idx++] = KERNELDOC;
240 vec[idx++] = DOCBOOK; 243 vec[idx++] = DOCBOOK;
244 vec[idx++] = NODOCSECTIONS;
241 for (i=0; i < symfilecnt; i++) { 245 for (i=0; i < symfilecnt; i++) {
242 struct symfile * sym = &symfilelist[i]; 246 struct symfile * sym = &symfilelist[i];
243 for (j=0; j < sym->symbolcnt; j++) { 247 for (j=0; j < sym->symbolcnt; j++) {
@@ -287,12 +291,36 @@ void singfunc(char * filename, char * line)
287} 291}
288 292
289/* 293/*
294 * Insert specific documentation section from a file.
295 * Call kernel-doc with the following parameters:
296 * kernel-doc -docbook -function "doc section" filename
297 */
298void docsect(char *filename, char *line)
299{
300 char *vec[6]; /* kerneldoc -docbook -function "section" file NULL */
301 char *s;
302
303 for (s = line; *s; s++)
304 if (*s == '\n')
305 *s = '\0';
306
307 vec[0] = KERNELDOC;
308 vec[1] = DOCBOOK;
309 vec[2] = FUNCTION;
310 vec[3] = line;
311 vec[4] = filename;
312 vec[5] = NULL;
313 exec_kernel_doc(vec);
314}
315
316/*
290 * Parse file, calling action specific functions for: 317 * Parse file, calling action specific functions for:
291 * 1) Lines containing !E 318 * 1) Lines containing !E
292 * 2) Lines containing !I 319 * 2) Lines containing !I
293 * 3) Lines containing !D 320 * 3) Lines containing !D
294 * 4) Lines containing !F 321 * 4) Lines containing !F
295 * 5) Default lines - lines not matching the above 322 * 5) Lines containing !P
323 * 6) Default lines - lines not matching the above
296 */ 324 */
297void parse_file(FILE *infile) 325void parse_file(FILE *infile)
298{ 326{
@@ -326,6 +354,15 @@ void parse_file(FILE *infile)
326 s++; 354 s++;
327 singlefunctions(line +2, s); 355 singlefunctions(line +2, s);
328 break; 356 break;
357 case 'P':
358 /* filename */
359 while (*s && !isspace(*s)) s++;
360 *s++ = '\0';
361 /* DOC: section name */
362 while (isspace(*s))
363 s++;
364 docsection(line + 2, s);
365 break;
329 default: 366 default:
330 defaultline(line); 367 defaultline(line);
331 } 368 }
@@ -372,6 +409,7 @@ int main(int argc, char *argv[])
372 externalfunctions = find_export_symbols; 409 externalfunctions = find_export_symbols;
373 symbolsonly = find_export_symbols; 410 symbolsonly = find_export_symbols;
374 singlefunctions = noaction2; 411 singlefunctions = noaction2;
412 docsection = noaction2;
375 parse_file(infile); 413 parse_file(infile);
376 414
377 /* Rewind to start from beginning of file again */ 415 /* Rewind to start from beginning of file again */
@@ -381,6 +419,7 @@ int main(int argc, char *argv[])
381 externalfunctions = extfunc; 419 externalfunctions = extfunc;
382 symbolsonly = printline; 420 symbolsonly = printline;
383 singlefunctions = singfunc; 421 singlefunctions = singfunc;
422 docsection = docsect;
384 423
385 parse_file(infile); 424 parse_file(infile);
386 } 425 }
@@ -394,6 +433,7 @@ int main(int argc, char *argv[])
394 externalfunctions = adddep; 433 externalfunctions = adddep;
395 symbolsonly = adddep; 434 symbolsonly = adddep;
396 singlefunctions = adddep2; 435 singlefunctions = adddep2;
436 docsection = adddep2;
397 parse_file(infile); 437 parse_file(infile);
398 printf("\n"); 438 printf("\n");
399 } 439 }
diff --git a/scripts/decodecode b/scripts/decodecode
index 1e1a8f620c47..235d3938529d 100644
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -6,7 +6,19 @@
6# e.g., to decode an i386 oops on an x86_64 system, use: 6# e.g., to decode an i386 oops on an x86_64 system, use:
7# AFLAGS=--32 decodecode < 386.oops 7# AFLAGS=--32 decodecode < 386.oops
8 8
9T=`mktemp` 9cleanup() {
10 rm -f $T $T.s $T.o
11 exit 1
12}
13
14die() {
15 echo "$@"
16 exit 1
17}
18
19trap cleanup EXIT
20
21T=`mktemp` || die "cannot create temp file"
10code= 22code=
11 23
12while read i ; do 24while read i ; do
@@ -20,6 +32,7 @@ esac
20done 32done
21 33
22if [ -z "$code" ]; then 34if [ -z "$code" ]; then
35 rm $T
23 exit 36 exit
24fi 37fi
25 38
@@ -48,4 +61,4 @@ echo -n " .byte 0x" > $T.s
48echo $code >> $T.s 61echo $code >> $T.s
49as $AFLAGS -o $T.o $T.s 62as $AFLAGS -o $T.o $T.s
50objdump -S $T.o 63objdump -S $T.o
51rm $T.o $T.s 64rm $T $T.s $T.o
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index a5121a6d8949..cc767b388baf 100644
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -9,7 +9,10 @@
9# gcc-2.95.3, `030301' for gcc-3.3.1, etc. 9# gcc-2.95.3, `030301' for gcc-3.3.1, etc.
10# 10#
11 11
12if [[ $1 = "-p" ]] ; then with_patchlevel=1; shift; fi 12if [ "$1" = "-p" ] ; then
13 with_patchlevel=1;
14 shift;
15fi
13 16
14compiler="$*" 17compiler="$*"
15 18
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index 511023b430a8..dca5e0dd09bf 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -440,17 +440,21 @@ void error_with_pos(const char *fmt, ...)
440 440
441static void genksyms_usage(void) 441static void genksyms_usage(void)
442{ 442{
443 fputs("Usage:\n" "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n" "\n" 443 fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n"
444#ifdef __GNU_LIBRARY__ 444#ifdef __GNU_LIBRARY__
445 " -a, --arch Select architecture\n"
445 " -d, --debug Increment the debug level (repeatable)\n" 446 " -d, --debug Increment the debug level (repeatable)\n"
446 " -D, --dump Dump expanded symbol defs (for debugging only)\n" 447 " -D, --dump Dump expanded symbol defs (for debugging only)\n"
448 " -T, --dump-types file Dump expanded types into file (for debugging only)\n"
447 " -w, --warnings Enable warnings\n" 449 " -w, --warnings Enable warnings\n"
448 " -q, --quiet Disable warnings (default)\n" 450 " -q, --quiet Disable warnings (default)\n"
449 " -h, --help Print this message\n" 451 " -h, --help Print this message\n"
450 " -V, --version Print the release version\n" 452 " -V, --version Print the release version\n"
451#else /* __GNU_LIBRARY__ */ 453#else /* __GNU_LIBRARY__ */
454 " -a Select architecture\n"
452 " -d Increment the debug level (repeatable)\n" 455 " -d Increment the debug level (repeatable)\n"
453 " -D Dump expanded symbol defs (for debugging only)\n" 456 " -D Dump expanded symbol defs (for debugging only)\n"
457 " -T file Dump expanded types into file (for debugging only)\n"
454 " -w Enable warnings\n" 458 " -w Enable warnings\n"
455 " -q Disable warnings (default)\n" 459 " -q Disable warnings (default)\n"
456 " -h Print this message\n" 460 " -h Print this message\n"
@@ -477,10 +481,10 @@ int main(int argc, char **argv)
477 {0, 0, 0, 0} 481 {0, 0, 0, 0}
478 }; 482 };
479 483
480 while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:", 484 while ((o = getopt_long(argc, argv, "a:dwqVDT:h",
481 &long_opts[0], NULL)) != EOF) 485 &long_opts[0], NULL)) != EOF)
482#else /* __GNU_LIBRARY__ */ 486#else /* __GNU_LIBRARY__ */
483 while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF) 487 while ((o = getopt(argc, argv, "a:dwqVDT:h")) != EOF)
484#endif /* __GNU_LIBRARY__ */ 488#endif /* __GNU_LIBRARY__ */
485 switch (o) { 489 switch (o) {
486 case 'a': 490 case 'a':
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 1ad6f7fc490a..32e8c5a227c3 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -24,22 +24,25 @@ oldconfig: $(obj)/conf
24silentoldconfig: $(obj)/conf 24silentoldconfig: $(obj)/conf
25 $< -s $(Kconfig) 25 $< -s $(Kconfig)
26 26
27# Create new linux.po file 27# Create new linux.pot file
28# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files 28# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
29# The symlink is used to repair a deficiency in arch/um 29# The symlink is used to repair a deficiency in arch/um
30update-po-config: $(obj)/kxgettext 30update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
31 xgettext --default-domain=linux \ 31 $(Q)echo " GEN config"
32 $(Q)xgettext --default-domain=linux \
32 --add-comments --keyword=_ --keyword=N_ \ 33 --add-comments --keyword=_ --keyword=N_ \
33 --from-code=UTF-8 \ 34 --from-code=UTF-8 \
34 --files-from=scripts/kconfig/POTFILES.in \ 35 --files-from=scripts/kconfig/POTFILES.in \
35 --output $(obj)/config.pot 36 --output $(obj)/config.pot
36 $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot 37 $(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
37 $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch 38 $(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
38 (for i in `ls arch/`; \ 39 $(Q)(for i in `ls arch/`; \
39 do \ 40 do \
40 $(obj)/kxgettext arch/$$i/Kconfig; \ 41 echo " GEN $$i"; \
41 done ) >> $(obj)/config.pot 42 $(obj)/kxgettext arch/$$i/Kconfig \
42 msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \ 43 >> $(obj)/config.pot; \
44 done )
45 $(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
43 --output $(obj)/linux.pot 46 --output $(obj)/linux.pot
44 $(Q)rm -f arch/um/Kconfig.arch 47 $(Q)rm -f arch/um/Kconfig.arch
45 $(Q)rm -f $(obj)/config.pot 48 $(Q)rm -f $(obj)/config.pot
@@ -93,12 +96,6 @@ HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
93 96
94HOST_EXTRACFLAGS += -DLOCALE 97HOST_EXTRACFLAGS += -DLOCALE
95 98
96PHONY += $(obj)/dochecklxdialog
97$(obj)/dochecklxdialog:
98 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
99
100always := dochecklxdialog
101
102 99
103# =========================================================================== 100# ===========================================================================
104# Shared Makefile for the various kconfig executables: 101# Shared Makefile for the various kconfig executables:
@@ -142,8 +139,17 @@ gconf-objs := gconf.o kconfig_load.o zconf.tab.o
142endif 139endif
143 140
144clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ 141clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
145 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c 142 .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
146clean-files += mconf qconf gconf 143clean-files += mconf qconf gconf
144clean-files += config.pot linux.pot
145
146# Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
147PHONY += $(obj)/dochecklxdialog
148$(addprefix $(obj)/,$(lxdialog)): $(obj)/dochecklxdialog
149$(obj)/dochecklxdialog:
150 $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES)
151
152always := dochecklxdialog
147 153
148# Add environment specific flags 154# Add environment specific flags
149HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS)) 155HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
@@ -248,6 +254,9 @@ $(obj)/%.moc: $(src)/%.h
248$(obj)/lkc_defs.h: $(src)/lkc_proto.h 254$(obj)/lkc_defs.h: $(src)/lkc_proto.h
249 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' 255 sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
250 256
257# Extract gconf menu items for I18N support
258$(obj)/gconf.glade.h: $(obj)/gconf.glade
259 intltool-extract --type=gettext/glade $(obj)/gconf.glade
251 260
252### 261###
253# The following requires flex/bison/gperf 262# The following requires flex/bison/gperf
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in
index cc94e46a79e8..967457396990 100644
--- a/scripts/kconfig/POTFILES.in
+++ b/scripts/kconfig/POTFILES.in
@@ -1,5 +1,12 @@
1scripts/kconfig/lxdialog/checklist.c
2scripts/kconfig/lxdialog/inputbox.c
3scripts/kconfig/lxdialog/menubox.c
4scripts/kconfig/lxdialog/textbox.c
5scripts/kconfig/lxdialog/util.c
6scripts/kconfig/lxdialog/yesno.c
1scripts/kconfig/mconf.c 7scripts/kconfig/mconf.c
2scripts/kconfig/conf.c 8scripts/kconfig/conf.c
3scripts/kconfig/confdata.c 9scripts/kconfig/confdata.c
4scripts/kconfig/gconf.c 10scripts/kconfig/gconf.c
11scripts/kconfig/gconf.glade.h
5scripts/kconfig/qconf.cc 12scripts/kconfig/qconf.cc
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 8d6f17490c5e..fda63136ae68 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -3,12 +3,13 @@
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6#include <locale.h>
6#include <ctype.h> 7#include <ctype.h>
7#include <stdlib.h>
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h>
9#include <string.h> 10#include <string.h>
10#include <unistd.h>
11#include <time.h> 11#include <time.h>
12#include <unistd.h>
12#include <sys/stat.h> 13#include <sys/stat.h>
13 14
14#define LKC_DIRECT_LINK 15#define LKC_DIRECT_LINK
@@ -40,7 +41,7 @@ static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"
40static const char *get_help(struct menu *menu) 41static const char *get_help(struct menu *menu)
41{ 42{
42 if (menu_has_help(menu)) 43 if (menu_has_help(menu))
43 return menu_get_help(menu); 44 return _(menu_get_help(menu));
44 else 45 else
45 return nohelp_text; 46 return nohelp_text;
46} 47}
@@ -78,7 +79,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
78 tristate val; 79 tristate val;
79 80
80 if (!sym_has_value(sym)) 81 if (!sym_has_value(sym))
81 printf("(NEW) "); 82 printf(_("(NEW) "));
82 83
83 line[0] = '\n'; 84 line[0] = '\n';
84 line[1] = 0; 85 line[1] = 0;
@@ -160,7 +161,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
160 } 161 }
161 case set_random: 162 case set_random:
162 do { 163 do {
163 val = (tristate)(random() % 3); 164 val = (tristate)(rand() % 3);
164 } while (!sym_tristate_within_range(sym, val)); 165 } while (!sym_tristate_within_range(sym, val));
165 switch (val) { 166 switch (val) {
166 case no: line[0] = 'n'; break; 167 case no: line[0] = 'n'; break;
@@ -183,7 +184,7 @@ int conf_string(struct menu *menu)
183 const char *def; 184 const char *def;
184 185
185 while (1) { 186 while (1) {
186 printf("%*s%s ", indent - 1, "", menu->prompt->text); 187 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
187 printf("(%s) ", sym->name); 188 printf("(%s) ", sym->name);
188 def = sym_get_string_value(sym); 189 def = sym_get_string_value(sym);
189 if (sym_get_string_value(sym)) 190 if (sym_get_string_value(sym))
@@ -216,7 +217,7 @@ static int conf_sym(struct menu *menu)
216 tristate oldval, newval; 217 tristate oldval, newval;
217 218
218 while (1) { 219 while (1) {
219 printf("%*s%s ", indent - 1, "", menu->prompt->text); 220 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
220 if (sym->name) 221 if (sym->name)
221 printf("(%s) ", sym->name); 222 printf("(%s) ", sym->name);
222 type = sym_get_type(sym); 223 type = sym_get_type(sym);
@@ -306,7 +307,7 @@ static int conf_choice(struct menu *menu)
306 case no: 307 case no:
307 return 1; 308 return 1;
308 case mod: 309 case mod:
309 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 310 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
310 return 0; 311 return 0;
311 case yes: 312 case yes:
312 break; 313 break;
@@ -316,7 +317,7 @@ static int conf_choice(struct menu *menu)
316 while (1) { 317 while (1) {
317 int cnt, def; 318 int cnt, def;
318 319
319 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 320 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
320 def_sym = sym_get_choice_value(sym); 321 def_sym = sym_get_choice_value(sym);
321 cnt = def = 0; 322 cnt = def = 0;
322 line[0] = 0; 323 line[0] = 0;
@@ -324,7 +325,7 @@ static int conf_choice(struct menu *menu)
324 if (!menu_is_visible(child)) 325 if (!menu_is_visible(child))
325 continue; 326 continue;
326 if (!child->sym) { 327 if (!child->sym) {
327 printf("%*c %s\n", indent, '*', menu_get_prompt(child)); 328 printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
328 continue; 329 continue;
329 } 330 }
330 cnt++; 331 cnt++;
@@ -333,14 +334,14 @@ static int conf_choice(struct menu *menu)
333 printf("%*c", indent, '>'); 334 printf("%*c", indent, '>');
334 } else 335 } else
335 printf("%*c", indent, ' '); 336 printf("%*c", indent, ' ');
336 printf(" %d. %s", cnt, menu_get_prompt(child)); 337 printf(" %d. %s", cnt, _(menu_get_prompt(child)));
337 if (child->sym->name) 338 if (child->sym->name)
338 printf(" (%s)", child->sym->name); 339 printf(" (%s)", child->sym->name);
339 if (!sym_has_value(child->sym)) 340 if (!sym_has_value(child->sym))
340 printf(" (NEW)"); 341 printf(_(" (NEW)"));
341 printf("\n"); 342 printf("\n");
342 } 343 }
343 printf("%*schoice", indent - 1, ""); 344 printf(_("%*schoice"), indent - 1, "");
344 if (cnt == 1) { 345 if (cnt == 1) {
345 printf("[1]: 1\n"); 346 printf("[1]: 1\n");
346 goto conf_childs; 347 goto conf_childs;
@@ -375,7 +376,7 @@ static int conf_choice(struct menu *menu)
375 break; 376 break;
376 case set_random: 377 case set_random:
377 if (is_new) 378 if (is_new)
378 def = (random() % cnt) + 1; 379 def = (rand() % cnt) + 1;
379 case set_default: 380 case set_default:
380 case set_yes: 381 case set_yes:
381 case set_mod: 382 case set_mod:
@@ -399,9 +400,9 @@ static int conf_choice(struct menu *menu)
399 continue; 400 continue;
400 } 401 }
401 sym_set_choice_value(sym, child->sym); 402 sym_set_choice_value(sym, child->sym);
402 if (child->list) { 403 for (child = child->list; child; child = child->next) {
403 indent += 2; 404 indent += 2;
404 conf(child->list); 405 conf(child);
405 indent -= 2; 406 indent -= 2;
406 } 407 }
407 return 1; 408 return 1;
@@ -433,7 +434,7 @@ static void conf(struct menu *menu)
433 if (prompt) 434 if (prompt)
434 printf("%*c\n%*c %s\n%*c\n", 435 printf("%*c\n%*c %s\n%*c\n",
435 indent, '*', 436 indent, '*',
436 indent, '*', prompt, 437 indent, '*', _(prompt),
437 indent, '*'); 438 indent, '*');
438 default: 439 default:
439 ; 440 ;
@@ -495,12 +496,16 @@ static void check_conf(struct menu *menu)
495 496
496int main(int ac, char **av) 497int main(int ac, char **av)
497{ 498{
498 int i = 1; 499 int opt;
499 const char *name; 500 const char *name;
500 struct stat tmpstat; 501 struct stat tmpstat;
501 502
502 if (ac > i && av[i][0] == '-') { 503 setlocale(LC_ALL, "");
503 switch (av[i++][1]) { 504 bindtextdomain(PACKAGE, LOCALEDIR);
505 textdomain(PACKAGE);
506
507 while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
508 switch (opt) {
504 case 'o': 509 case 'o':
505 input_mode = ask_new; 510 input_mode = ask_new;
506 break; 511 break;
@@ -513,12 +518,7 @@ int main(int ac, char **av)
513 break; 518 break;
514 case 'D': 519 case 'D':
515 input_mode = set_default; 520 input_mode = set_default;
516 defconfig_file = av[i++]; 521 defconfig_file = optarg;
517 if (!defconfig_file) {
518 printf(_("%s: No default config file specified\n"),
519 av[0]);
520 exit(1);
521 }
522 break; 522 break;
523 case 'n': 523 case 'n':
524 input_mode = set_no; 524 input_mode = set_no;
@@ -531,19 +531,22 @@ int main(int ac, char **av)
531 break; 531 break;
532 case 'r': 532 case 'r':
533 input_mode = set_random; 533 input_mode = set_random;
534 srandom(time(NULL)); 534 srand(time(NULL));
535 break; 535 break;
536 case 'h': 536 case 'h':
537 case '?': 537 printf(_("See README for usage info\n"));
538 fprintf(stderr, "See README for usage info\n");
539 exit(0); 538 exit(0);
539 break;
540 default:
541 fprintf(stderr, _("See README for usage info\n"));
542 exit(1);
540 } 543 }
541 } 544 }
542 name = av[i]; 545 if (ac == optind) {
543 if (!name) {
544 printf(_("%s: Kconfig file missing\n"), av[0]); 546 printf(_("%s: Kconfig file missing\n"), av[0]);
545 exit(1); 547 exit(1);
546 } 548 }
549 name = av[optind];
547 conf_parse(name); 550 conf_parse(name);
548 //zconfdump(stdout); 551 //zconfdump(stdout);
549 switch (input_mode) { 552 switch (input_mode) {
@@ -551,9 +554,9 @@ int main(int ac, char **av)
551 if (!defconfig_file) 554 if (!defconfig_file)
552 defconfig_file = conf_get_default_confname(); 555 defconfig_file = conf_get_default_confname();
553 if (conf_read(defconfig_file)) { 556 if (conf_read(defconfig_file)) {
554 printf("***\n" 557 printf(_("***\n"
555 "*** Can't find default configuration \"%s\"!\n" 558 "*** Can't find default configuration \"%s\"!\n"
556 "***\n", defconfig_file); 559 "***\n"), defconfig_file);
557 exit(1); 560 exit(1);
558 } 561 }
559 break; 562 break;
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index e0f402f3b75d..ee5fe943d58d 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -232,8 +232,7 @@ load:
232 sym->type = S_BOOLEAN; 232 sym->type = S_BOOLEAN;
233 } 233 }
234 if (sym->flags & def_flags) { 234 if (sym->flags & def_flags) {
235 conf_warning("trying to reassign symbol %s", sym->name); 235 conf_warning("override: reassigning to symbol %s", sym->name);
236 break;
237 } 236 }
238 switch (sym->type) { 237 switch (sym->type) {
239 case S_BOOLEAN: 238 case S_BOOLEAN:
@@ -272,8 +271,7 @@ load:
272 sym->type = S_OTHER; 271 sym->type = S_OTHER;
273 } 272 }
274 if (sym->flags & def_flags) { 273 if (sym->flags & def_flags) {
275 conf_warning("trying to reassign symbol %s", sym->name); 274 conf_warning("override: reassigning to symbol %s", sym->name);
276 break;
277 } 275 }
278 if (conf_set_sym_val(sym, def, def_flags, p)) 276 if (conf_set_sym_val(sym, def, def_flags, p))
279 continue; 277 continue;
@@ -297,14 +295,12 @@ load:
297 } 295 }
298 break; 296 break;
299 case yes: 297 case yes:
300 if (cs->def[def].tri != no) { 298 if (cs->def[def].tri != no)
301 conf_warning("%s creates inconsistent choice state", sym->name); 299 conf_warning("override: %s changes choice state", sym->name);
302 cs->flags &= ~def_flags; 300 cs->def[def].val = sym;
303 } else
304 cs->def[def].val = sym;
305 break; 301 break;
306 } 302 }
307 cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri); 303 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
308 } 304 }
309 } 305 }
310 fclose(in); 306 fclose(in);
@@ -316,7 +312,7 @@ load:
316 312
317int conf_read(const char *name) 313int conf_read(const char *name)
318{ 314{
319 struct symbol *sym; 315 struct symbol *sym, *choice_sym;
320 struct property *prop; 316 struct property *prop;
321 struct expr *e; 317 struct expr *e;
322 int i, flags; 318 int i, flags;
@@ -357,9 +353,9 @@ int conf_read(const char *name)
357 */ 353 */
358 prop = sym_get_choice_prop(sym); 354 prop = sym_get_choice_prop(sym);
359 flags = sym->flags; 355 flags = sym->flags;
360 for (e = prop->expr; e; e = e->left.expr) 356 expr_list_for_each_sym(prop->expr, e, choice_sym)
361 if (e->right.sym->visible != no) 357 if (choice_sym->visible != no)
362 flags &= e->right.sym->flags; 358 flags &= choice_sym->flags;
363 sym->flags &= flags | ~SYMBOL_DEF_USER; 359 sym->flags &= flags | ~SYMBOL_DEF_USER;
364 } 360 }
365 361
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 6f98dbfe70cf..579ece4fa584 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -87,7 +87,7 @@ struct expr *expr_copy(struct expr *org)
87 break; 87 break;
88 case E_AND: 88 case E_AND:
89 case E_OR: 89 case E_OR:
90 case E_CHOICE: 90 case E_LIST:
91 e->left.expr = expr_copy(org->left.expr); 91 e->left.expr = expr_copy(org->left.expr);
92 e->right.expr = expr_copy(org->right.expr); 92 e->right.expr = expr_copy(org->right.expr);
93 break; 93 break;
@@ -217,7 +217,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
217 expr_free(e2); 217 expr_free(e2);
218 trans_count = old_count; 218 trans_count = old_count;
219 return res; 219 return res;
220 case E_CHOICE: 220 case E_LIST:
221 case E_RANGE: 221 case E_RANGE:
222 case E_NONE: 222 case E_NONE:
223 /* panic */; 223 /* panic */;
@@ -648,7 +648,7 @@ struct expr *expr_transform(struct expr *e)
648 case E_EQUAL: 648 case E_EQUAL:
649 case E_UNEQUAL: 649 case E_UNEQUAL:
650 case E_SYMBOL: 650 case E_SYMBOL:
651 case E_CHOICE: 651 case E_LIST:
652 break; 652 break;
653 default: 653 default:
654 e->left.expr = expr_transform(e->left.expr); 654 e->left.expr = expr_transform(e->left.expr);
@@ -932,7 +932,7 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
932 break; 932 break;
933 case E_SYMBOL: 933 case E_SYMBOL:
934 return expr_alloc_comp(type, e->left.sym, sym); 934 return expr_alloc_comp(type, e->left.sym, sym);
935 case E_CHOICE: 935 case E_LIST:
936 case E_RANGE: 936 case E_RANGE:
937 case E_NONE: 937 case E_NONE:
938 /* panic */; 938 /* panic */;
@@ -955,14 +955,14 @@ tristate expr_calc_value(struct expr *e)
955 case E_AND: 955 case E_AND:
956 val1 = expr_calc_value(e->left.expr); 956 val1 = expr_calc_value(e->left.expr);
957 val2 = expr_calc_value(e->right.expr); 957 val2 = expr_calc_value(e->right.expr);
958 return E_AND(val1, val2); 958 return EXPR_AND(val1, val2);
959 case E_OR: 959 case E_OR:
960 val1 = expr_calc_value(e->left.expr); 960 val1 = expr_calc_value(e->left.expr);
961 val2 = expr_calc_value(e->right.expr); 961 val2 = expr_calc_value(e->right.expr);
962 return E_OR(val1, val2); 962 return EXPR_OR(val1, val2);
963 case E_NOT: 963 case E_NOT:
964 val1 = expr_calc_value(e->left.expr); 964 val1 = expr_calc_value(e->left.expr);
965 return E_NOT(val1); 965 return EXPR_NOT(val1);
966 case E_EQUAL: 966 case E_EQUAL:
967 sym_calc_value(e->left.sym); 967 sym_calc_value(e->left.sym);
968 sym_calc_value(e->right.sym); 968 sym_calc_value(e->right.sym);
@@ -1000,9 +1000,9 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
1000 if (t2 == E_OR) 1000 if (t2 == E_OR)
1001 return 1; 1001 return 1;
1002 case E_OR: 1002 case E_OR:
1003 if (t2 == E_CHOICE) 1003 if (t2 == E_LIST)
1004 return 1; 1004 return 1;
1005 case E_CHOICE: 1005 case E_LIST:
1006 if (t2 == 0) 1006 if (t2 == 0)
1007 return 1; 1007 return 1;
1008 default: 1008 default:
@@ -1034,12 +1034,18 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1034 expr_print(e->left.expr, fn, data, E_NOT); 1034 expr_print(e->left.expr, fn, data, E_NOT);
1035 break; 1035 break;
1036 case E_EQUAL: 1036 case E_EQUAL:
1037 fn(data, e->left.sym, e->left.sym->name); 1037 if (e->left.sym->name)
1038 fn(data, e->left.sym, e->left.sym->name);
1039 else
1040 fn(data, NULL, "<choice>");
1038 fn(data, NULL, "="); 1041 fn(data, NULL, "=");
1039 fn(data, e->right.sym, e->right.sym->name); 1042 fn(data, e->right.sym, e->right.sym->name);
1040 break; 1043 break;
1041 case E_UNEQUAL: 1044 case E_UNEQUAL:
1042 fn(data, e->left.sym, e->left.sym->name); 1045 if (e->left.sym->name)
1046 fn(data, e->left.sym, e->left.sym->name);
1047 else
1048 fn(data, NULL, "<choice>");
1043 fn(data, NULL, "!="); 1049 fn(data, NULL, "!=");
1044 fn(data, e->right.sym, e->right.sym->name); 1050 fn(data, e->right.sym, e->right.sym->name);
1045 break; 1051 break;
@@ -1053,11 +1059,11 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
1053 fn(data, NULL, " && "); 1059 fn(data, NULL, " && ");
1054 expr_print(e->right.expr, fn, data, E_AND); 1060 expr_print(e->right.expr, fn, data, E_AND);
1055 break; 1061 break;
1056 case E_CHOICE: 1062 case E_LIST:
1057 fn(data, e->right.sym, e->right.sym->name); 1063 fn(data, e->right.sym, e->right.sym->name);
1058 if (e->left.expr) { 1064 if (e->left.expr) {
1059 fn(data, NULL, " ^ "); 1065 fn(data, NULL, " ^ ");
1060 expr_print(e->left.expr, fn, data, E_CHOICE); 1066 expr_print(e->left.expr, fn, data, E_LIST);
1061 } 1067 }
1062 break; 1068 break;
1063 case E_RANGE: 1069 case E_RANGE:
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index a195986eec6f..9d4cba1c001d 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -25,14 +25,13 @@ struct file {
25 25
26#define FILE_BUSY 0x0001 26#define FILE_BUSY 0x0001
27#define FILE_SCANNED 0x0002 27#define FILE_SCANNED 0x0002
28#define FILE_PRINTED 0x0004
29 28
30typedef enum tristate { 29typedef enum tristate {
31 no, mod, yes 30 no, mod, yes
32} tristate; 31} tristate;
33 32
34enum expr_type { 33enum expr_type {
35 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE 34 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
36}; 35};
37 36
38union expr_data { 37union expr_data {
@@ -45,9 +44,12 @@ struct expr {
45 union expr_data left, right; 44 union expr_data left, right;
46}; 45};
47 46
48#define E_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) 47#define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
49#define E_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) 48#define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
50#define E_NOT(dep) (2-(dep)) 49#define EXPR_NOT(dep) (2-(dep))
50
51#define expr_list_for_each_sym(l, e, s) \
52 for (e = (l); e && (s = e->right.sym); e = e->left.expr)
51 53
52struct expr_value { 54struct expr_value {
53 struct expr *expr; 55 struct expr *expr;
@@ -86,7 +88,6 @@ struct symbol {
86#define SYMBOL_CHECK 0x0008 88#define SYMBOL_CHECK 0x0008
87#define SYMBOL_CHOICE 0x0010 89#define SYMBOL_CHOICE 0x0010
88#define SYMBOL_CHOICEVAL 0x0020 90#define SYMBOL_CHOICEVAL 0x0020
89#define SYMBOL_PRINTED 0x0040
90#define SYMBOL_VALID 0x0080 91#define SYMBOL_VALID 0x0080
91#define SYMBOL_OPTIONAL 0x0100 92#define SYMBOL_OPTIONAL 0x0100
92#define SYMBOL_WRITE 0x0200 93#define SYMBOL_WRITE 0x0200
@@ -105,7 +106,8 @@ struct symbol {
105#define SYMBOL_HASHMASK 0xff 106#define SYMBOL_HASHMASK 0xff
106 107
107enum prop_type { 108enum prop_type {
108 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE 109 P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE,
110 P_SELECT, P_RANGE, P_ENV
109}; 111};
110 112
111struct property { 113struct property {
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index 262908cfc2ac..199b22bb49e2 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -119,8 +119,6 @@ const char *dbg_print_flags(int val)
119 strcat(buf, "choice/"); 119 strcat(buf, "choice/");
120 if (val & SYMBOL_CHOICEVAL) 120 if (val & SYMBOL_CHOICEVAL)
121 strcat(buf, "choiceval/"); 121 strcat(buf, "choiceval/");
122 if (val & SYMBOL_PRINTED)
123 strcat(buf, "printed/");
124 if (val & SYMBOL_VALID) 122 if (val & SYMBOL_VALID)
125 strcat(buf, "valid/"); 123 strcat(buf, "valid/");
126 if (val & SYMBOL_OPTIONAL) 124 if (val & SYMBOL_OPTIONAL)
@@ -457,14 +455,18 @@ static void text_insert_help(struct menu *menu)
457{ 455{
458 GtkTextBuffer *buffer; 456 GtkTextBuffer *buffer;
459 GtkTextIter start, end; 457 GtkTextIter start, end;
460 const char *prompt = menu_get_prompt(menu); 458 const char *prompt = _(menu_get_prompt(menu));
461 gchar *name; 459 gchar *name;
462 const char *help; 460 const char *help;
463 461
464 help = _(menu_get_help(menu)); 462 help = menu_get_help(menu);
463
464 /* Gettextize if the help text not empty */
465 if ((help != 0) && (help[0] != 0))
466 help = _(help);
465 467
466 if (menu->sym && menu->sym->name) 468 if (menu->sym && menu->sym->name)
467 name = g_strdup_printf(_(menu->sym->name)); 469 name = g_strdup_printf(menu->sym->name);
468 else 470 else
469 name = g_strdup(""); 471 name = g_strdup("");
470 472
@@ -1171,7 +1173,7 @@ static gchar **fill_row(struct menu *menu)
1171 bzero(row, sizeof(row)); 1173 bzero(row, sizeof(row));
1172 1174
1173 row[COL_OPTION] = 1175 row[COL_OPTION] =
1174 g_strdup_printf("%s %s", menu_get_prompt(menu), 1176 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1175 sym && sym_has_value(sym) ? "(NEW)" : ""); 1177 sym && sym_has_value(sym) ? "(NEW)" : "");
1176 1178
1177 if (show_all && !menu_is_visible(menu)) 1179 if (show_all && !menu_is_visible(menu))
@@ -1221,7 +1223,7 @@ static gchar **fill_row(struct menu *menu)
1221 1223
1222 if (def_menu) 1224 if (def_menu)
1223 row[COL_VALUE] = 1225 row[COL_VALUE] =
1224 g_strdup(menu_get_prompt(def_menu)); 1226 g_strdup(_(menu_get_prompt(def_menu)));
1225 } 1227 }
1226 if (sym->flags & SYMBOL_CHOICEVAL) 1228 if (sym->flags & SYMBOL_CHOICEVAL)
1227 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); 1229 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index a065d5a57c01..bed0f4e2d2f7 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -1275,6 +1275,11 @@ YY_RULE_SETUP
1275case 32: 1275case 32:
1276YY_RULE_SETUP 1276YY_RULE_SETUP
1277{ 1277{
1278 while (zconfleng) {
1279 if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
1280 break;
1281 zconfleng--;
1282 }
1278 append_string(zconftext, zconfleng); 1283 append_string(zconftext, zconfleng);
1279 if (!first_ts) 1284 if (!first_ts)
1280 first_ts = last_ts; 1285 first_ts = last_ts;
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 8a07ee4f6bd4..4bc68f20a73c 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -44,6 +44,7 @@ extern "C" {
44 44
45#define T_OPT_MODULES 1 45#define T_OPT_MODULES 1
46#define T_OPT_DEFCONFIG_LIST 2 46#define T_OPT_DEFCONFIG_LIST 2
47#define T_OPT_ENV 3
47 48
48struct kconf_id { 49struct kconf_id {
49 int name; 50 int name;
@@ -74,6 +75,7 @@ void kconfig_load(void);
74 75
75/* menu.c */ 76/* menu.c */
76void menu_init(void); 77void menu_init(void);
78void menu_warn(struct menu *menu, const char *fmt, ...);
77struct menu *menu_add_menu(void); 79struct menu *menu_add_menu(void);
78void menu_end_menu(void); 80void menu_end_menu(void);
79void menu_add_entry(struct symbol *sym); 81void menu_add_entry(struct symbol *sym);
@@ -103,6 +105,8 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
103const char *str_get(struct gstr *gs); 105const char *str_get(struct gstr *gs);
104 106
105/* symbol.c */ 107/* symbol.c */
108extern struct expr *sym_env_list;
109
106void sym_init(void); 110void sym_init(void);
107void sym_clear_all_valid(void); 111void sym_clear_all_valid(void);
108void sym_set_all_changed(void); 112void sym_set_all_changed(void);
@@ -110,6 +114,7 @@ void sym_set_changed(struct symbol *sym);
110struct symbol *sym_check_deps(struct symbol *sym); 114struct symbol *sym_check_deps(struct symbol *sym);
111struct property *prop_alloc(enum prop_type type, struct symbol *sym); 115struct property *prop_alloc(enum prop_type type, struct symbol *sym);
112struct symbol *prop_get_symbol(struct property *prop); 116struct symbol *prop_get_symbol(struct property *prop);
117struct property *sym_get_env_prop(struct symbol *sym);
113 118
114static inline tristate sym_get_tristate_value(struct symbol *sym) 119static inline tristate sym_get_tristate_value(struct symbol *sym)
115{ 120{
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 9681476b96e7..62e1e02126e6 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -36,14 +36,16 @@ trap "rm -f $tmp" 0 1 2 3 15
36 36
37# Check if we can link to ncurses 37# Check if we can link to ncurses
38check() { 38check() {
39 echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null 39 echo -e " #include CURSES_LOC \n main() {}" |
40 $cc -xc - -o $tmp 2> /dev/null
40 if [ $? != 0 ]; then 41 if [ $? != 0 ]; then
41 echo " *** Unable to find the ncurses libraries." 1>&2 42 echo " *** Unable to find the ncurses libraries or the" 1>&2
42 echo " *** make menuconfig require the ncurses libraries" 1>&2 43 echo " *** required header files." 1>&2
43 echo " *** " 1>&2 44 echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
44 echo " *** Install ncurses (ncurses-devel) and try again" 1>&2 45 echo " *** " 1>&2
45 echo " *** " 1>&2 46 echo " *** Install ncurses (ncurses-devel) and try again." 1>&2
46 exit 1 47 echo " *** " 1>&2
48 exit 1
47 fi 49 fi
48} 50}
49 51
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index cf697080dddd..b2a878c936d6 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -97,8 +97,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
97 int x = width / 2 - 11; 97 int x = width / 2 - 11;
98 int y = height - 2; 98 int y = height - 2;
99 99
100 print_button(dialog, "Select", y, x, selected == 0); 100 print_button(dialog, gettext("Select"), y, x, selected == 0);
101 print_button(dialog, " Help ", y, x + 14, selected == 1); 101 print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
102 102
103 wmove(dialog, y, x + 1 + 14 * selected); 103 wmove(dialog, y, x + 1 + 14 * selected);
104 wrefresh(dialog); 104 wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 7e17eba75ae8..b5211fce0d94 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -26,6 +26,12 @@
26#include <string.h> 26#include <string.h>
27#include <stdbool.h> 27#include <stdbool.h>
28 28
29#ifndef KBUILD_NO_NLS
30# include <libintl.h>
31#else
32# define gettext(Msgid) ((const char *) (Msgid))
33#endif
34
29#ifdef __sun__ 35#ifdef __sun__
30#define CURS_MACROS 36#define CURS_MACROS
31#endif 37#endif
@@ -187,10 +193,9 @@ int item_is_tag(char tag);
187int on_key_esc(WINDOW *win); 193int on_key_esc(WINDOW *win);
188int on_key_resize(void); 194int on_key_resize(void);
189 195
190void init_dialog(const char *backtitle); 196int init_dialog(const char *backtitle);
191void set_dialog_backtitle(const char *backtitle); 197void set_dialog_backtitle(const char *backtitle);
192void reset_dialog(void); 198void end_dialog(int x, int y);
193void end_dialog(void);
194void attr_clear(WINDOW * win, int height, int width, chtype attr); 199void attr_clear(WINDOW * win, int height, int width, chtype attr);
195void dialog_clear(void); 200void dialog_clear(void);
196void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); 201void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
index 05e72066b359..4946bd02b46d 100644
--- a/scripts/kconfig/lxdialog/inputbox.c
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
31 int x = width / 2 - 11; 31 int x = width / 2 - 11;
32 int y = height - 2; 32 int y = height - 2;
33 33
34 print_button(dialog, " Ok ", y, x, selected == 0); 34 print_button(dialog, gettext(" Ok "), y, x, selected == 0);
35 print_button(dialog, " Help ", y, x + 14, selected == 1); 35 print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
36 36
37 wmove(dialog, y, x + 1 + 14 * selected); 37 wmove(dialog, y, x + 1 + 14 * selected);
38 wrefresh(dialog); 38 wrefresh(dialog);
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index 0d83159d9012..fa9d633f293c 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -157,9 +157,9 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
157 int x = width / 2 - 16; 157 int x = width / 2 - 16;
158 int y = height - 2; 158 int y = height - 2;
159 159
160 print_button(win, "Select", y, x, selected == 0); 160 print_button(win, gettext("Select"), y, x, selected == 0);
161 print_button(win, " Exit ", y, x + 12, selected == 1); 161 print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
162 print_button(win, " Help ", y, x + 24, selected == 2); 162 print_button(win, gettext(" Help "), y, x + 24, selected == 2);
163 163
164 wmove(win, y, x + 1 + 12 * selected); 164 wmove(win, y, x + 1 + 12 * selected);
165 wrefresh(win); 165 wrefresh(win);
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index fabfc1ad789d..c704712d0227 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -114,7 +114,7 @@ do_resize:
114 114
115 print_title(dialog, title, width); 115 print_title(dialog, title, width);
116 116
117 print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE); 117 print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
118 wnoutrefresh(dialog); 118 wnoutrefresh(dialog);
119 getyx(dialog, cur_y, cur_x); /* Save cursor position */ 119 getyx(dialog, cur_y, cur_x); /* Save cursor position */
120 120
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index a1bddefe73d0..86d95cca46a7 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -266,31 +266,41 @@ void dialog_clear(void)
266/* 266/*
267 * Do some initialization for dialog 267 * Do some initialization for dialog
268 */ 268 */
269void init_dialog(const char *backtitle) 269int init_dialog(const char *backtitle)
270{ 270{
271 dlg.backtitle = backtitle; 271 int height, width;
272 color_setup(getenv("MENUCONFIG_COLOR")); 272
273} 273 initscr(); /* Init curses */
274 getmaxyx(stdscr, height, width);
275 if (height < 19 || width < 80) {
276 endwin();
277 return -ERRDISPLAYTOOSMALL;
278 }
274 279
275void set_dialog_backtitle(const char *backtitle)
276{
277 dlg.backtitle = backtitle; 280 dlg.backtitle = backtitle;
278} 281 color_setup(getenv("MENUCONFIG_COLOR"));
279 282
280void reset_dialog(void)
281{
282 initscr(); /* Init curses */
283 keypad(stdscr, TRUE); 283 keypad(stdscr, TRUE);
284 cbreak(); 284 cbreak();
285 noecho(); 285 noecho();
286 dialog_clear(); 286 dialog_clear();
287
288 return 0;
289}
290
291void set_dialog_backtitle(const char *backtitle)
292{
293 dlg.backtitle = backtitle;
287} 294}
288 295
289/* 296/*
290 * End using dialog functions. 297 * End using dialog functions.
291 */ 298 */
292void end_dialog(void) 299void end_dialog(int x, int y)
293{ 300{
301 /* move cursor back to original position */
302 move(y, x);
303 refresh();
294 endwin(); 304 endwin();
295} 305}
296 306
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index ee0a04e3e012..4e6e8090c20b 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
29 int x = width / 2 - 10; 29 int x = width / 2 - 10;
30 int y = height - 2; 30 int y = height - 2;
31 31
32 print_button(dialog, " Yes ", y, x, selected == 0); 32 print_button(dialog, gettext(" Yes "), y, x, selected == 0);
33 print_button(dialog, " No ", y, x + 13, selected == 1); 33 print_button(dialog, gettext(" No "), y, x + 13, selected == 1);
34 34
35 wmove(dialog, y, x + 1 + 13 * selected); 35 wmove(dialog, y, x + 1 + 13 * selected);
36 wrefresh(dialog); 36 wrefresh(dialog);
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 47e226fdedd7..50e61c411bc0 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -8,17 +8,13 @@
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br> 8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 */ 9 */
10 10
11#include <sys/ioctl.h>
12#include <sys/wait.h>
13#include <ctype.h> 11#include <ctype.h>
14#include <errno.h> 12#include <errno.h>
15#include <fcntl.h> 13#include <fcntl.h>
16#include <limits.h> 14#include <limits.h>
17#include <signal.h>
18#include <stdarg.h> 15#include <stdarg.h>
19#include <stdlib.h> 16#include <stdlib.h>
20#include <string.h> 17#include <string.h>
21#include <termios.h>
22#include <unistd.h> 18#include <unistd.h>
23#include <locale.h> 19#include <locale.h>
24 20
@@ -275,8 +271,6 @@ search_help[] = N_(
275 "\n"); 271 "\n");
276 272
277static int indent; 273static int indent;
278static struct termios ios_org;
279static int rows = 0, cols = 0;
280static struct menu *current_menu; 274static struct menu *current_menu;
281static int child_count; 275static int child_count;
282static int single_menu_mode; 276static int single_menu_mode;
@@ -290,51 +284,16 @@ static void show_textbox(const char *title, const char *text, int r, int c);
290static void show_helptext(const char *title, const char *text); 284static void show_helptext(const char *title, const char *text);
291static void show_help(struct menu *menu); 285static void show_help(struct menu *menu);
292 286
293static void init_wsize(void)
294{
295 struct winsize ws;
296 char *env;
297
298 if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
299 rows = ws.ws_row;
300 cols = ws.ws_col;
301 }
302
303 if (!rows) {
304 env = getenv("LINES");
305 if (env)
306 rows = atoi(env);
307 if (!rows)
308 rows = 24;
309 }
310 if (!cols) {
311 env = getenv("COLUMNS");
312 if (env)
313 cols = atoi(env);
314 if (!cols)
315 cols = 80;
316 }
317
318 if (rows < 19 || cols < 80) {
319 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
320 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
321 exit(1);
322 }
323
324 rows -= 4;
325 cols -= 5;
326}
327
328static void get_prompt_str(struct gstr *r, struct property *prop) 287static void get_prompt_str(struct gstr *r, struct property *prop)
329{ 288{
330 int i, j; 289 int i, j;
331 struct menu *submenu[8], *menu; 290 struct menu *submenu[8], *menu;
332 291
333 str_printf(r, "Prompt: %s\n", prop->text); 292 str_printf(r, _("Prompt: %s\n"), _(prop->text));
334 str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, 293 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
335 prop->menu->lineno); 294 prop->menu->lineno);
336 if (!expr_is_yes(prop->visible.expr)) { 295 if (!expr_is_yes(prop->visible.expr)) {
337 str_append(r, " Depends on: "); 296 str_append(r, _(" Depends on: "));
338 expr_gstr_print(prop->visible.expr, r); 297 expr_gstr_print(prop->visible.expr, r);
339 str_append(r, "\n"); 298 str_append(r, "\n");
340 } 299 }
@@ -342,13 +301,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
342 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) 301 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
343 submenu[i++] = menu; 302 submenu[i++] = menu;
344 if (i > 0) { 303 if (i > 0) {
345 str_printf(r, " Location:\n"); 304 str_printf(r, _(" Location:\n"));
346 for (j = 4; --i >= 0; j += 2) { 305 for (j = 4; --i >= 0; j += 2) {
347 menu = submenu[i]; 306 menu = submenu[i];
348 str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu)); 307 str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
349 if (menu->sym) { 308 if (menu->sym) {
350 str_printf(r, " (%s [=%s])", menu->sym->name ? 309 str_printf(r, " (%s [=%s])", menu->sym->name ?
351 menu->sym->name : "<choice>", 310 menu->sym->name : _("<choice>"),
352 sym_get_string_value(menu->sym)); 311 sym_get_string_value(menu->sym));
353 } 312 }
354 str_append(r, "\n"); 313 str_append(r, "\n");
@@ -378,7 +337,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
378 if (hit) 337 if (hit)
379 str_append(r, "\n"); 338 str_append(r, "\n");
380 if (sym->rev_dep.expr) { 339 if (sym->rev_dep.expr) {
381 str_append(r, " Selected by: "); 340 str_append(r, _(" Selected by: "));
382 expr_gstr_print(sym->rev_dep.expr, r); 341 expr_gstr_print(sym->rev_dep.expr, r);
383 str_append(r, "\n"); 342 str_append(r, "\n");
384 } 343 }
@@ -394,7 +353,7 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
394 for (i = 0; sym_arr && (sym = sym_arr[i]); i++) 353 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
395 get_symbol_str(&res, sym); 354 get_symbol_str(&res, sym);
396 if (!i) 355 if (!i)
397 str_append(&res, "No matches found.\n"); 356 str_append(&res, _("No matches found.\n"));
398 return res; 357 return res;
399} 358}
400 359
@@ -474,6 +433,7 @@ static void build_conf(struct menu *menu)
474 switch (prop->type) { 433 switch (prop->type) {
475 case P_MENU: 434 case P_MENU:
476 child_count++; 435 child_count++;
436 prompt = _(prompt);
477 if (single_menu_mode) { 437 if (single_menu_mode) {
478 item_make("%s%*c%s", 438 item_make("%s%*c%s",
479 menu->data ? "-->" : "++>", 439 menu->data ? "-->" : "++>",
@@ -489,7 +449,7 @@ static void build_conf(struct menu *menu)
489 case P_COMMENT: 449 case P_COMMENT:
490 if (prompt) { 450 if (prompt) {
491 child_count++; 451 child_count++;
492 item_make(" %*c*** %s ***", indent + 1, ' ', prompt); 452 item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
493 item_set_tag(':'); 453 item_set_tag(':');
494 item_set_data(menu); 454 item_set_data(menu);
495 } 455 }
@@ -497,7 +457,7 @@ static void build_conf(struct menu *menu)
497 default: 457 default:
498 if (prompt) { 458 if (prompt) {
499 child_count++; 459 child_count++;
500 item_make("---%*c%s", indent + 1, ' ', prompt); 460 item_make("---%*c%s", indent + 1, ' ', _(prompt));
501 item_set_tag(':'); 461 item_set_tag(':');
502 item_set_data(menu); 462 item_set_data(menu);
503 } 463 }
@@ -541,10 +501,10 @@ static void build_conf(struct menu *menu)
541 item_set_data(menu); 501 item_set_data(menu);
542 } 502 }
543 503
544 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 504 item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
545 if (val == yes) { 505 if (val == yes) {
546 if (def_menu) { 506 if (def_menu) {
547 item_add_str(" (%s)", menu_get_prompt(def_menu)); 507 item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
548 item_add_str(" --->"); 508 item_add_str(" --->");
549 if (def_menu->list) { 509 if (def_menu->list) {
550 indent += 2; 510 indent += 2;
@@ -556,7 +516,7 @@ static void build_conf(struct menu *menu)
556 } 516 }
557 } else { 517 } else {
558 if (menu == current_menu) { 518 if (menu == current_menu) {
559 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 519 item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
560 item_set_tag(':'); 520 item_set_tag(':');
561 item_set_data(menu); 521 item_set_data(menu);
562 goto conf_childs; 522 goto conf_childs;
@@ -599,17 +559,17 @@ static void build_conf(struct menu *menu)
599 tmp = indent - tmp + 4; 559 tmp = indent - tmp + 4;
600 if (tmp < 0) 560 if (tmp < 0)
601 tmp = 0; 561 tmp = 0;
602 item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), 562 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
603 (sym_has_value(sym) || !sym_is_changable(sym)) ? 563 (sym_has_value(sym) || !sym_is_changable(sym)) ?
604 "" : " (NEW)"); 564 "" : _(" (NEW)"));
605 item_set_tag('s'); 565 item_set_tag('s');
606 item_set_data(menu); 566 item_set_data(menu);
607 goto conf_childs; 567 goto conf_childs;
608 } 568 }
609 } 569 }
610 item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), 570 item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
611 (sym_has_value(sym) || !sym_is_changable(sym)) ? 571 (sym_has_value(sym) || !sym_is_changable(sym)) ?
612 "" : " (NEW)"); 572 "" : _(" (NEW)"));
613 if (menu->prompt->type == P_MENU) { 573 if (menu->prompt->type == P_MENU) {
614 item_add_str(" --->"); 574 item_add_str(" --->");
615 return; 575 return;
@@ -647,7 +607,7 @@ static void conf(struct menu *menu)
647 item_set_tag('S'); 607 item_set_tag('S');
648 } 608 }
649 dialog_clear(); 609 dialog_clear();
650 res = dialog_menu(prompt ? prompt : _("Main Menu"), 610 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
651 _(menu_instructions), 611 _(menu_instructions),
652 active_menu, &s_scroll); 612 active_menu, &s_scroll);
653 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) 613 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
@@ -694,7 +654,7 @@ static void conf(struct menu *menu)
694 if (sym) 654 if (sym)
695 show_help(submenu); 655 show_help(submenu);
696 else 656 else
697 show_helptext("README", _(mconf_readme)); 657 show_helptext(_("README"), _(mconf_readme));
698 break; 658 break;
699 case 3: 659 case 3:
700 if (item_is_tag('t')) { 660 if (item_is_tag('t')) {
@@ -752,13 +712,13 @@ static void show_help(struct menu *menu)
752 str_append(&help, nohelp_text); 712 str_append(&help, nohelp_text);
753 } 713 }
754 get_symbol_str(&help, sym); 714 get_symbol_str(&help, sym);
755 show_helptext(menu_get_prompt(menu), str_get(&help)); 715 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
756 str_free(&help); 716 str_free(&help);
757} 717}
758 718
759static void conf_choice(struct menu *menu) 719static void conf_choice(struct menu *menu)
760{ 720{
761 const char *prompt = menu_get_prompt(menu); 721 const char *prompt = _(menu_get_prompt(menu));
762 struct menu *child; 722 struct menu *child;
763 struct symbol *active; 723 struct symbol *active;
764 724
@@ -772,7 +732,7 @@ static void conf_choice(struct menu *menu)
772 for (child = menu->list; child; child = child->next) { 732 for (child = menu->list; child; child = child->next) {
773 if (!menu_is_visible(child)) 733 if (!menu_is_visible(child))
774 continue; 734 continue;
775 item_make("%s", menu_get_prompt(child)); 735 item_make("%s", _(menu_get_prompt(child)));
776 item_set_data(child); 736 item_set_data(child);
777 if (child->sym == active) 737 if (child->sym == active)
778 item_set_selected(1); 738 item_set_selected(1);
@@ -780,7 +740,7 @@ static void conf_choice(struct menu *menu)
780 item_set_tag('X'); 740 item_set_tag('X');
781 } 741 }
782 dialog_clear(); 742 dialog_clear();
783 res = dialog_checklist(prompt ? prompt : _("Main Menu"), 743 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
784 _(radiolist_instructions), 744 _(radiolist_instructions),
785 15, 70, 6); 745 15, 70, 6);
786 selected = item_activate_selected(); 746 selected = item_activate_selected();
@@ -826,10 +786,10 @@ static void conf_string(struct menu *menu)
826 heading = _(inputbox_instructions_string); 786 heading = _(inputbox_instructions_string);
827 break; 787 break;
828 default: 788 default:
829 heading = "Internal mconf error!"; 789 heading = _("Internal mconf error!");
830 } 790 }
831 dialog_clear(); 791 dialog_clear();
832 res = dialog_inputbox(prompt ? prompt : _("Main Menu"), 792 res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
833 heading, 10, 75, 793 heading, 10, 75,
834 sym_get_string_value(menu->sym)); 794 sym_get_string_value(menu->sym));
835 switch (res) { 795 switch (res) {
@@ -900,13 +860,9 @@ static void conf_save(void)
900 } 860 }
901} 861}
902 862
903static void conf_cleanup(void)
904{
905 tcsetattr(1, TCSAFLUSH, &ios_org);
906}
907
908int main(int ac, char **av) 863int main(int ac, char **av)
909{ 864{
865 int saved_x, saved_y;
910 char *mode; 866 char *mode;
911 int res; 867 int res;
912 868
@@ -923,11 +879,13 @@ int main(int ac, char **av)
923 single_menu_mode = 1; 879 single_menu_mode = 1;
924 } 880 }
925 881
926 tcgetattr(1, &ios_org); 882 getyx(stdscr, saved_y, saved_x);
927 atexit(conf_cleanup); 883 if (init_dialog(NULL)) {
928 init_wsize(); 884 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
929 reset_dialog(); 885 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
930 init_dialog(NULL); 886 return 1;
887 }
888
931 set_config_filename(conf_get_configname()); 889 set_config_filename(conf_get_configname());
932 do { 890 do {
933 conf(&rootmenu); 891 conf(&rootmenu);
@@ -941,7 +899,7 @@ int main(int ac, char **av)
941 else 899 else
942 res = -1; 900 res = -1;
943 } while (res == KEY_ESC); 901 } while (res == KEY_ESC);
944 end_dialog(); 902 end_dialog(saved_x, saved_y);
945 903
946 switch (res) { 904 switch (res) {
947 case 0: 905 case 0:
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index f9d0d91a3fe4..fdad17367f61 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -15,7 +15,7 @@ static struct menu **last_entry_ptr;
15struct file *file_list; 15struct file *file_list;
16struct file *current_file; 16struct file *current_file;
17 17
18static void menu_warn(struct menu *menu, const char *fmt, ...) 18void menu_warn(struct menu *menu, const char *fmt, ...)
19{ 19{
20 va_list ap; 20 va_list ap;
21 va_start(ap, fmt); 21 va_start(ap, fmt);
@@ -172,6 +172,9 @@ void menu_add_option(int token, char *arg)
172 else if (sym_defconfig_list != current_entry->sym) 172 else if (sym_defconfig_list != current_entry->sym)
173 zconf_error("trying to redefine defconfig symbol"); 173 zconf_error("trying to redefine defconfig symbol");
174 break; 174 break;
175 case T_OPT_ENV:
176 prop_add_env(arg);
177 break;
175 } 178 }
176} 179}
177 180
@@ -239,9 +242,11 @@ void menu_finalize(struct menu *parent)
239 for (menu = parent->list; menu; menu = menu->next) { 242 for (menu = parent->list; menu; menu = menu->next) {
240 if (menu->sym) { 243 if (menu->sym) {
241 current_entry = parent; 244 current_entry = parent;
242 menu_set_type(menu->sym->type); 245 if (sym->type == S_UNKNOWN)
246 menu_set_type(menu->sym->type);
243 current_entry = menu; 247 current_entry = menu;
244 menu_set_type(sym->type); 248 if (menu->sym->type == S_UNKNOWN)
249 menu_set_type(sym->type);
245 break; 250 break;
246 } 251 }
247 } 252 }
@@ -326,12 +331,42 @@ void menu_finalize(struct menu *parent)
326 "values not supported"); 331 "values not supported");
327 } 332 }
328 current_entry = menu; 333 current_entry = menu;
329 menu_set_type(sym->type); 334 if (menu->sym->type == S_UNKNOWN)
335 menu_set_type(sym->type);
336 /* Non-tristate choice values of tristate choices must
337 * depend on the choice being set to Y. The choice
338 * values' dependencies were propagated to their
339 * properties above, so the change here must be re-
340 * propagated. */
341 if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
342 basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
343 basedep = expr_alloc_and(basedep, menu->dep);
344 basedep = expr_eliminate_dups(basedep);
345 menu->dep = basedep;
346 for (prop = menu->sym->prop; prop; prop = prop->next) {
347 if (prop->menu != menu)
348 continue;
349 dep = expr_alloc_and(expr_copy(basedep),
350 prop->visible.expr);
351 dep = expr_eliminate_dups(dep);
352 dep = expr_trans_bool(dep);
353 prop->visible.expr = dep;
354 if (prop->type == P_SELECT) {
355 struct symbol *es = prop_get_symbol(prop);
356 dep2 = expr_alloc_symbol(menu->sym);
357 dep = expr_alloc_and(dep2,
358 expr_copy(dep));
359 dep = expr_alloc_or(es->rev_dep.expr, dep);
360 dep = expr_eliminate_dups(dep);
361 es->rev_dep.expr = dep;
362 }
363 }
364 }
330 menu_add_symbol(P_CHOICE, sym, NULL); 365 menu_add_symbol(P_CHOICE, sym, NULL);
331 prop = sym_get_choice_prop(sym); 366 prop = sym_get_choice_prop(sym);
332 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) 367 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
333 ; 368 ;
334 *ep = expr_alloc_one(E_CHOICE, NULL); 369 *ep = expr_alloc_one(E_LIST, NULL);
335 (*ep)->right.sym = menu->sym; 370 (*ep)->right.sym = menu->sym;
336 } 371 }
337 if (menu->list && (!menu->prompt || !menu->prompt->text)) { 372 if (menu->list && (!menu->prompt || !menu->prompt->text)) {
@@ -394,9 +429,9 @@ bool menu_is_visible(struct menu *menu)
394const char *menu_get_prompt(struct menu *menu) 429const char *menu_get_prompt(struct menu *menu)
395{ 430{
396 if (menu->prompt) 431 if (menu->prompt)
397 return _(menu->prompt->text); 432 return menu->prompt->text;
398 else if (menu->sym) 433 else if (menu->sym)
399 return _(menu->sym->name); 434 return menu->sym->name;
400 return NULL; 435 return NULL;
401} 436}
402 437
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index b9bb32dfd628..5d0fd38b089b 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -114,7 +114,7 @@ void ConfigItem::updateMenu(void)
114 114
115 sym = menu->sym; 115 sym = menu->sym;
116 prop = menu->prompt; 116 prop = menu->prompt;
117 prompt = QString::fromLocal8Bit(menu_get_prompt(menu)); 117 prompt = _(menu_get_prompt(menu));
118 118
119 if (prop) switch (prop->type) { 119 if (prop) switch (prop->type) {
120 case P_MENU: 120 case P_MENU:
@@ -208,7 +208,7 @@ void ConfigItem::updateMenu(void)
208 break; 208 break;
209 } 209 }
210 if (!sym_has_value(sym) && visible) 210 if (!sym_has_value(sym) && visible)
211 prompt += " (NEW)"; 211 prompt += _(" (NEW)");
212set_prompt: 212set_prompt:
213 setText(promptColIdx, prompt); 213 setText(promptColIdx, prompt);
214} 214}
@@ -346,7 +346,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
346 346
347 for (i = 0; i < colNr; i++) 347 for (i = 0; i < colNr; i++)
348 colMap[i] = colRevMap[i] = -1; 348 colMap[i] = colRevMap[i] = -1;
349 addColumn(promptColIdx, "Option"); 349 addColumn(promptColIdx, _("Option"));
350 350
351 reinit(); 351 reinit();
352} 352}
@@ -360,14 +360,14 @@ void ConfigList::reinit(void)
360 removeColumn(nameColIdx); 360 removeColumn(nameColIdx);
361 361
362 if (showName) 362 if (showName)
363 addColumn(nameColIdx, "Name"); 363 addColumn(nameColIdx, _("Name"));
364 if (showRange) { 364 if (showRange) {
365 addColumn(noColIdx, "N"); 365 addColumn(noColIdx, "N");
366 addColumn(modColIdx, "M"); 366 addColumn(modColIdx, "M");
367 addColumn(yesColIdx, "Y"); 367 addColumn(yesColIdx, "Y");
368 } 368 }
369 if (showData) 369 if (showData)
370 addColumn(dataColIdx, "Value"); 370 addColumn(dataColIdx, _("Value"));
371 371
372 updateListAll(); 372 updateListAll();
373} 373}
@@ -803,7 +803,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
803 QAction *action; 803 QAction *action;
804 804
805 headerPopup = new QPopupMenu(this); 805 headerPopup = new QPopupMenu(this);
806 action = new QAction(NULL, "Show Name", 0, this); 806 action = new QAction(NULL, _("Show Name"), 0, this);
807 action->setToggleAction(TRUE); 807 action->setToggleAction(TRUE);
808 connect(action, SIGNAL(toggled(bool)), 808 connect(action, SIGNAL(toggled(bool)),
809 parent(), SLOT(setShowName(bool))); 809 parent(), SLOT(setShowName(bool)));
@@ -811,7 +811,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
811 action, SLOT(setOn(bool))); 811 action, SLOT(setOn(bool)));
812 action->setOn(showName); 812 action->setOn(showName);
813 action->addTo(headerPopup); 813 action->addTo(headerPopup);
814 action = new QAction(NULL, "Show Range", 0, this); 814 action = new QAction(NULL, _("Show Range"), 0, this);
815 action->setToggleAction(TRUE); 815 action->setToggleAction(TRUE);
816 connect(action, SIGNAL(toggled(bool)), 816 connect(action, SIGNAL(toggled(bool)),
817 parent(), SLOT(setShowRange(bool))); 817 parent(), SLOT(setShowRange(bool)));
@@ -819,7 +819,7 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
819 action, SLOT(setOn(bool))); 819 action, SLOT(setOn(bool)));
820 action->setOn(showRange); 820 action->setOn(showRange);
821 action->addTo(headerPopup); 821 action->addTo(headerPopup);
822 action = new QAction(NULL, "Show Data", 0, this); 822 action = new QAction(NULL, _("Show Data"), 0, this);
823 action->setToggleAction(TRUE); 823 action->setToggleAction(TRUE);
824 connect(action, SIGNAL(toggled(bool)), 824 connect(action, SIGNAL(toggled(bool)),
825 parent(), SLOT(setShowData(bool))); 825 parent(), SLOT(setShowData(bool)));
@@ -1041,7 +1041,12 @@ void ConfigInfoView::menuInfo(void)
1041 if (showDebug()) 1041 if (showDebug())
1042 debug = debug_info(sym); 1042 debug = debug_info(sym);
1043 1043
1044 help = print_filter(_(menu_get_help(menu))); 1044 help = menu_get_help(menu);
1045 /* Gettextize if the help text not empty */
1046 if (help.isEmpty())
1047 help = print_filter(menu_get_help(menu));
1048 else
1049 help = print_filter(_(menu_get_help(menu)));
1045 } else if (menu->prompt) { 1050 } else if (menu->prompt) {
1046 head += "<big><b>"; 1051 head += "<big><b>";
1047 head += print_filter(_(menu->prompt->text)); 1052 head += print_filter(_(menu->prompt->text));
@@ -1083,7 +1088,11 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
1083 debug += "</a><br>"; 1088 debug += "</a><br>";
1084 break; 1089 break;
1085 case P_DEFAULT: 1090 case P_DEFAULT:
1086 debug += "default: "; 1091 case P_SELECT:
1092 case P_RANGE:
1093 case P_ENV:
1094 debug += prop_get_type_name(prop->type);
1095 debug += ": ";
1087 expr_print(prop->expr, expr_print_help, &debug, E_NONE); 1096 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1088 debug += "<br>"; 1097 debug += "<br>";
1089 break; 1098 break;
@@ -1094,16 +1103,6 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
1094 debug += "<br>"; 1103 debug += "<br>";
1095 } 1104 }
1096 break; 1105 break;
1097 case P_SELECT:
1098 debug += "select: ";
1099 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1100 debug += "<br>";
1101 break;
1102 case P_RANGE:
1103 debug += "range: ";
1104 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1105 debug += "<br>";
1106 break;
1107 default: 1106 default:
1108 debug += "unknown property: "; 1107 debug += "unknown property: ";
1109 debug += prop_get_type_name(prop->type); 1108 debug += prop_get_type_name(prop->type);
@@ -1167,7 +1166,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
1167QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos) 1166QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1168{ 1167{
1169 QPopupMenu* popup = Parent::createPopupMenu(pos); 1168 QPopupMenu* popup = Parent::createPopupMenu(pos);
1170 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup); 1169 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
1171 action->setToggleAction(TRUE); 1170 action->setToggleAction(TRUE);
1172 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); 1171 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1173 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool))); 1172 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
@@ -1189,11 +1188,11 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
1189 1188
1190 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6); 1189 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1191 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6); 1190 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1192 layout2->addWidget(new QLabel("Find:", this)); 1191 layout2->addWidget(new QLabel(_("Find:"), this));
1193 editField = new QLineEdit(this); 1192 editField = new QLineEdit(this);
1194 connect(editField, SIGNAL(returnPressed()), SLOT(search())); 1193 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1195 layout2->addWidget(editField); 1194 layout2->addWidget(editField);
1196 searchButton = new QPushButton("Search", this); 1195 searchButton = new QPushButton(_("Search"), this);
1197 searchButton->setAutoDefault(FALSE); 1196 searchButton->setAutoDefault(FALSE);
1198 connect(searchButton, SIGNAL(clicked()), SLOT(search())); 1197 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1199 layout2->addWidget(searchButton); 1198 layout2->addWidget(searchButton);
@@ -1313,58 +1312,58 @@ ConfigMainWindow::ConfigMainWindow(void)
1313 menu = menuBar(); 1312 menu = menuBar();
1314 toolBar = new QToolBar("Tools", this); 1313 toolBar = new QToolBar("Tools", this);
1315 1314
1316 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this); 1315 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
1317 connect(backAction, SIGNAL(activated()), SLOT(goBack())); 1316 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1318 backAction->setEnabled(FALSE); 1317 backAction->setEnabled(FALSE);
1319 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this); 1318 QAction *quitAction = new QAction("Quit", _("&Quit"), CTRL+Key_Q, this);
1320 connect(quitAction, SIGNAL(activated()), SLOT(close())); 1319 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1321 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this); 1320 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), CTRL+Key_L, this);
1322 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); 1321 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1323 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this); 1322 saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), CTRL+Key_S, this);
1324 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); 1323 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1325 conf_set_changed_callback(conf_changed); 1324 conf_set_changed_callback(conf_changed);
1326 // Set saveAction's initial state 1325 // Set saveAction's initial state
1327 conf_changed(); 1326 conf_changed();
1328 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); 1327 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
1329 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); 1328 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1330 QAction *searchAction = new QAction("Find", "&Find", CTRL+Key_F, this); 1329 QAction *searchAction = new QAction("Find", _("&Find"), CTRL+Key_F, this);
1331 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig())); 1330 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1332 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); 1331 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1333 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); 1332 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1334 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); 1333 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1335 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); 1334 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1336 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this); 1335 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1337 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); 1336 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1338 1337
1339 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); 1338 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
1340 showNameAction->setToggleAction(TRUE); 1339 showNameAction->setToggleAction(TRUE);
1341 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool))); 1340 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1342 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool))); 1341 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1343 showNameAction->setOn(configView->showName()); 1342 showNameAction->setOn(configView->showName());
1344 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); 1343 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
1345 showRangeAction->setToggleAction(TRUE); 1344 showRangeAction->setToggleAction(TRUE);
1346 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool))); 1345 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1347 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool))); 1346 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1348 showRangeAction->setOn(configList->showRange); 1347 showRangeAction->setOn(configList->showRange);
1349 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); 1348 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
1350 showDataAction->setToggleAction(TRUE); 1349 showDataAction->setToggleAction(TRUE);
1351 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool))); 1350 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1352 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool))); 1351 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1353 showDataAction->setOn(configList->showData); 1352 showDataAction->setOn(configList->showData);
1354 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); 1353 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
1355 showAllAction->setToggleAction(TRUE); 1354 showAllAction->setToggleAction(TRUE);
1356 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool))); 1355 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1357 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool))); 1356 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1358 showAllAction->setOn(configList->showAll); 1357 showAllAction->setOn(configList->showAll);
1359 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); 1358 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1360 showDebugAction->setToggleAction(TRUE); 1359 showDebugAction->setToggleAction(TRUE);
1361 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool))); 1360 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1362 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool))); 1361 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1363 showDebugAction->setOn(helpText->showDebug()); 1362 showDebugAction->setOn(helpText->showDebug());
1364 1363
1365 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); 1364 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
1366 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); 1365 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1367 QAction *showAboutAction = new QAction(NULL, "About", 0, this); 1366 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
1368 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); 1367 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1369 1368
1370 // init tool bar 1369 // init tool bar
@@ -1379,7 +1378,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1379 1378
1380 // create config menu 1379 // create config menu
1381 QPopupMenu* config = new QPopupMenu(this); 1380 QPopupMenu* config = new QPopupMenu(this);
1382 menu->insertItem("&File", config); 1381 menu->insertItem(_("&File"), config);
1383 loadAction->addTo(config); 1382 loadAction->addTo(config);
1384 saveAction->addTo(config); 1383 saveAction->addTo(config);
1385 saveAsAction->addTo(config); 1384 saveAsAction->addTo(config);
@@ -1388,12 +1387,12 @@ ConfigMainWindow::ConfigMainWindow(void)
1388 1387
1389 // create edit menu 1388 // create edit menu
1390 QPopupMenu* editMenu = new QPopupMenu(this); 1389 QPopupMenu* editMenu = new QPopupMenu(this);
1391 menu->insertItem("&Edit", editMenu); 1390 menu->insertItem(_("&Edit"), editMenu);
1392 searchAction->addTo(editMenu); 1391 searchAction->addTo(editMenu);
1393 1392
1394 // create options menu 1393 // create options menu
1395 QPopupMenu* optionMenu = new QPopupMenu(this); 1394 QPopupMenu* optionMenu = new QPopupMenu(this);
1396 menu->insertItem("&Option", optionMenu); 1395 menu->insertItem(_("&Option"), optionMenu);
1397 showNameAction->addTo(optionMenu); 1396 showNameAction->addTo(optionMenu);
1398 showRangeAction->addTo(optionMenu); 1397 showRangeAction->addTo(optionMenu);
1399 showDataAction->addTo(optionMenu); 1398 showDataAction->addTo(optionMenu);
@@ -1404,7 +1403,7 @@ ConfigMainWindow::ConfigMainWindow(void)
1404 // create help menu 1403 // create help menu
1405 QPopupMenu* helpMenu = new QPopupMenu(this); 1404 QPopupMenu* helpMenu = new QPopupMenu(this);
1406 menu->insertSeparator(); 1405 menu->insertSeparator();
1407 menu->insertItem("&Help", helpMenu); 1406 menu->insertItem(_("&Help"), helpMenu);
1408 showIntroAction->addTo(helpMenu); 1407 showIntroAction->addTo(helpMenu);
1409 showAboutAction->addTo(helpMenu); 1408 showAboutAction->addTo(helpMenu);
1410 1409
@@ -1452,14 +1451,14 @@ void ConfigMainWindow::loadConfig(void)
1452 if (s.isNull()) 1451 if (s.isNull())
1453 return; 1452 return;
1454 if (conf_read(QFile::encodeName(s))) 1453 if (conf_read(QFile::encodeName(s)))
1455 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 1454 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1456 ConfigView::updateListAll(); 1455 ConfigView::updateListAll();
1457} 1456}
1458 1457
1459void ConfigMainWindow::saveConfig(void) 1458void ConfigMainWindow::saveConfig(void)
1460{ 1459{
1461 if (conf_write(NULL)) 1460 if (conf_write(NULL))
1462 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1461 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1463} 1462}
1464 1463
1465void ConfigMainWindow::saveConfigAs(void) 1464void ConfigMainWindow::saveConfigAs(void)
@@ -1468,7 +1467,7 @@ void ConfigMainWindow::saveConfigAs(void)
1468 if (s.isNull()) 1467 if (s.isNull())
1469 return; 1468 return;
1470 if (conf_write(QFile::encodeName(s))) 1469 if (conf_write(QFile::encodeName(s)))
1471 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1470 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1472} 1471}
1473 1472
1474void ConfigMainWindow::searchConfig(void) 1473void ConfigMainWindow::searchConfig(void)
@@ -1612,11 +1611,11 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1612 e->accept(); 1611 e->accept();
1613 return; 1612 return;
1614 } 1613 }
1615 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, 1614 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1616 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); 1615 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1617 mb.setButtonText(QMessageBox::Yes, "&Save Changes"); 1616 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1618 mb.setButtonText(QMessageBox::No, "&Discard Changes"); 1617 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1619 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); 1618 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1620 switch (mb.exec()) { 1619 switch (mb.exec()) {
1621 case QMessageBox::Yes: 1620 case QMessageBox::Yes:
1622 conf_write(NULL); 1621 conf_write(NULL);
@@ -1631,7 +1630,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
1631 1630
1632void ConfigMainWindow::showIntro(void) 1631void ConfigMainWindow::showIntro(void)
1633{ 1632{
1634 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" 1633 static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1635 "For each option, a blank box indicates the feature is disabled, a check\n" 1634 "For each option, a blank box indicates the feature is disabled, a check\n"
1636 "indicates it is enabled, and a dot indicates that it is to be compiled\n" 1635 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1637 "as a module. Clicking on the box will cycle through the three states.\n\n" 1636 "as a module. Clicking on the box will cycle through the three states.\n\n"
@@ -1641,15 +1640,15 @@ void ConfigMainWindow::showIntro(void)
1641 "options must be enabled to support the option you are interested in, you can\n" 1640 "options must be enabled to support the option you are interested in, you can\n"
1642 "still view the help of a grayed-out option.\n\n" 1641 "still view the help of a grayed-out option.\n\n"
1643 "Toggling Show Debug Info under the Options menu will show the dependencies,\n" 1642 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1644 "which you can then match by examining other options.\n\n"; 1643 "which you can then match by examining other options.\n\n");
1645 1644
1646 QMessageBox::information(this, "qconf", str); 1645 QMessageBox::information(this, "qconf", str);
1647} 1646}
1648 1647
1649void ConfigMainWindow::showAbout(void) 1648void ConfigMainWindow::showAbout(void)
1650{ 1649{
1651 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n" 1650 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1652 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; 1651 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1653 1652
1654 QMessageBox::information(this, "qconf", str); 1653 QMessageBox::information(this, "qconf", str);
1655} 1654}
@@ -1707,7 +1706,7 @@ static const char *progname;
1707 1706
1708static void usage(void) 1707static void usage(void)
1709{ 1708{
1710 printf("%s <config>\n", progname); 1709 printf(_("%s <config>\n"), progname);
1711 exit(0); 1710 exit(0);
1712} 1711}
1713 1712
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index c35dcc5d6189..3929e5b35e79 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -34,6 +34,8 @@ struct symbol *sym_defconfig_list;
34struct symbol *modules_sym; 34struct symbol *modules_sym;
35tristate modules_val; 35tristate modules_val;
36 36
37struct expr *sym_env_list;
38
37void sym_add_default(struct symbol *sym, const char *def) 39void sym_add_default(struct symbol *sym, const char *def)
38{ 40{
39 struct property *prop = prop_alloc(P_DEFAULT, sym); 41 struct property *prop = prop_alloc(P_DEFAULT, sym);
@@ -45,7 +47,6 @@ void sym_init(void)
45{ 47{
46 struct symbol *sym; 48 struct symbol *sym;
47 struct utsname uts; 49 struct utsname uts;
48 char *p;
49 static bool inited = false; 50 static bool inited = false;
50 51
51 if (inited) 52 if (inited)
@@ -54,20 +55,6 @@ void sym_init(void)
54 55
55 uname(&uts); 56 uname(&uts);
56 57
57 sym = sym_lookup("ARCH", 0);
58 sym->type = S_STRING;
59 sym->flags |= SYMBOL_AUTO;
60 p = getenv("ARCH");
61 if (p)
62 sym_add_default(sym, p);
63
64 sym = sym_lookup("KERNELVERSION", 0);
65 sym->type = S_STRING;
66 sym->flags |= SYMBOL_AUTO;
67 p = getenv("KERNELVERSION");
68 if (p)
69 sym_add_default(sym, p);
70
71 sym = sym_lookup("UNAME_RELEASE", 0); 58 sym = sym_lookup("UNAME_RELEASE", 0);
72 sym->type = S_STRING; 59 sym->type = S_STRING;
73 sym->flags |= SYMBOL_AUTO; 60 sym->flags |= SYMBOL_AUTO;
@@ -117,6 +104,15 @@ struct property *sym_get_choice_prop(struct symbol *sym)
117 return NULL; 104 return NULL;
118} 105}
119 106
107struct property *sym_get_env_prop(struct symbol *sym)
108{
109 struct property *prop;
110
111 for_all_properties(sym, prop, P_ENV)
112 return prop;
113 return NULL;
114}
115
120struct property *sym_get_default_prop(struct symbol *sym) 116struct property *sym_get_default_prop(struct symbol *sym)
121{ 117{
122 struct property *prop; 118 struct property *prop;
@@ -199,7 +195,7 @@ static void sym_calc_visibility(struct symbol *sym)
199 tri = no; 195 tri = no;
200 for_all_prompts(sym, prop) { 196 for_all_prompts(sym, prop) {
201 prop->visible.tri = expr_calc_value(prop->visible.expr); 197 prop->visible.tri = expr_calc_value(prop->visible.expr);
202 tri = E_OR(tri, prop->visible.tri); 198 tri = EXPR_OR(tri, prop->visible.tri);
203 } 199 }
204 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) 200 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
205 tri = yes; 201 tri = yes;
@@ -247,8 +243,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
247 243
248 /* just get the first visible value */ 244 /* just get the first visible value */
249 prop = sym_get_choice_prop(sym); 245 prop = sym_get_choice_prop(sym);
250 for (e = prop->expr; e; e = e->left.expr) { 246 expr_list_for_each_sym(prop->expr, e, def_sym) {
251 def_sym = e->right.sym;
252 sym_calc_visibility(def_sym); 247 sym_calc_visibility(def_sym);
253 if (def_sym->visible != no) 248 if (def_sym->visible != no)
254 return def_sym; 249 return def_sym;
@@ -303,7 +298,7 @@ void sym_calc_value(struct symbol *sym)
303 if (sym_is_choice_value(sym) && sym->visible == yes) { 298 if (sym_is_choice_value(sym) && sym->visible == yes) {
304 prop = sym_get_choice_prop(sym); 299 prop = sym_get_choice_prop(sym);
305 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; 300 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
306 } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { 301 } else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) {
307 sym->flags |= SYMBOL_WRITE; 302 sym->flags |= SYMBOL_WRITE;
308 if (sym_has_value(sym)) 303 if (sym_has_value(sym))
309 newval.tri = sym->def[S_DEF_USER].tri; 304 newval.tri = sym->def[S_DEF_USER].tri;
@@ -312,7 +307,7 @@ void sym_calc_value(struct symbol *sym)
312 if (prop) 307 if (prop)
313 newval.tri = expr_calc_value(prop->expr); 308 newval.tri = expr_calc_value(prop->expr);
314 } 309 }
315 newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); 310 newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri);
316 } else if (!sym_is_choice(sym)) { 311 } else if (!sym_is_choice(sym)) {
317 prop = sym_get_default_prop(sym); 312 prop = sym_get_default_prop(sym);
318 if (prop) { 313 if (prop) {
@@ -347,6 +342,9 @@ void sym_calc_value(struct symbol *sym)
347 ; 342 ;
348 } 343 }
349 344
345 if (sym->flags & SYMBOL_AUTO)
346 sym->flags &= ~SYMBOL_WRITE;
347
350 sym->curr = newval; 348 sym->curr = newval;
351 if (sym_is_choice(sym) && newval.tri == yes) 349 if (sym_is_choice(sym) && newval.tri == yes)
352 sym->curr.val = sym_calc_choice(sym); 350 sym->curr.val = sym_calc_choice(sym);
@@ -361,12 +359,14 @@ void sym_calc_value(struct symbol *sym)
361 } 359 }
362 360
363 if (sym_is_choice(sym)) { 361 if (sym_is_choice(sym)) {
362 struct symbol *choice_sym;
364 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); 363 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
364
365 prop = sym_get_choice_prop(sym); 365 prop = sym_get_choice_prop(sym);
366 for (e = prop->expr; e; e = e->left.expr) { 366 expr_list_for_each_sym(prop->expr, e, choice_sym) {
367 e->right.sym->flags |= flags; 367 choice_sym->flags |= flags;
368 if (flags & SYMBOL_CHANGED) 368 if (flags & SYMBOL_CHANGED)
369 sym_set_changed(e->right.sym); 369 sym_set_changed(choice_sym);
370 } 370 }
371 } 371 }
372} 372}
@@ -849,7 +849,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym)
849struct symbol *prop_get_symbol(struct property *prop) 849struct symbol *prop_get_symbol(struct property *prop)
850{ 850{
851 if (prop->expr && (prop->expr->type == E_SYMBOL || 851 if (prop->expr && (prop->expr->type == E_SYMBOL ||
852 prop->expr->type == E_CHOICE)) 852 prop->expr->type == E_LIST))
853 return prop->expr->left.sym; 853 return prop->expr->left.sym;
854 return NULL; 854 return NULL;
855} 855}
@@ -859,6 +859,8 @@ const char *prop_get_type_name(enum prop_type type)
859 switch (type) { 859 switch (type) {
860 case P_PROMPT: 860 case P_PROMPT:
861 return "prompt"; 861 return "prompt";
862 case P_ENV:
863 return "env";
862 case P_COMMENT: 864 case P_COMMENT:
863 return "comment"; 865 return "comment";
864 case P_MENU: 866 case P_MENU:
@@ -876,3 +878,32 @@ const char *prop_get_type_name(enum prop_type type)
876 } 878 }
877 return "unknown"; 879 return "unknown";
878} 880}
881
882void prop_add_env(const char *env)
883{
884 struct symbol *sym, *sym2;
885 struct property *prop;
886 char *p;
887
888 sym = current_entry->sym;
889 sym->flags |= SYMBOL_AUTO;
890 for_all_properties(sym, prop, P_ENV) {
891 sym2 = prop_get_symbol(prop);
892 if (strcmp(sym2->name, env))
893 menu_warn(current_entry, "redefining environment symbol from %s",
894 sym2->name);
895 return;
896 }
897
898 prop = prop_alloc(P_ENV, sym);
899 prop->expr = expr_alloc_symbol(sym_lookup(env, 1));
900
901 sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
902 sym_env_list->right.sym = sym;
903
904 p = getenv(env);
905 if (p)
906 sym_add_default(sym, p);
907 else
908 menu_warn(current_entry, "environment variable %s undefined", env);
909}
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index e1cad924c0a4..f8e73c039dc8 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -29,6 +29,8 @@ struct file *file_lookup(const char *name)
29/* write a dependency file as used by kbuild to track dependencies */ 29/* write a dependency file as used by kbuild to track dependencies */
30int file_write_dep(const char *name) 30int file_write_dep(const char *name)
31{ 31{
32 struct symbol *sym, *env_sym;
33 struct expr *e;
32 struct file *file; 34 struct file *file;
33 FILE *out; 35 FILE *out;
34 36
@@ -45,8 +47,25 @@ int file_write_dep(const char *name)
45 fprintf(out, "\t%s\n", file->name); 47 fprintf(out, "\t%s\n", file->name);
46 } 48 }
47 fprintf(out, "\ninclude/config/auto.conf: \\\n" 49 fprintf(out, "\ninclude/config/auto.conf: \\\n"
48 "\t$(deps_config)\n\n" 50 "\t$(deps_config)\n\n");
49 "$(deps_config): ;\n"); 51
52 expr_list_for_each_sym(sym_env_list, e, sym) {
53 struct property *prop;
54 const char *value;
55
56 prop = sym_get_env_prop(sym);
57 env_sym = prop_get_symbol(prop);
58 if (!env_sym)
59 continue;
60 value = getenv(env_sym->name);
61 if (!value)
62 value = "";
63 fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
64 fprintf(out, "include/config/auto.conf: FORCE\n");
65 fprintf(out, "endif\n");
66 }
67
68 fprintf(out, "\n$(deps_config): ;\n");
50 fclose(out); 69 fclose(out);
51 rename("..config.tmp", name); 70 rename("..config.tmp", name);
52 return 0; 71 return 0;
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index 93538e567bda..25ef5d01c0af 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -35,10 +35,10 @@ int, T_TYPE, TF_COMMAND, S_INT
35hex, T_TYPE, TF_COMMAND, S_HEX 35hex, T_TYPE, TF_COMMAND, S_HEX
36string, T_TYPE, TF_COMMAND, S_STRING 36string, T_TYPE, TF_COMMAND, S_STRING
37select, T_SELECT, TF_COMMAND 37select, T_SELECT, TF_COMMAND
38enable, T_SELECT, TF_COMMAND
39range, T_RANGE, TF_COMMAND 38range, T_RANGE, TF_COMMAND
40option, T_OPTION, TF_COMMAND 39option, T_OPTION, TF_COMMAND
41on, T_ON, TF_PARAM 40on, T_ON, TF_PARAM
42modules, T_OPT_MODULES, TF_OPTION 41modules, T_OPT_MODULES, TF_OPTION
43defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION 42defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
43env, T_OPT_ENV, TF_OPTION
44%% 44%%
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index ab28b18153a7..5c73d51339d8 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -1,4 +1,4 @@
1/* ANSI-C code produced by gperf version 3.0.2 */ 1/* ANSI-C code produced by gperf version 3.0.3 */
2/* Command-line: gperf */ 2/* Command-line: gperf */
3/* Computed positions: -k'1,3' */ 3/* Computed positions: -k'1,3' */
4 4
@@ -53,9 +53,9 @@ kconf_id_hash (register const char *str, register unsigned int len)
53 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 53 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
54 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
55 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 55 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
56 49, 49, 49, 49, 49, 49, 49, 18, 11, 5, 56 49, 49, 49, 49, 49, 49, 49, 49, 11, 5,
57 0, 0, 5, 49, 5, 20, 49, 49, 5, 20, 57 0, 0, 5, 49, 5, 20, 49, 49, 5, 20,
58 5, 0, 30, 49, 0, 15, 0, 10, 49, 49, 58 5, 0, 30, 49, 0, 15, 0, 10, 0, 49,
59 25, 49, 49, 49, 49, 49, 49, 49, 49, 49, 59 25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
60 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 60 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
61 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 61 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
@@ -89,6 +89,7 @@ kconf_id_hash (register const char *str, register unsigned int len)
89struct kconf_id_strings_t 89struct kconf_id_strings_t
90 { 90 {
91 char kconf_id_strings_str2[sizeof("on")]; 91 char kconf_id_strings_str2[sizeof("on")];
92 char kconf_id_strings_str3[sizeof("env")];
92 char kconf_id_strings_str5[sizeof("endif")]; 93 char kconf_id_strings_str5[sizeof("endif")];
93 char kconf_id_strings_str6[sizeof("option")]; 94 char kconf_id_strings_str6[sizeof("option")];
94 char kconf_id_strings_str7[sizeof("endmenu")]; 95 char kconf_id_strings_str7[sizeof("endmenu")];
@@ -107,7 +108,6 @@ struct kconf_id_strings_t
107 char kconf_id_strings_str21[sizeof("string")]; 108 char kconf_id_strings_str21[sizeof("string")];
108 char kconf_id_strings_str22[sizeof("if")]; 109 char kconf_id_strings_str22[sizeof("if")];
109 char kconf_id_strings_str23[sizeof("int")]; 110 char kconf_id_strings_str23[sizeof("int")];
110 char kconf_id_strings_str24[sizeof("enable")];
111 char kconf_id_strings_str26[sizeof("select")]; 111 char kconf_id_strings_str26[sizeof("select")];
112 char kconf_id_strings_str27[sizeof("modules")]; 112 char kconf_id_strings_str27[sizeof("modules")];
113 char kconf_id_strings_str28[sizeof("tristate")]; 113 char kconf_id_strings_str28[sizeof("tristate")];
@@ -123,6 +123,7 @@ struct kconf_id_strings_t
123static struct kconf_id_strings_t kconf_id_strings_contents = 123static struct kconf_id_strings_t kconf_id_strings_contents =
124 { 124 {
125 "on", 125 "on",
126 "env",
126 "endif", 127 "endif",
127 "option", 128 "option",
128 "endmenu", 129 "endmenu",
@@ -141,7 +142,6 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
141 "string", 142 "string",
142 "if", 143 "if",
143 "int", 144 "int",
144 "enable",
145 "select", 145 "select",
146 "modules", 146 "modules",
147 "tristate", 147 "tristate",
@@ -157,6 +157,9 @@ static struct kconf_id_strings_t kconf_id_strings_contents =
157#define kconf_id_strings ((const char *) &kconf_id_strings_contents) 157#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
158#ifdef __GNUC__ 158#ifdef __GNUC__
159__inline 159__inline
160#ifdef __GNUC_STDC_INLINE__
161__attribute__ ((__gnu_inline__))
162#endif
160#endif 163#endif
161struct kconf_id * 164struct kconf_id *
162kconf_id_lookup (register const char *str, register unsigned int len) 165kconf_id_lookup (register const char *str, register unsigned int len)
@@ -174,7 +177,8 @@ kconf_id_lookup (register const char *str, register unsigned int len)
174 { 177 {
175 {-1}, {-1}, 178 {-1}, {-1},
176 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM}, 179 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
177 {-1}, {-1}, 180 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_OPT_ENV, TF_OPTION},
181 {-1},
178 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, 182 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
179 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND}, 183 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND},
180 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, 184 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
@@ -194,8 +198,7 @@ kconf_id_lookup (register const char *str, register unsigned int len)
194 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING}, 198 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
195 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM}, 199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
196 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT}, 200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
197 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_SELECT, TF_COMMAND}, 201 {-1}, {-1},
198 {-1},
199 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND}, 202 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
200 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION}, 203 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
201 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE}, 204 {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index 187d38ccadd5..4cea5c85cd0a 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -217,6 +217,11 @@ n [A-Za-z0-9_]
217 append_string("\n", 1); 217 append_string("\n", 1);
218 } 218 }
219 [^ \t\n].* { 219 [^ \t\n].* {
220 while (yyleng) {
221 if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
222 break;
223 yyleng--;
224 }
220 append_string(yytext, yyleng); 225 append_string(yytext, yyleng);
221 if (!first_ts) 226 if (!first_ts)
222 first_ts = last_ts; 227 first_ts = last_ts;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 1d1401807e95..ec54f12f57b0 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -46,21 +46,24 @@ use strict;
46# Note: This only supports 'c'. 46# Note: This only supports 'c'.
47 47
48# usage: 48# usage:
49# kernel-doc [ -docbook | -html | -text | -man ] 49# kernel-doc [ -docbook | -html | -text | -man ] [ -no-doc-sections ]
50# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile 50# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
51# or 51# or
52# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile 52# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
53# 53#
54# Set output format using one of -docbook -html -text or -man. Default is man. 54# Set output format using one of -docbook -html -text or -man. Default is man.
55# 55#
56# -no-doc-sections
57# Do not output DOC: sections
58#
56# -function funcname 59# -function funcname
57# If set, then only generate documentation for the given function(s). All 60# If set, then only generate documentation for the given function(s) or
58# other functions are ignored. 61# DOC: section titles. All other functions and DOC: sections are ignored.
59# 62#
60# -nofunction funcname 63# -nofunction funcname
61# If set, then only generate documentation for the other function(s). 64# If set, then only generate documentation for the other function(s)/DOC:
62# Cannot be used together with -function 65# sections. Cannot be used together with -function (yes, that's a bug --
63# (yes, that's a bug -- perl hackers can fix it 8)) 66# perl hackers can fix it 8))
64# 67#
65# c files - list of 'c' files to process 68# c files - list of 'c' files to process
66# 69#
@@ -182,10 +185,10 @@ my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>"
182my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>", 185my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
183 $type_constant, "<constant>\$1</constant>", 186 $type_constant, "<constant>\$1</constant>",
184 $type_func, "<function>\$1</function>", 187 $type_func, "<function>\$1</function>",
185 $type_struct, "<structname>\$1</structname>", 188 $type_struct_xml, "<structname>\$1</structname>",
186 $type_env, "<envar>\$1</envar>", 189 $type_env, "<envar>\$1</envar>",
187 $type_param, "<parameter>\$1</parameter>" ); 190 $type_param, "<parameter>\$1</parameter>" );
188my $blankline_xml = "</para><para>\n"; 191my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
189 192
190# gnome, docbook format 193# gnome, docbook format
191my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>", 194my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
@@ -211,7 +214,7 @@ my $blankline_text = "";
211 214
212 215
213sub usage { 216sub usage {
214 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n"; 217 print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ] [ -no-doc-sections ]\n";
215 print " [ -function funcname [ -function funcname ...] ]\n"; 218 print " [ -function funcname [ -function funcname ...] ]\n";
216 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; 219 print " [ -nofunction funcname [ -nofunction funcname ...] ]\n";
217 print " c source file(s) > outputfile\n"; 220 print " c source file(s) > outputfile\n";
@@ -225,6 +228,7 @@ if ($#ARGV==-1) {
225 228
226my $verbose = 0; 229my $verbose = 0;
227my $output_mode = "man"; 230my $output_mode = "man";
231my $no_doc_sections = 0;
228my %highlights = %highlights_man; 232my %highlights = %highlights_man;
229my $blankline = $blankline_man; 233my $blankline = $blankline_man;
230my $modulename = "Kernel API"; 234my $modulename = "Kernel API";
@@ -329,12 +333,14 @@ while ($ARGV[0] =~ m/^-(.*)/) {
329 usage(); 333 usage();
330 } elsif ($cmd eq '-filelist') { 334 } elsif ($cmd eq '-filelist') {
331 $filelist = shift @ARGV; 335 $filelist = shift @ARGV;
336 } elsif ($cmd eq '-no-doc-sections') {
337 $no_doc_sections = 1;
332 } 338 }
333} 339}
334 340
335# get kernel version from env 341# get kernel version from env
336sub get_kernel_version() { 342sub get_kernel_version() {
337 my $version; 343 my $version = 'unknown kernel version';
338 344
339 if (defined($ENV{'KERNELVERSION'})) { 345 if (defined($ENV{'KERNELVERSION'})) {
340 $version = $ENV{'KERNELVERSION'}; 346 $version = $ENV{'KERNELVERSION'};
@@ -374,6 +380,29 @@ sub dump_section {
374} 380}
375 381
376## 382##
383# dump DOC: section after checking that it should go out
384#
385sub dump_doc_section {
386 my $name = shift;
387 my $contents = join "\n", @_;
388
389 if ($no_doc_sections) {
390 return;
391 }
392
393 if (($function_only == 0) ||
394 ( $function_only == 1 && defined($function_table{$name})) ||
395 ( $function_only == 2 && !defined($function_table{$name})))
396 {
397 dump_section $name, $contents;
398 output_blockhead({'sectionlist' => \@sectionlist,
399 'sections' => \%sections,
400 'module' => $modulename,
401 'content-only' => ($function_only != 0), });
402 }
403}
404
405##
377# output function 406# output function
378# 407#
379# parameterdescs, a hash. 408# parameterdescs, a hash.
@@ -394,7 +423,7 @@ sub output_highlight {
394# confess "output_highlight got called with no args?\n"; 423# confess "output_highlight got called with no args?\n";
395# } 424# }
396 425
397 if ($output_mode eq "html") { 426 if ($output_mode eq "html" || $output_mode eq "xml") {
398 $contents = local_unescape($contents); 427 $contents = local_unescape($contents);
399 # convert data read & converted thru xml_escape() into &xyz; format: 428 # convert data read & converted thru xml_escape() into &xyz; format:
400 $contents =~ s/\\\\\\/&/g; 429 $contents =~ s/\\\\\\/&/g;
@@ -564,8 +593,8 @@ sub output_function_html(%) {
564 print "<hr>\n"; 593 print "<hr>\n";
565} 594}
566 595
567# output intro in html 596# output DOC: block header in html
568sub output_intro_html(%) { 597sub output_blockhead_html(%) {
569 my %args = %{$_[0]}; 598 my %args = %{$_[0]};
570 my ($parameter, $section); 599 my ($parameter, $section);
571 my $count; 600 my $count;
@@ -871,7 +900,7 @@ sub output_typedef_xml(%) {
871} 900}
872 901
873# output in XML DocBook 902# output in XML DocBook
874sub output_intro_xml(%) { 903sub output_blockhead_xml(%) {
875 my %args = %{$_[0]}; 904 my %args = %{$_[0]};
876 my ($parameter, $section); 905 my ($parameter, $section);
877 my $count; 906 my $count;
@@ -882,15 +911,23 @@ sub output_intro_xml(%) {
882 # print out each section 911 # print out each section
883 $lineprefix=" "; 912 $lineprefix=" ";
884 foreach $section (@{$args{'sectionlist'}}) { 913 foreach $section (@{$args{'sectionlist'}}) {
885 print "<refsect1>\n <title>$section</title>\n <para>\n"; 914 if (!$args{'content-only'}) {
915 print "<refsect1>\n <title>$section</title>\n";
916 }
886 if ($section =~ m/EXAMPLE/i) { 917 if ($section =~ m/EXAMPLE/i) {
887 print "<example><para>\n"; 918 print "<example><para>\n";
919 } else {
920 print "<para>\n";
888 } 921 }
889 output_highlight($args{'sections'}{$section}); 922 output_highlight($args{'sections'}{$section});
890 if ($section =~ m/EXAMPLE/i) { 923 if ($section =~ m/EXAMPLE/i) {
891 print "</para></example>\n"; 924 print "</para></example>\n";
925 } else {
926 print "</para>";
927 }
928 if (!$args{'content-only'}) {
929 print "\n</refsect1>\n";
892 } 930 }
893 print " </para>\n</refsect1>\n";
894 } 931 }
895 932
896 print "\n\n"; 933 print "\n\n";
@@ -1137,7 +1174,7 @@ sub output_typedef_man(%) {
1137 } 1174 }
1138} 1175}
1139 1176
1140sub output_intro_man(%) { 1177sub output_blockhead_man(%) {
1141 my %args = %{$_[0]}; 1178 my %args = %{$_[0]};
1142 my ($parameter, $section); 1179 my ($parameter, $section);
1143 my $count; 1180 my $count;
@@ -1294,7 +1331,7 @@ sub output_struct_text(%) {
1294 output_section_text(@_); 1331 output_section_text(@_);
1295} 1332}
1296 1333
1297sub output_intro_text(%) { 1334sub output_blockhead_text(%) {
1298 my %args = %{$_[0]}; 1335 my %args = %{$_[0]};
1299 my ($parameter, $section); 1336 my ($parameter, $section);
1300 1337
@@ -1325,9 +1362,9 @@ sub output_declaration {
1325 1362
1326## 1363##
1327# generic output function - calls the right one based on current output mode. 1364# generic output function - calls the right one based on current output mode.
1328sub output_intro { 1365sub output_blockhead {
1329 no strict 'refs'; 1366 no strict 'refs';
1330 my $func = "output_intro_".$output_mode; 1367 my $func = "output_blockhead_".$output_mode;
1331 &$func(@_); 1368 &$func(@_);
1332 $section_counter++; 1369 $section_counter++;
1333} 1370}
@@ -1926,9 +1963,7 @@ sub process_file($) {
1926 } elsif ($state == 4) { 1963 } elsif ($state == 4) {
1927 # Documentation block 1964 # Documentation block
1928 if (/$doc_block/) { 1965 if (/$doc_block/) {
1929 dump_section($section, xml_escape($contents)); 1966 dump_doc_section($section, xml_escape($contents));
1930 output_intro({'sectionlist' => \@sectionlist,
1931 'sections' => \%sections });
1932 $contents = ""; 1967 $contents = "";
1933 $function = ""; 1968 $function = "";
1934 %constants = (); 1969 %constants = ();
@@ -1946,9 +1981,7 @@ sub process_file($) {
1946 } 1981 }
1947 elsif (/$doc_end/) 1982 elsif (/$doc_end/)
1948 { 1983 {
1949 dump_section($section, xml_escape($contents)); 1984 dump_doc_section($section, xml_escape($contents));
1950 output_intro({'sectionlist' => \@sectionlist,
1951 'sections' => \%sections });
1952 $contents = ""; 1985 $contents = "";
1953 $function = ""; 1986 $function = "";
1954 %constants = (); 1987 %constants = ();
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index e0f54b9d8fec..e65d8b33faa4 100644
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -25,8 +25,11 @@ cat << EOF > $2/Makefile
25VERSION = $3 25VERSION = $3
26PATCHLEVEL = $4 26PATCHLEVEL = $4
27 27
28KERNELSRC := $1 28lastword = \$(word \$(words \$(1)),\$(1))
29KERNELOUTPUT := $2 29makedir := \$(dir \$(call lastword,\$(MAKEFILE_LIST)))
30
31MAKEARGS := -C $1
32MAKEARGS += O=\$(if \$(patsubst /%,,\$(makedir)),\$(CURDIR)/)\$(patsubst %/,%,\$(makedir))
30 33
31MAKEFLAGS += --no-print-directory 34MAKEFLAGS += --no-print-directory
32 35
@@ -35,10 +38,11 @@ MAKEFLAGS += --no-print-directory
35all := \$(filter-out all Makefile,\$(MAKECMDGOALS)) 38all := \$(filter-out all Makefile,\$(MAKECMDGOALS))
36 39
37all: 40all:
38 \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$(all) 41 \$(MAKE) \$(MAKEARGS) \$(all)
39 42
40Makefile:; 43Makefile:;
41 44
42\$(all) %/: all 45\$(all) %/: all
43 @: 46 @:
47
44EOF 48EOF
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 93ac52adb498..f8efc93eb700 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Copyright 2003 Kai Germaschewski 3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation 4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5 * Copyright 2006 Sam Ravnborg 5 * Copyright 2006-2008 Sam Ravnborg
6 * Based in part on module-init-tools/depmod.c,file2alias 6 * Based in part on module-init-tools/depmod.c,file2alias
7 * 7 *
8 * This software may be used and distributed according to the terms 8 * This software may be used and distributed according to the terms
@@ -28,12 +28,17 @@ static int vmlinux_section_warnings = 1;
28/* Only warn about unresolved symbols */ 28/* Only warn about unresolved symbols */
29static int warn_unresolved = 0; 29static int warn_unresolved = 0;
30/* How a symbol is exported */ 30/* How a symbol is exported */
31static int sec_mismatch_count = 0;
32static int sec_mismatch_verbose = 1;
33
31enum export { 34enum export {
32 export_plain, export_unused, export_gpl, 35 export_plain, export_unused, export_gpl,
33 export_unused_gpl, export_gpl_future, export_unknown 36 export_unused_gpl, export_gpl_future, export_unknown
34}; 37};
35 38
36void fatal(const char *fmt, ...) 39#define PRINTF __attribute__ ((format (printf, 1, 2)))
40
41PRINTF void fatal(const char *fmt, ...)
37{ 42{
38 va_list arglist; 43 va_list arglist;
39 44
@@ -46,7 +51,7 @@ void fatal(const char *fmt, ...)
46 exit(1); 51 exit(1);
47} 52}
48 53
49void warn(const char *fmt, ...) 54PRINTF void warn(const char *fmt, ...)
50{ 55{
51 va_list arglist; 56 va_list arglist;
52 57
@@ -57,7 +62,7 @@ void warn(const char *fmt, ...)
57 va_end(arglist); 62 va_end(arglist);
58} 63}
59 64
60void merror(const char *fmt, ...) 65PRINTF void merror(const char *fmt, ...)
61{ 66{
62 va_list arglist; 67 va_list arglist;
63 68
@@ -72,7 +77,8 @@ static int is_vmlinux(const char *modname)
72{ 77{
73 const char *myname; 78 const char *myname;
74 79
75 if ((myname = strrchr(modname, '/'))) 80 myname = strrchr(modname, '/');
81 if (myname)
76 myname++; 82 myname++;
77 else 83 else
78 myname = modname; 84 myname = modname;
@@ -83,14 +89,13 @@ static int is_vmlinux(const char *modname)
83 89
84void *do_nofail(void *ptr, const char *expr) 90void *do_nofail(void *ptr, const char *expr)
85{ 91{
86 if (!ptr) { 92 if (!ptr)
87 fatal("modpost: Memory allocation failure: %s.\n", expr); 93 fatal("modpost: Memory allocation failure: %s.\n", expr);
88 } 94
89 return ptr; 95 return ptr;
90} 96}
91 97
92/* A list of all modules we processed */ 98/* A list of all modules we processed */
93
94static struct module *modules; 99static struct module *modules;
95 100
96static struct module *find_module(char *modname) 101static struct module *find_module(char *modname)
@@ -113,7 +118,8 @@ static struct module *new_module(char *modname)
113 p = NOFAIL(strdup(modname)); 118 p = NOFAIL(strdup(modname));
114 119
115 /* strip trailing .o */ 120 /* strip trailing .o */
116 if ((s = strrchr(p, '.')) != NULL) 121 s = strrchr(p, '.');
122 if (s != NULL)
117 if (strcmp(s, ".o") == 0) 123 if (strcmp(s, ".o") == 0)
118 *s = '\0'; 124 *s = '\0';
119 125
@@ -154,7 +160,7 @@ static inline unsigned int tdb_hash(const char *name)
154 unsigned i; /* Used to cycle through random values. */ 160 unsigned i; /* Used to cycle through random values. */
155 161
156 /* Set the initial value from the key size. */ 162 /* Set the initial value from the key size. */
157 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) 163 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
158 value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); 164 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
159 165
160 return (1103515243 * value + 12345); 166 return (1103515243 * value + 12345);
@@ -198,7 +204,7 @@ static struct symbol *find_symbol(const char *name)
198 if (name[0] == '.') 204 if (name[0] == '.')
199 name++; 205 name++;
200 206
201 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) { 207 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
202 if (strcmp(s->name, name) == 0) 208 if (strcmp(s->name, name) == 0)
203 return s; 209 return s;
204 } 210 }
@@ -223,9 +229,10 @@ static const char *export_str(enum export ex)
223 return export_list[ex].str; 229 return export_list[ex].str;
224} 230}
225 231
226static enum export export_no(const char * s) 232static enum export export_no(const char *s)
227{ 233{
228 int i; 234 int i;
235
229 if (!s) 236 if (!s)
230 return export_unknown; 237 return export_unknown;
231 for (i = 0; export_list[i].export != export_unknown; i++) { 238 for (i = 0; export_list[i].export != export_unknown; i++) {
@@ -315,7 +322,7 @@ void *grab_file(const char *filename, unsigned long *size)
315 * spaces in the beginning of the line is trimmed away. 322 * spaces in the beginning of the line is trimmed away.
316 * Return a pointer to a static buffer. 323 * Return a pointer to a static buffer.
317 **/ 324 **/
318char* get_next_line(unsigned long *pos, void *file, unsigned long size) 325char *get_next_line(unsigned long *pos, void *file, unsigned long size)
319{ 326{
320 static char line[4096]; 327 static char line[4096];
321 int skip = 1; 328 int skip = 1;
@@ -323,8 +330,7 @@ char* get_next_line(unsigned long *pos, void *file, unsigned long size)
323 signed char *p = (signed char *)file + *pos; 330 signed char *p = (signed char *)file + *pos;
324 char *s = line; 331 char *s = line;
325 332
326 for (; *pos < size ; (*pos)++) 333 for (; *pos < size ; (*pos)++) {
327 {
328 if (skip && isspace(*p)) { 334 if (skip && isspace(*p)) {
329 p++; 335 p++;
330 continue; 336 continue;
@@ -386,7 +392,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
386 392
387 /* Check if file offset is correct */ 393 /* Check if file offset is correct */
388 if (hdr->e_shoff > info->size) { 394 if (hdr->e_shoff > info->size) {
389 fatal("section header offset=%u in file '%s' is bigger then filesize=%lu\n", hdr->e_shoff, filename, info->size); 395 fatal("section header offset=%lu in file '%s' is bigger than "
396 "filesize=%lu\n", (unsigned long)hdr->e_shoff,
397 filename, info->size);
390 return 0; 398 return 0;
391 } 399 }
392 400
@@ -407,7 +415,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
407 const char *secname; 415 const char *secname;
408 416
409 if (sechdrs[i].sh_offset > info->size) { 417 if (sechdrs[i].sh_offset > info->size) {
410 fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr)); 418 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
419 "sizeof(*hrd)=%zu\n", filename,
420 (unsigned long)sechdrs[i].sh_offset,
421 sizeof(*hdr));
411 return 0; 422 return 0;
412 } 423 }
413 secname = secstrings + sechdrs[i].sh_name; 424 secname = secstrings + sechdrs[i].sh_name;
@@ -434,9 +445,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
434 info->strtab = (void *)hdr + 445 info->strtab = (void *)hdr +
435 sechdrs[sechdrs[i].sh_link].sh_offset; 446 sechdrs[sechdrs[i].sh_link].sh_offset;
436 } 447 }
437 if (!info->symtab_start) { 448 if (!info->symtab_start)
438 fatal("%s has no symtab?\n", filename); 449 fatal("%s has no symtab?\n", filename);
439 } 450
440 /* Fix endianness in symbols */ 451 /* Fix endianness in symbols */
441 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { 452 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
442 sym->st_shndx = TO_NATIVE(sym->st_shndx); 453 sym->st_shndx = TO_NATIVE(sym->st_shndx);
@@ -505,11 +516,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
505#endif 516#endif
506 517
507 if (memcmp(symname, MODULE_SYMBOL_PREFIX, 518 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
508 strlen(MODULE_SYMBOL_PREFIX)) == 0) 519 strlen(MODULE_SYMBOL_PREFIX)) == 0) {
509 mod->unres = alloc_symbol(symname + 520 mod->unres =
510 strlen(MODULE_SYMBOL_PREFIX), 521 alloc_symbol(symname +
511 ELF_ST_BIND(sym->st_info) == STB_WEAK, 522 strlen(MODULE_SYMBOL_PREFIX),
512 mod->unres); 523 ELF_ST_BIND(sym->st_info) == STB_WEAK,
524 mod->unres);
525 }
513 break; 526 break;
514 default: 527 default:
515 /* All exported symbols */ 528 /* All exported symbols */
@@ -578,69 +591,303 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
578 **/ 591 **/
579static int strrcmp(const char *s, const char *sub) 592static int strrcmp(const char *s, const char *sub)
580{ 593{
581 int slen, sublen; 594 int slen, sublen;
582 595
583 if (!s || !sub) 596 if (!s || !sub)
584 return 1; 597 return 1;
585 598
586 slen = strlen(s); 599 slen = strlen(s);
587 sublen = strlen(sub); 600 sublen = strlen(sub);
588 601
589 if ((slen == 0) || (sublen == 0)) 602 if ((slen == 0) || (sublen == 0))
590 return 1; 603 return 1;
591 604
592 if (sublen > slen) 605 if (sublen > slen)
593 return 1; 606 return 1;
594 607
595 return memcmp(s + slen - sublen, sub, sublen); 608 return memcmp(s + slen - sublen, sub, sublen);
596} 609}
597 610
598/* 611static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
599 * Functions used only during module init is marked __init and is stored in 612{
600 * a .init.text section. Likewise data is marked __initdata and stored in 613 if (sym)
601 * a .init.data section. 614 return elf->strtab + sym->st_name;
602 * If this section is one of these sections return 1 615 else
603 * See include/linux/init.h for the details 616 return "";
617}
618
619static const char *sec_name(struct elf_info *elf, int shndx)
620{
621 Elf_Shdr *sechdrs = elf->sechdrs;
622 return (void *)elf->hdr +
623 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
624 sechdrs[shndx].sh_name;
625}
626
627static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
628{
629 return (void *)elf->hdr +
630 elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
631 sechdr->sh_name;
632}
633
634/* if sym is empty or point to a string
635 * like ".[0-9]+" then return 1.
636 * This is the optional prefix added by ld to some sections
604 */ 637 */
605static int init_section(const char *name) 638static int number_prefix(const char *sym)
606{ 639{
607 if (strcmp(name, ".init") == 0) 640 if (*sym++ == '\0')
608 return 1;
609 if (strncmp(name, ".init.", strlen(".init.")) == 0)
610 return 1; 641 return 1;
642 if (*sym != '.')
643 return 0;
644 do {
645 char c = *sym++;
646 if (c < '0' || c > '9')
647 return 0;
648 } while (*sym);
649 return 1;
650}
651
652/* The pattern is an array of simple patterns.
653 * "foo" will match an exact string equal to "foo"
654 * "*foo" will match a string that ends with "foo"
655 * "foo*" will match a string that begins with "foo"
656 * "foo$" will match a string equal to "foo" or "foo.1"
657 * where the '1' can be any number including several digits.
658 * The $ syntax is for sections where ld append a dot number
659 * to make section name unique.
660 */
661int match(const char *sym, const char * const pat[])
662{
663 const char *p;
664 while (*pat) {
665 p = *pat++;
666 const char *endp = p + strlen(p) - 1;
667
668 /* "*foo" */
669 if (*p == '*') {
670 if (strrcmp(sym, p + 1) == 0)
671 return 1;
672 }
673 /* "foo*" */
674 else if (*endp == '*') {
675 if (strncmp(sym, p, strlen(p) - 1) == 0)
676 return 1;
677 }
678 /* "foo$" */
679 else if (*endp == '$') {
680 if (strncmp(sym, p, strlen(p) - 1) == 0) {
681 if (number_prefix(sym + strlen(p) - 1))
682 return 1;
683 }
684 }
685 /* no wildcards */
686 else {
687 if (strcmp(p, sym) == 0)
688 return 1;
689 }
690 }
691 /* no match */
611 return 0; 692 return 0;
612} 693}
613 694
695/* sections that we do not want to do full section mismatch check on */
696static const char *section_white_list[] =
697 { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
698
614/* 699/*
615 * Functions used only during module exit is marked __exit and is stored in 700 * Is this section one we do not want to check?
616 * a .exit.text section. Likewise data is marked __exitdata and stored in 701 * This is often debug sections.
617 * a .exit.data section. 702 * If we are going to check this section then
618 * If this section is one of these sections return 1 703 * test if section name ends with a dot and a number.
619 * See include/linux/init.h for the details 704 * This is used to find sections where the linker have
620 **/ 705 * appended a dot-number to make the name unique.
621static int exit_section(const char *name) 706 * The cause of this is often a section specified in assembler
707 * without "ax" / "aw" and the same section used in .c
708 * code where gcc add these.
709 */
710static int check_section(const char *modname, const char *sec)
622{ 711{
623 if (strcmp(name, ".exit.text") == 0) 712 const char *e = sec + strlen(sec) - 1;
624 return 1; 713 if (match(sec, section_white_list))
625 if (strcmp(name, ".exit.data") == 0)
626 return 1; 714 return 1;
627 return 0;
628 715
716 if (*e && isdigit(*e)) {
717 /* consume all digits */
718 while (*e && e != sec && isdigit(*e))
719 e--;
720 if (*e == '.') {
721 warn("%s (%s): unexpected section name.\n"
722 "The (.[number]+) following section name are "
723 "ld generated and not expected.\n"
724 "Did you forget to use \"ax\"/\"aw\" "
725 "in a .S file?\n"
726 "Note that for example <linux/init.h> contains\n"
727 "section definitions for use in .S files.\n\n",
728 modname, sec);
729 }
730 }
731 return 0;
629} 732}
630 733
631/* 734
632 * Data sections are named like this: 735
633 * .data | .data.rel | .data.rel.* 736#define ALL_INIT_DATA_SECTIONS \
634 * Return 1 if the specified section is a data section 737 ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
738#define ALL_EXIT_DATA_SECTIONS \
739 ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
740
741#define ALL_INIT_TEXT_SECTIONS \
742 ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$"
743#define ALL_EXIT_TEXT_SECTIONS \
744 ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
745
746#define ALL_INIT_SECTIONS ALL_INIT_DATA_SECTIONS, ALL_INIT_TEXT_SECTIONS
747#define ALL_EXIT_SECTIONS ALL_EXIT_DATA_SECTIONS, ALL_EXIT_TEXT_SECTIONS
748
749#define DATA_SECTIONS ".data$", ".data.rel$"
750#define TEXT_SECTIONS ".text$"
751
752#define INIT_SECTIONS ".init.data$", ".init.text$"
753#define DEV_INIT_SECTIONS ".devinit.data$", ".devinit.text$"
754#define CPU_INIT_SECTIONS ".cpuinit.data$", ".cpuinit.text$"
755#define MEM_INIT_SECTIONS ".meminit.data$", ".meminit.text$"
756
757#define EXIT_SECTIONS ".exit.data$", ".exit.text$"
758#define DEV_EXIT_SECTIONS ".devexit.data$", ".devexit.text$"
759#define CPU_EXIT_SECTIONS ".cpuexit.data$", ".cpuexit.text$"
760#define MEM_EXIT_SECTIONS ".memexit.data$", ".memexit.text$"
761
762/* init data sections */
763static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
764
765/* all init sections */
766static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
767
768/* All init and exit sections (code + data) */
769static const char *init_exit_sections[] =
770 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
771
772/* data section */
773static const char *data_sections[] = { DATA_SECTIONS, NULL };
774
775/* sections that may refer to an init/exit section with no warning */
776static const char *initref_sections[] =
777{
778 ".text.init.refok*",
779 ".exit.text.refok*",
780 ".data.init.refok*",
781 NULL
782};
783
784
785/* symbols in .data that may refer to init/exit sections */
786static const char *symbol_white_list[] =
787{
788 "*driver",
789 "*_template", /* scsi uses *_template a lot */
790 "*_timer", /* arm uses ops structures named _timer a lot */
791 "*_sht", /* scsi also used *_sht to some extent */
792 "*_ops",
793 "*_probe",
794 "*_probe_one",
795 "*_console",
796 NULL
797};
798
799static const char *head_sections[] = { ".head.text*", NULL };
800static const char *linker_symbols[] =
801 { "__init_begin", "_sinittext", "_einittext", NULL };
802
803enum mismatch {
804 NO_MISMATCH,
805 TEXT_TO_INIT,
806 DATA_TO_INIT,
807 TEXT_TO_EXIT,
808 DATA_TO_EXIT,
809 XXXINIT_TO_INIT,
810 XXXEXIT_TO_EXIT,
811 INIT_TO_EXIT,
812 EXIT_TO_INIT,
813 EXPORT_TO_INIT_EXIT,
814};
815
816struct sectioncheck {
817 const char *fromsec[20];
818 const char *tosec[20];
819 enum mismatch mismatch;
820};
821
822const struct sectioncheck sectioncheck[] = {
823/* Do not reference init/exit code/data from
824 * normal code and data
635 */ 825 */
636static int data_section(const char *name)
637{ 826{
638 if ((strcmp(name, ".data") == 0) || 827 .fromsec = { TEXT_SECTIONS, NULL },
639 (strcmp(name, ".data.rel") == 0) || 828 .tosec = { ALL_INIT_SECTIONS, NULL },
640 (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0)) 829 .mismatch = TEXT_TO_INIT,
641 return 1; 830},
642 else 831{
643 return 0; 832 .fromsec = { DATA_SECTIONS, NULL },
833 .tosec = { ALL_INIT_SECTIONS, NULL },
834 .mismatch = DATA_TO_INIT,
835},
836{
837 .fromsec = { TEXT_SECTIONS, NULL },
838 .tosec = { ALL_EXIT_SECTIONS, NULL },
839 .mismatch = TEXT_TO_EXIT,
840},
841{
842 .fromsec = { DATA_SECTIONS, NULL },
843 .tosec = { ALL_EXIT_SECTIONS, NULL },
844 .mismatch = DATA_TO_EXIT,
845},
846/* Do not reference init code/data from devinit/cpuinit/meminit code/data */
847{
848 .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL },
849 .tosec = { INIT_SECTIONS, NULL },
850 .mismatch = XXXINIT_TO_INIT,
851},
852/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
853{
854 .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL },
855 .tosec = { EXIT_SECTIONS, NULL },
856 .mismatch = XXXEXIT_TO_EXIT,
857},
858/* Do not use exit code/data from init code */
859{
860 .fromsec = { ALL_INIT_SECTIONS, NULL },
861 .tosec = { ALL_EXIT_SECTIONS, NULL },
862 .mismatch = INIT_TO_EXIT,
863},
864/* Do not use init code/data from exit code */
865{
866 .fromsec = { ALL_EXIT_SECTIONS, NULL },
867 .tosec = { ALL_INIT_SECTIONS, NULL },
868 .mismatch = EXIT_TO_INIT,
869},
870/* Do not export init/exit functions or data */
871{
872 .fromsec = { "__ksymtab*", NULL },
873 .tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL },
874 .mismatch = EXPORT_TO_INIT_EXIT
875}
876};
877
878static int section_mismatch(const char *fromsec, const char *tosec)
879{
880 int i;
881 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
882 const struct sectioncheck *check = &sectioncheck[0];
883
884 for (i = 0; i < elems; i++) {
885 if (match(fromsec, check->fromsec) &&
886 match(tosec, check->tosec))
887 return check->mismatch;
888 check++;
889 }
890 return NO_MISMATCH;
644} 891}
645 892
646/** 893/**
@@ -669,7 +916,8 @@ static int data_section(const char *name)
669 * the pattern is identified by: 916 * the pattern is identified by:
670 * tosec = init or exit section 917 * tosec = init or exit section
671 * fromsec = data section 918 * fromsec = data section
672 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer 919 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
920 * *probe_one, *_console, *_timer
673 * 921 *
674 * Pattern 3: 922 * Pattern 3:
675 * Whitelist all refereces from .text.head to .init.data 923 * Whitelist all refereces from .text.head to .init.data
@@ -684,77 +932,36 @@ static int data_section(const char *name)
684 * This pattern is identified by 932 * This pattern is identified by
685 * refsymname = __init_begin, _sinittext, _einittext 933 * refsymname = __init_begin, _sinittext, _einittext
686 * 934 *
687 * Pattern 5:
688 * Xtensa uses literal sections for constants that are accessed PC-relative.
689 * Literal sections may safely reference their text sections.
690 * (Note that the name for the literal section omits any trailing '.text')
691 * tosec = <section>[.text]
692 * fromsec = <section>.literal
693 **/ 935 **/
694static int secref_whitelist(const char *modname, const char *tosec, 936static int secref_whitelist(const char *fromsec, const char *fromsym,
695 const char *fromsec, const char *atsym, 937 const char *tosec, const char *tosym)
696 const char *refsymname)
697{ 938{
698 int len;
699 const char **s;
700 const char *pat2sym[] = {
701 "driver",
702 "_template", /* scsi uses *_template a lot */
703 "_timer", /* arm uses ops structures named _timer a lot */
704 "_sht", /* scsi also used *_sht to some extent */
705 "_ops",
706 "_probe",
707 "_probe_one",
708 "_console",
709 NULL
710 };
711
712 const char *pat3refsym[] = {
713 "__init_begin",
714 "_sinittext",
715 "_einittext",
716 NULL
717 };
718
719 /* Check for pattern 0 */ 939 /* Check for pattern 0 */
720 if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) || 940 if (match(fromsec, initref_sections))
721 (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) || 941 return 0;
722 (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
723 return 1;
724 942
725 /* Check for pattern 1 */ 943 /* Check for pattern 1 */
726 if ((strcmp(tosec, ".init.data") == 0) && 944 if (match(tosec, init_data_sections) &&
727 (strncmp(fromsec, ".data", strlen(".data")) == 0) && 945 match(fromsec, data_sections) &&
728 (strncmp(atsym, "__param", strlen("__param")) == 0)) 946 (strncmp(fromsym, "__param", strlen("__param")) == 0))
729 return 1; 947 return 0;
730 948
731 /* Check for pattern 2 */ 949 /* Check for pattern 2 */
732 if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec)) 950 if (match(tosec, init_exit_sections) &&
733 for (s = pat2sym; *s; s++) 951 match(fromsec, data_sections) &&
734 if (strrcmp(atsym, *s) == 0) 952 match(fromsym, symbol_white_list))
735 return 1; 953 return 0;
736 954
737 /* Check for pattern 3 */ 955 /* Check for pattern 3 */
738 if ((strcmp(fromsec, ".text.head") == 0) && 956 if (match(fromsec, head_sections) &&
739 ((strcmp(tosec, ".init.data") == 0) || 957 match(tosec, init_sections))
740 (strcmp(tosec, ".init.text") == 0))) 958 return 0;
741 return 1;
742 959
743 /* Check for pattern 4 */ 960 /* Check for pattern 4 */
744 for (s = pat3refsym; *s; s++) 961 if (match(tosym, linker_symbols))
745 if (strcmp(refsymname, *s) == 0) 962 return 0;
746 return 1;
747
748 /* Check for pattern 5 */
749 if (strrcmp(tosec, ".text") == 0)
750 len = strlen(tosec) - strlen(".text");
751 else
752 len = strlen(tosec);
753 if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) &&
754 (strcmp(fromsec + len, ".literal") == 0))
755 return 1;
756 963
757 return 0; 964 return 1;
758} 965}
759 966
760/** 967/**
@@ -764,10 +971,13 @@ static int secref_whitelist(const char *modname, const char *tosec,
764 * In other cases the symbol needs to be looked up in the symbol table 971 * In other cases the symbol needs to be looked up in the symbol table
765 * based on section and address. 972 * based on section and address.
766 * **/ 973 * **/
767static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, 974static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
768 Elf_Sym *relsym) 975 Elf_Sym *relsym)
769{ 976{
770 Elf_Sym *sym; 977 Elf_Sym *sym;
978 Elf_Sym *near = NULL;
979 Elf64_Sword distance = 20;
980 Elf64_Sword d;
771 981
772 if (relsym->st_name != 0) 982 if (relsym->st_name != 0)
773 return relsym; 983 return relsym;
@@ -778,8 +988,20 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
778 continue; 988 continue;
779 if (sym->st_value == addr) 989 if (sym->st_value == addr)
780 return sym; 990 return sym;
991 /* Find a symbol nearby - addr are maybe negative */
992 d = sym->st_value - addr;
993 if (d < 0)
994 d = addr - sym->st_value;
995 if (d < distance) {
996 distance = d;
997 near = sym;
998 }
781 } 999 }
782 return NULL; 1000 /* We need a close match */
1001 if (distance < 20)
1002 return near;
1003 else
1004 return NULL;
783} 1005}
784 1006
785static inline int is_arm_mapping_symbol(const char *str) 1007static inline int is_arm_mapping_symbol(const char *str)
@@ -812,121 +1034,245 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
812 * The ELF format may have a better way to detect what type of symbol 1034 * The ELF format may have a better way to detect what type of symbol
813 * it is, but this works for now. 1035 * it is, but this works for now.
814 **/ 1036 **/
815static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, 1037static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
816 const char *sec, 1038 const char *sec)
817 Elf_Sym **before, Elf_Sym **after)
818{ 1039{
819 Elf_Sym *sym; 1040 Elf_Sym *sym;
820 Elf_Ehdr *hdr = elf->hdr; 1041 Elf_Sym *near = NULL;
821 Elf_Addr beforediff = ~0; 1042 Elf_Addr distance = ~0;
822 Elf_Addr afterdiff = ~0;
823 const char *secstrings = (void *)hdr +
824 elf->sechdrs[hdr->e_shstrndx].sh_offset;
825
826 *before = NULL;
827 *after = NULL;
828 1043
829 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 1044 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
830 const char *symsec; 1045 const char *symsec;
831 1046
832 if (sym->st_shndx >= SHN_LORESERVE) 1047 if (sym->st_shndx >= SHN_LORESERVE)
833 continue; 1048 continue;
834 symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name; 1049 symsec = sec_name(elf, sym->st_shndx);
835 if (strcmp(symsec, sec) != 0) 1050 if (strcmp(symsec, sec) != 0)
836 continue; 1051 continue;
837 if (!is_valid_name(elf, sym)) 1052 if (!is_valid_name(elf, sym))
838 continue; 1053 continue;
839 if (sym->st_value <= addr) { 1054 if (sym->st_value <= addr) {
840 if ((addr - sym->st_value) < beforediff) { 1055 if ((addr - sym->st_value) < distance) {
841 beforediff = addr - sym->st_value; 1056 distance = addr - sym->st_value;
842 *before = sym; 1057 near = sym;
843 } 1058 } else if ((addr - sym->st_value) == distance) {
844 else if ((addr - sym->st_value) == beforediff) { 1059 near = sym;
845 *before = sym;
846 } 1060 }
847 } 1061 }
1062 }
1063 return near;
1064}
1065
1066/*
1067 * Convert a section name to the function/data attribute
1068 * .init.text => __init
1069 * .cpuinit.data => __cpudata
1070 * .memexitconst => __memconst
1071 * etc.
1072*/
1073static char *sec2annotation(const char *s)
1074{
1075 if (match(s, init_exit_sections)) {
1076 char *p = malloc(20);
1077 char *r = p;
1078
1079 *p++ = '_';
1080 *p++ = '_';
1081 if (*s == '.')
1082 s++;
1083 while (*s && *s != '.')
1084 *p++ = *s++;
1085 *p = '\0';
1086 if (*s == '.')
1087 s++;
1088 if (strstr(s, "rodata") != NULL)
1089 strcat(p, "const ");
1090 else if (strstr(s, "data") != NULL)
1091 strcat(p, "data ");
848 else 1092 else
849 { 1093 strcat(p, " ");
850 if ((sym->st_value - addr) < afterdiff) { 1094 return r; /* we leak her but we do not care */
851 afterdiff = sym->st_value - addr; 1095 } else {
852 *after = sym; 1096 return "";
853 }
854 else if ((sym->st_value - addr) == afterdiff) {
855 *after = sym;
856 }
857 }
858 } 1097 }
859} 1098}
860 1099
861/** 1100static int is_function(Elf_Sym *sym)
1101{
1102 if (sym)
1103 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1104 else
1105 return 0;
1106}
1107
1108/*
862 * Print a warning about a section mismatch. 1109 * Print a warning about a section mismatch.
863 * Try to find symbols near it so user can find it. 1110 * Try to find symbols near it so user can find it.
864 * Check whitelist before warning - it may be a false positive. 1111 * Check whitelist before warning - it may be a false positive.
865 **/ 1112 */
866static void warn_sec_mismatch(const char *modname, const char *fromsec, 1113static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
867 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) 1114 const char *fromsec,
1115 unsigned long long fromaddr,
1116 const char *fromsym,
1117 int from_is_func,
1118 const char *tosec, const char *tosym,
1119 int to_is_func)
868{ 1120{
869 const char *refsymname = ""; 1121 const char *from, *from_p;
870 Elf_Sym *before, *after; 1122 const char *to, *to_p;
871 Elf_Sym *refsym; 1123 from = from_is_func ? "function" : "variable";
872 Elf_Ehdr *hdr = elf->hdr; 1124 from_p = from_is_func ? "()" : "";
873 Elf_Shdr *sechdrs = elf->sechdrs; 1125 to = to_is_func ? "function" : "variable";
874 const char *secstrings = (void *)hdr + 1126 to_p = to_is_func ? "()" : "";
875 sechdrs[hdr->e_shstrndx].sh_offset; 1127
876 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; 1128 fprintf(stderr, "WARNING: %s(%s+0x%llx): Section mismatch in"
877 1129 " reference from the %s %s%s to the %s %s:%s%s\n",
878 find_symbols_between(elf, r.r_offset, fromsec, &before, &after); 1130 modname, fromsec, fromaddr, from, fromsym, from_p,
879 1131 to, tosec, tosym, to_p);
880 refsym = find_elf_symbol(elf, r.r_addend, sym); 1132
881 if (refsym && strlen(elf->strtab + refsym->st_name)) 1133 sec_mismatch_count++;
882 refsymname = elf->strtab + refsym->st_name; 1134 if (!sec_mismatch_verbose)
883
884 /* check whitelist - we may ignore it */
885 if (secref_whitelist(modname, secname, fromsec,
886 before ? elf->strtab + before->st_name : "",
887 refsymname))
888 return; 1135 return;
889 1136
890 if (before && after) { 1137 switch (mismatch) {
891 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " 1138 case TEXT_TO_INIT:
892 "(between '%s' and '%s')\n", 1139 fprintf(stderr,
893 modname, fromsec, (unsigned long long)r.r_offset, 1140 "The function %s %s() references\n"
894 secname, refsymname, 1141 "the %s %s%s%s.\n"
895 elf->strtab + before->st_name, 1142 "This is often because %s lacks a %s\n"
896 elf->strtab + after->st_name); 1143 "annotation or the annotation of %s is wrong.\n",
897 } else if (before) { 1144 sec2annotation(fromsec), fromsym,
898 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " 1145 to, sec2annotation(tosec), tosym, to_p,
899 "(after '%s')\n", 1146 fromsym, sec2annotation(tosec), tosym);
900 modname, fromsec, (unsigned long long)r.r_offset, 1147 break;
901 secname, refsymname, 1148 case DATA_TO_INIT: {
902 elf->strtab + before->st_name); 1149 const char **s = symbol_white_list;
903 } else if (after) { 1150 fprintf(stderr,
904 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " 1151 "The variable %s references\n"
905 "before '%s' (at offset -0x%llx)\n", 1152 "the %s %s%s%s\n"
906 modname, fromsec, (unsigned long long)r.r_offset, 1153 "If the reference is valid then annotate the\n"
907 secname, refsymname, 1154 "variable with __init* (see linux/init.h) "
908 elf->strtab + after->st_name); 1155 "or name the variable:\n",
909 } else { 1156 fromsym, to, sec2annotation(tosec), tosym, to_p);
910 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", 1157 while (*s)
911 modname, fromsec, (unsigned long long)r.r_offset, 1158 fprintf(stderr, "%s, ", *s++);
912 secname, refsymname); 1159 fprintf(stderr, "\n");
1160 break;
1161 }
1162 case TEXT_TO_EXIT:
1163 fprintf(stderr,
1164 "The function %s() references a %s in an exit section.\n"
1165 "Often the %s %s%s has valid usage outside the exit section\n"
1166 "and the fix is to remove the %sannotation of %s.\n",
1167 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
1168 break;
1169 case DATA_TO_EXIT: {
1170 const char **s = symbol_white_list;
1171 fprintf(stderr,
1172 "The variable %s references\n"
1173 "the %s %s%s%s\n"
1174 "If the reference is valid then annotate the\n"
1175 "variable with __exit* (see linux/init.h) or "
1176 "name the variable:\n",
1177 fromsym, to, sec2annotation(tosec), tosym, to_p);
1178 while (*s)
1179 fprintf(stderr, "%s, ", *s++);
1180 fprintf(stderr, "\n");
1181 break;
1182 }
1183 case XXXINIT_TO_INIT:
1184 case XXXEXIT_TO_EXIT:
1185 fprintf(stderr,
1186 "The %s %s%s%s references\n"
1187 "a %s %s%s%s.\n"
1188 "If %s is only used by %s then\n"
1189 "annotate %s with a matching annotation.\n",
1190 from, sec2annotation(fromsec), fromsym, from_p,
1191 to, sec2annotation(tosec), tosym, to_p,
1192 fromsym, tosym, fromsym);
1193 break;
1194 case INIT_TO_EXIT:
1195 fprintf(stderr,
1196 "The %s %s%s%s references\n"
1197 "a %s %s%s%s.\n"
1198 "This is often seen when error handling "
1199 "in the init function\n"
1200 "uses functionality in the exit path.\n"
1201 "The fix is often to remove the %sannotation of\n"
1202 "%s%s so it may be used outside an exit section.\n",
1203 from, sec2annotation(fromsec), fromsym, from_p,
1204 to, sec2annotation(tosec), tosym, to_p,
1205 sec2annotation(tosec), tosym, to_p);
1206 break;
1207 case EXIT_TO_INIT:
1208 fprintf(stderr,
1209 "The %s %s%s%s references\n"
1210 "a %s %s%s%s.\n"
1211 "This is often seen when error handling "
1212 "in the exit function\n"
1213 "uses functionality in the init path.\n"
1214 "The fix is often to remove the %sannotation of\n"
1215 "%s%s so it may be used outside an init section.\n",
1216 from, sec2annotation(fromsec), fromsym, from_p,
1217 to, sec2annotation(tosec), tosym, to_p,
1218 sec2annotation(tosec), tosym, to_p);
1219 break;
1220 case EXPORT_TO_INIT_EXIT:
1221 fprintf(stderr,
1222 "The symbol %s is exported and annotated %s\n"
1223 "Fix this by removing the %sannotation of %s "
1224 "or drop the export.\n",
1225 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
1226 case NO_MISMATCH:
1227 /* To get warnings on missing members */
1228 break;
1229 }
1230 fprintf(stderr, "\n");
1231}
1232
1233static void check_section_mismatch(const char *modname, struct elf_info *elf,
1234 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1235{
1236 const char *tosec;
1237 enum mismatch mismatch;
1238
1239 tosec = sec_name(elf, sym->st_shndx);
1240 mismatch = section_mismatch(fromsec, tosec);
1241 if (mismatch != NO_MISMATCH) {
1242 Elf_Sym *to;
1243 Elf_Sym *from;
1244 const char *tosym;
1245 const char *fromsym;
1246
1247 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1248 fromsym = sym_name(elf, from);
1249 to = find_elf_symbol(elf, r->r_addend, sym);
1250 tosym = sym_name(elf, to);
1251
1252 /* check whitelist - we may ignore it */
1253 if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
1254 report_sec_mismatch(modname, mismatch,
1255 fromsec, r->r_offset, fromsym,
1256 is_function(from), tosec, tosym,
1257 is_function(to));
1258 }
913 } 1259 }
914} 1260}
915 1261
916static unsigned int *reloc_location(struct elf_info *elf, 1262static unsigned int *reloc_location(struct elf_info *elf,
917 int rsection, Elf_Rela *r) 1263 Elf_Shdr *sechdr, Elf_Rela *r)
918{ 1264{
919 Elf_Shdr *sechdrs = elf->sechdrs; 1265 Elf_Shdr *sechdrs = elf->sechdrs;
920 int section = sechdrs[rsection].sh_info; 1266 int section = sechdr->sh_info;
921 1267
922 return (void *)elf->hdr + sechdrs[section].sh_offset + 1268 return (void *)elf->hdr + sechdrs[section].sh_offset +
923 (r->r_offset - sechdrs[section].sh_addr); 1269 (r->r_offset - sechdrs[section].sh_addr);
924} 1270}
925 1271
926static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 1272static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
927{ 1273{
928 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1274 unsigned int r_typ = ELF_R_TYPE(r->r_info);
929 unsigned int *location = reloc_location(elf, rsection, r); 1275 unsigned int *location = reloc_location(elf, sechdr, r);
930 1276
931 switch (r_typ) { 1277 switch (r_typ) {
932 case R_386_32: 1278 case R_386_32:
@@ -942,19 +1288,21 @@ static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
942 return 0; 1288 return 0;
943} 1289}
944 1290
945static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 1291static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
946{ 1292{
947 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1293 unsigned int r_typ = ELF_R_TYPE(r->r_info);
948 1294
949 switch (r_typ) { 1295 switch (r_typ) {
950 case R_ARM_ABS32: 1296 case R_ARM_ABS32:
951 /* From ARM ABI: (S + A) | T */ 1297 /* From ARM ABI: (S + A) | T */
952 r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info)); 1298 r->r_addend = (int)(long)
1299 (elf->symtab_start + ELF_R_SYM(r->r_info));
953 break; 1300 break;
954 case R_ARM_PC24: 1301 case R_ARM_PC24:
955 /* From ARM ABI: ((S + A) | T) - P */ 1302 /* From ARM ABI: ((S + A) | T) - P */
956 r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset + 1303 r->r_addend = (int)(long)(elf->hdr +
957 (r->r_offset - elf->sechdrs[rsection].sh_addr)); 1304 sechdr->sh_offset +
1305 (r->r_offset - sechdr->sh_addr));
958 break; 1306 break;
959 default: 1307 default:
960 return 1; 1308 return 1;
@@ -962,10 +1310,10 @@ static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
962 return 0; 1310 return 0;
963} 1311}
964 1312
965static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 1313static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
966{ 1314{
967 unsigned int r_typ = ELF_R_TYPE(r->r_info); 1315 unsigned int r_typ = ELF_R_TYPE(r->r_info);
968 unsigned int *location = reloc_location(elf, rsection, r); 1316 unsigned int *location = reloc_location(elf, sechdr, r);
969 unsigned int inst; 1317 unsigned int inst;
970 1318
971 if (r_typ == R_MIPS_HI16) 1319 if (r_typ == R_MIPS_HI16)
@@ -985,6 +1333,108 @@ static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
985 return 0; 1333 return 0;
986} 1334}
987 1335
1336static void section_rela(const char *modname, struct elf_info *elf,
1337 Elf_Shdr *sechdr)
1338{
1339 Elf_Sym *sym;
1340 Elf_Rela *rela;
1341 Elf_Rela r;
1342 unsigned int r_sym;
1343 const char *fromsec;
1344
1345 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
1346 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1347
1348 fromsec = sech_name(elf, sechdr);
1349 fromsec += strlen(".rela");
1350 /* if from section (name) is know good then skip it */
1351 if (check_section(modname, fromsec))
1352 return;
1353
1354 for (rela = start; rela < stop; rela++) {
1355 r.r_offset = TO_NATIVE(rela->r_offset);
1356#if KERNEL_ELFCLASS == ELFCLASS64
1357 if (elf->hdr->e_machine == EM_MIPS) {
1358 unsigned int r_typ;
1359 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1360 r_sym = TO_NATIVE(r_sym);
1361 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1362 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1363 } else {
1364 r.r_info = TO_NATIVE(rela->r_info);
1365 r_sym = ELF_R_SYM(r.r_info);
1366 }
1367#else
1368 r.r_info = TO_NATIVE(rela->r_info);
1369 r_sym = ELF_R_SYM(r.r_info);
1370#endif
1371 r.r_addend = TO_NATIVE(rela->r_addend);
1372 sym = elf->symtab_start + r_sym;
1373 /* Skip special sections */
1374 if (sym->st_shndx >= SHN_LORESERVE)
1375 continue;
1376 check_section_mismatch(modname, elf, &r, sym, fromsec);
1377 }
1378}
1379
1380static void section_rel(const char *modname, struct elf_info *elf,
1381 Elf_Shdr *sechdr)
1382{
1383 Elf_Sym *sym;
1384 Elf_Rel *rel;
1385 Elf_Rela r;
1386 unsigned int r_sym;
1387 const char *fromsec;
1388
1389 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
1390 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1391
1392 fromsec = sech_name(elf, sechdr);
1393 fromsec += strlen(".rel");
1394 /* if from section (name) is know good then skip it */
1395 if (check_section(modname, fromsec))
1396 return;
1397
1398 for (rel = start; rel < stop; rel++) {
1399 r.r_offset = TO_NATIVE(rel->r_offset);
1400#if KERNEL_ELFCLASS == ELFCLASS64
1401 if (elf->hdr->e_machine == EM_MIPS) {
1402 unsigned int r_typ;
1403 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1404 r_sym = TO_NATIVE(r_sym);
1405 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1406 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1407 } else {
1408 r.r_info = TO_NATIVE(rel->r_info);
1409 r_sym = ELF_R_SYM(r.r_info);
1410 }
1411#else
1412 r.r_info = TO_NATIVE(rel->r_info);
1413 r_sym = ELF_R_SYM(r.r_info);
1414#endif
1415 r.r_addend = 0;
1416 switch (elf->hdr->e_machine) {
1417 case EM_386:
1418 if (addend_386_rel(elf, sechdr, &r))
1419 continue;
1420 break;
1421 case EM_ARM:
1422 if (addend_arm_rel(elf, sechdr, &r))
1423 continue;
1424 break;
1425 case EM_MIPS:
1426 if (addend_mips_rel(elf, sechdr, &r))
1427 continue;
1428 break;
1429 }
1430 sym = elf->symtab_start + r_sym;
1431 /* Skip special sections */
1432 if (sym->st_shndx >= SHN_LORESERVE)
1433 continue;
1434 check_section_mismatch(modname, elf, &r, sym, fromsec);
1435 }
1436}
1437
988/** 1438/**
989 * A module includes a number of sections that are discarded 1439 * A module includes a number of sections that are discarded
990 * either when loaded or when used as built-in. 1440 * either when loaded or when used as built-in.
@@ -998,257 +1448,21 @@ static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
998 * be discarded and warns about it. 1448 * be discarded and warns about it.
999 **/ 1449 **/
1000static void check_sec_ref(struct module *mod, const char *modname, 1450static void check_sec_ref(struct module *mod, const char *modname,
1001 struct elf_info *elf, 1451 struct elf_info *elf)
1002 int section(const char*),
1003 int section_ref_ok(const char *))
1004{ 1452{
1005 int i; 1453 int i;
1006 Elf_Sym *sym;
1007 Elf_Ehdr *hdr = elf->hdr;
1008 Elf_Shdr *sechdrs = elf->sechdrs; 1454 Elf_Shdr *sechdrs = elf->sechdrs;
1009 const char *secstrings = (void *)hdr +
1010 sechdrs[hdr->e_shstrndx].sh_offset;
1011 1455
1012 /* Walk through all sections */ 1456 /* Walk through all sections */
1013 for (i = 0; i < hdr->e_shnum; i++) { 1457 for (i = 0; i < elf->hdr->e_shnum; i++) {
1014 const char *name = secstrings + sechdrs[i].sh_name;
1015 const char *secname;
1016 Elf_Rela r;
1017 unsigned int r_sym;
1018 /* We want to process only relocation sections and not .init */ 1458 /* We want to process only relocation sections and not .init */
1019 if (sechdrs[i].sh_type == SHT_RELA) { 1459 if (sechdrs[i].sh_type == SHT_RELA)
1020 Elf_Rela *rela; 1460 section_rela(modname, elf, &elf->sechdrs[i]);
1021 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; 1461 else if (sechdrs[i].sh_type == SHT_REL)
1022 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; 1462 section_rel(modname, elf, &elf->sechdrs[i]);
1023 name += strlen(".rela");
1024 if (section_ref_ok(name))
1025 continue;
1026
1027 for (rela = start; rela < stop; rela++) {
1028 r.r_offset = TO_NATIVE(rela->r_offset);
1029#if KERNEL_ELFCLASS == ELFCLASS64
1030 if (hdr->e_machine == EM_MIPS) {
1031 unsigned int r_typ;
1032 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1033 r_sym = TO_NATIVE(r_sym);
1034 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1035 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1036 } else {
1037 r.r_info = TO_NATIVE(rela->r_info);
1038 r_sym = ELF_R_SYM(r.r_info);
1039 }
1040#else
1041 r.r_info = TO_NATIVE(rela->r_info);
1042 r_sym = ELF_R_SYM(r.r_info);
1043#endif
1044 r.r_addend = TO_NATIVE(rela->r_addend);
1045 sym = elf->symtab_start + r_sym;
1046 /* Skip special sections */
1047 if (sym->st_shndx >= SHN_LORESERVE)
1048 continue;
1049
1050 secname = secstrings +
1051 sechdrs[sym->st_shndx].sh_name;
1052 if (section(secname))
1053 warn_sec_mismatch(modname, name,
1054 elf, sym, r);
1055 }
1056 } else if (sechdrs[i].sh_type == SHT_REL) {
1057 Elf_Rel *rel;
1058 Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
1059 Elf_Rel *stop = (void*)start + sechdrs[i].sh_size;
1060 name += strlen(".rel");
1061 if (section_ref_ok(name))
1062 continue;
1063
1064 for (rel = start; rel < stop; rel++) {
1065 r.r_offset = TO_NATIVE(rel->r_offset);
1066#if KERNEL_ELFCLASS == ELFCLASS64
1067 if (hdr->e_machine == EM_MIPS) {
1068 unsigned int r_typ;
1069 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1070 r_sym = TO_NATIVE(r_sym);
1071 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1072 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1073 } else {
1074 r.r_info = TO_NATIVE(rel->r_info);
1075 r_sym = ELF_R_SYM(r.r_info);
1076 }
1077#else
1078 r.r_info = TO_NATIVE(rel->r_info);
1079 r_sym = ELF_R_SYM(r.r_info);
1080#endif
1081 r.r_addend = 0;
1082 switch (hdr->e_machine) {
1083 case EM_386:
1084 if (addend_386_rel(elf, i, &r))
1085 continue;
1086 break;
1087 case EM_ARM:
1088 if(addend_arm_rel(elf, i, &r))
1089 continue;
1090 break;
1091 case EM_MIPS:
1092 if (addend_mips_rel(elf, i, &r))
1093 continue;
1094 break;
1095 }
1096 sym = elf->symtab_start + r_sym;
1097 /* Skip special sections */
1098 if (sym->st_shndx >= SHN_LORESERVE)
1099 continue;
1100
1101 secname = secstrings +
1102 sechdrs[sym->st_shndx].sh_name;
1103 if (section(secname))
1104 warn_sec_mismatch(modname, name,
1105 elf, sym, r);
1106 }
1107 }
1108 } 1463 }
1109} 1464}
1110 1465
1111/*
1112 * Identify sections from which references to either a
1113 * .init or a .exit section is OK.
1114 *
1115 * [OPD] Keith Ownes <kaos@sgi.com> commented:
1116 * For our future {in}sanity, add a comment that this is the ppc .opd
1117 * section, not the ia64 .opd section.
1118 * ia64 .opd should not point to discarded sections.
1119 * [.rodata] like for .init.text we ignore .rodata references -same reason
1120 */
1121static int initexit_section_ref_ok(const char *name)
1122{
1123 const char **s;
1124 /* Absolute section names */
1125 const char *namelist1[] = {
1126 "__bug_table", /* used by powerpc for BUG() */
1127 "__ex_table",
1128 ".altinstructions",
1129 ".cranges", /* used by sh64 */
1130 ".fixup",
1131 ".machvec", /* ia64 + powerpc uses these */
1132 ".machine.desc",
1133 ".opd", /* See comment [OPD] */
1134 "__dbe_table",
1135 ".parainstructions",
1136 ".pdr",
1137 ".plt", /* seen on ARCH=um build on x86_64. Harmless */
1138 ".smp_locks",
1139 ".stab",
1140 ".m68k_fixup",
1141 ".xt.prop", /* xtensa informational section */
1142 ".xt.lit", /* xtensa informational section */
1143 NULL
1144 };
1145 /* Start of section names */
1146 const char *namelist2[] = {
1147 ".debug",
1148 ".eh_frame",
1149 ".note", /* ignore ELF notes - may contain anything */
1150 ".got", /* powerpc - global offset table */
1151 ".toc", /* powerpc - table of contents */
1152 NULL
1153 };
1154 /* part of section name */
1155 const char *namelist3 [] = {
1156 ".unwind", /* Sample: IA_64.unwind.exit.text */
1157 NULL
1158 };
1159
1160 for (s = namelist1; *s; s++)
1161 if (strcmp(*s, name) == 0)
1162 return 1;
1163 for (s = namelist2; *s; s++)
1164 if (strncmp(*s, name, strlen(*s)) == 0)
1165 return 1;
1166 for (s = namelist3; *s; s++)
1167 if (strstr(name, *s) != NULL)
1168 return 1;
1169 return 0;
1170}
1171
1172
1173/*
1174 * Identify sections from which references to a .init section is OK.
1175 *
1176 * Unfortunately references to read only data that referenced .init
1177 * sections had to be excluded. Almost all of these are false
1178 * positives, they are created by gcc. The downside of excluding rodata
1179 * is that there really are some user references from rodata to
1180 * init code, e.g. drivers/video/vgacon.c:
1181 *
1182 * const struct consw vga_con = {
1183 * con_startup: vgacon_startup,
1184 *
1185 * where vgacon_startup is __init. If you want to wade through the false
1186 * positives, take out the check for rodata.
1187 */
1188static int init_section_ref_ok(const char *name)
1189{
1190 const char **s;
1191 /* Absolute section names */
1192 const char *namelist1[] = {
1193 "__dbe_table", /* MIPS generate these */
1194 "__ftr_fixup", /* powerpc cpu feature fixup */
1195 "__fw_ftr_fixup", /* powerpc firmware feature fixup */
1196 "__param",
1197 ".data.rel.ro", /* used by parisc64 */
1198 ".init",
1199 ".text.lock",
1200 NULL
1201 };
1202 /* Start of section names */
1203 const char *namelist2[] = {
1204 ".init.",
1205 ".pci_fixup",
1206 ".rodata",
1207 NULL
1208 };
1209
1210 if (initexit_section_ref_ok(name))
1211 return 1;
1212
1213 for (s = namelist1; *s; s++)
1214 if (strcmp(*s, name) == 0)
1215 return 1;
1216 for (s = namelist2; *s; s++)
1217 if (strncmp(*s, name, strlen(*s)) == 0)
1218 return 1;
1219
1220 /* If section name ends with ".init" we allow references
1221 * as is the case with .initcallN.init, .early_param.init, .taglist.init etc
1222 */
1223 if (strrcmp(name, ".init") == 0)
1224 return 1;
1225 return 0;
1226}
1227
1228/*
1229 * Identify sections from which references to a .exit section is OK.
1230 */
1231static int exit_section_ref_ok(const char *name)
1232{
1233 const char **s;
1234 /* Absolute section names */
1235 const char *namelist1[] = {
1236 ".exit.data",
1237 ".exit.text",
1238 ".exitcall.exit",
1239 ".rodata",
1240 NULL
1241 };
1242
1243 if (initexit_section_ref_ok(name))
1244 return 1;
1245
1246 for (s = namelist1; *s; s++)
1247 if (strcmp(*s, name) == 0)
1248 return 1;
1249 return 0;
1250}
1251
1252static void read_symbols(char *modname) 1466static void read_symbols(char *modname)
1253{ 1467{
1254 const char *symname; 1468 const char *symname;
@@ -1288,10 +1502,9 @@ static void read_symbols(char *modname)
1288 handle_modversions(mod, &info, sym, symname); 1502 handle_modversions(mod, &info, sym, symname);
1289 handle_moddevtable(mod, &info, sym, symname); 1503 handle_moddevtable(mod, &info, sym, symname);
1290 } 1504 }
1291 if (is_vmlinux(modname) && vmlinux_section_warnings) { 1505 if (!is_vmlinux(modname) ||
1292 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); 1506 (is_vmlinux(modname) && vmlinux_section_warnings))
1293 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); 1507 check_sec_ref(mod, modname, &info);
1294 }
1295 1508
1296 version = get_modinfo(info.modinfo, info.modinfo_len, "version"); 1509 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1297 if (version) 1510 if (version)
@@ -1365,7 +1578,7 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
1365 } 1578 }
1366} 1579}
1367 1580
1368static void check_for_unused(enum export exp, const char* m, const char* s) 1581static void check_for_unused(enum export exp, const char *m, const char *s)
1369{ 1582{
1370 const char *e = is_vmlinux(m) ?"":".ko"; 1583 const char *e = is_vmlinux(m) ?"":".ko";
1371 1584
@@ -1398,7 +1611,7 @@ static void check_exports(struct module *mod)
1398 if (!mod->gpl_compatible) 1611 if (!mod->gpl_compatible)
1399 check_for_gpl_usage(exp->export, basename, exp->name); 1612 check_for_gpl_usage(exp->export, basename, exp->name);
1400 check_for_unused(exp->export, basename, exp->name); 1613 check_for_unused(exp->export, basename, exp->name);
1401 } 1614 }
1402} 1615}
1403 1616
1404/** 1617/**
@@ -1458,13 +1671,12 @@ static int add_versions(struct buffer *b, struct module *mod)
1458 1671
1459 buf_printf(b, "\n"); 1672 buf_printf(b, "\n");
1460 buf_printf(b, "static const struct modversion_info ____versions[]\n"); 1673 buf_printf(b, "static const struct modversion_info ____versions[]\n");
1461 buf_printf(b, "__attribute_used__\n"); 1674 buf_printf(b, "__used\n");
1462 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); 1675 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
1463 1676
1464 for (s = mod->unres; s; s = s->next) { 1677 for (s = mod->unres; s; s = s->next) {
1465 if (!s->module) { 1678 if (!s->module)
1466 continue; 1679 continue;
1467 }
1468 if (!s->crc_valid) { 1680 if (!s->crc_valid) {
1469 warn("\"%s\" [%s.ko] has no CRC!\n", 1681 warn("\"%s\" [%s.ko] has no CRC!\n",
1470 s->name, mod->name); 1682 s->name, mod->name);
@@ -1485,13 +1697,12 @@ static void add_depends(struct buffer *b, struct module *mod,
1485 struct module *m; 1697 struct module *m;
1486 int first = 1; 1698 int first = 1;
1487 1699
1488 for (m = modules; m; m = m->next) { 1700 for (m = modules; m; m = m->next)
1489 m->seen = is_vmlinux(m->name); 1701 m->seen = is_vmlinux(m->name);
1490 }
1491 1702
1492 buf_printf(b, "\n"); 1703 buf_printf(b, "\n");
1493 buf_printf(b, "static const char __module_depends[]\n"); 1704 buf_printf(b, "static const char __module_depends[]\n");
1494 buf_printf(b, "__attribute_used__\n"); 1705 buf_printf(b, "__used\n");
1495 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); 1706 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1496 buf_printf(b, "\"depends="); 1707 buf_printf(b, "\"depends=");
1497 for (s = mod->unres; s; s = s->next) { 1708 for (s = mod->unres; s; s = s->next) {
@@ -1503,7 +1714,8 @@ static void add_depends(struct buffer *b, struct module *mod,
1503 continue; 1714 continue;
1504 1715
1505 s->module->seen = 1; 1716 s->module->seen = 1;
1506 if ((p = strrchr(s->module->name, '/')) != NULL) 1717 p = strrchr(s->module->name, '/');
1718 if (p)
1507 p++; 1719 p++;
1508 else 1720 else
1509 p = s->module->name; 1721 p = s->module->name;
@@ -1575,7 +1787,7 @@ static void read_dump(const char *fname, unsigned int kernel)
1575 void *file = grab_file(fname, &size); 1787 void *file = grab_file(fname, &size);
1576 char *line; 1788 char *line;
1577 1789
1578 if (!file) 1790 if (!file)
1579 /* No symbol versions, silently ignore */ 1791 /* No symbol versions, silently ignore */
1580 return; 1792 return;
1581 1793
@@ -1598,11 +1810,10 @@ static void read_dump(const char *fname, unsigned int kernel)
1598 crc = strtoul(line, &d, 16); 1810 crc = strtoul(line, &d, 16);
1599 if (*symname == '\0' || *modname == '\0' || *d != '\0') 1811 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1600 goto fail; 1812 goto fail;
1601 1813 mod = find_module(modname);
1602 if (!(mod = find_module(modname))) { 1814 if (!mod) {
1603 if (is_vmlinux(modname)) { 1815 if (is_vmlinux(modname))
1604 have_vmlinux = 1; 1816 have_vmlinux = 1;
1605 }
1606 mod = new_module(NOFAIL(strdup(modname))); 1817 mod = new_module(NOFAIL(strdup(modname)));
1607 mod->skip = 1; 1818 mod->skip = 1;
1608 } 1819 }
@@ -1653,38 +1864,40 @@ int main(int argc, char **argv)
1653{ 1864{
1654 struct module *mod; 1865 struct module *mod;
1655 struct buffer buf = { }; 1866 struct buffer buf = { };
1656 char fname[SZ];
1657 char *kernel_read = NULL, *module_read = NULL; 1867 char *kernel_read = NULL, *module_read = NULL;
1658 char *dump_write = NULL; 1868 char *dump_write = NULL;
1659 int opt; 1869 int opt;
1660 int err; 1870 int err;
1661 1871
1662 while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) { 1872 while ((opt = getopt(argc, argv, "i:I:msSo:aw")) != -1) {
1663 switch(opt) { 1873 switch (opt) {
1664 case 'i': 1874 case 'i':
1665 kernel_read = optarg; 1875 kernel_read = optarg;
1666 break; 1876 break;
1667 case 'I': 1877 case 'I':
1668 module_read = optarg; 1878 module_read = optarg;
1669 external_module = 1; 1879 external_module = 1;
1670 break; 1880 break;
1671 case 'm': 1881 case 'm':
1672 modversions = 1; 1882 modversions = 1;
1673 break; 1883 break;
1674 case 'o': 1884 case 'o':
1675 dump_write = optarg; 1885 dump_write = optarg;
1676 break; 1886 break;
1677 case 'a': 1887 case 'a':
1678 all_versions = 1; 1888 all_versions = 1;
1679 break; 1889 break;
1680 case 's': 1890 case 's':
1681 vmlinux_section_warnings = 0; 1891 vmlinux_section_warnings = 0;
1682 break; 1892 break;
1683 case 'w': 1893 case 'S':
1684 warn_unresolved = 1; 1894 sec_mismatch_verbose = 0;
1685 break; 1895 break;
1686 default: 1896 case 'w':
1687 exit(1); 1897 warn_unresolved = 1;
1898 break;
1899 default:
1900 exit(1);
1688 } 1901 }
1689 } 1902 }
1690 1903
@@ -1693,9 +1906,8 @@ int main(int argc, char **argv)
1693 if (module_read) 1906 if (module_read)
1694 read_dump(module_read, 0); 1907 read_dump(module_read, 0);
1695 1908
1696 while (optind < argc) { 1909 while (optind < argc)
1697 read_symbols(argv[optind++]); 1910 read_symbols(argv[optind++]);
1698 }
1699 1911
1700 for (mod = modules; mod; mod = mod->next) { 1912 for (mod = modules; mod; mod = mod->next) {
1701 if (mod->skip) 1913 if (mod->skip)
@@ -1706,6 +1918,8 @@ int main(int argc, char **argv)
1706 err = 0; 1918 err = 0;
1707 1919
1708 for (mod = modules; mod; mod = mod->next) { 1920 for (mod = modules; mod; mod = mod->next) {
1921 char fname[strlen(mod->name) + 10];
1922
1709 if (mod->skip) 1923 if (mod->skip)
1710 continue; 1924 continue;
1711 1925
@@ -1723,6 +1937,12 @@ int main(int argc, char **argv)
1723 1937
1724 if (dump_write) 1938 if (dump_write)
1725 write_dump(dump_write); 1939 write_dump(dump_write);
1940 if (sec_mismatch_count && !sec_mismatch_verbose)
1941 fprintf(stderr, "modpost: Found %d section mismatch(es).\n"
1942 "To see additional details select \"Enable full "
1943 "Section mismatch analysis\"\n"
1944 "in the Kernel Hacking menu "
1945 "(CONFIG_SECTION_MISMATCH).\n", sec_mismatch_count);
1726 1946
1727 return err; 1947 return err;
1728} 1948}
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 0ffed17ec20c..999f15e0e008 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -17,6 +17,7 @@
17#define Elf_Shdr Elf32_Shdr 17#define Elf_Shdr Elf32_Shdr
18#define Elf_Sym Elf32_Sym 18#define Elf_Sym Elf32_Sym
19#define Elf_Addr Elf32_Addr 19#define Elf_Addr Elf32_Addr
20#define Elf_Sword Elf64_Sword
20#define Elf_Section Elf32_Half 21#define Elf_Section Elf32_Half
21#define ELF_ST_BIND ELF32_ST_BIND 22#define ELF_ST_BIND ELF32_ST_BIND
22#define ELF_ST_TYPE ELF32_ST_TYPE 23#define ELF_ST_TYPE ELF32_ST_TYPE
@@ -31,6 +32,7 @@
31#define Elf_Shdr Elf64_Shdr 32#define Elf_Shdr Elf64_Shdr
32#define Elf_Sym Elf64_Sym 33#define Elf_Sym Elf64_Sym
33#define Elf_Addr Elf64_Addr 34#define Elf_Addr Elf64_Addr
35#define Elf_Sword Elf64_Sxword
34#define Elf_Section Elf64_Half 36#define Elf_Section Elf64_Half
35#define ELF_ST_BIND ELF64_ST_BIND 37#define ELF_ST_BIND ELF64_ST_BIND
36#define ELF_ST_TYPE ELF64_ST_TYPE 38#define ELF_ST_TYPE ELF64_ST_TYPE
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index 7c434e037e7f..5e326078a4a2 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -89,9 +89,8 @@ clean-dirs += $(objtree)/tar-install/
89# Help text displayed when executing 'make help' 89# Help text displayed when executing 'make help'
90# --------------------------------------------------------------------------- 90# ---------------------------------------------------------------------------
91help: FORCE 91help: FORCE
92 @echo ' rpm-pkg - Build the kernel as an RPM package' 92 @echo ' rpm-pkg - Build both source and binary RPM kernel packages'
93 @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel' 93 @echo ' binrpm-pkg - Build only the binary kernel package'
94 @echo ' and modules'
95 @echo ' deb-pkg - Build the kernel as an deb package' 94 @echo ' deb-pkg - Build the kernel as an deb package'
96 @echo ' tar-pkg - Build the kernel as an uncompressed tarball' 95 @echo ' tar-pkg - Build the kernel as an uncompressed tarball'
97 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' 96 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index aa0ccdbd1f47..28574ae55170 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -69,8 +69,8 @@ cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
69# Install arch-specific kernel image(s) 69# Install arch-specific kernel image(s)
70# 70#
71case "${ARCH}" in 71case "${ARCH}" in
72 i386|x86_64) 72 x86|i386|x86_64)
73 [ -f "${objtree}/arch/$ARCH/boot/bzImage" ] && cp -v -- "${objtree}/arch/$ARCH/boot/bzImage" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" 73 [ -f "${objtree}/arch/x86/boot/bzImage" ] && cp -v -- "${objtree}/arch/x86/boot/bzImage" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
74 ;; 74 ;;
75 alpha) 75 alpha)
76 [ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}" 76 [ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
diff --git a/scripts/patch-kernel b/scripts/patch-kernel
index 67e4b1868e50..ece46ef0ba54 100755
--- a/scripts/patch-kernel
+++ b/scripts/patch-kernel
@@ -65,7 +65,7 @@ sourcedir=${1-/usr/src/linux}
65patchdir=${2-.} 65patchdir=${2-.}
66stopvers=${3-default} 66stopvers=${3-default}
67 67
68if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then 68if [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then
69cat << USAGE 69cat << USAGE
70usage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] 70usage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
71 source directory defaults to /usr/src/linux, 71 source directory defaults to /usr/src/linux,
@@ -182,10 +182,12 @@ reversePatch () {
182} 182}
183 183
184# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION 184# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
185TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; } 185# force $TMPFILEs below to be in local directory: a slash character prevents
186# the dot command from using the search path.
187TMPFILE=`mktemp ./.tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
186grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE 188grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
187tr -d [:blank:] < $TMPFILE > $TMPFILE.1 189tr -d [:blank:] < $TMPFILE > $TMPFILE.1
188source $TMPFILE.1 190. $TMPFILE.1
189rm -f $TMPFILE* 191rm -f $TMPFILE*
190if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] 192if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
191then 193then
@@ -202,11 +204,7 @@ echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($
202EXTRAVER= 204EXTRAVER=
203if [ x$EXTRAVERSION != "x" ] 205if [ x$EXTRAVERSION != "x" ]
204then 206then
205 if [ ${EXTRAVERSION:0:1} == "." ]; then 207 EXTRAVER=${EXTRAVERSION#.}
206 EXTRAVER=${EXTRAVERSION:1}
207 else
208 EXTRAVER=$EXTRAVERSION
209 fi
210 EXTRAVER=${EXTRAVER%%[[:punct:]]*} 208 EXTRAVER=${EXTRAVER%%[[:punct:]]*}
211 #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER" 209 #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
212fi 210fi
@@ -251,16 +249,16 @@ while : # incrementing SUBLEVEL (s in v.p.s)
251do 249do
252 CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 250 CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
253 EXTRAVER= 251 EXTRAVER=
254 if [ $stopvers == $CURRENTFULLVERSION ]; then 252 if [ $stopvers = $CURRENTFULLVERSION ]; then
255 echo "Stopping at $CURRENTFULLVERSION base as requested." 253 echo "Stopping at $CURRENTFULLVERSION base as requested."
256 break 254 break
257 fi 255 fi
258 256
259 SUBLEVEL=$((SUBLEVEL + 1)) 257 SUBLEVEL=$(($SUBLEVEL + 1))
260 FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 258 FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
261 #echo "#___ trying $FULLVERSION ___" 259 #echo "#___ trying $FULLVERSION ___"
262 260
263 if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then 261 if [ $(($SUBLEVEL)) -gt $(($STOPSUBLEVEL)) ]; then
264 echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)" 262 echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
265 exit 1 263 exit 1
266 fi 264 fi
@@ -297,7 +295,7 @@ fi
297if [ x$gotac != x ]; then 295if [ x$gotac != x ]; then
298 # Out great user wants the -ac patches 296 # Out great user wants the -ac patches
299 # They could have done -ac (get latest) or -acxx where xx=version they want 297 # They could have done -ac (get latest) or -acxx where xx=version they want
300 if [ $gotac == "-ac" ]; then 298 if [ $gotac = "-ac" ]; then
301 # They want the latest version 299 # They want the latest version
302 HIGHESTPATCH=0 300 HIGHESTPATCH=0
303 for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* 301 for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.*
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 82e4993f0a73..52f032e409a3 100644
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -12,11 +12,36 @@ cd "${1:-.}" || usage
12if head=`git rev-parse --verify HEAD 2>/dev/null`; then 12if head=`git rev-parse --verify HEAD 2>/dev/null`; then
13 # Do we have an untagged version? 13 # Do we have an untagged version?
14 if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then 14 if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then
15 printf '%s%s' -g `echo "$head" | cut -c1-8` 15 git describe | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
16 fi 16 fi
17 17
18 # Are there uncommitted changes? 18 # Are there uncommitted changes?
19 if git diff-index HEAD | read dummy; then 19 git update-index --refresh --unmerged > /dev/null
20 if git diff-index --name-only HEAD | grep -v "^scripts/package" \
21 | read dummy; then
20 printf '%s' -dirty 22 printf '%s' -dirty
21 fi 23 fi
24
25 # All done with git
26 exit
27fi
28
29# Check for mercurial and a mercurial repo.
30if hgid=`hg id 2>/dev/null`; then
31 tag=`printf '%s' "$hgid" | cut -d' ' -f2`
32
33 # Do we have an untagged version?
34 if [ -z "$tag" -o "$tag" = tip ]; then
35 id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
36 printf '%s%s' -hg "$id"
37 fi
38
39 # Are there uncommitted changes?
40 # These are represented by + after the changeset id.
41 case "$hgid" in
42 *+|*+\ *) printf '%s' -dirty ;;
43 esac
44
45 # All done with mercurial
46 exit
22fi 47fi