From 9a2a82de4f893ca8fa1cdb7a738c1917c9cdc9c2 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 24 Jul 2006 21:40:46 +0200 Subject: [PATCH] --- yaml --- r: 38143 b: refs/heads/master c: 98e5a1579e7d34fe3803240750a1c48efcd9cb15 h: refs/heads/master i: 38141: 1fb776998ea082ac87b1fe41a8950d7a0392dd36 38139: 7289d19ee52594841eb670ca8faa88b4857fcf67 38135: a60cb7730b303fff83d8106fd0c1e8127482c2df 38127: 3f9b90bcfabaa6b37f135ac9753d924664c55ed1 38111: 94a77fe20467a3ee3b3aa66fc56239c8c0fc1a27 38079: e5482c7c11ed96604ffe71c2c00565519e5428c1 38015: c46ec45b24450ec5ae0bd339167e670948522a67 37887: 5cb91664a665da84e37cab5a5f398716d8c901a9 v: v3 --- [refs] | 2 +- trunk/CREDITS | 6 - trunk/Documentation/DocBook/kernel-api.tmpl | 5 - trunk/Documentation/HOWTO | 20 - trunk/Documentation/IPMI.txt | 19 +- trunk/Documentation/SubmitChecklist | 2 - trunk/Documentation/accounting/getdelays.c | 7 +- .../accounting/taskstats-struct.txt | 161 -- trunk/Documentation/fb/intel810.txt | 148 +- trunk/Documentation/fb/intelfb.txt | 21 +- .../feature-removal-schedule.txt | 28 +- trunk/Documentation/filesystems/Locking | 5 +- trunk/Documentation/filesystems/vfs.txt | 4 +- trunk/Documentation/ia64/serial.txt | 7 - trunk/Documentation/input/ff.txt | 112 +- trunk/Documentation/kprobes.txt | 89 +- trunk/Documentation/lockdep-design.txt | 22 - trunk/Documentation/md.txt | 26 +- trunk/Documentation/rt-mutex-design.txt | 14 +- trunk/Documentation/video4linux/CARDLIST.cx88 | 8 +- .../video4linux/CARDLIST.saa7134 | 7 +- .../video4linux/bttv/Insmod-options | 6 - .../video4linux/cx2341x/README.hm12 | 116 -- .../video4linux/cx2341x/README.vbi | 45 - trunk/Documentation/x86_64/boot-options.txt | 5 - trunk/MAINTAINERS | 53 +- trunk/arch/alpha/kernel/alpha_ksyms.c | 3 +- trunk/arch/alpha/kernel/entry.S | 10 +- trunk/arch/alpha/kernel/osf_sys.c | 34 +- trunk/arch/alpha/kernel/proto.h | 15 +- trunk/arch/alpha/kernel/srmcons.c | 2 +- trunk/arch/alpha/kernel/time.c | 15 +- trunk/arch/alpha/mm/Makefile | 2 +- trunk/arch/alpha/mm/remap.c | 86 + trunk/arch/arm/kernel/ecard.c | 2 +- trunk/arch/arm/kernel/setup.c | 2 +- trunk/arch/arm/kernel/smp.c | 2 - trunk/arch/arm/kernel/sys_arm.c | 4 +- trunk/arch/arm/kernel/time.c | 10 +- trunk/arch/arm/mach-pnx4008/clock.c | 11 - trunk/arch/arm/vfp/vfpsingle.c | 2 - trunk/arch/arm26/kernel/setup.c | 2 +- trunk/arch/arm26/kernel/sys_arm.c | 4 +- trunk/arch/arm26/kernel/time.c | 12 +- trunk/arch/avr32/kernel/sys_avr32.c | 14 - trunk/arch/avr32/mm/ioremap.c | 120 +- trunk/arch/cris/arch-v32/kernel/smp.c | 1 - trunk/arch/cris/kernel/setup.c | 2 +- trunk/arch/cris/kernel/time.c | 7 + trunk/arch/cris/mm/ioremap.c | 88 +- trunk/arch/frv/Kconfig | 8 - trunk/arch/frv/kernel/Makefile | 2 +- trunk/arch/frv/kernel/kernel_execve.S | 33 - trunk/arch/h8300/kernel/sys_h8300.c | 24 - trunk/arch/i386/Kconfig | 2 +- trunk/arch/i386/boot/video.S | 2 + trunk/arch/i386/defconfig | 7 +- .../i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 7 +- trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c | 56 +- .../kernel/cpu/cpufreq/speedstep-centrino.c | 2 +- trunk/arch/i386/kernel/crash.c | 10 +- trunk/arch/i386/kernel/i8237.c | 5 - trunk/arch/i386/kernel/kprobes.c | 41 +- trunk/arch/i386/kernel/nmi.c | 4 +- trunk/arch/i386/kernel/process.c | 11 +- trunk/arch/i386/kernel/setup.c | 10 +- trunk/arch/i386/kernel/smp.c | 27 - trunk/arch/i386/kernel/smpboot.c | 3 +- trunk/arch/i386/kernel/sys_i386.c | 42 +- trunk/arch/i386/kernel/time.c | 3 + trunk/arch/i386/kernel/traps.c | 8 +- trunk/arch/i386/lib/delay.c | 1 + trunk/arch/i386/mach-voyager/voyager_smp.c | 7 - trunk/arch/i386/mm/highmem.c | 18 +- trunk/arch/i386/mm/init.c | 1 - trunk/arch/i386/mm/ioremap.c | 84 +- trunk/arch/i386/pci/mmconfig.c | 5 +- trunk/arch/ia64/Kconfig | 2 +- trunk/arch/ia64/hp/sim/simserial.c | 2 +- trunk/arch/ia64/ia32/sys_ia32.c | 23 +- trunk/arch/ia64/kernel/entry.S | 4 +- trunk/arch/ia64/kernel/kprobes.c | 98 +- trunk/arch/ia64/kernel/mca.c | 2 +- trunk/arch/ia64/kernel/numa.c | 1 - trunk/arch/ia64/kernel/process.c | 2 + trunk/arch/ia64/kernel/time.c | 2 + trunk/arch/ia64/mm/numa.c | 18 - trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c | 2 +- trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c | 2 +- trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c | 2 +- trunk/arch/m32r/kernel/sys_m32r.c | 22 +- trunk/arch/m32r/kernel/time.c | 11 +- trunk/arch/m32r/mm/ioremap.c | 93 +- trunk/arch/m68k/kernel/sys_m68k.c | 16 - trunk/arch/m68k/kernel/time.c | 16 +- trunk/arch/m68knommu/kernel/sys_m68k.c | 15 - trunk/arch/m68knommu/kernel/time.c | 7 +- trunk/arch/mips/Kconfig | 9 - .../mips/basler/excite/excite_flashtest.c | 294 +++ trunk/arch/mips/configs/atlas_defconfig | 3 - trunk/arch/mips/configs/bigsur_defconfig | 3 - trunk/arch/mips/configs/capcella_defconfig | 3 - trunk/arch/mips/configs/cobalt_defconfig | 3 - trunk/arch/mips/configs/db1000_defconfig | 3 - trunk/arch/mips/configs/db1100_defconfig | 3 - trunk/arch/mips/configs/db1200_defconfig | 3 - trunk/arch/mips/configs/db1500_defconfig | 3 - trunk/arch/mips/configs/db1550_defconfig | 3 - trunk/arch/mips/configs/ddb5477_defconfig | 3 - trunk/arch/mips/configs/decstation_defconfig | 3 - trunk/arch/mips/configs/e55_defconfig | 2 - trunk/arch/mips/configs/emma2rh_defconfig | 3 - trunk/arch/mips/configs/ev64120_defconfig | 3 - trunk/arch/mips/configs/excite_defconfig | 3 - trunk/arch/mips/configs/ip22_defconfig | 3 - trunk/arch/mips/configs/ip27_defconfig | 3 - trunk/arch/mips/configs/ip32_defconfig | 3 - trunk/arch/mips/configs/it8172_defconfig | 3 - trunk/arch/mips/configs/ivr_defconfig | 3 - trunk/arch/mips/configs/jaguar-atx_defconfig | 3 - trunk/arch/mips/configs/jmr3927_defconfig | 3 - trunk/arch/mips/configs/lasat200_defconfig | 3 - trunk/arch/mips/configs/malta_defconfig | 3 - trunk/arch/mips/configs/mipssim_defconfig | 3 - trunk/arch/mips/configs/mpc30x_defconfig | 2 - trunk/arch/mips/configs/ocelot_3_defconfig | 3 - trunk/arch/mips/configs/ocelot_c_defconfig | 3 - trunk/arch/mips/configs/ocelot_defconfig | 3 - trunk/arch/mips/configs/ocelot_g_defconfig | 3 - trunk/arch/mips/configs/pb1100_defconfig | 3 - trunk/arch/mips/configs/pb1500_defconfig | 3 - trunk/arch/mips/configs/pb1550_defconfig | 3 - trunk/arch/mips/configs/pnx8550-jbs_defconfig | 3 - .../arch/mips/configs/pnx8550-v2pci_defconfig | 3 - trunk/arch/mips/configs/qemu_defconfig | 3 - trunk/arch/mips/configs/rbhma4500_defconfig | 3 - trunk/arch/mips/configs/rm200_defconfig | 3 - .../arch/mips/configs/sb1250-swarm_defconfig | 3 - trunk/arch/mips/configs/sead_defconfig | 3 - trunk/arch/mips/configs/tb0226_defconfig | 3 - trunk/arch/mips/configs/tb0229_defconfig | 3 - trunk/arch/mips/configs/tb0287_defconfig | 3 - trunk/arch/mips/configs/workpad_defconfig | 2 - trunk/arch/mips/configs/wrppmc_defconfig | 3 - trunk/arch/mips/configs/yosemite_defconfig | 3 - trunk/arch/mips/defconfig | 3 - trunk/arch/mips/kernel/Makefile | 1 - trunk/arch/mips/kernel/genex.S | 8 +- trunk/arch/mips/kernel/i8259.c | 4 +- trunk/arch/mips/kernel/linux32.c | 4 +- trunk/arch/mips/kernel/process.c | 37 +- trunk/arch/mips/kernel/scall32-o32.S | 13 +- trunk/arch/mips/kernel/scall64-64.S | 2 +- trunk/arch/mips/kernel/scall64-n32.S | 2 +- trunk/arch/mips/kernel/scall64-o32.S | 2 +- trunk/arch/mips/kernel/stacktrace.c | 85 - trunk/arch/mips/kernel/syscall.c | 56 +- trunk/arch/mips/kernel/sysirix.c | 22 +- trunk/arch/mips/kernel/time.c | 12 +- trunk/arch/mips/kernel/traps.c | 40 +- trunk/arch/mips/mm/c-r3k.c | 21 + trunk/arch/mips/mm/c-r4k.c | 77 + trunk/arch/mips/mm/c-sb1.c | 61 + trunk/arch/mips/mm/c-tx39.c | 29 + trunk/arch/mips/mm/cache.c | 1 + trunk/arch/mips/mm/tlbex-fault.S | 4 +- trunk/arch/mips/sgi-ip22/ip22-reset.c | 3 +- trunk/arch/mips/sgi-ip27/ip27-timer.c | 2 + trunk/arch/mips/sgi-ip32/ip32-reset.c | 2 +- trunk/arch/parisc/hpux/fs.c | 6 +- trunk/arch/parisc/hpux/sys_hpux.c | 37 +- trunk/arch/parisc/kernel/firmware.c | 7 +- trunk/arch/parisc/kernel/process.c | 9 +- trunk/arch/parisc/kernel/sys_parisc32.c | 19 +- trunk/arch/parisc/kernel/time.c | 5 +- trunk/arch/powerpc/Kconfig | 2 +- trunk/arch/powerpc/kernel/kprobes.c | 33 +- trunk/arch/powerpc/kernel/misc_32.S | 2 +- trunk/arch/powerpc/kernel/misc_64.S | 2 +- trunk/arch/powerpc/kernel/process.c | 2 +- trunk/arch/powerpc/kernel/setup_32.c | 4 + trunk/arch/powerpc/kernel/setup_64.c | 7 +- trunk/arch/powerpc/kernel/sys_ppc32.c | 15 +- trunk/arch/powerpc/kernel/syscalls.c | 14 +- trunk/arch/powerpc/kernel/time.c | 7 + trunk/arch/powerpc/platforms/iseries/mf.c | 2 +- .../powerpc/platforms/powermac/cpufreq_64.c | 2 +- trunk/arch/powerpc/platforms/powermac/nvram.c | 4 +- trunk/arch/powerpc/platforms/pseries/setup.c | 2 +- trunk/arch/ppc/4xx_io/serial_sicc.c | 2 +- trunk/arch/ppc/kernel/misc.S | 18 +- trunk/arch/ppc/kernel/setup.c | 4 + trunk/arch/ppc/kernel/time.c | 11 +- trunk/arch/s390/hypfs/inode.c | 17 +- trunk/arch/s390/kernel/compat_linux.c | 5 - trunk/arch/s390/kernel/head31.S | 11 - trunk/arch/s390/kernel/head64.S | 11 - trunk/arch/s390/kernel/kprobes.c | 9 +- trunk/arch/s390/kernel/sys_s390.c | 20 - trunk/arch/s390/kernel/time.c | 7 +- trunk/arch/s390/lib/spinlock.c | 62 +- trunk/arch/sh/kernel/setup.c | 2 +- trunk/arch/sh/kernel/smp.c | 1 - trunk/arch/sh/kernel/sys_sh.c | 19 +- trunk/arch/sh/kernel/time.c | 10 +- trunk/arch/sh64/kernel/process.c | 270 ++- trunk/arch/sh64/kernel/sys_sh64.c | 21 +- trunk/arch/sh64/kernel/time.c | 12 +- trunk/arch/sparc/kernel/pcic.c | 16 +- trunk/arch/sparc/kernel/sys_sparc.c | 27 +- trunk/arch/sparc/kernel/sys_sunos.c | 31 +- trunk/arch/sparc/kernel/time.c | 18 +- trunk/arch/sparc64/Kconfig | 2 +- trunk/arch/sparc64/kernel/power.c | 5 +- trunk/arch/sparc64/kernel/sys_sparc.c | 25 +- trunk/arch/sparc64/kernel/sys_sparc32.c | 5 - trunk/arch/sparc64/kernel/sys_sunos32.c | 22 +- trunk/arch/sparc64/kernel/time.c | 2 + trunk/arch/sparc64/solaris/fs.c | 7 +- trunk/arch/sparc64/solaris/misc.c | 6 +- trunk/arch/um/drivers/line.c | 6 +- trunk/arch/um/drivers/mconsole_kern.c | 6 +- trunk/arch/um/drivers/ubd_kern.c | 2 + trunk/arch/um/include/line.h | 7 +- trunk/arch/um/kernel/syscall.c | 35 +- trunk/arch/um/kernel/um_arch.c | 6 +- trunk/arch/um/os-Linux/process.c | 5 +- trunk/arch/um/os-Linux/sys-i386/tls.c | 5 +- trunk/arch/um/os-Linux/tls.c | 8 +- trunk/arch/um/sys-i386/unmap.c | 11 +- trunk/arch/um/sys-x86_64/syscalls.c | 2 +- trunk/arch/um/sys-x86_64/sysrq.c | 2 +- trunk/arch/um/sys-x86_64/unmap.c | 11 +- trunk/arch/v850/kernel/memcons.c | 4 +- trunk/arch/v850/kernel/rte_cb_leds.c | 2 +- trunk/arch/v850/kernel/rte_mb_a_pci.c | 12 +- trunk/arch/v850/kernel/simcons.c | 2 +- trunk/arch/v850/kernel/syscalls.c | 20 - trunk/arch/x86_64/Kconfig | 6 +- trunk/arch/x86_64/defconfig | 8 +- trunk/arch/x86_64/ia32/sys_ia32.c | 45 +- trunk/arch/x86_64/kernel/apic.c | 54 + trunk/arch/x86_64/kernel/entry.S | 4 +- trunk/arch/x86_64/kernel/kprobes.c | 48 +- trunk/arch/x86_64/kernel/mpparse.c | 37 +- trunk/arch/x86_64/kernel/nmi.c | 4 - trunk/arch/x86_64/kernel/pci-dma.c | 93 +- trunk/arch/x86_64/kernel/process.c | 6 +- trunk/arch/x86_64/kernel/setup.c | 11 +- trunk/arch/x86_64/kernel/sys_x86_64.c | 2 +- trunk/arch/x86_64/kernel/time.c | 12 +- trunk/arch/x86_64/kernel/vmlinux.lds.S | 17 +- trunk/arch/x86_64/kernel/vsyscall.c | 11 +- trunk/arch/x86_64/mm/init.c | 38 +- trunk/arch/x86_64/mm/ioremap.c | 111 +- trunk/arch/x86_64/mm/srat.c | 66 +- trunk/arch/xtensa/kernel/syscalls.c | 22 +- trunk/arch/xtensa/kernel/time.c | 13 +- trunk/arch/xtensa/platform-iss/console.c | 2 +- trunk/block/Kconfig | 20 - trunk/block/Kconfig.iosched | 3 - trunk/block/Makefile | 2 +- trunk/block/as-iosched.c | 674 ++++-- trunk/block/blktrace.c | 26 +- trunk/block/cfq-iosched.c | 867 +++++--- trunk/block/deadline-iosched.c | 464 ++++- trunk/block/elevator.c | 315 +-- trunk/block/ioctl.c | 5 +- trunk/block/ll_rw_blk.c | 236 ++- trunk/block/noop-iosched.c | 2 +- trunk/block/scsi_ioctl.c | 6 +- trunk/drivers/acpi/acpi_memhotplug.c | 4 - trunk/drivers/acpi/processor_idle.c | 38 +- trunk/drivers/ata/pata_hpt366.c | 2 +- trunk/drivers/base/Makefile | 2 +- trunk/drivers/block/DAC960.c | 4 +- trunk/drivers/block/DAC960.h | 2 +- trunk/drivers/block/Kconfig | 4 - trunk/drivers/block/cciss.c | 238 +-- trunk/drivers/block/cciss.h | 3 - trunk/drivers/block/cciss_cmd.h | 33 +- trunk/drivers/block/cciss_scsi.c | 2 +- trunk/drivers/block/cpqarray.c | 1 + trunk/drivers/block/floppy.c | 4 +- trunk/drivers/block/loop.c | 160 -- trunk/drivers/block/nbd.c | 8 +- trunk/drivers/block/paride/pd.c | 8 +- trunk/drivers/block/pktcdvd.c | 10 +- trunk/drivers/block/swim3.c | 4 +- trunk/drivers/block/swim_iop.c | 4 +- trunk/drivers/block/umem.c | 3 +- trunk/drivers/block/xd.c | 2 +- trunk/drivers/cdrom/Kconfig | 2 +- trunk/drivers/cdrom/cdrom.c | 2 +- trunk/drivers/cdrom/cdu31a.c | 4 +- trunk/drivers/char/Kconfig | 1 - trunk/drivers/char/agp/amd64-agp.c | 8 +- trunk/drivers/char/agp/generic.c | 9 +- trunk/drivers/char/amiserial.c | 2 +- trunk/drivers/char/cyclades.c | 2 +- trunk/drivers/char/drm/Kconfig | 9 +- trunk/drivers/char/drm/Makefile | 6 +- trunk/drivers/char/drm/drmP.h | 68 +- trunk/drivers/char/drm/drm_auth.c | 64 +- trunk/drivers/char/drm/drm_bufs.c | 74 +- trunk/drivers/char/drm/drm_drv.c | 12 +- trunk/drivers/char/drm/drm_fops.c | 10 +- trunk/drivers/char/drm/drm_hashtab.c | 190 -- trunk/drivers/char/drm/drm_hashtab.h | 67 - trunk/drivers/char/drm/drm_ioc32.c | 2 +- trunk/drivers/char/drm/drm_ioctl.c | 34 +- trunk/drivers/char/drm/drm_irq.c | 12 +- trunk/drivers/char/drm/drm_mm.c | 201 -- trunk/drivers/char/drm/drm_pciids.h | 187 +- trunk/drivers/char/drm/drm_proc.c | 2 +- trunk/drivers/char/drm/drm_sman.c | 352 ---- trunk/drivers/char/drm/drm_sman.h | 176 -- trunk/drivers/char/drm/drm_stub.c | 12 +- trunk/drivers/char/drm/drm_vm.c | 45 +- trunk/drivers/char/drm/i810_dma.c | 10 +- trunk/drivers/char/drm/i830_dma.c | 4 +- trunk/drivers/char/drm/i915_dma.c | 45 +- trunk/drivers/char/drm/i915_drm.h | 6 - trunk/drivers/char/drm/i915_drv.h | 10 +- trunk/drivers/char/drm/i915_irq.c | 16 +- trunk/drivers/char/drm/radeon_cp.c | 72 +- trunk/drivers/char/drm/radeon_drv.c | 2 +- trunk/drivers/char/drm/radeon_drv.h | 36 +- trunk/drivers/char/drm/radeon_state.c | 48 +- trunk/drivers/char/drm/sis_drv.c | 39 +- trunk/drivers/char/drm/sis_drv.h | 34 +- trunk/drivers/char/drm/sis_ds.c | 299 +++ trunk/drivers/char/drm/sis_ds.h | 146 ++ trunk/drivers/char/drm/sis_mm.c | 504 +++-- trunk/drivers/char/drm/via_dmablit.c | 68 +- trunk/drivers/char/drm/via_drm.h | 8 +- trunk/drivers/char/drm/via_drv.c | 3 +- trunk/drivers/char/drm/via_drv.h | 16 +- trunk/drivers/char/drm/via_ds.c | 273 +++ trunk/drivers/char/drm/via_ds.h | 104 + trunk/drivers/char/drm/via_map.c | 9 +- trunk/drivers/char/drm/via_mm.c | 375 +++- trunk/drivers/char/ds1286.c | 15 +- trunk/drivers/char/epca.c | 2 +- trunk/drivers/char/esp.c | 2 +- trunk/drivers/char/hvc_console.c | 2 +- trunk/drivers/char/hvcs.c | 2 +- trunk/drivers/char/hvsi.c | 2 +- trunk/drivers/char/ip2/ip2main.c | 14 +- trunk/drivers/char/ipmi/ipmi_devintf.c | 34 +- trunk/drivers/char/ipmi/ipmi_msghandler.c | 75 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 26 +- trunk/drivers/char/isicom.c | 37 +- trunk/drivers/char/istallion.c | 2 +- trunk/drivers/char/keyboard.c | 25 +- trunk/drivers/char/mbcs.c | 7 +- trunk/drivers/char/moxa.c | 82 +- trunk/drivers/char/mwave/mwavedd.c | 4 +- trunk/drivers/char/mxser.c | 68 +- trunk/drivers/char/nwbutton.c | 5 +- trunk/drivers/char/pcmcia/synclink_cs.c | 2 +- trunk/drivers/char/pty.c | 2 +- trunk/drivers/char/random.c | 8 +- trunk/drivers/char/raw.c | 31 +- trunk/drivers/char/rio/rio_linux.c | 2 +- trunk/drivers/char/riscom8.c | 24 +- trunk/drivers/char/rocket.c | 2 +- trunk/drivers/char/ser_a2232.c | 2 +- trunk/drivers/char/serial167.c | 2 +- trunk/drivers/char/snsc_event.c | 2 +- trunk/drivers/char/specialix.c | 13 +- trunk/drivers/char/stallion.c | 2 +- trunk/drivers/char/sx.c | 2 +- trunk/drivers/char/synclink.c | 2 +- trunk/drivers/char/synclink_gt.c | 96 +- trunk/drivers/char/synclinkmp.c | 2 +- trunk/drivers/char/sysrq.c | 1 - trunk/drivers/char/tipar.c | 6 +- trunk/drivers/char/tty_io.c | 3 +- trunk/drivers/char/viocons.c | 2 +- trunk/drivers/char/vme_scc.c | 2 +- trunk/drivers/char/vt.c | 42 +- trunk/drivers/char/vt_ioctl.c | 17 +- trunk/drivers/char/watchdog/Kconfig | 11 - trunk/drivers/char/watchdog/Makefile | 1 - trunk/drivers/char/watchdog/acquirewdt.c | 2 +- trunk/drivers/char/watchdog/advantechwdt.c | 2 +- trunk/drivers/char/watchdog/alim1535_wdt.c | 12 +- trunk/drivers/char/watchdog/alim7101_wdt.c | 17 +- trunk/drivers/char/watchdog/at91_wdt.c | 2 +- trunk/drivers/char/watchdog/booke_wdt.c | 2 +- trunk/drivers/char/watchdog/cpu5wdt.c | 2 +- trunk/drivers/char/watchdog/ep93xx_wdt.c | 2 +- trunk/drivers/char/watchdog/eurotechwdt.c | 2 +- trunk/drivers/char/watchdog/i6300esb.c | 2 +- trunk/drivers/char/watchdog/i8xx_tco.c | 35 +- trunk/drivers/char/watchdog/ib700wdt.c | 2 +- trunk/drivers/char/watchdog/ibmasr.c | 2 +- trunk/drivers/char/watchdog/indydog.c | 2 +- trunk/drivers/char/watchdog/ixp2000_wdt.c | 2 +- trunk/drivers/char/watchdog/ixp4xx_wdt.c | 2 +- trunk/drivers/char/watchdog/machzwd.c | 5 +- trunk/drivers/char/watchdog/mixcomwd.c | 2 +- trunk/drivers/char/watchdog/mpc83xx_wdt.c | 2 +- trunk/drivers/char/watchdog/mpc8xx_wdt.c | 2 +- trunk/drivers/char/watchdog/mpcore_wdt.c | 4 +- trunk/drivers/char/watchdog/mv64x60_wdt.c | 2 +- trunk/drivers/char/watchdog/pcwd.c | 2 +- trunk/drivers/char/watchdog/pcwd_pci.c | 2 +- trunk/drivers/char/watchdog/pcwd_usb.c | 2 +- trunk/drivers/char/watchdog/pnx4008_wdt.c | 362 ---- trunk/drivers/char/watchdog/s3c2410_wdt.c | 12 +- trunk/drivers/char/watchdog/sa1100_wdt.c | 2 +- trunk/drivers/char/watchdog/sbc60xxwdt.c | 2 +- trunk/drivers/char/watchdog/sbc_epx_c3.c | 2 +- trunk/drivers/char/watchdog/sc1200wdt.c | 2 +- trunk/drivers/char/watchdog/sc520_wdt.c | 2 +- trunk/drivers/char/watchdog/scx200_wdt.c | 2 +- trunk/drivers/char/watchdog/shwdt.c | 2 +- trunk/drivers/char/watchdog/softdog.c | 2 +- trunk/drivers/char/watchdog/w83627hf_wdt.c | 2 +- trunk/drivers/char/watchdog/w83877f_wdt.c | 2 +- trunk/drivers/char/watchdog/w83977f_wdt.c | 2 +- trunk/drivers/char/watchdog/wafer5823wdt.c | 2 +- trunk/drivers/char/watchdog/wdrtas.c | 2 +- trunk/drivers/char/watchdog/wdt.c | 2 +- trunk/drivers/char/watchdog/wdt285.c | 2 +- trunk/drivers/char/watchdog/wdt977.c | 2 +- trunk/drivers/char/watchdog/wdt_pci.c | 2 +- trunk/drivers/cpufreq/cpufreq.c | 2 +- trunk/drivers/fc4/fc.c | 1 + trunk/drivers/firmware/dell_rbu.c | 4 +- trunk/drivers/hwmon/hdaps.c | 1 - trunk/drivers/i2c/busses/i2c-ite.c | 2 +- trunk/drivers/i2c/i2c-core.c | 25 +- trunk/drivers/ide/Kconfig | 12 +- trunk/drivers/ide/ide-cd.c | 69 +- trunk/drivers/ide/ide-disk.c | 5 +- trunk/drivers/ide/ide-dma.c | 64 +- trunk/drivers/ide/ide-floppy.c | 17 +- trunk/drivers/ide/ide-io.c | 82 +- trunk/drivers/ide/ide-iops.c | 4 - trunk/drivers/ide/ide-lib.c | 130 +- trunk/drivers/ide/ide-probe.c | 25 +- trunk/drivers/ide/ide-proc.c | 22 +- trunk/drivers/ide/ide-tape.c | 16 +- trunk/drivers/ide/ide-taskfile.c | 8 +- trunk/drivers/ide/ide.c | 35 +- trunk/drivers/ide/legacy/hd.c | 2 +- trunk/drivers/ide/legacy/ide-cs.c | 7 +- trunk/drivers/ide/pci/Makefile | 1 - trunk/drivers/ide/pci/cs5530.c | 13 +- trunk/drivers/ide/pci/cy82c693.c | 5 +- trunk/drivers/ide/pci/generic.c | 11 +- trunk/drivers/ide/pci/jmicron.c | 269 --- trunk/drivers/ide/pci/pdc202xx_old.c | 22 +- trunk/drivers/ide/pci/piix.c | 33 +- trunk/drivers/ide/pci/sc1200.c | 4 - trunk/drivers/ide/pci/serverworks.c | 8 +- trunk/drivers/ide/pci/sgiioc4.c | 20 +- trunk/drivers/ide/pci/siimage.c | 1 + trunk/drivers/ide/pci/sis5513.c | 3 +- trunk/drivers/ide/pci/via82cxxx.c | 5 +- trunk/drivers/ide/setup-pci.c | 20 +- trunk/drivers/ieee1394/Kconfig | 11 +- trunk/drivers/ieee1394/csr.c | 31 +- trunk/drivers/ieee1394/csr.h | 109 +- trunk/drivers/ieee1394/dma.c | 7 +- trunk/drivers/ieee1394/dma.h | 90 +- trunk/drivers/ieee1394/dv1394-private.h | 6 +- trunk/drivers/ieee1394/dv1394.c | 47 +- trunk/drivers/ieee1394/eth1394.c | 12 +- trunk/drivers/ieee1394/highlevel.h | 201 +- trunk/drivers/ieee1394/hosts.c | 23 +- trunk/drivers/ieee1394/hosts.h | 51 +- trunk/drivers/ieee1394/ieee1394-ioctl.h | 9 +- trunk/drivers/ieee1394/ieee1394.h | 316 +-- trunk/drivers/ieee1394/ieee1394_core.c | 9 +- trunk/drivers/ieee1394/ieee1394_core.h | 28 +- trunk/drivers/ieee1394/ieee1394_hotplug.h | 30 +- .../drivers/ieee1394/ieee1394_transactions.c | 114 +- .../drivers/ieee1394/ieee1394_transactions.h | 41 +- trunk/drivers/ieee1394/ieee1394_types.h | 68 +- trunk/drivers/ieee1394/iso.c | 5 +- trunk/drivers/ieee1394/iso.h | 87 +- trunk/drivers/ieee1394/nodemgr.c | 227 ++- trunk/drivers/ieee1394/nodemgr.h | 27 +- trunk/drivers/ieee1394/ohci1394.c | 73 +- trunk/drivers/ieee1394/raw1394-private.h | 3 +- trunk/drivers/ieee1394/raw1394.c | 138 +- trunk/drivers/ieee1394/sbp2.c | 481 +++-- trunk/drivers/ieee1394/sbp2.h | 37 +- trunk/drivers/ieee1394/video1394.c | 52 +- trunk/drivers/infiniband/core/cma.c | 47 +- trunk/drivers/infiniband/hw/ehca/ehca_main.c | 36 +- trunk/drivers/infiniband/hw/ehca/ehca_tools.h | 2 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 4 +- trunk/drivers/infiniband/hw/ipath/ipath_rc.c | 59 +- .../drivers/infiniband/hw/ipath/ipath_verbs.c | 2 +- trunk/drivers/input/Kconfig | 14 - trunk/drivers/input/Makefile | 6 +- trunk/drivers/input/evbug.c | 11 +- trunk/drivers/input/evdev.c | 42 +- trunk/drivers/input/ff-core.c | 367 ---- trunk/drivers/input/ff-memless.c | 515 ----- trunk/drivers/input/input.c | 46 +- trunk/drivers/input/joydev.c | 12 +- .../drivers/input/joystick/iforce/iforce-ff.c | 118 +- .../input/joystick/iforce/iforce-main.c | 226 ++- .../input/joystick/iforce/iforce-packets.c | 15 +- trunk/drivers/input/joystick/iforce/iforce.h | 26 +- trunk/drivers/input/keyboard/Kconfig | 11 - trunk/drivers/input/keyboard/Makefile | 1 - trunk/drivers/input/keyboard/atkbd.c | 4 +- trunk/drivers/input/keyboard/stowaway.c | 187 -- trunk/drivers/input/misc/uinput.c | 67 +- trunk/drivers/input/misc/wistron_btns.c | 18 +- trunk/drivers/input/mouse/alps.c | 8 +- trunk/drivers/input/mouse/alps.h | 2 +- trunk/drivers/input/mouse/lifebook.c | 8 +- trunk/drivers/input/mouse/logips2pp.c | 23 +- trunk/drivers/input/mouse/psmouse-base.c | 42 +- trunk/drivers/input/mouse/sermouse.c | 2 +- trunk/drivers/input/mouse/synaptics.c | 10 +- trunk/drivers/input/mousedev.c | 28 +- trunk/drivers/input/power.c | 7 +- trunk/drivers/input/serio/i8042-io.h | 15 +- trunk/drivers/input/serio/i8042-x86ia64io.h | 14 - trunk/drivers/input/serio/i8042.c | 741 ++++--- trunk/drivers/input/serio/i8042.h | 9 + trunk/drivers/input/serio/libps2.c | 36 +- trunk/drivers/input/touchscreen/Kconfig | 36 - trunk/drivers/input/touchscreen/Makefile | 3 - trunk/drivers/input/touchscreen/elo.c | 167 +- trunk/drivers/input/touchscreen/penmount.c | 185 -- trunk/drivers/input/touchscreen/touchright.c | 196 -- trunk/drivers/input/touchscreen/touchwin.c | 203 -- trunk/drivers/input/tsdev.c | 12 +- trunk/drivers/isdn/capi/capi.c | 2 +- trunk/drivers/isdn/gigaset/interface.c | 2 +- trunk/drivers/isdn/gigaset/proc.c | 3 +- trunk/drivers/isdn/hardware/eicon/dsp_defs.h | 3 + trunk/drivers/isdn/hisax/config.c | 6 +- trunk/drivers/isdn/hisax/hfc4s8s_l1.c | 7 +- trunk/drivers/isdn/hisax/hfc_sx.c | 4 +- trunk/drivers/isdn/hisax/hfc_usb.c | 4 +- trunk/drivers/isdn/hisax/hisax.h | 13 +- trunk/drivers/isdn/hisax/hisax_fcpcipnp.c | 17 +- trunk/drivers/isdn/hisax/st5481_b.c | 8 +- trunk/drivers/isdn/hisax/st5481_d.c | 4 +- trunk/drivers/isdn/i4l/isdn_tty.c | 2 +- trunk/drivers/isdn/sc/command.c | 22 +- trunk/drivers/isdn/sc/event.c | 2 - trunk/drivers/isdn/sc/interrupt.c | 2 +- trunk/drivers/isdn/sc/timer.c | 2 +- trunk/drivers/leds/led-triggers.c | 1 - trunk/drivers/macintosh/smu.c | 4 +- trunk/drivers/macintosh/via-pmu.c | 14 +- trunk/drivers/macintosh/via-pmu68k.c | 6 +- .../drivers/macintosh/windfarm_smu_controls.c | 2 +- .../drivers/macintosh/windfarm_smu_sensors.c | 2 +- trunk/drivers/md/Kconfig | 21 +- trunk/drivers/md/bitmap.c | 17 +- trunk/drivers/md/dm-crypt.c | 506 ++--- trunk/drivers/md/dm-emc.c | 3 +- trunk/drivers/md/dm-exception-store.c | 176 +- trunk/drivers/md/dm-linear.c | 19 +- trunk/drivers/md/dm-mpath.c | 83 +- trunk/drivers/md/dm-raid1.c | 4 +- trunk/drivers/md/dm-snap.c | 351 ++-- trunk/drivers/md/dm-snap.h | 17 +- trunk/drivers/md/dm-table.c | 109 +- trunk/drivers/md/dm.c | 113 +- trunk/drivers/md/dm.h | 7 +- trunk/drivers/md/linear.c | 15 - trunk/drivers/md/md.c | 275 +-- trunk/drivers/md/multipath.c | 27 +- trunk/drivers/md/raid0.c | 17 - trunk/drivers/md/raid1.c | 247 +-- trunk/drivers/md/raid10.c | 261 +-- trunk/drivers/md/raid5.c | 74 +- trunk/drivers/media/common/Kconfig | 1 + trunk/drivers/media/common/ir-keymaps.c | 79 - trunk/drivers/media/common/saa7146_fops.c | 1 + trunk/drivers/media/dvb/b2c2/Kconfig | 14 +- .../drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 24 +- trunk/drivers/media/dvb/bt8xx/Kconfig | 14 +- trunk/drivers/media/dvb/bt8xx/dst.c | 9 - trunk/drivers/media/dvb/bt8xx/dst_ca.c | 11 +- trunk/drivers/media/dvb/bt8xx/dst_common.h | 3 +- trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c | 37 +- trunk/drivers/media/dvb/dvb-core/Kconfig | 13 - .../drivers/media/dvb/dvb-core/dvb_frontend.c | 42 +- .../drivers/media/dvb/dvb-core/dvb_frontend.h | 7 +- .../media/dvb/dvb-core/dvb_ringbuffer.c | 1 + trunk/drivers/media/dvb/dvb-core/dvbdev.h | 22 - trunk/drivers/media/dvb/dvb-usb/Kconfig | 17 +- trunk/drivers/media/dvb/dvb-usb/a800.c | 8 - trunk/drivers/media/dvb/dvb-usb/cxusb.c | 11 +- .../drivers/media/dvb/dvb-usb/dibusb-common.c | 200 +- trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c | 18 +- trunk/drivers/media/dvb/dvb-usb/dibusb-mc.c | 41 +- trunk/drivers/media/dvb/dvb-usb/dibusb.h | 3 - trunk/drivers/media/dvb/dvb-usb/digitv.c | 86 +- trunk/drivers/media/dvb/dvb-usb/dtt200u.c | 50 +- trunk/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | 20 +- trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 124 +- .../media/dvb/dvb-usb/dvb-usb-remote.c | 5 +- trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c | 2 +- trunk/drivers/media/dvb/dvb-usb/umt-010.c | 2 +- trunk/drivers/media/dvb/frontends/Kconfig | 71 +- trunk/drivers/media/dvb/frontends/Makefile | 8 +- trunk/drivers/media/dvb/frontends/bcm3510.h | 9 - trunk/drivers/media/dvb/frontends/cx22700.h | 9 - trunk/drivers/media/dvb/frontends/cx22702.c | 4 +- trunk/drivers/media/dvb/frontends/cx22702.h | 9 - trunk/drivers/media/dvb/frontends/cx24110.c | 17 +- trunk/drivers/media/dvb/frontends/cx24110.h | 19 +- trunk/drivers/media/dvb/frontends/cx24123.c | 98 +- trunk/drivers/media/dvb/frontends/cx24123.h | 12 - .../media/dvb/frontends/dib3000-common.c | 83 + .../media/dvb/frontends/dib3000-common.h | 135 ++ trunk/drivers/media/dvb/frontends/dib3000.h | 11 +- trunk/drivers/media/dvb/frontends/dib3000mb.c | 76 +- .../media/dvb/frontends/dib3000mb_priv.h | 93 - trunk/drivers/media/dvb/frontends/dib3000mc.c | 1432 +++++++------ trunk/drivers/media/dvb/frontends/dib3000mc.h | 58 - .../media/dvb/frontends/dib3000mc_priv.h | 428 ++++ .../media/dvb/frontends/dibx000_common.c | 152 -- .../media/dvb/frontends/dibx000_common.h | 166 -- trunk/drivers/media/dvb/frontends/dvb-pll.c | 11 +- trunk/drivers/media/dvb/frontends/dvb-pll.h | 4 +- trunk/drivers/media/dvb/frontends/isl6421.c | 30 +- trunk/drivers/media/dvb/frontends/isl6421.h | 11 +- trunk/drivers/media/dvb/frontends/l64781.h | 10 +- trunk/drivers/media/dvb/frontends/lgdt330x.h | 9 - trunk/drivers/media/dvb/frontends/lnbp21.c | 30 +- trunk/drivers/media/dvb/frontends/lnbp21.h | 12 +- trunk/drivers/media/dvb/frontends/mt2060.c | 367 ---- trunk/drivers/media/dvb/frontends/mt2060.h | 35 - .../drivers/media/dvb/frontends/mt2060_priv.h | 105 - trunk/drivers/media/dvb/frontends/mt312.h | 10 +- trunk/drivers/media/dvb/frontends/mt352.c | 16 +- trunk/drivers/media/dvb/frontends/mt352.h | 16 +- trunk/drivers/media/dvb/frontends/nxt200x.h | 9 - trunk/drivers/media/dvb/frontends/nxt6000.h | 9 - trunk/drivers/media/dvb/frontends/or51132.h | 9 - trunk/drivers/media/dvb/frontends/or51211.h | 9 - trunk/drivers/media/dvb/frontends/s5h1420.h | 9 - trunk/drivers/media/dvb/frontends/sp8870.h | 9 - trunk/drivers/media/dvb/frontends/sp887x.h | 9 - trunk/drivers/media/dvb/frontends/stv0297.h | 9 - trunk/drivers/media/dvb/frontends/stv0299.c | 9 +- trunk/drivers/media/dvb/frontends/stv0299.h | 19 +- trunk/drivers/media/dvb/frontends/tda10021.c | 63 +- trunk/drivers/media/dvb/frontends/tda10021.h | 19 +- trunk/drivers/media/dvb/frontends/tda1004x.c | 10 +- trunk/drivers/media/dvb/frontends/tda1004x.h | 25 +- trunk/drivers/media/dvb/frontends/tda10086.c | 740 ------- trunk/drivers/media/dvb/frontends/tda10086.h | 41 - trunk/drivers/media/dvb/frontends/tda8083.h | 9 - trunk/drivers/media/dvb/frontends/tda826x.c | 173 -- trunk/drivers/media/dvb/frontends/tda826x.h | 40 - trunk/drivers/media/dvb/frontends/tua6100.c | 205 -- trunk/drivers/media/dvb/frontends/tua6100.h | 47 - trunk/drivers/media/dvb/frontends/ves1820.h | 9 - trunk/drivers/media/dvb/frontends/ves1x93.h | 9 - trunk/drivers/media/dvb/frontends/zl10353.c | 11 +- trunk/drivers/media/dvb/frontends/zl10353.h | 14 +- trunk/drivers/media/dvb/ttpci/Kconfig | 57 +- trunk/drivers/media/dvb/ttpci/av7110.c | 58 +- trunk/drivers/media/dvb/ttpci/av7110_av.c | 1 + trunk/drivers/media/dvb/ttpci/av7110_ca.c | 1 + trunk/drivers/media/dvb/ttpci/av7110_hw.c | 1 + trunk/drivers/media/dvb/ttpci/av7110_v4l.c | 3 +- trunk/drivers/media/dvb/ttpci/budget-av.c | 184 +- trunk/drivers/media/dvb/ttpci/budget-ci.c | 32 +- trunk/drivers/media/dvb/ttpci/budget-patch.c | 17 +- trunk/drivers/media/dvb/ttpci/budget.c | 53 +- trunk/drivers/media/dvb/ttusb-budget/Kconfig | 14 +- .../media/dvb/ttusb-budget/dvb-ttusb-budget.c | 28 +- trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 6 +- trunk/drivers/media/radio/Kconfig | 30 +- trunk/drivers/media/radio/dsbr100.c | 198 +- trunk/drivers/media/radio/radio-aimslab.c | 151 +- trunk/drivers/media/radio/radio-aztech.c | 166 +- trunk/drivers/media/radio/radio-cadet.c | 250 ++- trunk/drivers/media/radio/radio-gemtek-pci.c | 170 +- trunk/drivers/media/radio/radio-gemtek.c | 165 +- trunk/drivers/media/radio/radio-maestro.c | 197 +- trunk/drivers/media/radio/radio-maxiradio.c | 166 +- trunk/drivers/media/radio/radio-rtrack2.c | 163 +- trunk/drivers/media/radio/radio-sf16fmi.c | 158 +- trunk/drivers/media/radio/radio-sf16fmr2.c | 223 +- trunk/drivers/media/radio/radio-terratec.c | 154 +- trunk/drivers/media/radio/radio-trust.c | 188 +- trunk/drivers/media/radio/radio-typhoon.c | 171 +- trunk/drivers/media/radio/radio-zoltrix.c | 183 +- trunk/drivers/media/video/Kconfig | 476 ++--- trunk/drivers/media/video/Makefile | 45 +- trunk/drivers/media/video/bt866.c | 2 +- trunk/drivers/media/video/bt8xx/Kconfig | 5 +- trunk/drivers/media/video/bt8xx/bttv-cards.c | 2 +- trunk/drivers/media/video/bt8xx/bttv-driver.c | 12 - trunk/drivers/media/video/bt8xx/bttv-i2c.c | 16 - trunk/drivers/media/video/compat_ioctl32.c | 59 +- trunk/drivers/media/video/cpia2/cpia2.h | 4 + trunk/drivers/media/video/cx2341x.c | 25 +- trunk/drivers/media/video/cx25840/Kconfig | 2 +- .../drivers/media/video/cx25840/cx25840-vbi.c | 4 - trunk/drivers/media/video/cx88/Kconfig | 109 +- trunk/drivers/media/video/cx88/Makefile | 7 + .../drivers/media/video/cx88/cx88-blackbird.c | 2 - trunk/drivers/media/video/cx88/cx88-cards.c | 161 +- trunk/drivers/media/video/cx88/cx88-core.c | 13 +- trunk/drivers/media/video/cx88/cx88-dvb.c | 330 +-- trunk/drivers/media/video/cx88/cx88-i2c.c | 13 - trunk/drivers/media/video/cx88/cx88-input.c | 19 +- trunk/drivers/media/video/cx88/cx88-tvaudio.c | 5 + trunk/drivers/media/video/cx88/cx88-video.c | 7 +- trunk/drivers/media/video/cx88/cx88.h | 5 - trunk/drivers/media/video/em28xx/Kconfig | 3 +- .../drivers/media/video/em28xx/em28xx-video.c | 2 +- trunk/drivers/media/video/ks0127.c | 3 +- trunk/drivers/media/video/pvrusb2/Kconfig | 18 +- trunk/drivers/media/video/pvrusb2/Makefile | 6 +- .../media/video/pvrusb2/pvrusb2-ctrl.c | 21 +- .../media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 2 +- .../media/video/pvrusb2/pvrusb2-encoder.c | 4 +- .../video/pvrusb2/pvrusb2-hdw-internal.h | 31 +- .../drivers/media/video/pvrusb2/pvrusb2-hdw.c | 84 +- .../video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 4 + .../video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | 2 +- .../media/video/pvrusb2/pvrusb2-i2c-core.c | 6 + .../media/video/pvrusb2/pvrusb2-main.c | 1 + .../media/video/pvrusb2/pvrusb2-sysfs.c | 3 + .../media/video/pvrusb2/pvrusb2-v4l2.c | 36 +- trunk/drivers/media/video/saa5246a.c | 1 + trunk/drivers/media/video/saa5249.c | 1 + trunk/drivers/media/video/saa7115.c | 1250 +++++------- trunk/drivers/media/video/saa711x_regs.h | 549 ----- trunk/drivers/media/video/saa7134/Kconfig | 50 +- trunk/drivers/media/video/saa7134/Makefile | 3 + .../media/video/saa7134/saa7134-alsa.c | 8 - .../media/video/saa7134/saa7134-cards.c | 127 +- .../media/video/saa7134/saa7134-core.c | 2 +- .../drivers/media/video/saa7134/saa7134-dvb.c | 197 +- .../media/video/saa7134/saa7134-input.c | 6 - .../media/video/saa7134/saa7134-tvaudio.c | 1 - trunk/drivers/media/video/saa7134/saa7134.h | 3 - trunk/drivers/media/video/tda9887.c | 2 - trunk/drivers/media/video/tuner-simple.c | 6 +- trunk/drivers/media/video/tuner-types.c | 1 - trunk/drivers/media/video/tvaudio.c | 42 +- trunk/drivers/media/video/tveeprom.c | 2 - trunk/drivers/media/video/tvp5150.c | 7 +- trunk/drivers/media/video/usbvideo/konicawc.c | 9 +- trunk/drivers/media/video/usbvideo/vicam.c | 4 - trunk/drivers/media/video/v4l1-compat.c | 12 +- trunk/drivers/media/video/v4l2-common.c | 1 - trunk/drivers/media/video/video-buf-dvb.c | 2 - trunk/drivers/media/video/videodev.c | 32 +- trunk/drivers/media/video/vino.c | 1 + trunk/drivers/media/video/vivi.c | 5 +- trunk/drivers/media/video/vpx3220.c | 2 +- trunk/drivers/media/video/zoran_card.c | 6 +- trunk/drivers/media/video/zoran_driver.c | 7 - trunk/drivers/media/video/zr36120.c | 6 +- trunk/drivers/message/i2o/Kconfig | 2 +- trunk/drivers/message/i2o/i2o_block.c | 7 +- trunk/drivers/message/i2o/pci.c | 7 +- trunk/drivers/misc/Makefile | 3 +- trunk/drivers/misc/lkdtm.c | 342 ---- trunk/drivers/mmc/Kconfig | 2 +- trunk/drivers/mmc/Makefile | 3 +- trunk/drivers/mmc/mmc_queue.c | 6 +- trunk/drivers/mmc/sdhci.c | 5 +- trunk/drivers/mmc/sdhci.h | 5 +- trunk/drivers/mmc/wbsd.c | 5 +- trunk/drivers/mmc/wbsd.h | 5 +- trunk/drivers/mtd/Kconfig | 12 +- trunk/drivers/mtd/devices/Kconfig | 2 +- trunk/drivers/mtd/maps/arctic-mtd.c | 6 +- trunk/drivers/mtd/maps/beech-mtd.c | 6 +- trunk/drivers/mtd/maps/cstm_mips_ixx.c | 8 +- trunk/drivers/mtd/maps/nettel.c | 2 +- trunk/drivers/mtd/maps/redwood.c | 2 +- trunk/drivers/mtd/mtd_blkdevs.c | 4 +- trunk/drivers/mtd/nand/edb7312.c | 2 +- trunk/drivers/mtd/nand/nand_base.c | 172 +- trunk/drivers/mtd/nand/nand_bbt.c | 2 +- trunk/drivers/mtd/nftlcore.c | 4 +- trunk/drivers/mtd/onenand/Kconfig | 6 + trunk/drivers/mtd/onenand/onenand_base.c | 154 +- trunk/drivers/net/Space.c | 2 +- trunk/drivers/net/dgrs.c | 1 + trunk/drivers/net/e100.c | 82 +- trunk/drivers/net/e1000/LICENSE | 339 ++++ trunk/drivers/net/e1000/Makefile | 35 +- trunk/drivers/net/e1000/e1000.h | 59 +- trunk/drivers/net/e1000/e1000_ethtool.c | 150 +- trunk/drivers/net/e1000/e1000_hw.c | 1074 +++++----- trunk/drivers/net/e1000/e1000_hw.h | 86 +- trunk/drivers/net/e1000/e1000_main.c | 271 +-- trunk/drivers/net/e1000/e1000_osdep.h | 35 +- trunk/drivers/net/e1000/e1000_param.c | 47 +- trunk/drivers/net/hp100.c | 9 +- trunk/drivers/net/ifb.c | 4 +- trunk/drivers/net/ixgb/Makefile | 38 +- trunk/drivers/net/ixgb/ixgb.h | 38 +- trunk/drivers/net/ixgb/ixgb_ee.c | 36 +- trunk/drivers/net/ixgb/ixgb_ee.h | 36 +- trunk/drivers/net/ixgb/ixgb_ethtool.c | 36 +- trunk/drivers/net/ixgb/ixgb_hw.c | 36 +- trunk/drivers/net/ixgb/ixgb_hw.h | 36 +- trunk/drivers/net/ixgb/ixgb_ids.h | 36 +- trunk/drivers/net/ixgb/ixgb_main.c | 46 +- trunk/drivers/net/ixgb/ixgb_osdep.h | 36 +- trunk/drivers/net/ixgb/ixgb_param.c | 36 +- trunk/drivers/net/phy/fixed.c | 6 +- trunk/drivers/net/phy/phy_device.c | 8 +- trunk/drivers/net/sky2.c | 548 ++--- trunk/drivers/net/sky2.h | 62 +- trunk/drivers/net/spider_net.c | 6 +- trunk/drivers/net/tun.c | 39 +- trunk/drivers/net/wireless/airo.c | 23 +- trunk/drivers/net/wireless/ipw2100.c | 22 +- trunk/drivers/parisc/led.c | 2 +- trunk/drivers/parisc/power.c | 3 +- trunk/drivers/pci/quirks.c | 17 +- trunk/drivers/pcmcia/cardbus.c | 5 +- trunk/drivers/pcmcia/omap_cf.c | 25 +- trunk/drivers/pcmcia/socket_sysfs.c | 27 +- trunk/drivers/pnp/pnpbios/core.c | 8 - trunk/drivers/rtc/Kconfig | 26 +- trunk/drivers/rtc/Makefile | 4 - trunk/drivers/rtc/class.c | 6 +- trunk/drivers/rtc/rtc-at91.c | 24 +- trunk/drivers/rtc/rtc-dev.c | 7 +- trunk/drivers/rtc/rtc-ds1307.c | 2 +- trunk/drivers/rtc/rtc-ds1553.c | 10 +- trunk/drivers/rtc/rtc-ds1672.c | 2 +- trunk/drivers/rtc/rtc-ds1742.c | 12 +- trunk/drivers/rtc/rtc-ep93xx.c | 2 +- trunk/drivers/rtc/rtc-isl1208.c | 2 +- trunk/drivers/rtc/rtc-lib.c | 8 +- trunk/drivers/rtc/rtc-m48t86.c | 2 +- trunk/drivers/rtc/rtc-max6902.c | 2 +- trunk/drivers/rtc/rtc-pcf8563.c | 6 +- trunk/drivers/rtc/rtc-pcf8583.c | 2 +- trunk/drivers/rtc/rtc-pl031.c | 2 +- trunk/drivers/rtc/rtc-proc.c | 6 +- trunk/drivers/rtc/rtc-rs5c348.c | 2 +- trunk/drivers/rtc/rtc-rs5c372.c | 2 +- trunk/drivers/rtc/rtc-s3c.c | 2 +- trunk/drivers/rtc/rtc-sa1100.c | 2 +- trunk/drivers/rtc/rtc-sysfs.c | 2 +- trunk/drivers/rtc/rtc-test.c | 2 +- trunk/drivers/rtc/rtc-v3020.c | 5 +- trunk/drivers/rtc/rtc-vr41xx.c | 2 +- trunk/drivers/rtc/rtc-x1205.c | 2 +- trunk/drivers/s390/block/Kconfig | 2 +- trunk/drivers/s390/block/dasd_diag.c | 2 +- trunk/drivers/s390/block/dasd_eckd.c | 2 +- trunk/drivers/s390/block/dasd_fba.c | 2 +- trunk/drivers/s390/char/con3215.c | 2 +- trunk/drivers/s390/char/fs3270.c | 11 +- trunk/drivers/s390/char/sclp_tty.c | 2 +- trunk/drivers/s390/char/sclp_vt220.c | 2 +- trunk/drivers/s390/char/tty3270.c | 2 +- trunk/drivers/s390/s390mach.c | 2 +- trunk/drivers/s390/scsi/zfcp_scsi.c | 2 +- trunk/drivers/sbus/char/aurora.c | 2 +- trunk/drivers/sbus/char/bbc_envctrl.c | 5 +- trunk/drivers/sbus/char/envctrl.c | 7 +- trunk/drivers/scsi/53c700.c | 2 +- trunk/drivers/scsi/BusLogic.h | 5 +- trunk/drivers/scsi/Kconfig | 2 - trunk/drivers/scsi/aic7xxx/aic79xx_osm.c | 4 +- trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c | 2 +- trunk/drivers/scsi/aic7xxx_old.c | 4 +- trunk/drivers/scsi/gdth.c | 4 +- trunk/drivers/scsi/ide-scsi.c | 16 +- trunk/drivers/scsi/libsas/sas_scsi_host.c | 2 +- trunk/drivers/scsi/lpfc/lpfc_ct.c | 8 +- trunk/drivers/scsi/pluto.c | 6 +- trunk/drivers/scsi/qla1280.c | 4 +- trunk/drivers/scsi/scsi.c | 13 +- trunk/drivers/scsi/scsi_lib.c | 37 +- trunk/drivers/scsi/sd.c | 5 +- trunk/drivers/scsi/sun3_NCR5380.c | 2 +- trunk/drivers/scsi/sun3_scsi.c | 2 +- trunk/drivers/scsi/sun3_scsi_vme.c | 2 +- trunk/drivers/serial/68328serial.c | 2 +- trunk/drivers/serial/68360serial.c | 2 +- trunk/drivers/serial/8250_acorn.c | 9 +- trunk/drivers/serial/8250_gsc.c | 1 - trunk/drivers/serial/crisv10.c | 2 +- trunk/drivers/serial/ioc4_serial.c | 3 - trunk/drivers/serial/ip22zilog.c | 16 +- trunk/drivers/serial/mcfserial.c | 2 +- trunk/drivers/serial/mpc52xx_uart.c | 11 +- trunk/drivers/serial/mpsc.c | 12 - trunk/drivers/serial/mux.c | 2 - trunk/drivers/serial/serial_core.c | 2 +- trunk/drivers/serial/sunsu.c | 3 - trunk/drivers/tc/zs.c | 2 +- trunk/drivers/usb/class/cdc-acm.c | 2 +- trunk/drivers/usb/core/devio.c | 10 +- trunk/drivers/usb/core/hcd.c | 4 +- trunk/drivers/usb/core/inode.c | 13 +- trunk/drivers/usb/core/usb.h | 2 +- trunk/drivers/usb/gadget/ether.c | 2 +- trunk/drivers/usb/gadget/file_storage.c | 2 +- trunk/drivers/usb/gadget/gmidi.c | 2 +- trunk/drivers/usb/gadget/inode.c | 82 +- trunk/drivers/usb/gadget/omap_udc.c | 2 +- trunk/drivers/usb/gadget/serial.c | 4 +- trunk/drivers/usb/gadget/zero.c | 2 +- trunk/drivers/usb/input/Kconfig | 18 +- trunk/drivers/usb/input/Makefile | 5 +- trunk/drivers/{ => usb}/input/fixp-arith.h | 0 trunk/drivers/usb/input/hid-core.c | 5 +- trunk/drivers/usb/input/hid-ff.c | 49 +- trunk/drivers/usb/input/hid-input.c | 23 +- trunk/drivers/usb/input/hid-lgff.c | 523 ++++- trunk/drivers/usb/input/hid-pidff.c | 1330 ------------ trunk/drivers/usb/input/hid-tmff.c | 399 +++- trunk/drivers/usb/input/hid-zpff.c | 110 - trunk/drivers/usb/input/hid.h | 32 +- trunk/drivers/usb/input/pid.c | 295 +++ trunk/drivers/usb/input/pid.h | 62 + trunk/drivers/usb/serial/usb-serial.c | 2 +- trunk/drivers/usb/storage/Kconfig | 5 +- trunk/drivers/video/Kconfig | 39 +- trunk/drivers/video/Makefile | 1 - trunk/drivers/video/aty/atyfb.h | 6 +- trunk/drivers/video/aty/atyfb_base.c | 11 +- trunk/drivers/video/aty/mach64_ct.c | 2 +- trunk/drivers/video/aty/radeon_i2c.c | 106 +- trunk/drivers/video/aty/radeon_pm.c | 3 - trunk/drivers/video/au1100fb.c | 30 +- trunk/drivers/video/console/fbcon.c | 54 +- trunk/drivers/video/console/fbcon.h | 2 - trunk/drivers/video/console/fbcon_ccw.c | 2 +- trunk/drivers/video/console/fbcon_cw.c | 2 +- trunk/drivers/video/console/fbcon_ud.c | 2 +- trunk/drivers/video/console/softcursor.c | 31 +- trunk/drivers/video/fb_ddc.c | 116 -- trunk/drivers/video/fbmem.c | 3 +- trunk/drivers/video/fbsysfs.c | 35 +- trunk/drivers/video/i810/i810-i2c.c | 42 +- trunk/drivers/video/i810/i810_main.c | 6 +- trunk/drivers/video/intelfb/Makefile | 4 +- trunk/drivers/video/intelfb/intelfb.h | 79 +- trunk/drivers/video/intelfb/intelfb_i2c.c | 200 -- trunk/drivers/video/intelfb/intelfbdrv.c | 64 - trunk/drivers/video/intelfb/intelfbhw.c | 136 +- trunk/drivers/video/intelfb/intelfbhw.h | 25 - trunk/drivers/video/matrox/matroxfb_base.c | 12 +- trunk/drivers/video/mbx/mbxfb.c | 21 +- trunk/drivers/video/nvidia/nv_i2c.c | 45 +- trunk/drivers/video/nvidia/nvidia.c | 16 +- trunk/drivers/video/riva/fbdev.c | 8 +- trunk/drivers/video/riva/rivafb-i2c.c | 44 +- trunk/drivers/video/savage/savagefb-i2c.c | 49 +- trunk/drivers/video/sis/init.h | 7 + trunk/drivers/video/sis/init301.h | 7 + trunk/drivers/video/sis/initextlfb.c | 4 + trunk/drivers/video/sis/osdef.h | 4 + trunk/drivers/video/sis/sis_accel.c | 26 + trunk/drivers/video/sis/sis_accel.h | 14 + trunk/drivers/video/sis/sis_main.c | 232 ++- trunk/drivers/video/sis/sis_main.h | 65 + trunk/drivers/video/sis/vgatypes.h | 2 + trunk/drivers/video/sstfb.c | 170 +- trunk/fs/9p/vfs_inode.c | 2 +- trunk/fs/Kconfig | 31 +- trunk/fs/Makefile | 14 +- trunk/fs/adfs/file.c | 6 +- trunk/fs/affs/file.c | 6 +- trunk/fs/afs/dir.c | 4 +- trunk/fs/afs/file.c | 2 + trunk/fs/aio.c | 170 +- trunk/fs/autofs/root.c | 4 +- trunk/fs/autofs4/root.c | 8 +- trunk/fs/bad_inode.c | 2 + trunk/fs/bfs/dir.c | 11 +- trunk/fs/bfs/file.c | 6 +- trunk/fs/binfmt_elf.c | 78 +- trunk/fs/bio.c | 4 +- trunk/fs/block_dev.c | 47 +- trunk/fs/buffer.c | 174 ++ trunk/fs/char_dev.c | 1 - trunk/fs/cifs/cifsfs.c | 22 +- trunk/fs/cifs/connect.c | 22 +- trunk/fs/cifs/file.c | 1 + trunk/fs/cifs/inode.c | 15 +- trunk/fs/cifs/ioctl.c | 7 +- trunk/fs/cifs/sess.c | 6 +- trunk/fs/coda/dir.c | 6 +- trunk/fs/compat.c | 72 +- trunk/fs/compat_ioctl.c | 406 +++- trunk/fs/configfs/dir.c | 4 +- trunk/fs/configfs/file.c | 4 +- trunk/fs/configfs/mount.c | 2 +- trunk/fs/dcache.c | 4 +- trunk/fs/debugfs/inode.c | 4 +- trunk/fs/dnotify.c | 2 +- trunk/fs/eventpoll.c | 5 +- trunk/fs/exec.c | 27 +- trunk/fs/exportfs/expfs.c | 2 +- trunk/fs/ext2/dir.c | 3 - trunk/fs/ext2/ext2.h | 1 - trunk/fs/ext2/file.c | 12 +- trunk/fs/ext2/ioctl.c | 32 - trunk/fs/ext2/namei.c | 2 +- trunk/fs/ext3/dir.c | 3 - trunk/fs/ext3/file.c | 10 +- trunk/fs/ext3/inode.c | 5 +- trunk/fs/ext3/ioctl.c | 55 +- trunk/fs/ext3/namei.c | 25 +- trunk/fs/fat/dir.c | 58 +- trunk/fs/fat/file.c | 2 + trunk/fs/fcntl.c | 79 +- trunk/fs/file_table.c | 1 - trunk/fs/fs-writeback.c | 9 +- trunk/fs/fuse/control.c | 2 +- trunk/fs/fuse/dev.c | 37 +- trunk/fs/fuse/dir.c | 4 +- trunk/fs/fuse/file.c | 6 +- trunk/fs/hfs/dir.c | 4 +- trunk/fs/hfs/inode.c | 6 +- trunk/fs/hfsplus/dir.c | 8 +- trunk/fs/hfsplus/hfsplus_fs.h | 8 +- trunk/fs/hfsplus/inode.c | 6 +- trunk/fs/hfsplus/ioctl.c | 17 +- trunk/fs/hostfs/hostfs_kern.c | 6 +- trunk/fs/hpfs/file.c | 6 +- trunk/fs/hpfs/namei.c | 14 +- trunk/fs/hugetlbfs/inode.c | 4 +- trunk/fs/inode.c | 35 +- trunk/fs/internal.h | 55 - trunk/fs/ioprio.c | 19 +- trunk/fs/jffs/inode-v23.c | 9 +- trunk/fs/jffs2/dir.c | 12 +- trunk/fs/jffs2/file.c | 6 +- trunk/fs/jffs2/fs.c | 6 +- trunk/fs/jfs/acl.c | 8 +- trunk/fs/jfs/endian24.h | 2 +- trunk/fs/jfs/file.c | 14 +- trunk/fs/jfs/inode.c | 10 +- trunk/fs/jfs/ioctl.c | 15 +- trunk/fs/jfs/jfs_acl.h | 8 +- trunk/fs/jfs/jfs_btree.h | 6 +- trunk/fs/jfs/jfs_debug.c | 6 +- trunk/fs/jfs/jfs_dinode.h | 8 +- trunk/fs/jfs/jfs_dmap.c | 192 +- trunk/fs/jfs/jfs_dmap.h | 28 +- trunk/fs/jfs/jfs_dtree.c | 18 +- trunk/fs/jfs/jfs_dtree.h | 10 +- trunk/fs/jfs/jfs_extent.c | 56 +- trunk/fs/jfs/jfs_extent.h | 12 +- trunk/fs/jfs/jfs_filsys.h | 24 +- trunk/fs/jfs/jfs_imap.c | 242 +-- trunk/fs/jfs/jfs_imap.h | 18 +- trunk/fs/jfs/jfs_incore.h | 8 +- trunk/fs/jfs/jfs_inode.c | 15 +- trunk/fs/jfs/jfs_inode.h | 6 +- trunk/fs/jfs/jfs_lock.h | 10 +- trunk/fs/jfs/jfs_logmgr.c | 38 +- trunk/fs/jfs/jfs_logmgr.h | 76 +- trunk/fs/jfs/jfs_metapage.c | 12 +- trunk/fs/jfs/jfs_metapage.h | 12 +- trunk/fs/jfs/jfs_mount.c | 34 +- trunk/fs/jfs/jfs_superblock.h | 22 +- trunk/fs/jfs/jfs_txnmgr.c | 24 +- trunk/fs/jfs/jfs_txnmgr.h | 12 +- trunk/fs/jfs/jfs_types.h | 4 + trunk/fs/jfs/jfs_umount.c | 24 +- trunk/fs/jfs/jfs_unicode.c | 12 +- trunk/fs/jfs/jfs_unicode.h | 10 +- trunk/fs/jfs/jfs_uniupr.c | 8 +- trunk/fs/jfs/jfs_xattr.h | 2 +- trunk/fs/jfs/jfs_xtree.c | 14 +- trunk/fs/jfs/jfs_xtree.h | 8 +- trunk/fs/jfs/namei.c | 89 +- trunk/fs/jfs/resize.c | 6 +- trunk/fs/jfs/super.c | 12 +- trunk/fs/jfs/symlink.c | 6 +- trunk/fs/jfs/xattr.c | 48 +- trunk/fs/libfs.c | 14 +- trunk/fs/lockd/clntlock.c | 2 +- trunk/fs/lockd/clntproc.c | 4 +- trunk/fs/lockd/mon.c | 2 +- trunk/fs/lockd/svc.c | 74 +- trunk/fs/lockd/svclock.c | 2 +- trunk/fs/lockd/xdr.c | 2 +- trunk/fs/locks.c | 14 +- trunk/fs/minix/file.c | 6 +- trunk/fs/minix/namei.c | 2 +- trunk/fs/mpage.c | 2 - trunk/fs/msdos/namei.c | 17 +- trunk/fs/namei.c | 123 +- trunk/fs/namespace.c | 25 +- trunk/fs/ncpfs/dir.c | 3 - trunk/fs/ncpfs/file.c | 3 - trunk/fs/ncpfs/ioctl.c | 239 +-- trunk/fs/nfs/callback.c | 7 +- trunk/fs/nfs/client.c | 3 +- trunk/fs/nfs/dir.c | 8 +- trunk/fs/nfs/direct.c | 26 +- trunk/fs/nfs/file.c | 34 +- trunk/fs/nfs/nfsroot.c | 2 +- trunk/fs/nfs/write.c | 1 + trunk/fs/nfsd/export.c | 12 +- trunk/fs/nfsd/nfs4callback.c | 2 +- trunk/fs/nfsd/nfs4proc.c | 2 +- trunk/fs/nfsd/nfs4recover.c | 2 +- trunk/fs/nfsd/nfsctl.c | 152 +- trunk/fs/nfsd/nfssvc.c | 318 ++- trunk/fs/nfsd/vfs.c | 8 +- trunk/fs/nls/nls_base.c | 2 + trunk/fs/no-block.c | 22 - trunk/fs/ntfs/aops.c | 30 +- trunk/fs/ntfs/aops.h | 2 +- trunk/fs/ntfs/attrib.c | 54 +- trunk/fs/ntfs/attrib.h | 8 +- trunk/fs/ntfs/bitmap.c | 8 +- trunk/fs/ntfs/bitmap.h | 4 +- trunk/fs/ntfs/collate.h | 8 +- trunk/fs/ntfs/compress.c | 4 +- trunk/fs/ntfs/file.c | 46 +- trunk/fs/ntfs/index.c | 4 +- trunk/fs/ntfs/index.h | 12 +- trunk/fs/ntfs/inode.c | 10 +- trunk/fs/ntfs/layout.h | 6 +- trunk/fs/ntfs/lcnalloc.c | 20 +- trunk/fs/ntfs/lcnalloc.h | 8 +- trunk/fs/ntfs/logfile.c | 108 +- trunk/fs/ntfs/logfile.h | 6 +- trunk/fs/ntfs/mft.c | 58 +- trunk/fs/ntfs/mft.h | 2 +- trunk/fs/ntfs/ntfs.h | 2 +- trunk/fs/ntfs/quota.c | 12 +- trunk/fs/ntfs/quota.h | 2 +- trunk/fs/ntfs/runlist.c | 54 +- trunk/fs/ntfs/super.c | 178 +- trunk/fs/ntfs/types.h | 5 + trunk/fs/ntfs/unistr.c | 8 +- trunk/fs/ntfs/usnjrnl.c | 8 +- trunk/fs/ntfs/usnjrnl.h | 2 +- trunk/fs/ocfs2/dlm/dlmfs.c | 6 +- trunk/fs/ocfs2/file.c | 28 +- trunk/fs/ocfs2/namei.c | 51 +- trunk/fs/open.c | 198 +- trunk/fs/partitions/Makefile | 2 +- trunk/fs/partitions/ldm.c | 267 +-- trunk/fs/pipe.c | 214 +- trunk/fs/posix_acl.c | 6 +- trunk/fs/proc/array.c | 85 +- trunk/fs/proc/base.c | 1807 +++++++++-------- trunk/fs/proc/proc_misc.c | 14 +- trunk/fs/proc/root.c | 12 - trunk/fs/qnx4/file.c | 6 +- trunk/fs/qnx4/namei.c | 8 +- trunk/fs/quota.c | 44 +- trunk/fs/ramfs/file-mmu.c | 6 +- trunk/fs/ramfs/file-nommu.c | 6 +- trunk/fs/ramfs/inode.c | 4 +- trunk/fs/read_write.c | 253 +-- trunk/fs/read_write.h | 14 - trunk/fs/readdir.c | 18 +- trunk/fs/reiserfs/bitmap.c | 216 +- trunk/fs/reiserfs/dir.c | 3 - trunk/fs/reiserfs/file.c | 9 +- trunk/fs/reiserfs/ioctl.c | 35 - trunk/fs/reiserfs/namei.c | 16 +- trunk/fs/reiserfs/resize.c | 71 +- trunk/fs/reiserfs/super.c | 155 +- trunk/fs/reiserfs/xattr.c | 6 +- trunk/fs/smbfs/file.c | 24 +- trunk/fs/splice.c | 2 +- trunk/fs/stat.c | 6 - trunk/fs/super.c | 35 - trunk/fs/sync.c | 113 -- trunk/fs/sysfs/dir.c | 4 +- trunk/fs/sysfs/file.c | 4 +- trunk/fs/sysfs/mount.c | 2 +- trunk/fs/sysv/file.c | 6 +- trunk/fs/sysv/namei.c | 2 +- trunk/fs/udf/file.c | 16 +- trunk/fs/udf/inode.c | 2 +- trunk/fs/udf/namei.c | 26 +- trunk/fs/ufs/file.c | 6 +- trunk/fs/ufs/namei.c | 2 +- trunk/fs/utimes.c | 137 -- trunk/fs/vfat/namei.c | 17 +- trunk/fs/xfs/Kconfig | 1 - trunk/fs/xfs/linux-2.6/xfs_file.c | 140 +- trunk/fs/xfs/linux-2.6/xfs_lrw.c | 4 +- trunk/include/asm-alpha/spinlock.h | 4 - trunk/include/asm-alpha/unistd.h | 69 + trunk/include/asm-arm/arch-pnx4008/clock.h | 1 - trunk/include/asm-arm/spinlock.h | 4 - trunk/include/asm-arm/unistd.h | 24 + trunk/include/asm-arm26/unistd.h | 24 + trunk/include/asm-avr32/unistd.h | 80 +- trunk/include/asm-cris/arch-v32/spinlock.h | 4 - trunk/include/asm-cris/unistd.h | 61 + trunk/include/asm-frv/pgtable.h | 2 + trunk/include/asm-frv/timex.h | 5 + trunk/include/asm-frv/unistd.h | 25 + trunk/include/asm-generic/pgtable.h | 37 +- trunk/include/asm-h8300/keyboard.h | 8 + trunk/include/asm-h8300/unistd.h | 51 + trunk/include/asm-i386/bugs.h | 2 +- trunk/include/asm-i386/elf.h | 2 +- trunk/include/asm-i386/mca_dma.h | 3 +- trunk/include/asm-i386/nmi.h | 6 - trunk/include/asm-i386/pgtable-2level.h | 1 - trunk/include/asm-i386/pgtable-3level.h | 16 +- trunk/include/asm-i386/pgtable.h | 80 +- trunk/include/asm-i386/ptrace.h | 3 - trunk/include/asm-i386/smp.h | 2 - trunk/include/asm-i386/spinlock.h | 4 - trunk/include/asm-i386/topology.h | 1 - trunk/include/asm-i386/unistd.h | 39 + trunk/include/asm-ia64/ptrace.h | 3 - trunk/include/asm-ia64/spinlock.h | 4 - trunk/include/asm-ia64/topology.h | 2 - trunk/include/asm-ia64/unistd.h | 72 + trunk/include/asm-m32r/pgtable-2level.h | 2 +- trunk/include/asm-m32r/spinlock.h | 4 - trunk/include/asm-m32r/timex.h | 3 + trunk/include/asm-m32r/unistd.h | 37 + trunk/include/asm-m68k/unistd.h | 6 + trunk/include/asm-m68knommu/unistd.h | 55 + trunk/include/asm-mips/cacheflush.h | 2 + .../include/asm-mips/galileo-boards/ev96100.h | 55 + .../asm-mips/galileo-boards/ev96100int.h | 12 + trunk/include/asm-mips/irqflags.h | 25 - .../asm-mips/mach-ev64120/mach-gt64120.h | 1 - trunk/include/asm-mips/mach-ip27/topology.h | 1 - trunk/include/asm-mips/serial.h | 17 +- trunk/include/asm-mips/spinlock.h | 4 - trunk/include/asm-mips/stacktrace.h | 44 - trunk/include/asm-mips/unistd.h | 39 + trunk/include/asm-parisc/spinlock.h | 4 - trunk/include/asm-parisc/unistd.h | 86 + trunk/include/asm-powerpc/io.h | 1 - trunk/include/asm-powerpc/kprobes.h | 22 - trunk/include/asm-powerpc/ptrace.h | 2 - trunk/include/asm-powerpc/spinlock.h | 4 - trunk/include/asm-powerpc/topology.h | 1 - trunk/include/asm-powerpc/unistd.h | 7 + trunk/include/asm-ppc/spinlock.h | 4 - trunk/include/asm-s390/ptrace.h | 1 - trunk/include/asm-s390/setup.h | 1 - trunk/include/asm-s390/spinlock.h | 35 +- trunk/include/asm-s390/spinlock_types.h | 6 +- trunk/include/asm-s390/unistd.h | 51 + trunk/include/asm-sh/bugs.h | 2 +- trunk/include/asm-sh/ec3104/keyboard.h | 2 + trunk/include/asm-sh/mpc1211/keyboard.h | 4 + trunk/include/asm-sh/spinlock.h | 4 - trunk/include/asm-sh/unistd.h | 70 + trunk/include/asm-sh64/keyboard.h | 4 + trunk/include/asm-sh64/timex.h | 3 + trunk/include/asm-sh64/unistd.h | 41 + trunk/include/asm-sparc/spinlock.h | 4 - trunk/include/asm-sparc/unistd.h | 47 + trunk/include/asm-sparc64/spinlock.h | 4 - trunk/include/asm-sparc64/unistd.h | 42 + trunk/include/asm-um/unistd.h | 28 + trunk/include/asm-v850/unistd.h | 51 + trunk/include/asm-x86_64/nmi.h | 7 - trunk/include/asm-x86_64/ptrace.h | 2 - trunk/include/asm-x86_64/semaphore.h | 4 +- trunk/include/asm-x86_64/spinlock.h | 4 - trunk/include/asm-x86_64/topology.h | 1 - trunk/include/asm-x86_64/uaccess.h | 7 +- trunk/include/asm-x86_64/unistd.h | 93 +- trunk/include/asm-x86_64/vsyscall.h | 3 + trunk/include/asm-xtensa/timex.h | 3 + trunk/include/asm-xtensa/unistd.h | 5 + trunk/include/linux/acct.h | 4 + trunk/include/linux/aio.h | 12 +- trunk/include/linux/aio_abi.h | 2 - trunk/include/linux/bio.h | 2 - trunk/include/linux/blkdev.h | 333 ++- trunk/include/linux/blktrace_api.h | 3 +- trunk/include/linux/buffer_head.h | 19 +- trunk/include/linux/compat.h | 2 - trunk/include/linux/compat_ioctl.h | 22 +- trunk/include/linux/compiler.h | 8 +- trunk/include/linux/console.h | 3 - trunk/include/linux/console_struct.h | 2 +- trunk/include/linux/consolemap.h | 1 - trunk/include/linux/device-mapper.h | 14 - trunk/include/linux/dm-ioctl.h | 4 +- trunk/include/linux/elevator.h | 68 +- trunk/include/linux/ext2_fs.h | 64 +- trunk/include/linux/ext3_fs.h | 26 +- trunk/include/linux/fb.h | 3 - trunk/include/linux/fs.h | 125 +- trunk/include/linux/genalloc.h | 1 - trunk/include/linux/genhd.h | 4 - trunk/include/linux/getcpu.h | 12 +- trunk/include/linux/i2c-id.h | 1 - trunk/include/linux/ide.h | 12 +- trunk/include/linux/init_task.h | 12 - trunk/include/linux/input.h | 272 +-- trunk/include/linux/io.h | 4 - trunk/include/linux/ipc.h | 54 - trunk/include/linux/ipmi.h | 48 +- trunk/include/linux/kallsyms.h | 11 - trunk/include/linux/kernel.h | 6 +- trunk/include/linux/kmod.h | 4 - trunk/include/linux/kprobes.h | 8 +- trunk/include/linux/latency.h | 25 - trunk/include/linux/libps2.h | 1 - trunk/include/linux/lockd/bind.h | 2 +- trunk/include/linux/lockd/lockd.h | 2 +- trunk/include/linux/memory.h | 4 +- trunk/include/linux/memory_hotplug.h | 2 - trunk/include/linux/mm.h | 6 +- trunk/include/linux/module.h | 2 - trunk/include/linux/mpage.h | 7 +- trunk/include/linux/mtd/nand.h | 25 +- trunk/include/linux/mtd/onenand.h | 6 +- trunk/include/linux/mtd/onenand_regs.h | 4 +- trunk/include/linux/namei.h | 1 - trunk/include/linux/namespace.h | 6 +- trunk/include/linux/ncp_fs.h | 1 - trunk/include/linux/nfs_fs.h | 10 +- trunk/include/linux/nfsd/nfsd.h | 5 - trunk/include/linux/nfsd/nfsfh.h | 11 +- trunk/include/linux/nfsd/syscall.h | 17 + trunk/include/linux/nodemask.h | 2 - trunk/include/linux/nsproxy.h | 52 - trunk/include/linux/pci.h | 5 +- trunk/include/linux/pid.h | 49 +- trunk/include/linux/proc_fs.h | 10 +- trunk/include/linux/pspace.h | 23 - trunk/include/linux/raid/bitmap.h | 2 - trunk/include/linux/raid/md.h | 4 +- trunk/include/linux/raid/md_k.h | 14 +- trunk/include/linux/raid/md_u.h | 2 +- trunk/include/linux/raid/raid1.h | 1 + trunk/include/linux/raid/raid10.h | 1 + trunk/include/linux/raid/raid5.h | 7 +- trunk/include/linux/ramfs.h | 1 - trunk/include/linux/rbtree.h | 2 +- trunk/include/linux/reiserfs_fs.h | 41 +- trunk/include/linux/reiserfs_fs_sb.h | 2 +- trunk/include/linux/rtc.h | 4 +- trunk/include/linux/sched.h | 73 +- trunk/include/linux/serio.h | 3 - trunk/include/linux/stat.h | 2 +- trunk/include/linux/stddef.h | 6 - trunk/include/linux/string.h | 1 - trunk/include/linux/sunrpc/svc.h | 69 +- trunk/include/linux/sunrpc/svcsock.h | 15 +- trunk/include/linux/synclink.h | 4 +- trunk/include/linux/syscalls.h | 2 - trunk/include/linux/sysrq.h | 4 - trunk/include/linux/taskstats.h | 64 +- trunk/include/linux/timex.h | 58 +- trunk/include/linux/topology.h | 46 +- trunk/include/linux/tsacct_kern.h | 34 - trunk/include/linux/tty.h | 3 - trunk/include/linux/tty_driver.h | 3 +- trunk/include/linux/types.h | 2 - trunk/include/linux/uinput.h | 35 +- trunk/include/linux/unistd.h | 6 +- trunk/include/linux/unwind.h | 2 + trunk/include/linux/utime.h | 2 - trunk/include/linux/utsname.h | 55 +- trunk/include/linux/videodev2.h | 5 +- trunk/include/linux/vt_kern.h | 7 - trunk/include/linux/writeback.h | 2 - trunk/include/media/ir-common.h | 2 - trunk/include/media/tuner-types.h | 3 - trunk/include/media/tuner.h | 1 - trunk/include/media/v4l2-common.h | 16 +- trunk/include/media/v4l2-dev.h | 10 +- trunk/include/mtd/Kbuild | 3 +- trunk/include/mtd/mtd-abi.h | 6 + trunk/include/net/genetlink.h | 18 - trunk/include/net/sock.h | 1 + trunk/include/scsi/scsi_device.h | 4 +- trunk/include/scsi/scsi_tcq.h | 5 +- trunk/include/sound/pcm.h | 1 - trunk/include/video/sstfb.h | 4 + trunk/init/Kconfig | 44 +- trunk/init/do_mounts.c | 13 +- trunk/init/do_mounts_initrd.c | 3 +- trunk/init/do_mounts_md.c | 8 +- trunk/init/main.c | 6 +- trunk/init/version.c | 23 +- trunk/ipc/mqueue.c | 31 +- trunk/ipc/msg.c | 157 +- trunk/ipc/sem.c | 206 +- trunk/ipc/shm.c | 254 +-- trunk/ipc/util.c | 132 +- trunk/ipc/util.h | 24 +- trunk/kernel/Makefile | 5 +- trunk/kernel/acct.c | 30 + trunk/kernel/cpuset.c | 8 +- trunk/kernel/dma.c | 10 +- trunk/kernel/exit.c | 13 +- trunk/kernel/fork.c | 82 +- trunk/kernel/futex.c | 2 +- trunk/kernel/kallsyms.c | 124 +- trunk/kernel/kmod.c | 62 +- trunk/kernel/kprobes.c | 53 +- trunk/kernel/latency.c | 279 --- trunk/kernel/lockdep.c | 6 +- trunk/kernel/module.c | 40 +- trunk/kernel/nsproxy.c | 139 -- trunk/kernel/panic.c | 1 + trunk/kernel/pid.c | 111 +- trunk/kernel/power/snapshot.c | 10 +- trunk/kernel/resource.c | 83 +- trunk/kernel/sched.c | 326 ++- trunk/kernel/signal.c | 65 +- trunk/kernel/spinlock.c | 4 +- trunk/kernel/sys.c | 110 +- trunk/kernel/sys_ni.c | 5 - trunk/kernel/sysctl.c | 363 +--- trunk/kernel/taskstats.c | 10 +- trunk/kernel/time.c | 173 ++ trunk/kernel/time/Makefile | 2 +- trunk/kernel/time/ntp.c | 350 ---- trunk/kernel/timer.c | 230 ++- trunk/kernel/tsacct.c | 124 -- trunk/kernel/utsname.c | 95 - trunk/lib/Kconfig.debug | 14 - trunk/lib/Makefile | 3 +- trunk/lib/cpumask.c | 16 - trunk/lib/errno.c | 7 + trunk/lib/genalloc.c | 63 +- trunk/lib/ioremap.c | 92 - trunk/lib/list_debug.c | 3 + trunk/lib/rbtree.c | 6 - trunk/lib/sort.c | 10 +- trunk/mm/Kconfig | 7 +- trunk/mm/Makefile | 3 - trunk/mm/bounce.c | 302 --- trunk/mm/filemap.c | 180 +- trunk/mm/fremap.c | 2 +- trunk/mm/highmem.c | 281 +++ trunk/mm/memory.c | 12 +- trunk/mm/memory_hotplug.c | 66 +- trunk/mm/mempolicy.c | 3 +- trunk/mm/migrate.c | 4 +- trunk/mm/mprotect.c | 2 - trunk/mm/mremap.c | 2 - trunk/mm/nommu.c | 3 +- trunk/mm/page-writeback.c | 143 +- trunk/mm/shmem.c | 18 +- trunk/mm/truncate.c | 60 +- trunk/mm/util.c | 18 - trunk/net/bluetooth/rfcomm/tty.c | 2 +- trunk/net/ipv4/ipconfig.c | 16 +- trunk/net/ipv4/ipvs/ip_vs_sync.c | 2 +- trunk/net/ipv4/tcp_probe.c | 6 +- trunk/net/irda/ircomm/ircomm_tty.c | 2 +- trunk/net/rxrpc/transport.c | 3 +- trunk/net/socket.c | 87 +- trunk/net/sunrpc/clnt.c | 4 +- trunk/net/sunrpc/rpc_pipe.c | 6 +- trunk/net/sunrpc/sunrpc_syms.c | 2 - trunk/net/sunrpc/svc.c | 457 +---- trunk/net/sunrpc/svcauth_unix.c | 5 +- trunk/net/sunrpc/svcsock.c | 375 +--- trunk/scripts/.gitignore | 1 - trunk/scripts/Makefile | 2 +- trunk/scripts/kconfig/lxdialog/checklist.c | 28 +- trunk/scripts/kconfig/lxdialog/colors.h | 154 -- trunk/scripts/kconfig/lxdialog/dialog.h | 82 +- trunk/scripts/kconfig/lxdialog/inputbox.c | 18 +- trunk/scripts/kconfig/lxdialog/lxdialog.c | 6 +- trunk/scripts/kconfig/lxdialog/menubox.c | 28 +- trunk/scripts/kconfig/lxdialog/msgbox.c | 9 +- trunk/scripts/kconfig/lxdialog/textbox.c | 19 +- trunk/scripts/kconfig/lxdialog/util.c | 259 ++- trunk/scripts/kconfig/lxdialog/yesno.c | 9 +- trunk/security/inode.c | 4 +- trunk/security/selinux/selinuxfs.c | 4 +- trunk/sound/core/info_oss.c | 10 +- trunk/sound/core/pcm.c | 3 - trunk/sound/core/pcm_native.c | 63 +- trunk/sound/oss/cs46xx.c | 3 +- trunk/sound/oss/swarm_cs4297a.c | 2 +- trunk/sound/oss/trident.c | 48 +- trunk/sound/oss/via82cxxx_audio.c | 6 +- trunk/sound/pci/echoaudio/layla24_dsp.c | 4 +- trunk/sound/usb/usbaudio.c | 11 +- trunk/sound/usb/usbmidi.c | 3 +- 1501 files changed, 26415 insertions(+), 37384 deletions(-) delete mode 100644 trunk/Documentation/accounting/taskstats-struct.txt delete mode 100644 trunk/Documentation/video4linux/cx2341x/README.hm12 delete mode 100644 trunk/Documentation/video4linux/cx2341x/README.vbi create mode 100644 trunk/arch/alpha/mm/remap.c delete mode 100644 trunk/arch/frv/kernel/kernel_execve.S create mode 100644 trunk/arch/mips/basler/excite/excite_flashtest.c delete mode 100644 trunk/arch/mips/kernel/stacktrace.c delete mode 100644 trunk/drivers/char/drm/drm_hashtab.c delete mode 100644 trunk/drivers/char/drm/drm_hashtab.h delete mode 100644 trunk/drivers/char/drm/drm_mm.c delete mode 100644 trunk/drivers/char/drm/drm_sman.c delete mode 100644 trunk/drivers/char/drm/drm_sman.h create mode 100644 trunk/drivers/char/drm/sis_ds.c create mode 100644 trunk/drivers/char/drm/sis_ds.h create mode 100644 trunk/drivers/char/drm/via_ds.c create mode 100644 trunk/drivers/char/drm/via_ds.h delete mode 100644 trunk/drivers/char/watchdog/pnx4008_wdt.c delete mode 100644 trunk/drivers/ide/pci/jmicron.c delete mode 100644 trunk/drivers/input/ff-core.c delete mode 100644 trunk/drivers/input/ff-memless.c delete mode 100644 trunk/drivers/input/keyboard/stowaway.c delete mode 100644 trunk/drivers/input/touchscreen/penmount.c delete mode 100644 trunk/drivers/input/touchscreen/touchright.c delete mode 100644 trunk/drivers/input/touchscreen/touchwin.c create mode 100644 trunk/drivers/media/dvb/frontends/dib3000-common.c create mode 100644 trunk/drivers/media/dvb/frontends/dib3000-common.h delete mode 100644 trunk/drivers/media/dvb/frontends/dib3000mc.h create mode 100644 trunk/drivers/media/dvb/frontends/dib3000mc_priv.h delete mode 100644 trunk/drivers/media/dvb/frontends/dibx000_common.c delete mode 100644 trunk/drivers/media/dvb/frontends/dibx000_common.h delete mode 100644 trunk/drivers/media/dvb/frontends/mt2060.c delete mode 100644 trunk/drivers/media/dvb/frontends/mt2060.h delete mode 100644 trunk/drivers/media/dvb/frontends/mt2060_priv.h delete mode 100644 trunk/drivers/media/dvb/frontends/tda10086.c delete mode 100644 trunk/drivers/media/dvb/frontends/tda10086.h delete mode 100644 trunk/drivers/media/dvb/frontends/tda826x.c delete mode 100644 trunk/drivers/media/dvb/frontends/tda826x.h delete mode 100644 trunk/drivers/media/dvb/frontends/tua6100.c delete mode 100644 trunk/drivers/media/dvb/frontends/tua6100.h delete mode 100644 trunk/drivers/media/video/saa711x_regs.h delete mode 100644 trunk/drivers/misc/lkdtm.c create mode 100644 trunk/drivers/net/e1000/LICENSE rename trunk/drivers/{ => usb}/input/fixp-arith.h (100%) delete mode 100644 trunk/drivers/usb/input/hid-pidff.c delete mode 100644 trunk/drivers/usb/input/hid-zpff.c create mode 100644 trunk/drivers/usb/input/pid.c create mode 100644 trunk/drivers/usb/input/pid.h delete mode 100644 trunk/drivers/video/fb_ddc.c delete mode 100644 trunk/drivers/video/intelfb/intelfb_i2c.c delete mode 100644 trunk/fs/internal.h delete mode 100644 trunk/fs/no-block.c delete mode 100644 trunk/fs/read_write.h delete mode 100644 trunk/fs/utimes.c create mode 100644 trunk/include/asm-mips/galileo-boards/ev96100.h create mode 100644 trunk/include/asm-mips/galileo-boards/ev96100int.h delete mode 100644 trunk/include/asm-mips/stacktrace.h delete mode 100644 trunk/include/linux/latency.h delete mode 100644 trunk/include/linux/nsproxy.h delete mode 100644 trunk/include/linux/pspace.h delete mode 100644 trunk/include/linux/tsacct_kern.h delete mode 100644 trunk/kernel/latency.c delete mode 100644 trunk/kernel/nsproxy.c delete mode 100644 trunk/kernel/time/ntp.c delete mode 100644 trunk/kernel/tsacct.c delete mode 100644 trunk/kernel/utsname.c create mode 100644 trunk/lib/errno.c delete mode 100644 trunk/lib/ioremap.c delete mode 100644 trunk/mm/bounce.c delete mode 100644 trunk/scripts/kconfig/lxdialog/colors.h diff --git a/[refs] b/[refs] index d9d0418adb11..439d523943ed 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8b2a1fd1b394c60eaa2587716102dd5e9b4e5990 +refs/heads/master: 98e5a1579e7d34fe3803240750a1c48efcd9cb15 diff --git a/trunk/CREDITS b/trunk/CREDITS index 6c06ded9882b..66e82466dde8 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -951,12 +951,6 @@ S: Brevia 1043 S: S-114 79 Stockholm S: Sweden -N: Pekka Enberg -E: penberg@cs.helsinki.fi -W: http://www.cs.helsinki.fi/u/penberg/ -D: Various kernel hacks, fixes, and cleanups. -S: Finland - N: David Engebretsen E: engebret@us.ibm.com D: Linux port to 64-bit PowerPC architecture diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index 49c745720f47..6d4b1ef5b6f1 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -325,13 +325,8 @@ X!Ekernel/module.c !Ekernel/irq/manage.c - DMA Channels -!Ekernel/dma.c - - Resources Management !Ikernel/resource.c -!Ekernel/resource.c MTRR Handling diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index d6f3dd1a3464..1d6560413cc5 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -375,26 +375,6 @@ of information is needed by the kernel developers to help track down the problem. -Managing bug reports --------------------- - -One of the best ways to put into practice your hacking skills is by fixing -bugs reported by other people. Not only you will help to make the kernel -more stable, you'll learn to fix real world problems and you will improve -your skills, and other developers will be aware of your presence. Fixing -bugs is one of the best ways to earn merit amongst the developers, because -not many people like wasting time fixing other people's bugs. - -To work in the already reported bug reports, go to http://bugzilla.kernel.org. -If you want to be advised of the future bug reports, you can subscribe to the -bugme-new mailing list (only new bug reports are mailed here) or to the -bugme-janitor mailing list (every change in the bugzilla is mailed here) - - http://lists.osdl.org/mailman/listinfo/bugme-new - http://lists.osdl.org/mailman/listinfo/bugme-janitors - - - Mailing lists ------------- diff --git a/trunk/Documentation/IPMI.txt b/trunk/Documentation/IPMI.txt index 9f08d73d90bf..0256805b548f 100644 --- a/trunk/Documentation/IPMI.txt +++ b/trunk/Documentation/IPMI.txt @@ -326,12 +326,9 @@ for events, they will all receive all events that come in. For receiving commands, you have to individually register commands you want to receive. Call ipmi_register_for_cmd() and supply the netfn -and command name for each command you want to receive. You also -specify a bitmask of the channels you want to receive the command from -(or use IPMI_CHAN_ALL for all channels if you don't care). Only one -user may be registered for each netfn/cmd/channel, but different users -may register for different commands, or the same command if the -channel bitmasks do not overlap. +and command name for each command you want to receive. Only one user +may be registered for each netfn/cmd, but different users may register +for different commands. From userland, equivalent IOCTLs are provided to do these functions. @@ -364,7 +361,6 @@ You can change this at module load time (for a module) with: regspacings=,,... regsizes=,,... regshifts=,,... slave_addrs=,,... - force_kipmid=,,... Each of these except si_trydefaults is a list, the first item for the first interface, second item for the second interface, etc. @@ -410,13 +406,7 @@ The slave_addrs specifies the IPMI address of the local BMC. This is usually 0x20 and the driver defaults to that, but in case it's not, it can be specified when the driver starts up. -The force_ipmid parameter forcefully enables (if set to 1) or disables -(if set to 0) the kernel IPMI daemon. Normally this is auto-detected -by the driver, but systems with broken interrupts might need an enable, -or users that don't want the daemon (don't need the performance, don't -want the CPU hit) can disable it. - -When compiled into the kernel, the parameters can be specified on the +When compiled into the kernel, the addresses can be specified on the kernel command line as: ipmi_si.type=,... @@ -426,7 +416,6 @@ kernel command line as: ipmi_si.regsizes=,,... ipmi_si.regshifts=,,... ipmi_si.slave_addrs=,,... - ipmi_si.force_kipmid=,,... It works the same as the module parameters of the same names. diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist index 7ac61f60037a..a6cb6ffd2933 100644 --- a/trunk/Documentation/SubmitChecklist +++ b/trunk/Documentation/SubmitChecklist @@ -64,5 +64,3 @@ kernel patches. 19: All new userspace interfaces are documented in Documentation/ABI/. See Documentation/ABI/README for more information. - -20: Check that it all passes `make headers_check'. diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index b11792abd6b6..795ca3911cc5 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -285,7 +285,7 @@ int main(int argc, char *argv[]) if (maskset) { rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, - &cpumask, strlen(cpumask) + 1); + &cpumask, sizeof(cpumask)); PRINTF("Sent register cpumask, retval %d\n", rc); if (rc < 0) { printf("error sending register cpumask\n"); @@ -315,8 +315,7 @@ int main(int argc, char *argv[]) } if (msg.n.nlmsg_type == NLMSG_ERROR || !NLMSG_OK((&msg.n), rep_len)) { - struct nlmsgerr *err = NLMSG_DATA(&msg); - printf("fatal reply error, errno %d\n", err->error); + printf("fatal reply error, errno %d\n", errno); goto done; } @@ -384,7 +383,7 @@ int main(int argc, char *argv[]) if (maskset) { rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK, - &cpumask, strlen(cpumask) + 1); + &cpumask, sizeof(cpumask)); printf("Sent deregister mask, retval %d\n", rc); if (rc < 0) err(rc, "error sending deregister cpumask\n"); diff --git a/trunk/Documentation/accounting/taskstats-struct.txt b/trunk/Documentation/accounting/taskstats-struct.txt deleted file mode 100644 index 661c797eaf79..000000000000 --- a/trunk/Documentation/accounting/taskstats-struct.txt +++ /dev/null @@ -1,161 +0,0 @@ -The struct taskstats --------------------- - -This document contains an explanation of the struct taskstats fields. - -There are three different groups of fields in the struct taskstats: - -1) Common and basic accounting fields - If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and - the common fields and basic accounting fields are collected for - delivery at do_exit() of a task. -2) Delay accounting fields - These fields are placed between - /* Delay accounting fields start */ - and - /* Delay accounting fields end */ - Their values are collected if CONFIG_TASK_DELAY_ACCT is set. -3) Extended accounting fields - These fields are placed between - /* Extended accounting fields start */ - and - /* Extended accounting fields end */ - Their values are collected if CONFIG_TASK_XACCT is set. - -Future extension should add fields to the end of the taskstats struct, and -should not change the relative position of each field within the struct. - - -struct taskstats { - -1) Common and basic accounting fields: - /* The version number of this struct. This field is always set to - * TAKSTATS_VERSION, which is defined in . - * Each time the struct is changed, the value should be incremented. - */ - __u16 version; - - /* The exit code of a task. */ - __u32 ac_exitcode; /* Exit status */ - - /* The accounting flags of a task as defined in - * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG. - */ - __u8 ac_flag; /* Record flags */ - - /* The value of task_nice() of a task. */ - __u8 ac_nice; /* task_nice */ - - /* The name of the command that started this task. */ - char ac_comm[TS_COMM_LEN]; /* Command name */ - - /* The scheduling discipline as set in task->policy field. */ - __u8 ac_sched; /* Scheduling discipline */ - - __u8 ac_pad[3]; - __u32 ac_uid; /* User ID */ - __u32 ac_gid; /* Group ID */ - __u32 ac_pid; /* Process ID */ - __u32 ac_ppid; /* Parent process ID */ - - /* The time when a task begins, in [secs] since 1970. */ - __u32 ac_btime; /* Begin time [sec since 1970] */ - - /* The elapsed time of a task, in [usec]. */ - __u64 ac_etime; /* Elapsed time [usec] */ - - /* The user CPU time of a task, in [usec]. */ - __u64 ac_utime; /* User CPU time [usec] */ - - /* The system CPU time of a task, in [usec]. */ - __u64 ac_stime; /* System CPU time [usec] */ - - /* The minor page fault count of a task, as set in task->min_flt. */ - __u64 ac_minflt; /* Minor Page Fault Count */ - - /* The major page fault count of a task, as set in task->maj_flt. */ - __u64 ac_majflt; /* Major Page Fault Count */ - - -2) Delay accounting fields: - /* Delay accounting fields start - * - * All values, until the comment "Delay accounting fields end" are - * available only if delay accounting is enabled, even though the last - * few fields are not delays - * - * xxx_count is the number of delay values recorded - * xxx_delay_total is the corresponding cumulative delay in nanoseconds - * - * xxx_delay_total wraps around to zero on overflow - * xxx_count incremented regardless of overflow - */ - - /* Delay waiting for cpu, while runnable - * count, delay_total NOT updated atomically - */ - __u64 cpu_count; - __u64 cpu_delay_total; - - /* Following four fields atomically updated using task->delays->lock */ - - /* Delay waiting for synchronous block I/O to complete - * does not account for delays in I/O submission - */ - __u64 blkio_count; - __u64 blkio_delay_total; - - /* Delay waiting for page fault I/O (swap in only) */ - __u64 swapin_count; - __u64 swapin_delay_total; - - /* cpu "wall-clock" running time - * On some architectures, value will adjust for cpu time stolen - * from the kernel in involuntary waits due to virtualization. - * Value is cumulative, in nanoseconds, without a corresponding count - * and wraps around to zero silently on overflow - */ - __u64 cpu_run_real_total; - - /* cpu "virtual" running time - * Uses time intervals seen by the kernel i.e. no adjustment - * for kernel's involuntary waits due to virtualization. - * Value is cumulative, in nanoseconds, without a corresponding count - * and wraps around to zero silently on overflow - */ - __u64 cpu_run_virtual_total; - /* Delay accounting fields end */ - /* version 1 ends here */ - - -3) Extended accounting fields - /* Extended accounting fields start */ - - /* Accumulated RSS usage in duration of a task, in MBytes-usecs. - * The current rss usage is added to this counter every time - * a tick is charged to a task's system time. So, at the end we - * will have memory usage multiplied by system time. Thus an - * average usage per system time unit can be calculated. - */ - __u64 coremem; /* accumulated RSS usage in MB-usec */ - - /* Accumulated virtual memory usage in duration of a task. - * Same as acct_rss_mem1 above except that we keep track of VM usage. - */ - __u64 virtmem; /* accumulated VM usage in MB-usec */ - - /* High watermark of RSS usage in duration of a task, in KBytes. */ - __u64 hiwater_rss; /* High-watermark of RSS usage */ - - /* High watermark of VM usage in duration of a task, in KBytes. */ - __u64 hiwater_vm; /* High-water virtual memory usage */ - - /* The following four fields are I/O statistics of a task. */ - __u64 read_char; /* bytes read */ - __u64 write_char; /* bytes written */ - __u64 read_syscalls; /* read syscalls */ - __u64 write_syscalls; /* write syscalls */ - - /* Extended accounting fields end */ - -} diff --git a/trunk/Documentation/fb/intel810.txt b/trunk/Documentation/fb/intel810.txt index be3e7836abef..4f0d6bc789ef 100644 --- a/trunk/Documentation/fb/intel810.txt +++ b/trunk/Documentation/fb/intel810.txt @@ -9,9 +9,8 @@ Intel 810/815 Framebuffer driver ================================================================ A. Introduction - This is a framebuffer driver for various Intel 810/815 compatible - graphics devices. These include: +graphics devices. These would include: Intel 810 Intel 810E @@ -22,136 +21,136 @@ A. Introduction B. Features - - Choice of using Discrete Video Timings, VESA Generalized Timing + - Choice of using Discrete Video Timings, VESA Generalized Timing Formula, or a framebuffer specific database to set the video mode - - Supports a variable range of horizontal and vertical resolution and - vertical refresh rates if the VESA Generalized Timing Formula is + - Supports a variable range of horizontal and vertical resolution, and + vertical refresh rates if the VESA Generalized Timing Formula is enabled. - - Supports color depths of 8, 16, 24 and 32 bits per pixel + - Supports color depths of 8, 16, 24 and 32 bits per pixel - Supports pseudocolor, directcolor, or truecolor visuals - - Full and optimized hardware acceleration at 8, 16 and 24 bpp + - Full and optimized hardware acceleration at 8, 16 and 24 bpp - Robust video state save and restore - - MTRR support + - MTRR support - Utilizes user-entered monitor specifications to automatically calculate required video mode parameters. - - Can concurrently run with xfree86 running with native i810 drivers + - Can concurrently run with xfree86 running with native i810 drivers - Hardware Cursor Support - Supports EDID probing either by DDC/I2C or through the BIOS C. List of available options - - a. "video=i810fb" + + a. "video=i810fb" enables the i810 driver Recommendation: required - - b. "xres:" + + b. "xres:" select horizontal resolution in pixels. (This parameter will be ignored if 'mode_option' is specified. See 'o' below). - Recommendation: user preference + Recommendation: user preference (default = 640) c. "yres:" select vertical resolution in scanlines. If Discrete Video Timings is enabled, this will be ignored and computed as 3*xres/4. (This parameter will be ignored if 'mode_option' is specified. See 'o' - below) + below) Recommendation: user preference (default = 480) - - d. "vyres:" + + d. "vyres:" select virtual vertical resolution in scanlines. If (0) or none - is specified, this will be computed against maximum available memory. + is specified, this will be computed against maximum available memory. Recommendation: do not set (default = 480) e. "vram:" - select amount of system RAM in MB to allocate for the video memory + select amount of system RAM in MB to allocate for the video memory Recommendation: 1 - 4 MB. (default = 4) - f. "bpp:" - select desired pixel depth + f. "bpp:" + select desired pixel depth Recommendation: 8 (default = 8) - g. "hsync1/hsync2:" - select the minimum and maximum Horizontal Sync Frequency of the - monitor in kHz. If using a fixed frequency monitor, hsync1 must + g. "hsync1/hsync2:" + select the minimum and maximum Horizontal Sync Frequency of the + monitor in KHz. If a using a fixed frequency monitor, hsync1 must be equal to hsync2. If EDID probing is successful, these will be ignored and values will be taken from the EDID block. Recommendation: check monitor manual for correct values - (default = 29/30) + default (29/30) - h. "vsync1/vsync2:" + h. "vsync1/vsync2:" select the minimum and maximum Vertical Sync Frequency of the monitor - in Hz. You can also use this option to lock your monitor's refresh + in Hz. You can also use this option to lock your monitor's refresh rate. If EDID probing is successful, these will be ignored and values will be taken from the EDID block. Recommendation: check monitor manual for correct values (default = 60/60) - IMPORTANT: If you need to clamp your timings, try to give some - leeway for computational errors (over/underflows). Example: if + IMPORTANT: If you need to clamp your timings, try to give some + leeway for computational errors (over/underflows). Example: if using vsync1/vsync2 = 60/60, make sure hsync1/hsync2 has at least a 1 unit difference, and vice versa. - i. "voffset:" - select at what offset in MB of the logical memory to allocate the + i. "voffset:" + select at what offset in MB of the logical memory to allocate the framebuffer memory. The intent is to avoid the memory blocks used by standard graphics applications (XFree86). The default - offset (16 MB for a 64 MB aperture, 8 MB for a 32 MB aperture) will - avoid XFree86's usage and allows up to 7 MB/15 MB of framebuffer - memory. Depending on your usage, adjust the value up or down - (0 for maximum usage, 31/63 MB for the least amount). Note, an + offset (16 MB for a 64MB aperture, 8 MB for a 32MB aperture) will + avoid XFree86's usage and allows up to 7MB/15MB of framebuffer + memory. Depending on your usage, adjust the value up or down, + (0 for maximum usage, 31/63 MB for the least amount). Note, an arbitrary setting may conflict with XFree86. Recommendation: do not set (default = 8 or 16 MB) - - j. "accel" - enable text acceleration. This can be enabled/reenabled anytime - by using 'fbset -accel true/false'. + + j. "accel" + enable text acceleration. This can be enabled/reenabled anytime + by using 'fbset -accel true/false'. Recommendation: enable - (default = not set) + (default = not set) - k. "mtrr" + k. "mtrr" enable MTRR. This allows data transfers to the framebuffer memory to occur in bursts which can significantly increase performance. - Not very helpful with the i810/i815 because of 'shared memory'. + Not very helpful with the i810/i815 because of 'shared memory'. Recommendation: do not set - (default = not set) + (default = not set) l. "extvga" if specified, secondary/external VGA output will always be enabled. Useful if the BIOS turns off the VGA port when no monitor is attached. - The external VGA monitor can then be attached without rebooting. + The external VGA monitor can then be attached without rebooting. Recommendation: do not set (default = not set) - - m. "sync" + + m. "sync" Forces the hardware engine to do a "sync" or wait for the hardware - to finish before starting another instruction. This will produce a + to finish before starting another instruction. This will produce a more stable setup, but will be slower. Recommendation: do not set @@ -163,7 +162,6 @@ C. List of available options Recommendation: do not set (default = not set) - o. x[-][@] The driver will now accept specification of boot mode option. If this is specified, the options 'xres' and 'yres' will be ignored. See @@ -185,8 +183,8 @@ append="video=i810fb:vram:2,xres:1024,yres:768,bpp:8,hsync1:30,hsync2:55, \ vsync1:50,vsync2:85,accel,mtrr" This will initialize the framebuffer to 1024x768 at 8bpp. The framebuffer -will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate -will be computed based on the hsync1/hsync2 and vsync1/vsync2 values. +will use 2 MB of System RAM. MTRR support will be enabled. The refresh rate +will be computed based on the hsync1/hsync2 and vsync1/vsync2 values. IMPORTANT: You must include hsync1, hsync2, vsync1 and vsync2 to enable video modes @@ -196,10 +194,10 @@ vsync1 and vsync2 parameters. These parameters will be taken from the EDID block. E. Module options - -The module parameters are essentially similar to the kernel -parameters. The main difference is that you need to include a Boolean value -(1 for TRUE, and 0 for FALSE) for those options which don't need a value. + + The module parameters are essentially similar to the kernel +parameters. The main difference is that you need to include a Boolean value +(1 for TRUE, and 0 for FALSE) for those options which don't need a value. Example, to enable MTRR, include "mtrr=1". @@ -216,62 +214,62 @@ Or just add the following to /etc/modprobe.conf options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \ vsync2=85 accel=1 mtrr=1 -and just do a +and just do a modprobe i810fb F. Setup - a. Do your usual method of configuring the kernel. - + a. Do your usual method of configuring the kernel. + make menuconfig/xconfig/config - b. Under "Code maturity level options" enable "Prompt for development - and/or incomplete code/drivers". + b. Under "Code Maturity Options", enable "Prompt for experimental/ + incomplete code/drivers". c. Enable agpgart support for the Intel 810/815 on-board graphics. - This is required. The option is under "Character Devices". + This is required. The option is under "Character Devices" d. Under "Graphics Support", select "Intel 810/815" either statically or as a module. Choose "use VESA Generalized Timing Formula" if - you need to maximize the capability of your display. To be on the - safe side, you can leave this unselected. - + you need to maximize the capability of your display. To be on the + safe side, you can leave this unselected. + e. If you want support for DDC/I2C probing (Plug and Play Displays), set 'Enable DDC Support' to 'y'. To make this option appear, set 'use VESA Generalized Timing Formula' to 'y'. - f. If you want a framebuffer console, enable it under "Console - Drivers". - - g. Compile your kernel. - - h. Load the driver as described in sections D and E. + f. If you want a framebuffer console, enable it under "Console + Drivers" + g. Compile your kernel. + + h. Load the driver as described in section D and E. + i. Try the DirectFB (http://www.directfb.org) + the i810 gfxdriver patch to see the chipset in action (or inaction :-). G. Acknowledgment: - + 1. Geert Uytterhoeven - his excellent howto and the virtual - framebuffer driver code made this possible. + framebuffer driver code made this possible. - 2. Jeff Hartmann for his agpgart code. + 2. Jeff Hartmann for his agpgart code. 3. The X developers. Insights were provided just by reading the XFree86 source code. 4. Intel(c). For this value-oriented chipset driver and for - providing documentation. + providing documentation. 5. Matt Sottek. His inputs and ideas helped in making some - optimizations possible. + optimizations possible. H. Home Page: A more complete, and probably updated information is provided at - http://i810fb.sourceforge.net. +http://i810fb.sourceforge.net. ########################### Tony diff --git a/trunk/Documentation/fb/intelfb.txt b/trunk/Documentation/fb/intelfb.txt index da5ee74219e8..c12d39a23c3d 100644 --- a/trunk/Documentation/fb/intelfb.txt +++ b/trunk/Documentation/fb/intelfb.txt @@ -1,19 +1,16 @@ -Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver +Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver ================================================================ A. Introduction - This is a framebuffer driver for various Intel 8xx/9xx compatible + This is a framebuffer driver for various Intel 810/815 compatible graphics devices. These would include: Intel 830M - Intel 845G + Intel 810E845G Intel 852GM Intel 855GM Intel 865G Intel 915G - Intel 915GM - Intel 945G - Intel 945GM B. List of available options @@ -81,27 +78,19 @@ C. Kernel booting Separate each option/option-pair by commas (,) and the option from its value with an equals sign (=) as in the following: -video=intelfb:option1,option2=value2 +video=i810fb:option1,option2=value2 Sample Usage ------------ In /etc/lilo.conf, add the line: -append="video=intelfb:mode=800x600-32@75,accel,hwcursor,vram=8" +append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8" This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor will be enabled. -Remarks -------- - -If setting this parameter doesn't work (you stay in a 80x25 text-mode), -you might need to set the "vga=" parameter too - see vesafb.txt -in this directory. - - D. Module options The module parameters are essentially similar to the kernel diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index b98f01fc14bf..436697cb9388 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -46,8 +46,17 @@ Who: Jody McIntyre --------------------------- +What: sbp2: module parameter "force_inquiry_hack" +When: July 2006 +Why: Superceded by parameter "workarounds". Both parameters are meant to be + used ad-hoc and for single devices only, i.e. not in modprobe.conf, + therefore the impact of this feature replacement should be low. +Who: Stefan Richter + +--------------------------- + What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. -When: December 2006 +When: July 2006 Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 series. The old API have lots of drawbacks and don't provide enough means to work with all video and audio standards. The newer API is @@ -122,6 +131,15 @@ Who: Arjan van de Ven --------------------------- +What: START_ARRAY ioctl for md +When: July 2006 +Files: drivers/md/md.c +Why: Not reliable by design - can fail when most needed. + Alternatives exist +Who: NeilBrown + +--------------------------- + What: eepro100 network driver When: January 2007 Why: replaced by the e100 driver @@ -316,11 +334,3 @@ Why: i2c-isa is a non-sense and doesn't fit in the device driver Who: Jean Delvare --------------------------- - -What: ftape -When: 2.6.20 -Why: Orphaned for ages. SMP bugs long unfixed. Few users left - in the world. -Who: Jeff Garzik - ---------------------------- diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index eb1a6cad21e6..247d7f619aa2 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -356,9 +356,10 @@ The last two are called only from check_disk_change(). prototypes: loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); - ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); - ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); + ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, + loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index cd07c21b8400..1cb7e8be927a 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -699,9 +699,9 @@ This describes how the VFS can manipulate an open file. As of kernel struct file_operations { loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); - ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); - ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); + ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); diff --git a/trunk/Documentation/ia64/serial.txt b/trunk/Documentation/ia64/serial.txt index 040b9773209f..f51eb4bc2ff1 100644 --- a/trunk/Documentation/ia64/serial.txt +++ b/trunk/Documentation/ia64/serial.txt @@ -124,13 +124,6 @@ TROUBLESHOOTING SERIAL CONSOLE PROBLEMS - Add entry to /etc/securetty for console tty. - No ACPI serial devices found in 2.6.17 or later: - - - Turn on CONFIG_PNP and CONFIG_PNPACPI. Prior to 2.6.17, ACPI - serial devices were discovered by 8250_acpi. In 2.6.17, - 8250_acpi was replaced by the combination of 8250_pnp and - CONFIG_PNPACPI. - [1] http://www.dig64.org/specifications/DIG64_PCDPv20.pdf diff --git a/trunk/Documentation/input/ff.txt b/trunk/Documentation/input/ff.txt index c53b1c11aa40..c7e10eaff203 100644 --- a/trunk/Documentation/input/ff.txt +++ b/trunk/Documentation/input/ff.txt @@ -1,37 +1,67 @@ Force feedback for Linux. By Johann Deneux on 2001/04/22. -Updated by Anssi Hannula on 2006/04/09. You may redistribute this file. Please remember to include shape.fig and interactive.fig as well. ---------------------------------------------------------------------------- -1. Introduction +0. Introduction ~~~~~~~~~~~~~~~ This document describes how to use force feedback devices under Linux. The goal is not to support these devices as if they were simple input-only devices (as it is already the case), but to really enable the rendering of force effects. -This document only describes the force feedback part of the Linux input -interface. Please read joystick.txt and input.txt before reading further this -document. +At the moment, only I-Force devices are supported, and not officially. That +means I had to find out how the protocol works on my own. Of course, the +information I managed to grasp is far from being complete, and I can not +guarranty that this driver will work for you. +This document only describes the force feedback part of the driver for I-Force +devices. Please read joystick.txt before reading further this document. 2. Instructions to the user ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To enable force feedback, you have to: - -1. have your kernel configured with evdev and a driver that supports your - device. -2. make sure evdev module is loaded and /dev/input/event* device files are - created. +Here are instructions on how to compile and use the driver. In fact, this +driver is the normal iforce, input and evdev drivers written by Vojtech +Pavlik, plus additions to support force feedback. Before you start, let me WARN you that some devices shake violently during the initialisation phase. This happens for example with my "AVB Top Shot Pegasus". To stop this annoying behaviour, move you joystick to its limits. Anyway, you -should keep a hand on your device, in order to avoid it to break down if +should keep a hand on your device, in order to avoid it to brake down if something goes wrong. -If you have a serial iforce device, you need to start inputattach. See -joystick.txt for details. +At the kernel's compilation: + - Enable IForce/Serial + - Enable Event interface + +Compile the modules, install them. + +You also need inputattach. + +You then need to insert the modules into the following order: +% modprobe joydev +% modprobe serport # Only for serial +% modprobe iforce +% modprobe evdev +% ./inputattach -ifor $2 & # Only for serial +If you are using USB, you don't need the inputattach step. + +Please check that you have all the /dev/input entries needed: +cd /dev +rm js* +mkdir input +mknod input/js0 c 13 0 +mknod input/js1 c 13 1 +mknod input/js2 c 13 2 +mknod input/js3 c 13 3 +ln -s input/js0 js0 +ln -s input/js1 js1 +ln -s input/js2 js2 +ln -s input/js3 js3 + +mknod input/event0 c 13 64 +mknod input/event1 c 13 65 +mknod input/event2 c 13 66 +mknod input/event3 c 13 67 2.1 Does it work ? ~~~~~~~~~~~~~~~~~~ @@ -40,9 +70,9 @@ There is an utility called fftest that will allow you to test the driver. 3. Instructions to the developper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All interactions are done using the event API. That is, you can use ioctl() + All interactions are done using the event API. That is, you can use ioctl() and write() on /dev/input/eventXX. -This information is subject to change. + This information is subject to change. 3.1 Querying device capabilities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -56,29 +86,18 @@ int ioctl(int file_descriptor, int request, unsigned long *features); Returns the features supported by the device. features is a bitfield with the following bits: +- FF_X has an X axis (usually joysticks) +- FF_Y has an Y axis (usually joysticks) +- FF_WHEEL has a wheel (usually sterring wheels) - FF_CONSTANT can render constant force effects -- FF_PERIODIC can render periodic effects with the following waveforms: - - FF_SQUARE square waveform - - FF_TRIANGLE triangle waveform - - FF_SINE sine waveform - - FF_SAW_UP sawtooth up waveform - - FF_SAW_DOWN sawtooth down waveform - - FF_CUSTOM custom waveform +- FF_PERIODIC can render periodic effects (sine, triangle, square...) - FF_RAMP can render ramp effects - FF_SPRING can simulate the presence of a spring -- FF_FRICTION can simulate friction +- FF_FRICTION can simulate friction - FF_DAMPER can simulate damper effects -- FF_RUMBLE rumble effects +- FF_RUMBLE rumble effects (normally the only effect supported by rumble + pads) - FF_INERTIA can simulate inertia -- FF_GAIN gain is adjustable -- FF_AUTOCENTER autocenter is adjustable - -Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All - devices that support FF_RUMBLE support FF_PERIODIC (square, triangle, - sine) and the other way around. - -Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver - supports it yet. int ioctl(int fd, EVIOCGEFFECTS, int *n); @@ -89,7 +108,7 @@ Returns the number of effects the device can keep in its memory. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include #include - + int ioctl(int file_descriptor, int request, struct ff_effect *effect); "request" must be EVIOCSFF. @@ -101,9 +120,6 @@ to the unique id assigned by the driver. This data is required for performing some operations (removing an effect, controlling the playback). This if field must be set to -1 by the user in order to tell the driver to allocate a new effect. - -Effects are file descriptor specific. - See for a description of the ff_effect struct. You should also find help in a few sketches, contained in files shape.fig and interactive.fig. You need xfig to visualize these files. @@ -112,8 +128,8 @@ You need xfig to visualize these files. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int ioctl(int fd, EVIOCRMFF, effect.id); -This makes room for new effects in the device's memory. Note that this also -stops the effect if it was playing. +This makes room for new effects in the device's memory. Please note this won't +stop the effect if it was playing. 3.4 Controlling the playback of effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -133,21 +149,22 @@ Control of playing is done with write(). Below is an example: play.type = EV_FF; play.code = effect.id; play.value = 3; - + write(fd, (const void*) &play, sizeof(play)); ... /* Stop an effect */ stop.type = EV_FF; stop.code = effect.id; stop.value = 0; - + write(fd, (const void*) &play, sizeof(stop)); 3.5 Setting the gain ~~~~~~~~~~~~~~~~~~~~ Not all devices have the same strength. Therefore, users should set a gain factor depending on how strong they want effects to be. This setting is -persistent across access to the driver. +persistent across access to the driver, so you should not care about it if +you are writing games, as another utility probably already set this for you. /* Set the gain of the device int gain; /* between 0 and 100 */ @@ -187,14 +204,11 @@ type of device, not all parameters can be dynamically updated. For example, the direction of an effect cannot be updated with iforce devices. In this case, the driver stops the effect, up-load it, and restart it. -Therefore it is recommended to dynamically change direction while the effect -is playing only when it is ok to restart the effect with a replay count of 1. 3.8 Information about the status of effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Every time the status of an effect is changed, an event is sent. The values and meanings of the fields of the event are as follows: - struct input_event { /* When the status of the effect changed */ struct timeval time; @@ -211,9 +225,3 @@ struct input_event { FF_STATUS_STOPPED The effect stopped playing FF_STATUS_PLAYING The effect started to play - -NOTE: Status feedback is only supported by iforce driver. If you have - a really good reason to use this, please contact - linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com - so that support for it can be added to the rest of the drivers. - diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index ba26201d5023..2c3b1eae4280 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -151,9 +151,9 @@ So that you can load and unload Kprobes-based instrumentation modules, make sure "Loadable module support" (CONFIG_MODULES) and "Module unloading" (CONFIG_MODULE_UNLOAD) are set to "y". -Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL -are set to "y", since kallsyms_lookup_name() is used by the in-kernel -kprobe address resolution code. +You may also want to ensure that CONFIG_KALLSYMS and perhaps even +CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name() +is a handy, version-independent way to find a function's address. If you need to insert a probe in the middle of a function, you may find it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO), @@ -179,27 +179,6 @@ occurs during execution of kp->pre_handler or kp->post_handler, or during single-stepping of the probed instruction, Kprobes calls kp->fault_handler. Any or all handlers can be NULL. -NOTE: -1. With the introduction of the "symbol_name" field to struct kprobe, -the probepoint address resolution will now be taken care of by the kernel. -The following will now work: - - kp.symbol_name = "symbol_name"; - -(64-bit powerpc intricacies such as function descriptors are handled -transparently) - -2. Use the "offset" field of struct kprobe if the offset into the symbol -to install a probepoint is known. This field is used to calculate the -probepoint. - -3. Specify either the kprobe "symbol_name" OR the "addr". If both are -specified, kprobe registration will fail with -EINVAL. - -4. With CISC architectures (such as i386 and x86_64), the kprobes code -does not validate if the kprobe.addr is at an instruction boundary. -Use "offset" with caution. - register_kprobe() returns 0 on success, or a negative errno otherwise. User's pre-handler (kp->pre_handler): @@ -246,12 +225,6 @@ control to Kprobes.) If the probed function is declared asmlinkage, fastcall, or anything else that affects how args are passed, the handler's declaration must match. -NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific -aliasing of jp->entry. In the interest of portability, it is advised -to use: - - jp->entry = JPROBE_ENTRY(handler); - register_jprobe() returns 0 on success, or a negative errno otherwise. 4.3 register_kretprobe @@ -278,11 +251,6 @@ of interest: - ret_addr: the return address - rp: points to the corresponding kretprobe object - task: points to the corresponding task struct - -The regs_return_value(regs) macro provides a simple abstraction to -extract the return value from the appropriate register as defined by -the architecture's ABI. - The handler's return value is currently ignored. 4.4 unregister_*probe @@ -401,6 +369,7 @@ stack trace and selected i386 registers when do_fork() is called. #include #include #include +#include #include /*For each probe you need to allocate a kprobe structure*/ @@ -434,14 +403,18 @@ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) return 0; } -static int __init kprobe_init(void) +int init_module(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; - kp.symbol_name = "do_fork"; - + kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); + /* register the kprobe now */ + if (!kp.addr) { + printk("Couldn't find %s to plant kprobe\n", "do_fork"); + return -1; + } if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; @@ -450,14 +423,12 @@ static int __init kprobe_init(void) return 0; } -static void __exit kprobe_exit(void) +void cleanup_module(void) { unregister_kprobe(&kp); printk("kprobe unregistered\n"); } -module_init(kprobe_init) -module_exit(kprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -492,6 +463,7 @@ the arguments of do_fork(). #include #include #include +#include /* * Jumper probe for do_fork. @@ -513,13 +485,17 @@ long jdo_fork(unsigned long clone_flags, unsigned long stack_start, } static struct jprobe my_jprobe = { - .entry = JPROBE_ENTRY(jdo_fork) + .entry = (kprobe_opcode_t *) jdo_fork }; -static int __init jprobe_init(void) +int init_module(void) { int ret; - my_jprobe.kp.symbol_name = "do_fork"; + my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); + if (!my_jprobe.kp.addr) { + printk("Couldn't find %s to plant jprobe\n", "do_fork"); + return -1; + } if ((ret = register_jprobe(&my_jprobe)) <0) { printk("register_jprobe failed, returned %d\n", ret); @@ -530,14 +506,12 @@ static int __init jprobe_init(void) return 0; } -static void __exit jprobe_exit(void) +void cleanup_module(void) { unregister_jprobe(&my_jprobe); printk("jprobe unregistered\n"); } -module_init(jprobe_init) -module_exit(jprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -556,13 +530,16 @@ report failed calls to sys_open(). #include #include #include +#include static const char *probed_func = "sys_open"; /* Return-probe handler: If the probed function fails, log the return value. */ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { - int retval = regs_return_value(regs); + // Substitute the appropriate register name for your architecture -- + // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. + int retval = (int) regs->eax; if (retval < 0) { printk("%s returns %d\n", probed_func, retval); } @@ -575,11 +552,15 @@ static struct kretprobe my_kretprobe = { .maxactive = 20 }; -static int __init kretprobe_init(void) +int init_module(void) { int ret; - my_kretprobe.kp.symbol_name = (char *)probed_func; - + my_kretprobe.kp.addr = + (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); + if (!my_kretprobe.kp.addr) { + printk("Couldn't find %s to plant return probe\n", probed_func); + return -1; + } if ((ret = register_kretprobe(&my_kretprobe)) < 0) { printk("register_kretprobe failed, returned %d\n", ret); return -1; @@ -588,7 +569,7 @@ static int __init kretprobe_init(void) return 0; } -static void __exit kretprobe_exit(void) +void cleanup_module(void) { unregister_kretprobe(&my_kretprobe); printk("kretprobe unregistered\n"); @@ -597,8 +578,6 @@ static void __exit kretprobe_exit(void) my_kretprobe.nmissed, probed_func); } -module_init(kretprobe_init) -module_exit(kretprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -611,5 +590,3 @@ messages.) For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ -http://www-users.cs.umn.edu/~boutcher/kprobes/ -http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) diff --git a/trunk/Documentation/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index 55a7e4fa8cc2..00d93605bfd3 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -36,28 +36,6 @@ The validator tracks lock-class usage history into 5 separate state bits: - 'ever used' [ == !unused ] -When locking rules are violated, these 4 state bits are presented in the -locking error messages, inside curlies. A contrived example: - - modprobe/2287 is trying to acquire lock: - (&sio_locks[i].lock){--..}, at: [] mutex_lock+0x21/0x24 - - but task is already holding lock: - (&sio_locks[i].lock){--..}, at: [] mutex_lock+0x21/0x24 - - -The bit position indicates hardirq, softirq, hardirq-read, -softirq-read respectively, and the character displayed in each -indicates: - - '.' acquired while irqs enabled - '+' acquired in irq context - '-' acquired in process context with irqs disabled - '?' read-acquired both with irqs enabled and in irq context - -Unused mutexes cannot be part of the cause of an error. - - Single-lock state rules: ------------------------ diff --git a/trunk/Documentation/md.txt b/trunk/Documentation/md.txt index 9ae9e4078985..0668f9dc9d29 100644 --- a/trunk/Documentation/md.txt +++ b/trunk/Documentation/md.txt @@ -154,12 +154,11 @@ contains further md-specific information about the device. All md devices contain: level - a text file indicating the 'raid level'. e.g. raid0, raid1, - raid5, linear, multipath, faulty. + a text file indicating the 'raid level'. This may be a standard + numerical level prefixed by "RAID-" - e.g. "RAID-5", or some + other name such as "linear" or "multipath". If no raid level has been set yet (array is still being - assembled), the value will reflect whatever has been written - to it, which may be a name like the above, or may be a number - such as '0', '5', etc. + assembled), this file will be empty. raid_disks a text file with a simple number indicating the number of devices @@ -193,6 +192,14 @@ All md devices contain: 1.2 (newer format in varying locations) or "none" indicating that the kernel isn't managing metadata at all. + level + The raid 'level' for this array. The name will often (but not + always) be the same as the name of the module that implements the + level. To be auto-loaded the module must have an alias + md-$LEVEL e.g. md-raid5 + This can be written only while the array is being assembled, not + after it is started. + layout The "layout" for the array for the particular level. This is simply a number that is interpretted differently by different @@ -403,15 +410,6 @@ also have than sectors, this my be larger than the number of actual errors by a factor of the number of sectors in a page. - bitmap_set_bits - If the array has a write-intent bitmap, then writing to this - attribute can set bits in the bitmap, indicating that a resync - would need to check the corresponding blocks. Either individual - numbers or start-end pairs can be written. Multiple numbers - can be separated by a space. - Note that the numbers are 'bit' numbers, not 'block' numbers. - They should be scaled by the bitmap_chunksize. - Each active md device may also have attributes specific to the personality module that manages it. These are specific to the implementation of the module and could diff --git a/trunk/Documentation/rt-mutex-design.txt b/trunk/Documentation/rt-mutex-design.txt index 4b736d24da7a..c472ffacc2f6 100644 --- a/trunk/Documentation/rt-mutex-design.txt +++ b/trunk/Documentation/rt-mutex-design.txt @@ -333,11 +333,11 @@ cmpxchg is basically the following function performed atomically: unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C) { - unsigned long T = *A; - if (*A == *B) { - *A = *C; - } - return T; + unsigned long T = *A; + if (*A == *B) { + *A = *C; + } + return T; } #define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c) @@ -582,7 +582,7 @@ contention). try_to_take_rt_mutex is used every time the task tries to grab a mutex in the slow path. The first thing that is done here is an atomic setting of the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the mutex has no owner, there are no waiters and +be false, because if the the mutex has no owner, there are no waiters and the current task also won't have any waiters. But we don't have the lock yet, so we assume we are going to be a waiter. The reason for this is to play nice for those architectures that do have CMPXCHG. By setting this flag @@ -735,7 +735,7 @@ do have CMPXCHG, that check is done in the fast path, but it is still needed in the slow path too. If a waiter of a mutex woke up because of a signal or timeout between the time the owner failed the fast path CMPXCHG check and the grabbing of the wait_lock, the mutex may not have any waiters, thus the -owner still needs to make this check. If there are no waiters then the mutex +owner still needs to make this check. If there are no waiters than the mutex owner field is set to NULL, the wait_lock is released and nothing more is needed. diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 669a09aa5bb4..00d9a1f2a54c 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -7,10 +7,10 @@ 6 -> AverTV Studio 303 (M126) [1461:000b] 7 -> MSI TV-@nywhere Master [1462:8606] 8 -> Leadtek Winfast DV2000 [107d:6620] - 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632] + 9 -> Leadtek PVR 2000 [107d:663b,107d:663C] 10 -> IODATA GV-VCP3/PCI [10fc:d003] 11 -> Prolink PlayTV PVR - 12 -> ASUS PVR-416 [1043:4823,1461:c111] + 12 -> ASUS PVR-416 [1043:4823] 13 -> MSI TV-@nywhere 14 -> KWorld/VStream XPert DVB-T [17de:08a6] 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] @@ -51,7 +51,3 @@ 50 -> NPG Tech Real TV FM Top 10 [14f1:0842] 51 -> WinFast DTV2000 H [107d:665e] 52 -> Geniatech DVB-S [14f1:0084] - 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404] - 54 -> Norwood Micro TV Tuner - 55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980] - 56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602] diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index 94cf695b1378..9068b669f5ee 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -58,7 +58,7 @@ 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 - 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489:0502] + 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus [5168:0502,4e42:0502] 61 -> Philips TOUGH DVB-T reference design [1131:2004] 62 -> Compro VideoMate TV Gold+II 63 -> Kworld Xpert TV PVR7134 @@ -83,7 +83,7 @@ 82 -> MSI TV@Anywhere plus [1462:6231] 83 -> Terratec Cinergy 250 PCI TV [153b:1160] 84 -> LifeView FlyDVB Trio [5168:0319] - 85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05] + 85 -> AverTV DVB-T 777 [1461:2c05] 86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301] 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] 88 -> Tevion/KWorld DVB-T 220RF [17de:7201] @@ -94,6 +94,3 @@ 93 -> Medion 7134 Bridge #2 [16be:0005] 94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] - 96 -> Medion Md8800 Quadro [16be:0007,16be:0008] - 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] - 98 -> Proteus Pro 2309 [0919:2003] diff --git a/trunk/Documentation/video4linux/bttv/Insmod-options b/trunk/Documentation/video4linux/bttv/Insmod-options index bb7c2cac7917..fc94ff235ffa 100644 --- a/trunk/Documentation/video4linux/bttv/Insmod-options +++ b/trunk/Documentation/video4linux/bttv/Insmod-options @@ -54,12 +54,6 @@ bttv.o dropouts. chroma_agc=0/1 AGC of chroma signal, off by default. adc_crush=0/1 Luminance ADC crush, on by default. - i2c_udelay= Allow reduce I2C speed. Default is 5 usecs - (meaning 66,67 Kbps). The default is the - maximum supported speed by kernel bitbang - algoritm. You may use lower numbers, if I2C - messages are lost (16 is known to work on - all supported cards). bttv_gpio=0/1 gpiomask= diff --git a/trunk/Documentation/video4linux/cx2341x/README.hm12 b/trunk/Documentation/video4linux/cx2341x/README.hm12 deleted file mode 100644 index 0e213ed095e6..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/README.hm12 +++ /dev/null @@ -1,116 +0,0 @@ -The cx23416 can produce (and the cx23415 can also read) raw YUV output. The -format of a YUV frame is specific to this chip and is called HM12. 'HM' stands -for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would -be more accurate. - -The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per -four pixels. - -The data is encoded as two macroblock planes, the first containing the Y -values, the second containing UV macroblocks. - -The Y plane is divided into blocks of 16x16 pixels from left to right -and from top to bottom. Each block is transmitted in turn, line-by-line. - -So the first 16 bytes are the first line of the top-left block, the -second 16 bytes are the second line of the top-left block, etc. After -transmitting this block the first line of the block on the right to the -first block is transmitted, etc. - -The UV plane is divided into blocks of 16x8 UV values going from left -to right, top to bottom. Each block is transmitted in turn, line-by-line. - -So the first 16 bytes are the first line of the top-left block and -contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the -second line of 8 UV pairs of the top-left block, etc. After transmitting -this block the first line of the block on the right to the first block is -transmitted, etc. - -The code below is given as an example on how to convert HM12 to separate -Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels. - -The width of a frame is always 720 pixels, regardless of the actual specified -width. - --------------------------------------------------------------------------- - -#include -#include -#include - -static unsigned char frame[576*720*3/2]; -static unsigned char framey[576*720]; -static unsigned char frameu[576*720 / 4]; -static unsigned char framev[576*720 / 4]; - -static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h) -{ - unsigned int y, x, i; - - // descramble Y plane - // dstride = 720 = w - // The Y plane is divided into blocks of 16x16 pixels - // Each block in transmitted in turn, line-by-line. - for (y = 0; y < h; y += 16) { - for (x = 0; x < w; x += 16) { - for (i = 0; i < 16; i++) { - memcpy(dst + x + (y + i) * dstride, src, 16); - src += 16; - } - } - } -} - -static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h) -{ - unsigned int y, x, i; - - // descramble U/V plane - // dstride = 720 / 2 = w - // The U/V values are interlaced (UVUV...). - // Again, the UV plane is divided into blocks of 16x16 UV values. - // Each block in transmitted in turn, line-by-line. - for (y = 0; y < h; y += 16) { - for (x = 0; x < w; x += 8) { - for (i = 0; i < 16; i++) { - int idx = x + (y + i) * dstride; - - dstu[idx+0] = src[0]; dstv[idx+0] = src[1]; - dstu[idx+1] = src[2]; dstv[idx+1] = src[3]; - dstu[idx+2] = src[4]; dstv[idx+2] = src[5]; - dstu[idx+3] = src[6]; dstv[idx+3] = src[7]; - dstu[idx+4] = src[8]; dstv[idx+4] = src[9]; - dstu[idx+5] = src[10]; dstv[idx+5] = src[11]; - dstu[idx+6] = src[12]; dstv[idx+6] = src[13]; - dstu[idx+7] = src[14]; dstv[idx+7] = src[15]; - src += 16; - } - } - } -} - -/*************************************************************************/ -int main(int argc, char **argv) -{ - FILE *fin; - int i; - - if (argc == 1) fin = stdin; - else fin = fopen(argv[1], "r"); - - if (fin == NULL) { - fprintf(stderr, "cannot open input\n"); - exit(-1); - } - while (fread(frame, sizeof(frame), 1, fin) == 1) { - de_macro_y(framey, frame, 720, 720, 576); - de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2); - fwrite(framey, sizeof(framey), 1, stdout); - fwrite(framev, sizeof(framev), 1, stdout); - fwrite(frameu, sizeof(frameu), 1, stdout); - } - fclose(fin); - return 0; -} - --------------------------------------------------------------------------- diff --git a/trunk/Documentation/video4linux/cx2341x/README.vbi b/trunk/Documentation/video4linux/cx2341x/README.vbi deleted file mode 100644 index 5807cf156173..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/README.vbi +++ /dev/null @@ -1,45 +0,0 @@ - -Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data -========================================================= - -This document describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data -embedded in an MPEG-2 program stream. This format is in part dictated by some -hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6 -chips), in particular a maximum size for the VBI data. Anything longer is cut -off when the MPEG stream is played back through the cx23415. - -The advantage of this format is it is very compact and that all VBI data for -all lines can be stored while still fitting within the maximum allowed size. - -The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is -4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte -header and a 42 bytes payload each. Anything beyond this limit is cut off by -the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits -for a bitmask determining which lines are captured and 4 bytes for a magic cookie, -signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data. -If all lines are used, then there is no longer room for the bitmask. To solve this -two different magic numbers were introduced: - -'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first -unsigned long denote which lines of the first field are captured. Bits 18-31 of -the first unsigned long and bits 0-3 of the second unsigned long are used for the -second field. - -'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly -implies that the bitmasks are 0xffffffff and 0xf. - -After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the -captured VBI lines start: - -For each line the least significant 4 bits of the first byte contain the data type. -Possible values are shown in the table below. The payload is in the following 42 -bytes. - -Here is the list of possible data types: - -#define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL) -#define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC) -#define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL) -#define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16) - -Hans Verkuil diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 74b77f9e91bc..4303e0c12476 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -199,11 +199,6 @@ IOMMU allowed overwrite iommu off workarounds for specific chipsets. soft Use software bounce buffering (default for Intel machines) noaperture Don't touch the aperture for AGP. - allowdac Allow DMA >4GB - When off all DMA over >4GB is forced through an IOMMU or bounce - buffering. - nodac Forbid DMA >4GB - panic Always panic when IOMMU overflows swiotlb=pages[,force] diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index b62ab43c6094..2c752d18e24b 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -501,7 +501,7 @@ S: Maintained BLOCK LAYER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git S: Maintained @@ -1380,7 +1380,7 @@ S: Maintained IDE/ATAPI CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -1398,29 +1398,36 @@ M: Gadi Oxman L: linux-kernel@vger.kernel.org S: Maintained +IEEE 1394 ETHERNET (eth1394) +L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ +S: Orphan + IEEE 1394 SUBSYSTEM P: Ben Collins M: bcollins@debian.org -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de +P: Jody McIntyre +M: scjody@modernduck.com L: linux1394-devel@lists.sourceforge.net W: http://www.linux1394.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git +T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git S: Maintained -IEEE 1394 IPV4 DRIVER (eth1394) -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de +IEEE 1394 OHCI DRIVER +P: Ben Collins +M: bcollins@debian.org +P: Jody McIntyre +M: scjody@modernduck.com L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes +W: http://www.linux1394.org/ +S: Maintained IEEE 1394 PCILYNX DRIVER P: Jody McIntyre M: scjody@modernduck.com -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes +W: http://www.linux1394.org/ +S: Maintained IEEE 1394 RAW I/O DRIVER P: Ben Collins @@ -1428,6 +1435,16 @@ M: bcollins@debian.org P: Dan Dennedy M: dan@dennedy.org L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ +S: Maintained + +IEEE 1394 SBP2 +P: Ben Collins +M: bcollins@debian.org +P: Stefan Richter +M: stefanr@s5r6.in-berlin.de +L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ S: Maintained IMS TWINTURBO FRAMEBUFFER DRIVER @@ -2531,7 +2548,7 @@ S: Maintained SCSI CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-scsi@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -2711,6 +2728,14 @@ M: chrisw@sous-sol.org L: stable@kernel.org S: Maintained +STABLE BRANCH: +P: Greg Kroah-Hartman +M: greg@kroah.com +P: Chris Wright +M: chrisw@sous-sol.org +L: stable@kernel.org +S: Maintained + TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com @@ -2968,7 +2993,7 @@ S: Maintained UNIFORM CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained diff --git a/trunk/arch/alpha/kernel/alpha_ksyms.c b/trunk/arch/alpha/kernel/alpha_ksyms.c index dbe327d32b6f..f042cc42b00f 100644 --- a/trunk/arch/alpha/kernel/alpha_ksyms.c +++ b/trunk/arch/alpha/kernel/alpha_ksyms.c @@ -36,6 +36,7 @@ #include #include +#define __KERNEL_SYSCALLS__ #include extern struct hwrpb_struct *hwrpb; @@ -115,7 +116,7 @@ EXPORT_SYMBOL(sys_dup); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_write); EXPORT_SYMBOL(sys_lseek); -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); EXPORT_SYMBOL(sys_setsid); EXPORT_SYMBOL(sys_wait4); diff --git a/trunk/arch/alpha/kernel/entry.S b/trunk/arch/alpha/kernel/entry.S index c95e95e1ab04..01ecd09d4a64 100644 --- a/trunk/arch/alpha/kernel/entry.S +++ b/trunk/arch/alpha/kernel/entry.S @@ -655,12 +655,12 @@ kernel_thread: .end kernel_thread /* - * kernel_execve(path, argv, envp) + * execve(path, argv, envp) */ .align 4 - .globl kernel_execve - .ent kernel_execve -kernel_execve: + .globl execve + .ent execve +execve: /* We can be called from a module. */ ldgp $gp, 0($27) lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) @@ -704,7 +704,7 @@ kernel_execve: 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) ret -.end kernel_execve +.end execve /* diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index ad6173651995..73c7622b5297 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -111,26 +111,22 @@ struct osf_dirent_callback { static int osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, - u64 ino, unsigned int d_type) + ino_t ino, unsigned int d_type) { struct osf_dirent __user *dirent; struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); - unsigned int d_ino; buf->error = -EINVAL; /* only used if we fail */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; if (buf->basep) { if (put_user(offset, buf->basep)) return -EFAULT; buf->basep = NULL; } dirent = buf->dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); if (copy_to_user(dirent->d_name, name, namlen) || @@ -406,15 +402,15 @@ osf_utsname(char __user *name) down_read(&uts_sem); error = -EFAULT; - if (copy_to_user(name + 0, utsname()->sysname, 32)) + if (copy_to_user(name + 0, system_utsname.sysname, 32)) goto out; - if (copy_to_user(name + 32, utsname()->nodename, 32)) + if (copy_to_user(name + 32, system_utsname.nodename, 32)) goto out; - if (copy_to_user(name + 64, utsname()->release, 32)) + if (copy_to_user(name + 64, system_utsname.release, 32)) goto out; - if (copy_to_user(name + 96, utsname()->version, 32)) + if (copy_to_user(name + 96, system_utsname.version, 32)) goto out; - if (copy_to_user(name + 128, utsname()->machine, 32)) + if (copy_to_user(name + 128, system_utsname.machine, 32)) goto out; error = 0; @@ -453,8 +449,8 @@ osf_getdomainname(char __user *name, int namelen) down_read(&uts_sem); for (i = 0; i < len; ++i) { - __put_user(utsname()->domainname[i], name + i); - if (utsname()->domainname[i] == '\0') + __put_user(system_utsname.domainname[i], name + i); + if (system_utsname.domainname[i] == '\0') break; } up_read(&uts_sem); @@ -611,12 +607,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss) asmlinkage long osf_sysinfo(int command, char __user *buf, long count) { - char *sysinfo_table[] = { - utsname()->sysname, - utsname()->nodename, - utsname()->release, - utsname()->version, - utsname()->machine, + static char * sysinfo_table[] = { + system_utsname.sysname, + system_utsname.nodename, + system_utsname.release, + system_utsname.version, + system_utsname.machine, "alpha", /* instruction set architecture */ "dummy", /* hardware serial number */ "dummy", /* hardware manufacturer */ diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 21f71287b6f5..2a6e3da8144f 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -1,7 +1,5 @@ #include -#include -#include /* Prototypes of functions used across modules here in this directory. */ @@ -183,16 +181,9 @@ extern void titan_dispatch_irqs(u64, struct pt_regs *); extern void switch_to_system_map(void); extern void srm_paging_stop(void); -static inline int -__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - pgprot_t prot; - - prot = __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE - | _PAGE_KWE | flags); - return ioremap_page_range(address, address + size, phys_addr, prot); -} +/* ../mm/remap.c */ +extern int __alpha_remap_area_pages(unsigned long, unsigned long, + unsigned long, unsigned long); /* irq.c */ diff --git a/trunk/arch/alpha/kernel/srmcons.c b/trunk/arch/alpha/kernel/srmcons.c index 756923203860..9d7dff27f815 100644 --- a/trunk/arch/alpha/kernel/srmcons.c +++ b/trunk/arch/alpha/kernel/srmcons.c @@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp) static struct tty_driver *srmcons_driver; -static const struct tty_operations srmcons_ops = { +static struct tty_operations srmcons_ops = { .open = srmcons_open, .close = srmcons_close, .write = srmcons_write, diff --git a/trunk/arch/alpha/kernel/time.c b/trunk/arch/alpha/kernel/time.c index 581ddcc22fc5..7c1e44420a78 100644 --- a/trunk/arch/alpha/kernel/time.c +++ b/trunk/arch/alpha/kernel/time.c @@ -54,6 +54,8 @@ #include "proto.h" #include "irq_impl.h" +extern unsigned long wall_jiffies; /* kernel/timer.c */ + static int set_rtc_mmss(unsigned long); DEFINE_SPINLOCK(rtc_lock); @@ -411,7 +413,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, seq; + unsigned long sec, usec, lost, seq; unsigned long delta_cycles, delta_usec, partial_tick; do { @@ -421,13 +423,14 @@ do_gettimeofday(struct timeval *tv) sec = xtime.tv_sec; usec = (xtime.tv_nsec / 1000); partial_tick = state.partial_tick; + lost = jiffies - wall_jiffies; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); #ifdef CONFIG_SMP /* Until and unless we figure out how to get cpu cycle counters in sync and keep them there, we can't use the rpcc tricks. */ - delta_usec = 0; + delta_usec = lost * (1000000 / HZ); #else /* * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks) @@ -443,7 +446,8 @@ do_gettimeofday(struct timeval *tv) */ delta_usec = (delta_cycles * state.scaled_ticks_per_cycle - + partial_tick) * 15625; + + partial_tick + + (lost << FIX_SHIFT)) * 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; #endif @@ -476,11 +480,12 @@ do_settimeofday(struct timespec *tv) time. Without this, a full-tick error is possible. */ #ifdef CONFIG_SMP - delta_nsec = 0; + delta_nsec = (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ); #else delta_nsec = rpcc() - state.last_time; delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle - + state.partial_tick) * 15625; + + state.partial_tick + + ((jiffies - wall_jiffies) << FIX_SHIFT)) * 15625; delta_nsec = ((delta_nsec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; delta_nsec *= 1000; #endif diff --git a/trunk/arch/alpha/mm/Makefile b/trunk/arch/alpha/mm/Makefile index 09399c5386cb..6edd9a09ea4f 100644 --- a/trunk/arch/alpha/mm/Makefile +++ b/trunk/arch/alpha/mm/Makefile @@ -4,6 +4,6 @@ EXTRA_CFLAGS := -Werror -obj-y := init.o fault.o extable.o +obj-y := init.o fault.o extable.o remap.o obj-$(CONFIG_DISCONTIGMEM) += numa.o diff --git a/trunk/arch/alpha/mm/remap.c b/trunk/arch/alpha/mm/remap.c new file mode 100644 index 000000000000..a78356c3ead5 --- /dev/null +++ b/trunk/arch/alpha/mm/remap.c @@ -0,0 +1,86 @@ +#include +#include +#include + +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, + __pgprot(_PAGE_VALID | _PAGE_ASM | + _PAGE_KRE | _PAGE_KWE | flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, + address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +int +__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + pgd_t * dir; + int error = 0; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + return error; +} + diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index 3e14b1348c0b..eca248d9eba4 100644 --- a/trunk/arch/arm/kernel/ecard.c +++ b/trunk/arch/arm/kernel/ecard.c @@ -295,7 +295,7 @@ ecard_task(void * unused) */ static void ecard_call(struct ecard_request *req) { - DECLARE_COMPLETION_ONSTACK(completion); + DECLARE_COMPLETION(completion); req->complete = &completion; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 6bbd93dd186a..0a722e77c143 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -348,7 +348,7 @@ static void __init setup_processor(void) cpu_name, processor_id, (int)processor_id & 15, proc_arch[cpu_architecture()], cr_alignment); - sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; #ifndef CONFIG_ARM_THUMB diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 421329f5e18e..68e9634d260a 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -36,9 +36,7 @@ * The online bitmask indicates that the CPU is up and running. */ cpumask_t cpu_possible_map; -EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; -EXPORT_SYMBOL(cpu_online_map); /* * as from 2.5, kernels no longer have an init_tasks structure diff --git a/trunk/arch/arm/kernel/sys_arm.c b/trunk/arch/arm/kernel/sys_arm.c index 00c18d35913c..8170af471439 100644 --- a/trunk/arch/arm/kernel/sys_arm.c +++ b/trunk/arch/arm/kernel/sys_arm.c @@ -279,7 +279,7 @@ asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv, return error; } -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +long execve(const char *filename, char **argv, char **envp) { struct pt_regs regs; int ret; @@ -317,7 +317,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) out: return ret; } -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); /* * Since loff_t is a 64 bit type we avoid a lot of ABI hastle diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index b030320b17c7..f7d5165796ef 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -37,6 +37,8 @@ */ struct sys_timer *system_timer; +extern unsigned long wall_jiffies; + /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -235,11 +237,16 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = system_timer->offset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -272,6 +279,7 @@ int do_settimeofday(struct timespec *tv) * done, and then undo it! */ nsec -= system_timer->offset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/arm/mach-pnx4008/clock.c b/trunk/arch/arm/mach-pnx4008/clock.c index daa8d3d98eff..f582ed2ec43c 100644 --- a/trunk/arch/arm/mach-pnx4008/clock.c +++ b/trunk/arch/arm/mach-pnx4008/clock.c @@ -735,16 +735,6 @@ static struct clk uart6_ck = { .enable_reg = UARTCLKCTRL_REG, }; -static struct clk wdt_ck = { - .name = "wdt_ck", - .parent = &per_ck, - .flags = NEEDS_INITIALIZATION, - .round_rate = &on_off_round_rate, - .set_rate = &on_off_set_rate, - .enable_shift = 0, - .enable_reg = TIMCLKCTRL_REG, -}; - /* These clocks are visible outside this module * and can be initialized */ @@ -775,7 +765,6 @@ static struct clk *onchip_clks[] = { &uart4_ck, &uart5_ck, &uart6_ck, - &wdt_ck, }; static int local_clk_enable(struct clk *clk) diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c index 0221ba3bc799..ab5e9503bae5 100644 --- a/trunk/arch/arm/vfp/vfpsingle.c +++ b/trunk/arch/arm/vfp/vfpsingle.c @@ -198,10 +198,8 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce vfp_single_dump("pack: final", vs); { s32 d = vfp_single_pack(vs); -#ifdef DEBUG pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func, sd, d, exceptions); -#endif vfp_put_float(d, sd); } diff --git a/trunk/arch/arm26/kernel/setup.c b/trunk/arch/arm26/kernel/setup.c index 466ddb54b44f..e7eb070f794f 100644 --- a/trunk/arch/arm26/kernel/setup.c +++ b/trunk/arch/arm26/kernel/setup.c @@ -143,7 +143,7 @@ static void __init setup_processor(void) dump_cpu_info(); - sprintf(init_utsname()->machine, "%s", list->arch_name); + sprintf(system_utsname.machine, "%s", list->arch_name); sprintf(elf_platform, "%s", list->elf_name); elf_hwcap = list->elf_hwcap; diff --git a/trunk/arch/arm26/kernel/sys_arm.c b/trunk/arch/arm26/kernel/sys_arm.c index dc05aba58baf..85457897b8a9 100644 --- a/trunk/arch/arm26/kernel/sys_arm.c +++ b/trunk/arch/arm26/kernel/sys_arm.c @@ -283,7 +283,7 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r } /* FIXME - see if this is correct for arm26 */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +long execve(const char *filename, char **argv, char **envp) { struct pt_regs regs; int ret; @@ -320,4 +320,4 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) return ret; } -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); diff --git a/trunk/arch/arm26/kernel/time.c b/trunk/arch/arm26/kernel/time.c index 1206469b2b86..80adbd005fc5 100644 --- a/trunk/arch/arm26/kernel/time.c +++ b/trunk/arch/arm26/kernel/time.c @@ -33,6 +33,8 @@ #include #include +extern unsigned long wall_jiffies; + /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -134,11 +136,16 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = gettimeoffset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -167,7 +174,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * done, and then undo it! */ - tv->tv_nsec -= 1000 * gettimeoffset(); + tv->tv_nsec -= 1000 * (gettimeoffset() + + (jiffies - wall_jiffies) * USECS_PER_JIFFY); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; diff --git a/trunk/arch/avr32/kernel/sys_avr32.c b/trunk/arch/avr32/kernel/sys_avr32.c index 8deb6003ee62..6ec5693da448 100644 --- a/trunk/arch/avr32/kernel/sys_avr32.c +++ b/trunk/arch/avr32/kernel/sys_avr32.c @@ -49,17 +49,3 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, fput(file); return error; } - -int kernel_execve(const char *file, char **argv, char **envp) -{ - register long scno asm("r8") = __NR_execve; - register long sc1 asm("r12") = (long)file; - register long sc2 asm("r11") = (long)argv; - register long sc3 asm("r10") = (long)envp; - - asm volatile("scall" - : "=r"(sc1) - : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3) - : "cc", "memory"); - return sc1; -} diff --git a/trunk/arch/avr32/mm/ioremap.c b/trunk/arch/avr32/mm/ioremap.c index 8cfec65e37f7..536021877df6 100644 --- a/trunk/arch/avr32/mm/ioremap.c +++ b/trunk/arch/avr32/mm/ioremap.c @@ -7,11 +7,119 @@ */ #include #include -#include +#include #include +#include +#include #include +static inline int remap_area_pte(pte_t *pte, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long pfn; + + pfn = phys_addr >> PAGE_SHIFT; + do { + WARN_ON(!pte_none(*pte)); + + set_pte(pte, pfn_pte(pfn, prot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); + + return 0; +} + +static inline int remap_area_pmd(pmd_t *pmd, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long next; + + phys_addr -= address; + + do { + pte_t *pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + + next = (address + PMD_SIZE) & PMD_MASK; + if (remap_area_pte(pte, address, next, + address + phys_addr, prot)) + return -ENOMEM; + + address = next; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pud(pud_t *pud, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long next; + + phys_addr -= address; + + do { + pmd_t *pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + return -ENOMEM; + next = (address + PUD_SIZE) & PUD_MASK; + if (remap_area_pmd(pmd, address, next, + phys_addr + address, prot)) + return -ENOMEM; + + address = next; + pud++; + } while (address && address < end); + + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + size_t size, pgprot_t prot) +{ + unsigned long end = address + size; + unsigned long next; + pgd_t *pgd; + int err = 0; + + phys_addr -= address; + + pgd = pgd_offset_k(address); + flush_cache_all(); + BUG_ON(address >= end); + + spin_lock(&init_mm.page_table_lock); + do { + pud_t *pud = pud_alloc(&init_mm, pgd, address); + + err = -ENOMEM; + if (!pud) + break; + + next = (address + PGDIR_SIZE) & PGDIR_MASK; + if (next < address || next > end) + next = end; + err = remap_area_pud(pud, address, next, + phys_addr + address, prot); + if (err) + break; + + address = next; + pgd++; + } while (address && (address < end)); + + spin_unlock(&init_mm.page_table_lock); + flush_tlb_all(); + return err; +} + /* * Re-map an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access physical @@ -20,7 +128,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { - unsigned long addr; + void *addr; struct vm_struct *area; unsigned long offset, last_addr; pgprot_t prot; @@ -51,7 +159,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr + 1) - phys_addr; - prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY + prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); /* @@ -61,9 +169,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, if (!area) return NULL; area->phys_addr = phys_addr; - addr = (unsigned long )area->addr; - if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { - vunmap((void *)addr); + addr = area->addr; + if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) { + vunmap(addr); return NULL; } diff --git a/trunk/arch/cris/arch-v32/kernel/smp.c b/trunk/arch/cris/arch-v32/kernel/smp.c index 2d0023f2d49b..464ecaec3bc0 100644 --- a/trunk/arch/cris/arch-v32/kernel/smp.c +++ b/trunk/arch/cris/arch-v32/kernel/smp.c @@ -28,7 +28,6 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; /* CPU masks */ cpumask_t cpu_online_map = CPU_MASK_NONE; -EXPORT_SYMBOL(cpu_online_map); cpumask_t phys_cpu_present_map = CPU_MASK_NONE; EXPORT_SYMBOL(phys_cpu_present_map); diff --git a/trunk/arch/cris/kernel/setup.c b/trunk/arch/cris/kernel/setup.c index ca8b45a0fe2e..7af3d5d43e43 100644 --- a/trunk/arch/cris/kernel/setup.c +++ b/trunk/arch/cris/kernel/setup.c @@ -160,7 +160,7 @@ setup_arch(char **cmdline_p) show_etrax_copyright(); /* Setup utsname */ - strcpy(init_utsname()->machine, cris_machine_name); + strcpy(system_utsname.machine, cris_machine_name); } static void *c_start(struct seq_file *m, loff_t *pos) diff --git a/trunk/arch/cris/kernel/time.c b/trunk/arch/cris/kernel/time.c index 0f9213cbd48e..66ba8898db07 100644 --- a/trunk/arch/cris/kernel/time.c +++ b/trunk/arch/cris/kernel/time.c @@ -37,6 +37,7 @@ int have_rtc; /* used to remember if we have an RTC or not */; #define TICK_SIZE tick +extern unsigned long wall_jiffies; extern unsigned long loops_per_jiffy; /* init/main.c */ unsigned long loops_per_usec; @@ -57,6 +58,11 @@ void do_gettimeofday(struct timeval *tv) local_irq_save(flags); local_irq_disable(); usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } /* * If time_adjust is negative then NTP is slowing the clock @@ -97,6 +103,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/cris/mm/ioremap.c b/trunk/arch/cris/mm/ioremap.c index 8b0b9348b574..1780df3ed9e5 100644 --- a/trunk/arch/cris/mm/ioremap.c +++ b/trunk/arch/cris/mm/ioremap.c @@ -10,10 +10,93 @@ */ #include -#include +#include #include +#include +#include #include +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, mk_pte_phys(phys_addr, prot)); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, prot); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, pgprot_t prot) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pmd_t *pmd; + + error = -ENOMEM; + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); + + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, prot)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} + /* * Generic mapping function (not visible outside): */ @@ -52,8 +135,7 @@ void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgpro if (!area) return NULL; addr = (void __iomem *)area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, prot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) { vfree((void __force *)addr); return NULL; } diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index cf1c446e003a..f7b171b92ea2 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -86,14 +86,6 @@ config HIGHPTE with a lot of RAM, this can be wasteful of precious low memory. Setting this option will put user-space page tables in high memory. -config LARGE_ALLOCS - bool "Allow allocating large blocks (> 1MB) of memory" - help - Allow the slab memory allocator to keep chains for very large memory - sizes - up to 32MB. You may need this if your system has a lot of - RAM, and you need to able to allocate very large contiguous chunks. - If unsure, say N. - source "mm/Kconfig" choice diff --git a/trunk/arch/frv/kernel/Makefile b/trunk/arch/frv/kernel/Makefile index e8f73ed28b52..32db3499c461 100644 --- a/trunk/arch/frv/kernel/Makefile +++ b/trunk/arch/frv/kernel/Makefile @@ -8,7 +8,7 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o extra-y:= head.o init_task.o vmlinux.lds obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ - kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ + process.o traps.o ptrace.o signal.o dma.o \ sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ debug-stub.o irq.o sleep.o uaccess.o diff --git a/trunk/arch/frv/kernel/kernel_execve.S b/trunk/arch/frv/kernel/kernel_execve.S deleted file mode 100644 index 9b074a16a052..000000000000 --- a/trunk/arch/frv/kernel/kernel_execve.S +++ /dev/null @@ -1,33 +0,0 @@ -/* in-kernel program execution - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include - -############################################################################### -# -# Do a system call from kernel instead of calling sys_execve so we end up with -# proper pt_regs. -# -# int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -# -# On entry: GR8/GR9/GR10: arguments to function -# On return: GR8: syscall return. -# -############################################################################### - .globl kernel_execve - .type kernel_execve,@function -kernel_execve: - setlos __NR_execve,gr7 - tira gr0,#0 - bralr - - .size kernel_execve,.-kernel_execve diff --git a/trunk/arch/h8300/kernel/sys_h8300.c b/trunk/arch/h8300/kernel/sys_h8300.c index 302a2dfe634a..0f61b7ad69ab 100644 --- a/trunk/arch/h8300/kernel/sys_h8300.c +++ b/trunk/arch/h8300/kernel/sys_h8300.c @@ -25,7 +25,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -281,26 +280,3 @@ asmlinkage void syscall_print(void *dummy,...) ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0); } #endif - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long res __asm__("er0"); - register const char * _a __asm__("er1") = filename; - register void *_b __asm__("er2") = argv; - register void *_c __asm__("er3") = envp; - __asm__ __volatile__ ("mov.l %1,er0\n\t" - "trapa #0\n\t" - : "=r" (res) - : "g" (__NR_execve), - "g" (_a), - "g" (_b), - "g" (_c) - : "cc", "memory"); - return res; -} - - diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index af219e51734f..3fd2f256f2be 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -1142,7 +1142,7 @@ source "arch/i386/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/i386/boot/video.S b/trunk/arch/i386/boot/video.S index 2c5b5cc55f79..8c2a6faeeae5 100644 --- a/trunk/arch/i386/boot/video.S +++ b/trunk/arch/i386/boot/video.S @@ -11,6 +11,8 @@ * */ +#include /* for CONFIG_VIDEO_* */ + /* Enable autodetection of SVGA adapters and modes. */ #undef CONFIG_VIDEO_SVGA diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index ee2d79bd8af7..1a29bfa26d0c 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git7 -# Wed Sep 27 21:53:10 2006 +# Linux kernel version: 2.6.18-git5 +# Tue Sep 26 09:30:47 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -210,7 +210,6 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set -CONFIG_PM_SYSFS_DEPRECATED=y # # ACPI (Advanced Configuration and Power Interface) Support @@ -293,7 +292,6 @@ CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y # CONFIG_PCIEPORTBUS is not set CONFIG_PCI_MSI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set CONFIG_ISA_DMA_API=y # CONFIG_ISA is not set @@ -1429,7 +1427,6 @@ CONFIG_KPROBES=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 57c880bf0bd6..ea19d091fd41 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -396,13 +396,13 @@ static int acpi_cpufreq_early_init_acpi(void) */ static int bios_with_sw_any_bug; -static int sw_any_bug_found(struct dmi_system_id *d) +static int __init sw_any_bug_found(struct dmi_system_id *d) { bios_with_sw_any_bug = 1; return 0; } -static struct dmi_system_id sw_any_bug_dmi_table[] = { +static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = { { .callback = sw_any_bug_found, .ident = "Supermicro Server X6DLP", @@ -597,6 +597,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .name = "acpi-cpufreq", .owner = THIS_MODULE, .attr = acpi_cpufreq_attr, + .flags = CPUFREQ_STICKY, }; @@ -607,7 +608,7 @@ acpi_cpufreq_init (void) acpi_cpufreq_early_init_acpi(); - return cpufreq_register_driver(&acpi_cpufreq_driver); + return cpufreq_register_driver(&acpi_cpufreq_driver); } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c index 7233abe5d695..f5cc9f5c9bab 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -178,17 +178,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index) safe_halt(); /* Change frequency on next halt or sleep */ wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - if (port22_en) { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C1 */ - halt(); - } else { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C3 */ - inb(cx_address); - /* Dummy op - must do something useless after P_LVL3 read */ - t = inl(acpi_fadt.xpm_tmr_blk.address); - } + ACPI_FLUSH_CPU_CACHE(); + /* Invoke C3 */ + inb(cx_address); + /* Dummy op - must do something useless after P_LVL3 read */ + t = inl(acpi_fadt.xpm_tmr_blk.address); /* Disable bus ratio bit */ local_irq_disable(); @@ -573,23 +567,16 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle, static int enable_arbiter_disable(void) { struct pci_dev *dev; - int reg; u8 pci_cmd; /* Find PLE133 host bridge */ - reg = 0x78; dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); - /* Find CLE266 host bridge */ - if (dev == NULL) { - reg = 0x76; - dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL); - } if (dev != NULL) { /* Enable access to port 0x22 */ - pci_read_config_byte(dev, reg, &pci_cmd); + pci_read_config_byte(dev, 0x78, &pci_cmd); if ( !(pci_cmd & 1<<7) ) { pci_cmd |= 1<<7; - pci_write_config_byte(dev, reg, pci_cmd); + pci_write_config_byte(dev, 0x78, pci_cmd); } return 1; } @@ -693,24 +680,19 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) if (longhaul_version == TYPE_POWERSAVER) { /* Check ACPI support for C3 state */ cx = &pr->power.states[ACPI_STATE_C3]; - if (cx->address > 0 && - (cx->latency <= 1000 || ignore_latency != 0) ) { - goto print_support_type; - } - } - /* Check ACPI support for bus master arbiter disable */ - if (!pr->flags.bm_control) { - if (enable_arbiter_disable()) { - port22_en = 1; - } else { + if (cx->address == 0 || + (cx->latency > 1000 && ignore_latency == 0) ) goto err_acpi; - } - } -print_support_type: - if (!port22_en) { - printk (KERN_INFO PFX "Using ACPI support.\n"); + } else { - printk (KERN_INFO PFX "Using northbridge support.\n"); + /* Check ACPI support for bus master arbiter disable */ + if (!pr->flags.bm_control) { + if (!enable_arbiter_disable()) { + printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n"); + return -ENODEV; + } else + port22_en = 1; + } } ret = longhaul_get_ranges(); @@ -734,7 +716,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) return 0; err_acpi: - printk(KERN_ERR PFX "No ACPI support. No VT8601 or VT8623 northbridge. Aborting.\n"); + printk(KERN_ERR PFX "No ACPI support for CPU frequency changes.\n"); return -ENODEV; } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index e8993baf3d14..7a9325349e94 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -386,7 +386,7 @@ static int centrino_cpu_early_init_acpi(void) * than OS intended it to run at. Detect it and handle it cleanly. */ static int bios_with_sw_any_bug; -static int sw_any_bug_found(struct dmi_system_id *d) +static int __init sw_any_bug_found(struct dmi_system_id *d) { bios_with_sw_any_bug = 1; return 0; diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 144b43288965..67d297dc1003 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -89,7 +88,7 @@ static void crash_save_self(struct pt_regs *regs) { int cpu; - cpu = safe_smp_processor_id(); + cpu = smp_processor_id(); crash_save_this_cpu(regs, cpu); } @@ -134,10 +133,7 @@ static int crash_nmi_callback(struct notifier_block *self, static void smp_send_nmi_allbutself(void) { - cpumask_t mask = cpu_online_map; - cpu_clear(safe_smp_processor_id(), mask); - if (!cpus_empty(mask)) - send_IPI_mask(mask, NMI_VECTOR); + send_IPI_allbutself(NMI_VECTOR); } static struct notifier_block crash_nmi_nb = { @@ -189,7 +185,7 @@ void machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); /* Make a note of crashing cpu. Will be used in NMI callback.*/ - crashing_cpu = safe_smp_processor_id(); + crashing_cpu = smp_processor_id(); nmi_shootdown_cpus(); lapic_shutdown(); #if defined(CONFIG_X86_IO_APIC) diff --git a/trunk/arch/i386/kernel/i8237.c b/trunk/arch/i386/kernel/i8237.c index 6f508e8d7c57..c36d1c006c2f 100644 --- a/trunk/arch/i386/kernel/i8237.c +++ b/trunk/arch/i386/kernel/i8237.c @@ -2,11 +2,6 @@ * i8237.c: 8237A DMA controller suspend functions. * * Written by Pierre Ossman, 2005. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. */ #include diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index d98e44b16fe2..afe6505ca0b3 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -230,20 +230,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; + struct kretprobe_instance *ri; - struct kretprobe_instance *ri; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - add_rp_inst(ri); - } else { - rp->nmissed++; - } + + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -359,7 +359,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) void __kprobes kretprobe_trampoline_holder(void) { asm volatile ( ".global kretprobe_trampoline\n" - "kretprobe_trampoline: \n" + "kretprobe_trampoline: \n" " pushf\n" /* skip cs, eip, orig_eax, es, ds */ " subl $20, %esp\n" @@ -395,15 +395,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) */ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -414,14 +413,14 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler){ __get_cpu_var(current_kprobe) = &ri->rp->kp; @@ -430,7 +429,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) } orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -445,10 +444,6 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } return (void*)orig_ret_address; } diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index 3e8e3adb0489..dbda706fdd14 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -13,6 +13,7 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ +#include #include #include #include @@ -30,9 +31,6 @@ #include "mach_traps.h" -int unknown_nmi_panic; -int nmi_watchdog_enabled; - /* perfctr_nmi_owner tracks the ownership of the perfctr registers: * evtsel_nmi_owner tracks the ownership of the event selection * - different performance counters/ event selection may be reserved for diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index dad02a960e03..8c190ca7ae44 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -297,9 +297,9 @@ void show_regs(struct pt_regs * regs) if (user_mode_vm(regs)) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx %s (%s %.*s)\n", - regs->eflags, print_tainted(), init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + regs->eflags, print_tainted(), system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", @@ -425,12 +425,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, tsk = current; if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { - p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr, - IO_BITMAP_BYTES, GFP_KERNEL); + p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); if (!p->thread.io_bitmap_ptr) { p->thread.io_bitmap_max = 0; return -ENOMEM; } + memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, + IO_BITMAP_BYTES); set_tsk_thread_flag(p, TIF_IO_BITMAP); } diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 000cf03751fe..814cdebf7377 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -209,6 +209,9 @@ static struct resource adapter_rom_resources[] = { { .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM } }; +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + static struct resource video_rom_resource = { .name = "Video ROM", .start = 0xc0000, @@ -270,6 +273,9 @@ static struct resource standard_io_resources[] = { { .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + #define romsignature(x) (*(unsigned short *)(x) == 0xaa55) static int __init romchecksum(unsigned char *rom, unsigned long length) @@ -326,7 +332,7 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -1266,7 +1272,7 @@ static int __init request_standard_resources(void) request_resource(&iomem_resource, &video_ram_resource); /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); return 0; } diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 1b080ab8a49f..465188e2d701 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -700,30 +700,3 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, return 0; } EXPORT_SYMBOL(smp_call_function_single); - -static int convert_apicid_to_cpu(int apic_id) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) { - if (x86_cpu_to_apicid[i] == apic_id) - return i; - } - return -1; -} - -int safe_smp_processor_id(void) -{ - int apicid, cpuid; - - if (!boot_cpu_has(X86_FEATURE_APIC)) - return 0; - - apicid = hard_smp_processor_id(); - if (apicid == BAD_APICID) - return 0; - - cpuid = convert_apicid_to_cpu(apicid); - - return cpuid >= 0 ? cpuid : 0; -} diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 9d93ecf6d999..82b26d5ce476 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -612,7 +612,6 @@ extern struct { /* which logical CPUs are on which nodes */ cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; -EXPORT_SYMBOL(node_2_cpu_mask); /* which node each logical CPU is on */ int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_2_node); @@ -1062,7 +1061,7 @@ static void __cpuinit do_warm_boot_cpu(void *p) static int __cpuinit __smp_prepare_cpu(int cpu) { - DECLARE_COMPLETION_ONSTACK(done); + DECLARE_COMPLETION(done); struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; diff --git a/trunk/arch/i386/kernel/sys_i386.c b/trunk/arch/i386/kernel/sys_i386.c index 4048397f1740..8fdb1fb17a5f 100644 --- a/trunk/arch/i386/kernel/sys_i386.c +++ b/trunk/arch/i386/kernel/sys_i386.c @@ -21,7 +21,6 @@ #include #include -#include #include /* @@ -211,7 +210,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -227,21 +226,16 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, - __OLD_UTS_LEN); - error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, - __OLD_UTS_LEN); - error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, - __OLD_UTS_LEN); - error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, - __OLD_UTS_LEN); - error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, - __OLD_UTS_LEN); - error |= __put_user(0, name->machine + __OLD_UTS_LEN); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); up_read(&uts_sem); @@ -249,17 +243,3 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) return error; } - - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" - : "=a" (__res) - : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory"); - return __res; -} diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 58a2d5582419..86944acfb647 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -76,6 +76,8 @@ int pit_latch_buggy; /* extern */ unsigned int cpu_khz; /* Detected as we calibrate the TSC */ EXPORT_SYMBOL(cpu_khz); +extern unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -327,6 +329,7 @@ static int timer_resume(struct sys_device *dev) do_settimeofday(&ts); write_seqlock_irqsave(&xtime_lock, flags); jiffies_64 += sleep_length; + wall_jiffies += sleep_length; write_sequnlock_irqrestore(&xtime_lock, flags); touch_softlockup_watchdog(); return 0; diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 00489b706d27..a13037fe0ee3 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -57,8 +57,6 @@ #include "mach_traps.h" -int panic_on_unrecovered_nmi; - asmlinkage int system_call(void); struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -357,9 +355,9 @@ void show_registers(struct pt_regs *regs) KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", smp_processor_id(), 0xffff & regs->xcs, regs->eip, - print_tainted(), regs->eflags, init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + print_tainted(), regs->eflags, system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); diff --git a/trunk/arch/i386/lib/delay.c b/trunk/arch/i386/lib/delay.c index f6edb11364df..3c0714c4b669 100644 --- a/trunk/arch/i386/lib/delay.c +++ b/trunk/arch/i386/lib/delay.c @@ -11,6 +11,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 856c73fcb7e7..6c86575ffdcb 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -99,7 +99,6 @@ static void do_boot_cpu(__u8 cpuid); static void do_quad_bootstrap(void); int hard_smp_processor_id(void); -int safe_smp_processor_id(void); /* Inline functions */ static inline void @@ -1248,12 +1247,6 @@ hard_smp_processor_id(void) return 0; } -int -safe_smp_processor_id(void) -{ - return hard_smp_processor_id(); -} - /* broadcast a halt to all other CPUs */ void smp_send_stop(void) diff --git a/trunk/arch/i386/mm/highmem.c b/trunk/arch/i386/mm/highmem.c index f9f647cdbc7b..ba44000b9069 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -38,19 +38,22 @@ void *kmap_atomic(struct page *page, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM if (!pte_none(*(kmap_pte-idx))) BUG(); +#endif set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); return (void*) vaddr; } void kunmap_atomic(void *kvaddr, enum km_type type) { +#ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); -#ifdef CONFIG_DEBUG_HIGHMEM if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { dec_preempt_count(); preempt_check_resched(); @@ -59,14 +62,14 @@ void kunmap_atomic(void *kvaddr, enum km_type type) if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) BUG(); -#endif + /* - * Force other mappings to Oops if they'll try to access this pte - * without first remap it. Keeping stale mappings around is a bad idea - * also, in case the page changes cacheability attributes or becomes - * a protected page in a hypervisor. + * force other mappings to Oops if they'll try to access + * this pte without first remap it */ - kpte_clear_flush(kmap_pte-idx, vaddr); + pte_clear(&init_mm, vaddr, kmap_pte-idx); + __flush_tlb_one(vaddr); +#endif dec_preempt_count(); preempt_check_resched(); @@ -85,6 +88,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); + __flush_tlb_one(vaddr); return (void*) vaddr; } diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index 90089c14c23d..4a5a914b3432 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -493,7 +493,6 @@ int __init set_kernel_exec(unsigned long vaddr, int enable) pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32)); else pte->pte_high |= 1 << (_PAGE_BIT_NX - 32); - pte_update_defer(&init_mm, vaddr, pte); __flush_tlb_all(); out: return ret; diff --git a/trunk/arch/i386/mm/ioremap.c b/trunk/arch/i386/mm/ioremap.c index fff08ae7b5ed..247fde76aaed 100644 --- a/trunk/arch/i386/mm/ioremap.c +++ b/trunk/arch/i386/mm/ioremap.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -21,6 +21,82 @@ #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +static int ioremap_pte_range(pmd_t *pmd, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pte_t *pte; + unsigned long pfn; + + pfn = phys_addr >> PAGE_SHIFT; + pte = pte_alloc_kernel(pmd, addr); + if (!pte) + return -ENOMEM; + do { + BUG_ON(!pte_none(*pte)); + set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_DIRTY | _PAGE_ACCESSED | flags))); + pfn++; + } while (pte++, addr += PAGE_SIZE, addr != end); + return 0; +} + +static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pmd_t *pmd; + unsigned long next; + + phys_addr -= addr; + pmd = pmd_alloc(&init_mm, pud, addr); + if (!pmd) + return -ENOMEM; + do { + next = pmd_addr_end(addr, end); + if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, flags)) + return -ENOMEM; + } while (pmd++, addr = next, addr != end); + return 0; +} + +static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pud_t *pud; + unsigned long next; + + phys_addr -= addr; + pud = pud_alloc(&init_mm, pgd, addr); + if (!pud) + return -ENOMEM; + do { + next = pud_addr_end(addr, end); + if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, flags)) + return -ENOMEM; + } while (pud++, addr = next, addr != end); + return 0; +} + +static int ioremap_page_range(unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pgd_t *pgd; + unsigned long next; + int err; + + BUG_ON(addr >= end); + flush_cache_all(); + phys_addr -= addr; + pgd = pgd_offset_k(addr); + do { + next = pgd_addr_end(addr, end); + err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags); + if (err) + break; + } while (pgd++, addr = next, addr != end); + flush_tlb_all(); + return err; +} + /* * Generic mapping function (not visible outside): */ @@ -39,7 +115,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void __iomem * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t prot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -67,9 +142,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; } - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY - | _PAGE_ACCESSED | flags); - /* * Mappings have to be page-aligned */ @@ -86,7 +158,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; if (ioremap_page_range((unsigned long) addr, - (unsigned long) addr + size, phys_addr, prot)) { + (unsigned long) addr + size, phys_addr, flags)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index d0c3da3aa2aa..05be8db58a8c 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -67,10 +67,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) return 0; } -/* - * This is always called under pci_config_lock - */ -static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) { u32 dev_base = base | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 70f7eb9fed35..0b7f701d5cf7 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -516,7 +516,7 @@ source "arch/ia64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index 246eb3d3757a..0daacc20ed36 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -940,7 +940,7 @@ static inline void show_serial_version(void) printk(KERN_INFO " no serial options enabled\n"); } -static const struct tty_operations hp_ops = { +static struct tty_operations hp_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index 9d6a3f210148..bddbd22706ed 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -125,7 +125,6 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) { - compat_ino_t ino; int err; if ((u64) stat->size > MAX_NON_LFS || @@ -133,15 +132,11 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) !old_valid_dev(stat->rdev)) return -EOVERFLOW; - ino = stat->ino; - if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) - return -EOVERFLOW; - if (clear_user(ubuf, sizeof(*ubuf))) return -EFAULT; err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); - err |= __put_user(ino, &ubuf->st_ino); + err |= __put_user(stat->ino, &ubuf->st_ino); err |= __put_user(stat->mode, &ubuf->st_mode); err |= __put_user(stat->nlink, &ubuf->st_nlink); err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); @@ -1227,20 +1222,16 @@ struct readdir32_callback { }; static int -filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, +filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { struct compat_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); - u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; buf->error = -EFAULT; /* only used if we fail.. */ dirent = buf->previous; if (dirent) @@ -1248,7 +1239,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, return -EFAULT; dirent = buf->current_dir; buf->previous = dirent; - if (put_user(d_ino, &dirent->d_ino) + if (put_user(ino, &dirent->d_ino) || put_user(reclen, &dirent->d_reclen) || copy_to_user(dirent->d_name, name, namlen) || put_user(0, dirent->d_name + namlen)) @@ -1296,21 +1287,17 @@ sys32_getdents (unsigned int fd, struct compat_dirent __user *dirent, unsigned i } static int -fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino, +fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent __user * dirent; - u32 d_ino; if (buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; buf->count++; dirent = buf->dirent; - if (put_user(d_ino, &dirent->d_ino) + if (put_user(ino, &dirent->d_ino) || put_user(offset, &dirent->d_offset) || put_user(namlen, &dirent->d_namlen) || copy_to_user(dirent->d_name, name, namlen) diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index e5b1be51b197..12701cf32d99 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -492,11 +492,11 @@ GLOBAL_ENTRY(prefetch_stack) br.ret.sptk.many rp END(prefetch_stack) -GLOBAL_ENTRY(kernel_execve) +GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL br.ret.sptk.many rp -END(kernel_execve) +END(execve) GLOBAL_ENTRY(clone) mov r15=__NR_clone // put syscall number in place diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 51217d63285e..169ec3a7156c 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, p->ainsn.target_br_reg = 0; /* Check for Break instruction - * Bits 37:40 Major opcode to be zero + * Bits 37:40 Major opcode to be zero * Bits 27:32 X6 to be zero * Bits 32:35 X3 to be zero */ @@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, switch (major_opcode) { case INDIRECT_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; case IP_RELATIVE_PREDICT_OPCODE: case IP_RELATIVE_BRANCH_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - break; + break; case IP_RELATIVE_CALL_OPCODE: - p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; + p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; } - } else if (bundle_encoding[template][slot] == X) { + } else if (bundle_encoding[template][slot] == X) { switch (major_opcode) { case LONG_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; @@ -258,18 +258,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot, switch (slot) { case 0: - *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); - *kprobe_inst = bundle->quad0.slot0; - break; + *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); + *kprobe_inst = bundle->quad0.slot0; + break; case 1: - *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); - kprobe_inst_p0 = bundle->quad0.slot1_p0; - kprobe_inst_p1 = bundle->quad1.slot1_p1; - *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); + *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); + kprobe_inst_p0 = bundle->quad0.slot1_p0; + kprobe_inst_p1 = bundle->quad1.slot1_p1; + *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); break; case 2: - *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); - *kprobe_inst = bundle->quad1.slot2; + *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); + *kprobe_inst = bundle->quad1.slot2; break; } } @@ -290,11 +290,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot, return -EINVAL; } - if (in_ivt_functions(addr)) { - printk(KERN_WARNING "Kprobes can't be inserted inside " + if (in_ivt_functions(addr)) { + printk(KERN_WARNING "Kprobes can't be inserted inside " "IVT functions at 0x%lx\n", addr); - return -EINVAL; - } + return -EINVAL; + } if (slot == 1 && bundle_encoding[template][1] != L) { printk(KERN_WARNING "Inserting kprobes on slot #1 " @@ -338,13 +338,12 @@ static void kretprobe_trampoline(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; + struct hlist_head *head; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = ((struct fnptr *)kretprobe_trampoline)->ip; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -370,7 +369,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -388,10 +387,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler @@ -429,14 +424,14 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) bundle_t *bundle; bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle; - template = bundle->quad0.template; + template = bundle->quad0.template; if(valid_kprobe_addr(template, slot, addr)) return -EINVAL; /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ - if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + if (slot == 1 && bundle_encoding[template][1] == L) + slot++; /* Get kprobe_inst and major_opcode from the bundle */ get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); @@ -494,22 +489,21 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) */ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); - unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; - unsigned long template; - int slot = ((unsigned long)p->addr & 0xf); + unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); + unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; + unsigned long template; + int slot = ((unsigned long)p->addr & 0xf); template = p->ainsn.insn->bundle.quad0.template; - if (slot == 1 && bundle_encoding[template][1] == L) - slot = 2; + if (slot == 1 && bundle_encoding[template][1] == L) + slot = 2; if (p->ainsn.inst_flag) { if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) { /* Fix relative IP address */ - regs->cr_iip = (regs->cr_iip - bundle_addr) + - resume_addr; + regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr; } if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) { @@ -546,18 +540,18 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) } if (slot == 2) { - if (regs->cr_iip == bundle_addr + 0x10) { - regs->cr_iip = resume_addr + 0x10; - } - } else { - if (regs->cr_iip == bundle_addr) { - regs->cr_iip = resume_addr; - } + if (regs->cr_iip == bundle_addr + 0x10) { + regs->cr_iip = resume_addr + 0x10; + } + } else { + if (regs->cr_iip == bundle_addr) { + regs->cr_iip = resume_addr; + } } turn_ss_off: - /* Turn off Single Step bit */ - ia64_psr(regs)->ss = 0; + /* Turn off Single Step bit */ + ia64_psr(regs)->ss = 0; } static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) @@ -593,7 +587,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs) /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + slot++; /* Get Kprobe probe instruction at given slot*/ get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode); @@ -633,7 +627,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) if (p) { if ((kcb->kprobe_status == KPROBE_HIT_SS) && (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { - ia64_psr(regs)->ss = 0; + ia64_psr(regs)->ss = 0; goto no_kprobe; } /* We have reentered the pre_kprobe_handler(), since @@ -893,7 +887,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) * fix the return address to our jprobe_inst_return() function * in the jprobes.S file */ - regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; + regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; return 1; } diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 663230183254..bfbd8986153b 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -388,7 +388,7 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) { sal_log_record_header_t *log_buffer; u64 total_len = 0; - unsigned long s; + int s; IA64_LOG_LOCK(sal_info_type); diff --git a/trunk/arch/ia64/kernel/numa.c b/trunk/arch/ia64/kernel/numa.c index a78b45f5fe2f..20340631179f 100644 --- a/trunk/arch/ia64/kernel/numa.c +++ b/trunk/arch/ia64/kernel/numa.c @@ -28,7 +28,6 @@ u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_to_node_map); cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; -EXPORT_SYMBOL(node_to_cpu_mask); void __cpuinit map_cpu_to_node(int cpu, int nid) { diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 51922b98086a..ea914cc6812a 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -8,6 +8,8 @@ * 2005-10-07 Keith Owens * Add notify_die() hooks. */ +#define __KERNEL_SYSCALLS__ /* see */ + #include #include #include diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 62e07f906e05..16262687a103 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -29,6 +29,8 @@ #include #include +extern unsigned long wall_jiffies; + volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */ #ifdef CONFIG_IA64_DEBUG_IRQ diff --git a/trunk/arch/ia64/mm/numa.c b/trunk/arch/ia64/mm/numa.c index 7807fc5c0422..64e4c21f311c 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -70,21 +69,4 @@ int early_pfn_to_nid(unsigned long pfn) return 0; } - -#ifdef CONFIG_MEMORY_HOTPLUG -/* - * SRAT information is stored in node_memblk[], then we can use SRAT - * information at memory-hot-add if necessary. - */ - -int memory_add_physaddr_to_nid(u64 addr) -{ - int nid = paddr_to_nid(addr); - if (nid < 0) - return 0; - return nid; -} - -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); -#endif #endif diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 462ea178f49a..b632b9c1e3b3 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -423,7 +423,7 @@ static int sn_topology_show(struct seq_file *s, void *d) "coherency_domain %d, " "region_size %d\n", - partid, utsname()->nodename, + partid, system_utsname.nodename, shubtype ? "shub2" : "shub1", (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift, system_size, sharing_size, coher, region_size); diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 5eb1e1e078b4..1f0253bfe0a0 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -160,7 +160,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) volatile u64 ate; int count; - unsigned long flags; + u64 flags; if (pcibr_invalidate_ate) { /* For debugging purposes, clear the valid bit in the ATE */ diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 1ee977fb6ebb..a86c7b945962 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -237,7 +237,7 @@ void sn_dma_flush(u64 addr) int is_tio; int wid_num; int i, j; - unsigned long flags; + u64 flags; u64 itte; struct hubdev_info *hubinfo; struct sn_flush_device_kernel *p; diff --git a/trunk/arch/m32r/kernel/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c index b567351f3c52..a9cea32eb824 100644 --- a/trunk/arch/m32r/kernel/sys_m32r.c +++ b/trunk/arch/m32r/kernel/sys_m32r.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include /* * sys_tas() - test-and-set @@ -207,7 +205,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -225,21 +223,3 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) return -ENOSYS; } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __scno __asm__ ("r7") = __NR_execve; - register long __arg3 __asm__ ("r2") = (long)(envp); - register long __arg2 __asm__ ("r1") = (long)(argv); - register long __res __asm__ ("r0") = (long)(filename); - __asm__ __volatile__ ( - "trap #" SYSCALL_VECTOR "|| nop" - : "=r" (__res) - : "r" (__scno), "0" (__res), "r" (__arg2), - "r" (__arg3) - : "memory"); - return __res; -} diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index d8af155db984..7a896893cd28 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -38,6 +38,7 @@ extern void send_IPI_allbutself(int, int); extern void smp_local_timer_interrupt(struct pt_regs *); #endif +extern unsigned long wall_jiffies; #define TICK_SIZE (tick_nsec / 1000) /* @@ -107,17 +108,24 @@ void do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin(&xtime_lock); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } else if (unlikely(lost)) + usec += lost * tick_usec; sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); @@ -150,6 +158,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/m32r/mm/ioremap.c b/trunk/arch/m32r/mm/ioremap.c index 5152c4e6ac80..a151849a605e 100644 --- a/trunk/arch/m32r/mm/ioremap.c +++ b/trunk/arch/m32r/mm/ioremap.c @@ -20,8 +20,92 @@ #include #include -#include +#include #include +#include +#include + +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ + | _PAGE_WRITE | flags); + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, pgprot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int +remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} /* * Generic mapping function (not visible outside): @@ -45,7 +129,6 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) void __iomem * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -74,9 +157,6 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) return NULL; } - pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ - | _PAGE_WRITE | flags); - /* * Mappings have to be page-aligned */ @@ -92,8 +172,7 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) return NULL; area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c index 90238a8c9e14..143c552d38f3 100644 --- a/trunk/arch/m68k/kernel/sys_m68k.c +++ b/trunk/arch/m68k/kernel/sys_m68k.c @@ -27,7 +27,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -664,18 +663,3 @@ asmlinkage int sys_getpagesize(void) { return PAGE_SIZE; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __res asm ("%d0") = __NR_execve; - register long __a asm ("%d1") = (long)(filename); - register long __b asm ("%d2") = (long)(argv); - register long __c asm ("%d3") = (long)(envp); - asm volatile ("trap #0" : "+d" (__res) - : "d" (__a), "d" (__b), "d" (__c)); - return __res; -} diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 6cfc984380d9..1072e4946a4a 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -96,23 +96,31 @@ void time_init(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; + extern unsigned long wall_jiffies; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; unsigned long max_ntp_tick = tick_usec - tickadj; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = mach_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += xtime.tv_nsec/1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -133,6 +141,7 @@ int do_settimeofday(struct timespec *tv) { time_t wtm_sec, sec = tv->tv_sec; long wtm_nsec, nsec = tv->tv_nsec; + extern unsigned long wall_jiffies; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; @@ -144,7 +153,8 @@ int do_settimeofday(struct timespec *tv) * Discover what correction gettimeofday * would have done, and then undo it! */ - nsec -= 1000 * mach_gettimeoffset(); + nsec -= 1000 * (mach_gettimeoffset() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/m68knommu/kernel/sys_m68k.c b/trunk/arch/m68knommu/kernel/sys_m68k.c index c3494b8447d1..d87e1e0a1336 100644 --- a/trunk/arch/m68knommu/kernel/sys_m68k.c +++ b/trunk/arch/m68knommu/kernel/sys_m68k.c @@ -26,7 +26,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -207,17 +206,3 @@ asmlinkage int sys_getpagesize(void) return PAGE_SIZE; } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __res asm ("%d0") = __NR_execve; - register long __a asm ("%d1") = (long)(filename); - register long __b asm ("%d2") = (long)(argv); - register long __c asm ("%d3") = (long)(envp); - asm volatile ("trap #0" : "+d" (__res) - : "d" (__a), "d" (__b), "d" (__c)); - return __res; -} diff --git a/trunk/arch/m68knommu/kernel/time.c b/trunk/arch/m68knommu/kernel/time.c index c5667bdddd5e..db1e1ce0a349 100644 --- a/trunk/arch/m68knommu/kernel/time.c +++ b/trunk/arch/m68knommu/kernel/time.c @@ -26,6 +26,8 @@ #define TICK_SIZE (tick_nsec / 1000) +extern unsigned long wall_jiffies; + static inline int set_rtc_mmss(unsigned long nowtime) { @@ -122,12 +124,15 @@ void time_init(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long seq; + unsigned long lost, seq; unsigned long usec, sec; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = mach_gettimeoffset ? mach_gettimeoffset() : 0; + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 87cee341eb54..30750c54bdf5 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -537,7 +537,6 @@ config QEMU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_SPARSEMEM_ENABLE help Qemu is a software emulator which among other architectures also @@ -1842,14 +1841,6 @@ config RWSEM_GENERIC_SPINLOCK bool default y -config LOCKDEP_SUPPORT - bool - default y - -config STACKTRACE_SUPPORT - bool - default y - source "init/Kconfig" menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" diff --git a/trunk/arch/mips/basler/excite/excite_flashtest.c b/trunk/arch/mips/basler/excite/excite_flashtest.c new file mode 100644 index 000000000000..f0024a8e3294 --- /dev/null +++ b/trunk/arch/mips/basler/excite/excite_flashtest.c @@ -0,0 +1,294 @@ +/* +* Copyright (C) 2005 by Basler Vision Technologies AG +* Author: Thies Moeller +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include // for ocd_write +#include // for queue + +#include "excite_nandflash.h" +#include "nandflash.h" + +#define PFX "excite flashtest: " +typedef void __iomem *io_reg_t; + +#define io_readb(__a__) __raw_readb((__a__)) +#define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__)) + + + +static inline const struct resource *excite_nandflash_get_resource( + struct platform_device *d, unsigned long flags, const char *basename) +{ + const char fmt[] = "%s_%u"; + char buf[80]; + + if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf)) + return NULL; + + return platform_get_resource_byname(d, flags, buf); +} + +static inline io_reg_t +excite_nandflash_map_regs(struct platform_device *d, const char *basename) +{ + void *result = NULL; + const struct resource *const r = + excite_nandflash_get_resource(d, IORESOURCE_MEM, basename); + if (r) + result = ioremap_nocache(r->start, r->end + 1 - r->start); + return result; +} + +/* controller and mtd information */ + +struct excite_nandflash_drvdata { + struct mtd_info board_mtd; + struct nand_chip board_chip; + io_reg_t regs; +}; + + +/* command and control functions */ +static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs; + + switch (cmd) { + /* Select the command latch */ + case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD; + break; + /* Deselect the command latch */ + case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; + break; + /* Select the address latch */ + case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR; + break; + /* Deselect the address latch */ + case NAND_CTL_CLRALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; + break; + /* Select the chip -- not used */ + case NAND_CTL_SETNCE: + break; + /* Deselect the chip -- not used */ + case NAND_CTL_CLRNCE: + break; + } + + this->IO_ADDR_R = this->IO_ADDR_W; +} + +/* excite_nandflash_devready() + * + * returns 0 if the nand is busy, 1 if it is ready + */ +static int excite_nandflash_devready(struct mtd_info *mtd) +{ + struct excite_nandflash_drvdata *drvdata = + container_of(mtd, struct excite_nandflash_drvdata, board_mtd); + + return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); +} + +/* device management functions */ + +/* excite_nandflash_remove + * + * called by device layer to remove the driver + * the binding to the mtd and all allocated + * resources are released + */ +static int excite_nandflash_remove(struct device *dev) +{ + struct excite_nandflash_drvdata *this = dev_get_drvdata(dev); + + pr_info(PFX "remove"); + + dev_set_drvdata(dev, NULL); + + if (this == NULL) { + pr_debug(PFX "call remove without private data!!"); + return 0; + } + + + /* free the common resources */ + if (this->regs != NULL) { + iounmap(this->regs); + this->regs = NULL; + } + + kfree(this); + + return 0; +} + +static int elapsed; + +void my_workqueue_handler(void *arg) +{ + elapsed = 1; +} + +DECLARE_WORK(sigElapsed, my_workqueue_handler, 0); + + +/* excite_nandflash_probe + * + * called by device layer when it finds a device matching + * one our driver can handled. This code checks to see if + * it can allocate all necessary resources then calls the + * nand layer to look for devices +*/ +static int excite_nandflash_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + struct excite_nandflash_drvdata *drvdata; /* private driver data */ + struct nand_chip *board_chip; /* private flash chip data */ + struct mtd_info *board_mtd; /* mtd info for this board */ + + int err = 0; + int count = 0; + struct timeval tv,endtv; + unsigned int dt; + + pr_info(PFX "probe dev: (%p)\n", dev); + + pr_info(PFX "adjust LB timing\n"); + ocd_writel(0x00000330, LDP2); + + drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL); + if (unlikely(!drvdata)) { + printk(KERN_ERR PFX "no memory for drvdata\n"); + err = -ENOMEM; + goto mem_error; + } + + /* Initialize structures */ + memset(drvdata, 0, sizeof(*drvdata)); + + /* bind private data into driver */ + dev_set_drvdata(dev, drvdata); + + /* allocate and map the resource */ + drvdata->regs = + excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS); + + if (unlikely(!drvdata->regs)) { + printk(KERN_ERR PFX "cannot reserve register region\n"); + err = -ENXIO; + goto io_error; + } + + /* initialise our chip */ + board_chip = &drvdata->board_chip; + + board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA; + board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA; + + board_chip->hwcontrol = excite_nandflash_hwcontrol; + board_chip->dev_ready = excite_nandflash_devready; + + board_chip->chip_delay = 25; + #if 0 + /* TODO: speedup the initial scan */ + board_chip->options = NAND_USE_FLASH_BBT; + #endif + board_chip->eccmode = NAND_ECC_SOFT; + + /* link chip to mtd */ + board_mtd = &drvdata->board_mtd; + board_mtd->priv = board_chip; + + + pr_info(PFX "FlashTest\n"); + elapsed = 0; +/* schedule_delayed_work(&sigElapsed, 1*HZ); + while (!elapsed) { + io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); + count++; + } + pr_info(PFX "reads in 1 sec --> %d\n",count); +*/ + do_gettimeofday(&tv); + for (count = 0 ; count < 1000000; count ++) { + io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); + } + do_gettimeofday(&endtv); + dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec - tv.tv_usec; + pr_info(PFX "%8d us timeval\n",dt); + pr_info(PFX "EndFlashTest\n"); + +/* return with error to unload everything +*/ +io_error: + iounmap(drvdata->regs); + +mem_error: + kfree(drvdata); + + if (err == 0) + err = -EINVAL; + return err; +} + +static struct device_driver excite_nandflash_driver = { + .name = "excite_nand", + .bus = &platform_bus_type, + .probe = excite_nandflash_probe, + .remove = excite_nandflash_remove, +}; + +static int __init excite_nandflash_init(void) +{ + pr_info(PFX "register Driver (Rev: $Revision:$)\n"); + return driver_register(&excite_nandflash_driver); +} + +static void __exit excite_nandflash_exit(void) +{ + driver_unregister(&excite_nandflash_driver); + pr_info(PFX "Driver unregistered"); +} + +module_init(excite_nandflash_init); +module_exit(excite_nandflash_exit); + +MODULE_AUTHOR("Thies Moeller "); +MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/arch/mips/configs/atlas_defconfig b/trunk/arch/mips/configs/atlas_defconfig index 35931bedc3df..d3705284de39 100644 --- a/trunk/arch/mips/configs/atlas_defconfig +++ b/trunk/arch/mips/configs/atlas_defconfig @@ -161,8 +161,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1306,7 +1304,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/bigsur_defconfig b/trunk/arch/mips/configs/bigsur_defconfig index c6a015940b41..e12a475dcbf4 100644 --- a/trunk/arch/mips/configs/bigsur_defconfig +++ b/trunk/arch/mips/configs/bigsur_defconfig @@ -167,8 +167,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -906,7 +904,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/capcella_defconfig b/trunk/arch/mips/configs/capcella_defconfig index e5358121d2da..bfade9abb767 100644 --- a/trunk/arch/mips/configs/capcella_defconfig +++ b/trunk/arch/mips/configs/capcella_defconfig @@ -149,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -893,7 +891,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/cobalt_defconfig b/trunk/arch/mips/configs/cobalt_defconfig index adf1e8c98c65..4baf2ff1128a 100644 --- a/trunk/arch/mips/configs/cobalt_defconfig +++ b/trunk/arch/mips/configs/cobalt_defconfig @@ -146,8 +146,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -891,7 +889,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1000_defconfig b/trunk/arch/mips/configs/db1000_defconfig index 4fd29ffdfb8d..93cca1585bc3 100644 --- a/trunk/arch/mips/configs/db1000_defconfig +++ b/trunk/arch/mips/configs/db1000_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1008,7 +1006,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1100_defconfig b/trunk/arch/mips/configs/db1100_defconfig index 025b960ba990..ffd99252a837 100644 --- a/trunk/arch/mips/configs/db1100_defconfig +++ b/trunk/arch/mips/configs/db1100_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1008,7 +1006,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1200_defconfig b/trunk/arch/mips/configs/db1200_defconfig index 80c9dd98f897..63eac5e89b9c 100644 --- a/trunk/arch/mips/configs/db1200_defconfig +++ b/trunk/arch/mips/configs/db1200_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1089,7 +1087,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1500_defconfig b/trunk/arch/mips/configs/db1500_defconfig index 6caa90b0e176..25a095f7dc4e 100644 --- a/trunk/arch/mips/configs/db1500_defconfig +++ b/trunk/arch/mips/configs/db1500_defconfig @@ -149,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1292,7 +1290,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1550_defconfig b/trunk/arch/mips/configs/db1550_defconfig index c6cae86c6ab7..dda469c842b3 100644 --- a/trunk/arch/mips/configs/db1550_defconfig +++ b/trunk/arch/mips/configs/db1550_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1113,7 +1111,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ddb5477_defconfig b/trunk/arch/mips/configs/ddb5477_defconfig index 72f24001c99e..fcd3dd19bc74 100644 --- a/trunk/arch/mips/configs/ddb5477_defconfig +++ b/trunk/arch/mips/configs/ddb5477_defconfig @@ -146,8 +146,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -854,7 +852,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/decstation_defconfig b/trunk/arch/mips/configs/decstation_defconfig index be901df7fefa..8683e0df12e0 100644 --- a/trunk/arch/mips/configs/decstation_defconfig +++ b/trunk/arch/mips/configs/decstation_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=128 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -830,7 +828,6 @@ CONFIG_ULTRIX_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/e55_defconfig b/trunk/arch/mips/configs/e55_defconfig index 6133c28beb8c..4ace61c95778 100644 --- a/trunk/arch/mips/configs/e55_defconfig +++ b/trunk/arch/mips/configs/e55_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/trunk/arch/mips/configs/emma2rh_defconfig b/trunk/arch/mips/configs/emma2rh_defconfig index a484b7d396fc..5847c916c130 100644 --- a/trunk/arch/mips/configs/emma2rh_defconfig +++ b/trunk/arch/mips/configs/emma2rh_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1182,7 +1180,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ev64120_defconfig b/trunk/arch/mips/configs/ev64120_defconfig index 21bfcdebf8f5..bc4c4f125c48 100644 --- a/trunk/arch/mips/configs/ev64120_defconfig +++ b/trunk/arch/mips/configs/ev64120_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -844,7 +842,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/excite_defconfig b/trunk/arch/mips/configs/excite_defconfig index 1a5b06cfb4d6..eb87cbbfd037 100644 --- a/trunk/arch/mips/configs/excite_defconfig +++ b/trunk/arch/mips/configs/excite_defconfig @@ -149,8 +149,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1186,7 +1184,6 @@ CONFIG_NLS_ISO8859_1=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip22_defconfig b/trunk/arch/mips/configs/ip22_defconfig index 21d53e0c9ee8..cc9b24eda9e8 100644 --- a/trunk/arch/mips/configs/ip22_defconfig +++ b/trunk/arch/mips/configs/ip22_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1149,7 +1147,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig index e3e94c7e5ee1..50092ba8aa71 100644 --- a/trunk/arch/mips/configs/ip27_defconfig +++ b/trunk/arch/mips/configs/ip27_defconfig @@ -162,8 +162,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y # CONFIG_MIPS_INSANE_LARGE is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -982,7 +980,6 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip32_defconfig b/trunk/arch/mips/configs/ip32_defconfig index b4ab2bea9723..dec2ba6ba03f 100644 --- a/trunk/arch/mips/configs/ip32_defconfig +++ b/trunk/arch/mips/configs/ip32_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -924,7 +922,6 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/it8172_defconfig b/trunk/arch/mips/configs/it8172_defconfig index 18d20fb7d5f0..37f9dd7187b1 100644 --- a/trunk/arch/mips/configs/it8172_defconfig +++ b/trunk/arch/mips/configs/it8172_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -902,7 +900,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ivr_defconfig b/trunk/arch/mips/configs/ivr_defconfig index 99831d0bf76b..18874a4c24fe 100644 --- a/trunk/arch/mips/configs/ivr_defconfig +++ b/trunk/arch/mips/configs/ivr_defconfig @@ -144,8 +144,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -858,7 +856,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/jaguar-atx_defconfig b/trunk/arch/mips/configs/jaguar-atx_defconfig index 9d4d17ace123..9f1e3048d623 100644 --- a/trunk/arch/mips/configs/jaguar-atx_defconfig +++ b/trunk/arch/mips/configs/jaguar-atx_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -777,7 +775,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/jmr3927_defconfig b/trunk/arch/mips/configs/jmr3927_defconfig index d03746667a96..fded3f73815f 100644 --- a/trunk/arch/mips/configs/jmr3927_defconfig +++ b/trunk/arch/mips/configs/jmr3927_defconfig @@ -143,8 +143,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_RTC_DS1742=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -874,7 +872,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/lasat200_defconfig b/trunk/arch/mips/configs/lasat200_defconfig index 1db8249b4c0f..320b8cdd6e58 100644 --- a/trunk/arch/mips/configs/lasat200_defconfig +++ b/trunk/arch/mips/configs/lasat200_defconfig @@ -151,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -972,7 +970,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/malta_defconfig b/trunk/arch/mips/configs/malta_defconfig index aeefe2873e38..0ba1ef5048fb 100644 --- a/trunk/arch/mips/configs/malta_defconfig +++ b/trunk/arch/mips/configs/malta_defconfig @@ -170,8 +170,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1343,7 +1341,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig index a3cbd23bf217..adbeeadddb8f 100644 --- a/trunk/arch/mips/configs/mipssim_defconfig +++ b/trunk/arch/mips/configs/mipssim_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -801,7 +799,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/mpc30x_defconfig b/trunk/arch/mips/configs/mpc30x_defconfig index 6570b47426ce..79fd544fcb2a 100644 --- a/trunk/arch/mips/configs/mpc30x_defconfig +++ b/trunk/arch/mips/configs/mpc30x_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/trunk/arch/mips/configs/ocelot_3_defconfig b/trunk/arch/mips/configs/ocelot_3_defconfig index 440d65f93a94..4d87da2b99fd 100644 --- a/trunk/arch/mips/configs/ocelot_3_defconfig +++ b/trunk/arch/mips/configs/ocelot_3_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1093,7 +1091,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_c_defconfig b/trunk/arch/mips/configs/ocelot_c_defconfig index c2c7ae77da3e..a7ac2b0a8273 100644 --- a/trunk/arch/mips/configs/ocelot_c_defconfig +++ b/trunk/arch/mips/configs/ocelot_c_defconfig @@ -150,8 +150,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -841,7 +839,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_defconfig b/trunk/arch/mips/configs/ocelot_defconfig index 67efe270e0cc..853e7bba5122 100644 --- a/trunk/arch/mips/configs/ocelot_defconfig +++ b/trunk/arch/mips/configs/ocelot_defconfig @@ -154,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -790,7 +788,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_g_defconfig b/trunk/arch/mips/configs/ocelot_g_defconfig index a10f34de5f7e..8524efa23a49 100644 --- a/trunk/arch/mips/configs/ocelot_g_defconfig +++ b/trunk/arch/mips/configs/ocelot_g_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -844,7 +842,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1100_defconfig b/trunk/arch/mips/configs/pb1100_defconfig index 741f8258075c..1a16e92900cb 100644 --- a/trunk/arch/mips/configs/pb1100_defconfig +++ b/trunk/arch/mips/configs/pb1100_defconfig @@ -149,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1002,7 +1000,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1500_defconfig b/trunk/arch/mips/configs/pb1500_defconfig index 8576340714da..9ea8edea6f29 100644 --- a/trunk/arch/mips/configs/pb1500_defconfig +++ b/trunk/arch/mips/configs/pb1500_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1108,7 +1106,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1550_defconfig b/trunk/arch/mips/configs/pb1550_defconfig index 3db7427d1b55..c4a158976f8f 100644 --- a/trunk/arch/mips/configs/pb1550_defconfig +++ b/trunk/arch/mips/configs/pb1550_defconfig @@ -148,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1100,7 +1098,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pnx8550-jbs_defconfig b/trunk/arch/mips/configs/pnx8550-jbs_defconfig index 26b0b9883496..1cbf270c301c 100644 --- a/trunk/arch/mips/configs/pnx8550-jbs_defconfig +++ b/trunk/arch/mips/configs/pnx8550-jbs_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -878,7 +876,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig index e93266b37dd9..bec30b15b9bd 100644 --- a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1059,7 +1057,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/qemu_defconfig b/trunk/arch/mips/configs/qemu_defconfig index 9b0dab822bd0..f5f799e93707 100644 --- a/trunk/arch/mips/configs/qemu_defconfig +++ b/trunk/arch/mips/configs/qemu_defconfig @@ -145,8 +145,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -735,7 +733,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/rbhma4500_defconfig b/trunk/arch/mips/configs/rbhma4500_defconfig index dd0296036026..2f5650227ba3 100644 --- a/trunk/arch/mips/configs/rbhma4500_defconfig +++ b/trunk/arch/mips/configs/rbhma4500_defconfig @@ -155,8 +155,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1337,7 +1335,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/rm200_defconfig b/trunk/arch/mips/configs/rm200_defconfig index d8a498d64d62..4fee90b2b100 100644 --- a/trunk/arch/mips/configs/rm200_defconfig +++ b/trunk/arch/mips/configs/rm200_defconfig @@ -158,8 +158,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1586,7 +1584,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig index 805a4fe450f5..9041f095f96f 100644 --- a/trunk/arch/mips/configs/sb1250-swarm_defconfig +++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig @@ -171,8 +171,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -875,7 +873,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/sead_defconfig b/trunk/arch/mips/configs/sead_defconfig index 6fcb656d8d87..02abb2f1bfaf 100644 --- a/trunk/arch/mips/configs/sead_defconfig +++ b/trunk/arch/mips/configs/sead_defconfig @@ -151,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -583,7 +581,6 @@ CONFIG_PARTITION_ADVANCED=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0226_defconfig b/trunk/arch/mips/configs/tb0226_defconfig index dc312f19ada7..ca3d0c4ba15b 100644 --- a/trunk/arch/mips/configs/tb0226_defconfig +++ b/trunk/arch/mips/configs/tb0226_defconfig @@ -151,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1061,7 +1059,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0229_defconfig b/trunk/arch/mips/configs/tb0229_defconfig index 85615d99b01a..4e2009ace278 100644 --- a/trunk/arch/mips/configs/tb0229_defconfig +++ b/trunk/arch/mips/configs/tb0229_defconfig @@ -151,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -970,7 +968,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0287_defconfig b/trunk/arch/mips/configs/tb0287_defconfig index ad7271b3f266..535a813d01a9 100644 --- a/trunk/arch/mips/configs/tb0287_defconfig +++ b/trunk/arch/mips/configs/tb0287_defconfig @@ -151,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1148,7 +1146,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/workpad_defconfig b/trunk/arch/mips/configs/workpad_defconfig index 863f6a7cadfd..3a3ef20b21cc 100644 --- a/trunk/arch/mips/configs/workpad_defconfig +++ b/trunk/arch/mips/configs/workpad_defconfig @@ -147,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # diff --git a/trunk/arch/mips/configs/wrppmc_defconfig b/trunk/arch/mips/configs/wrppmc_defconfig index c10267d61cc9..e6b1dea55842 100644 --- a/trunk/arch/mips/configs/wrppmc_defconfig +++ b/trunk/arch/mips/configs/wrppmc_defconfig @@ -155,8 +155,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -831,7 +829,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/yosemite_defconfig b/trunk/arch/mips/configs/yosemite_defconfig index 4d3c1329f3cf..06a072b77b1c 100644 --- a/trunk/arch/mips/configs/yosemite_defconfig +++ b/trunk/arch/mips/configs/yosemite_defconfig @@ -152,8 +152,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -762,7 +760,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/defconfig b/trunk/arch/mips/defconfig index 21d53e0c9ee8..cc9b24eda9e8 100644 --- a/trunk/arch/mips/defconfig +++ b/trunk/arch/mips/defconfig @@ -153,8 +153,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1149,7 +1147,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index cd9cec9e39e9..881c467c6982 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -11,7 +11,6 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_APM) += apm.o diff --git a/trunk/arch/mips/kernel/genex.S b/trunk/arch/mips/kernel/genex.S index af6ef2fd8300..37fda3dcdfc5 100644 --- a/trunk/arch/mips/kernel/genex.S +++ b/trunk/arch/mips/kernel/genex.S @@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp) CLI TRACE_IRQS_OFF move a0, sp - PTR_LA ra, ret_from_irq - jr v0 + jalr v0 + j ret_from_irq END(except_vec_vi_handler) /* @@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp) .set at __BUILD_\verbose \exception move a0, sp - PTR_LA ra, ret_from_exception - j do_\handler + jal do_\handler + j ret_from_exception END(handle_\exception) .endm diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index 48e3418c217b..ea36c8e8852c 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -302,11 +302,11 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY + .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY + .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY }; /* diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 53f4171fc188..43b1162d714f 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -77,8 +77,6 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) memset(&tmp, 0, sizeof(tmp)); tmp.st_dev = new_encode_dev(stat->dev); tmp.st_ino = stat->ino; - if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) - return -EOVERFLOW; tmp.st_mode = stat->mode; tmp.st_nlink = stat->nlink; SET_UID(tmp.st_uid, stat->uid); @@ -1041,7 +1039,7 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name) int ret = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof *name)) + if (copy_to_user(name,&system_utsname,sizeof *name)) ret = -EFAULT; up_read(&uts_sem); diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index 045d987bc683..2613a0dd4b82 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_MIPS_MT_SMTC #include extern void smtc_idle_loop_hook(void); @@ -399,7 +398,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) #ifdef CONFIG_KALLSYMS /* used by show_backtrace() */ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long *ra) + unsigned long pc, unsigned long ra) { unsigned long stack_page; struct mips_frame_info info; @@ -407,42 +406,18 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; - extern void ret_from_irq(void); - extern void ret_from_exception(void); stack_page = (unsigned long)task_stack_page(task); if (!stack_page) return 0; - /* - * If we reached the bottom of interrupt context, - * return saved pc in pt_regs. - */ - if (pc == (unsigned long)ret_from_irq || - pc == (unsigned long)ret_from_exception) { - struct pt_regs *regs; - if (*sp >= stack_page && - *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { - regs = (struct pt_regs *)*sp; - pc = regs->cp0_epc; - if (__kernel_text_address(pc)) { - *sp = regs->regs[29]; - *ra = regs->regs[31]; - return pc; - } - } - return 0; - } if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) return 0; /* * Return ra if an exception occured at the first instruction */ - if (unlikely(ofs == 0)) { - pc = *ra; - *ra = 0; - return pc; - } + if (unlikely(ofs == 0)) + return ra; info.func = (void *)(pc - ofs); info.func_size = ofs; /* analyze from start to ofs */ @@ -461,12 +436,11 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, * one. In that cases avoid to return always the * same value. */ - pc = pc != *ra ? *ra : 0; + pc = pc != ra ? ra : 0; else pc = ((unsigned long *)(*sp))[info.pc_offset]; *sp += info.frame_size; - *ra = 0; return __kernel_text_address(pc) ? pc : 0; } #endif @@ -479,7 +453,6 @@ unsigned long get_wchan(struct task_struct *task) unsigned long pc = 0; #ifdef CONFIG_KALLSYMS unsigned long sp; - unsigned long ra = 0; #endif if (!task || task == current || task->state == TASK_RUNNING) @@ -493,7 +466,7 @@ unsigned long get_wchan(struct task_struct *task) sp = task->thread.reg29 + schedule_mfi.frame_size; while (in_sched_functions(pc)) - pc = unwind_stack(task, &sp, pc, &ra); + pc = unwind_stack(task, &sp, pc, 0); #endif out: diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 61362e6fa9ec..e71785102206 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -28,7 +28,18 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD +#ifdef CONFIG_TRACE_IRQFLAGS + TRACE_IRQS_ON +#ifdef CONFIG_64BIT + LONG_L $8, PT_R8(sp) + LONG_L $9, PT_R9(sp) +#endif + LONG_L $7, PT_R7(sp) + LONG_L $6, PT_R6(sp) + LONG_L $5, PT_R5(sp) + LONG_L $4, PT_R4(sp) + LONG_L $2, PT_R2(sp) +#endif STI .set at diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 6c7b5ed0ea6e..4c22d0b4825d 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp) */ .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at #endif diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 6d9f18727ac5..f25c2a2f1038 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) #ifndef CONFIG_MIPS32_O32 .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at #endif diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 2e6d0673163e..288ee4ac4dbb 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -28,7 +28,7 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at ld t1, PT_EPC(sp) # skip syscall on return diff --git a/trunk/arch/mips/kernel/stacktrace.c b/trunk/arch/mips/kernel/stacktrace.c deleted file mode 100644 index 4aabe526a68e..000000000000 --- a/trunk/arch/mips/kernel/stacktrace.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * arch/mips/kernel/stacktrace.c - * - * Stack trace management functions - * - * Copyright (C) 2006 Atsushi Nemoto - */ -#include -#include -#include - -/* - * Save stack-backtrace addresses into a stack_trace buffer: - */ -static void save_raw_context_stack(struct stack_trace *trace, - unsigned long reg29) -{ - unsigned long *sp = (unsigned long *)reg29; - unsigned long addr; - - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = addr; - if (trace->nr_entries >= trace->max_entries) - break; - } - } -} - -static void save_context_stack(struct stack_trace *trace, - struct task_struct *task, struct pt_regs *regs) -{ - unsigned long sp = regs->regs[29]; -#ifdef CONFIG_KALLSYMS - unsigned long ra = regs->regs[31]; - unsigned long pc = regs->cp0_epc; - - if (raw_show_trace || !__kernel_text_address(pc)) { - unsigned long stack_page = - (unsigned long)task_stack_page(task); - if (stack_page && sp >= stack_page && - sp <= stack_page + THREAD_SIZE - 32) - save_raw_context_stack(trace, sp); - return; - } - do { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = pc; - if (trace->nr_entries >= trace->max_entries) - break; - pc = unwind_stack(task, &sp, pc, &ra); - } while (pc); -#else - save_raw_context_stack(sp); -#endif -} - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) -{ - struct pt_regs dummyregs; - struct pt_regs *regs = &dummyregs; - - WARN_ON(trace->nr_entries || !trace->max_entries); - - if (task && task != current) { - regs->regs[29] = task->thread.reg29; - regs->regs[31] = 0; - regs->cp0_epc = task->thread.reg31; - } else { - if (!task) - task = current; - prepare_frametrace(regs); - } - - save_context_stack(trace, task, regs); -} diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 26e1a7e78d13..9951240cc3fd 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -231,7 +231,7 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) */ asmlinkage int sys_uname(struct old_utsname __user * name) { - if (name && !copy_to_user(name, utsname(), sizeof (*name))) + if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) return 0; return -EFAULT; } @@ -248,21 +248,16 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - error = __copy_to_user(&name->sysname, &utsname()->sysname, - __OLD_UTS_LEN); - error -= __put_user(0, name->sysname + __OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename, &utsname()->nodename, - __OLD_UTS_LEN); - error -= __put_user(0, name->nodename + __OLD_UTS_LEN); - error -= __copy_to_user(&name->release, &utsname()->release, - __OLD_UTS_LEN); - error -= __put_user(0, name->release + __OLD_UTS_LEN); - error -= __copy_to_user(&name->version, &utsname()->version, - __OLD_UTS_LEN); - error -= __put_user(0, name->version + __OLD_UTS_LEN); - error -= __copy_to_user(&name->machine, &utsname()->machine, - __OLD_UTS_LEN); - error = __put_user(0, name->machine + __OLD_UTS_LEN); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + error -= __put_user(0,name->sysname+__OLD_UTS_LEN); + error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error -= __put_user(0,name->nodename+__OLD_UTS_LEN); + error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error -= __put_user(0,name->release+__OLD_UTS_LEN); + error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error -= __put_user(0,name->version+__OLD_UTS_LEN); + error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error = __put_user(0,name->machine+__OLD_UTS_LEN); error = error ? -EFAULT : 0; return error; @@ -406,32 +401,3 @@ asmlinkage void bad_stack(void) { do_exit(SIGSEGV); } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register unsigned long __a0 asm("$4") = (unsigned long) filename; - register unsigned long __a1 asm("$5") = (unsigned long) argv; - register unsigned long __a2 asm("$6") = (unsigned long) envp; - register unsigned long __a3 asm("$7"); - unsigned long __v0; - - __asm__ volatile (" \n" - " .set noreorder \n" - " li $2, %5 # __NR_execve \n" - " syscall \n" - " move %0, $2 \n" - " .set reorder \n" - : "=&r" (__v0), "=r" (__a3) - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve) - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", - "memory"); - - if (__a3 == 0) - return __v0; - - return -__v0; -} diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 93c74fefff76..1137dd6ea7aa 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -884,7 +884,7 @@ asmlinkage int irix_getdomainname(char __user *name, int len) down_read(&uts_sem); if (len > __NEW_UTS_LEN) len = __NEW_UTS_LEN; - err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0; + err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0; up_read(&uts_sem); return err; @@ -1127,11 +1127,11 @@ struct iuname { asmlinkage int irix_uname(struct iuname __user *buf) { down_read(&uts_sem); - if (copy_from_user(utsname()->sysname, buf->sysname, 65) - || copy_from_user(utsname()->nodename, buf->nodename, 65) - || copy_from_user(utsname()->release, buf->release, 65) - || copy_from_user(utsname()->version, buf->version, 65) - || copy_from_user(utsname()->machine, buf->machine, 65)) { + if (copy_from_user(system_utsname.sysname, buf->sysname, 65) + || copy_from_user(system_utsname.nodename, buf->nodename, 65) + || copy_from_user(system_utsname.release, buf->release, 65) + || copy_from_user(system_utsname.version, buf->version, 65) + || copy_from_user(system_utsname.machine, buf->machine, 65)) { return -EFAULT; } up_read(&uts_sem); @@ -1739,13 +1739,12 @@ struct irix_dirent32_callback { #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) static int irix_filldir32(void *__buf, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) + int namlen, loff_t offset, ino_t ino, unsigned int d_type) { struct irix_dirent32 __user *dirent; struct irix_dirent32_callback *buf = __buf; unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); int err = 0; - u32 d_ino; #ifdef DEBUG_GETDENTS printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", @@ -1754,15 +1753,12 @@ static int irix_filldir32(void *__buf, const char *name, buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; if (dirent) err = __put_user(offset, &dirent->d_off); dirent = buf->current_dir; err |= __put_user(dirent, &buf->previous); - err |= __put_user(d_ino, &dirent->d_ino); + err |= __put_user(ino, &dirent->d_ino); err |= __put_user(reclen, &dirent->d_reclen); err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; err |= __put_user(0, &dirent->d_name[namlen]); @@ -1841,7 +1837,7 @@ struct irix_dirent64_callback { #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) static int irix_filldir64(void *__buf, const char *name, - int namlen, loff_t offset, u64 ino, unsigned int d_type) + int namlen, loff_t offset, ino_t ino, unsigned int d_type) { struct irix_dirent64 __user *dirent; struct irix_dirent64_callback * buf = __buf; diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c index 845c7e55505d..6ab8d975a974 100644 --- a/trunk/arch/mips/kernel/time.c +++ b/trunk/arch/mips/kernel/time.c @@ -47,6 +47,8 @@ /* * forward reference */ +extern volatile unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); /* @@ -157,6 +159,7 @@ void (*mips_hpt_init)(unsigned int); void do_gettimeofday(struct timeval *tv) { unsigned long seq; + unsigned long lost; unsigned long usec, sec; unsigned long max_ntp_tick; @@ -165,6 +168,8 @@ void do_gettimeofday(struct timeval *tv) usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; + /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. @@ -173,7 +178,11 @@ void do_gettimeofday(struct timeval *tv) if (unlikely(time_adjust < 0)) { max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; usec = min(usec, max_ntp_tick); - } + + if (lost) + usec += lost * max_ntp_tick; + } else if (unlikely(lost)) + usec += lost * (USEC_PER_SEC / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); @@ -208,6 +217,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * tick_nsec; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index b7292a56d4cd..e51d8fd9a152 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -41,7 +41,6 @@ #include #include #include -#include extern asmlinkage void handle_int(void); extern asmlinkage void handle_tlbm(void); @@ -93,14 +92,16 @@ static void show_raw_backtrace(unsigned long reg29) } #ifdef CONFIG_KALLSYMS -int raw_show_trace; +static int raw_show_trace; static int __init set_raw_show_trace(char *str) { raw_show_trace = 1; return 1; } __setup("raw_show_trace", set_raw_show_trace); -#endif + +extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long ra); static void show_backtrace(struct task_struct *task, struct pt_regs *regs) { @@ -115,10 +116,14 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs) printk("Call Trace:\n"); do { print_ip_sym(pc); - pc = unwind_stack(task, &sp, pc, &ra); + pc = unwind_stack(task, &sp, pc, ra); + ra = 0; } while (pc); printk("\n"); } +#else +#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]); +#endif /* * This routine abuses get_user()/put_user() to reference pointers @@ -153,6 +158,28 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) show_backtrace(task, regs); } +static __always_inline void prepare_frametrace(struct pt_regs *regs) +{ + __asm__ __volatile__( + ".set push\n\t" + ".set noat\n\t" +#ifdef CONFIG_64BIT + "1: dla $1, 1b\n\t" + "sd $1, %0\n\t" + "sd $29, %1\n\t" + "sd $31, %2\n\t" +#else + "1: la $1, 1b\n\t" + "sw $1, %0\n\t" + "sw $29, %1\n\t" + "sw $31, %2\n\t" +#endif + ".set pop\n\t" + : "=m" (regs->cp0_epc), + "=m" (regs->regs[29]), "=m" (regs->regs[31]) + : : "memory"); +} + void show_stack(struct task_struct *task, unsigned long *sp) { struct pt_regs regs; @@ -179,6 +206,11 @@ void dump_stack(void) { struct pt_regs regs; + /* + * Remove any garbage that may be in regs (specially func + * addresses) to avoid show_raw_backtrace() to report them + */ + memset(®s, 0, sizeof(regs)); prepare_frametrace(®s); show_backtrace(current, ®s); } diff --git a/trunk/arch/mips/mm/c-r3k.c b/trunk/arch/mips/mm/c-r3k.c index d1af42c2a52e..e1f35ef81145 100644 --- a/trunk/arch/mips/mm/c-r3k.c +++ b/trunk/arch/mips/mm/c-r3k.c @@ -268,6 +268,26 @@ static void r3k_flush_data_cache_page(unsigned long addr) { } +static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long physpage; + + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + if (!(vma->vm_flags & VM_EXEC)) + return; + +#ifdef DEBUG_CACHE + printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); +#endif + + physpage = (unsigned long) page_address(page); + if (physpage) + r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); +} + static void r3k_flush_cache_sigtramp(unsigned long addr) { unsigned long flags; @@ -315,6 +335,7 @@ void __init r3k_cache_init(void) flush_cache_mm = r3k_flush_cache_mm; flush_cache_range = r3k_flush_cache_range; flush_cache_page = r3k_flush_cache_page; + __flush_icache_page = r3k_flush_icache_page; flush_icache_range = r3k_flush_icache_range; flush_cache_sigtramp = r3k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index cc895dad71d2..0b2da53750bd 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -551,6 +551,82 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ + +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static inline void local_r4k_flush_icache_page(void *args) +{ + struct flush_icache_page_args *fip_args = args; + struct vm_area_struct *vma = fip_args->vma; + struct page *page = fip_args->page; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_inclusive_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + if (!cpu_icache_snoops_remote_store) + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + /* + * If there's no context yet, or the page isn't executable, no I-cache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.page = page; + + r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1); +} + + #ifdef CONFIG_DMA_NONCOHERENT static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1215,6 +1291,7 @@ void __init r4k_cache_init(void) __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; + __flush_icache_page = r4k_flush_icache_page; flush_cache_range = r4k_flush_cache_range; flush_cache_sigtramp = r4k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-sb1.c b/trunk/arch/mips/mm/c-sb1.c index 5537558f19f7..16bad7c0a63f 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -306,6 +306,66 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) __attribute__((alias("local_sb1_flush_icache_range"))); #endif +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); + /* + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) + */ + if (vma->vm_mm == current->active_mm) { + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + __sb1_flush_icache_range(start, start + PAGE_SIZE); + +} + +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) +{ + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) + __attribute__((alias("local_sb1_flush_icache_page"))); +#endif + /* * A signal trampoline must fit into a single cacheline. */ @@ -466,6 +526,7 @@ void sb1_cache_init(void) /* These routines are for Icache coherence with the Dcache */ flush_icache_range = sb1_flush_icache_range; + __flush_icache_page = sb1_flush_icache_page; flush_icache_all = __sb1_flush_icache_all; /* local only */ /* This implies an Icache flush too, so can't be nop'ed */ diff --git a/trunk/arch/mips/mm/c-tx39.c b/trunk/arch/mips/mm/c-tx39.c index f32ebde30ccf..932a09d7ef84 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -248,6 +248,33 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end) } } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + unsigned long addr; + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + addr = (unsigned long) page_address(page); + tx39_blast_dcache_page(addr); + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + tx39_blast_icache(); +} + static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end; @@ -355,6 +382,7 @@ void __init tx39_cache_init(void) flush_cache_mm = (void *) tx39h_flush_icache_all; flush_cache_range = (void *) tx39h_flush_icache_all; flush_cache_page = (void *) tx39h_flush_icache_all; + __flush_icache_page = (void *) tx39h_flush_icache_all; flush_icache_range = (void *) tx39h_flush_icache_all; flush_cache_sigtramp = (void *) tx39h_flush_icache_all; @@ -380,6 +408,7 @@ void __init tx39_cache_init(void) flush_cache_mm = tx39_flush_cache_mm; flush_cache_range = tx39_flush_cache_range; flush_cache_page = tx39_flush_cache_page; + __flush_icache_page = tx39_flush_icache_page; flush_icache_range = tx39_flush_icache_range; flush_cache_sigtramp = tx39_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/cache.c b/trunk/arch/mips/mm/cache.c index caf807ded514..40c8b0235183 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -25,6 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); +void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); diff --git a/trunk/arch/mips/mm/tlbex-fault.S b/trunk/arch/mips/mm/tlbex-fault.S index e99eaa1fbedc..9e7f4175b493 100644 --- a/trunk/arch/mips/mm/tlbex-fault.S +++ b/trunk/arch/mips/mm/tlbex-fault.S @@ -19,8 +19,8 @@ move a0, sp REG_S a2, PT_BVADDR(sp) li a1, \write - PTR_LA ra, ret_from_exception - j do_page_fault + jal do_page_fault + j ret_from_exception END(tlb_do_page_fault_\write) .endm diff --git a/trunk/arch/mips/sgi-ip22/ip22-reset.c b/trunk/arch/mips/sgi-ip22/ip22-reset.c index 7a941ecff3bb..8134220ed600 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-reset.c +++ b/trunk/arch/mips/sgi-ip22/ip22-reset.c @@ -123,8 +123,7 @@ static inline void power_button(void) if (machine_state & MACHINE_PANICED) return; - if ((machine_state & MACHINE_SHUTTING_DOWN) || - kill_cad_pid(SIGINT, 1)) { + if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { /* No init process or button pressed twice. */ sgi_machine_power_off(); } diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 257ce118e380..c62a3a9ef867 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -42,6 +42,8 @@ static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ static long last_rtc_update; /* Last time the rtc clock got updated */ +extern volatile unsigned long wall_jiffies; + #if 0 static int set_rtc_mmss(unsigned long nowtime) { diff --git a/trunk/arch/mips/sgi-ip32/ip32-reset.c b/trunk/arch/mips/sgi-ip32/ip32-reset.c index fd0932b2d521..79ddb4605659 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-reset.c +++ b/trunk/arch/mips/sgi-ip32/ip32-reset.c @@ -120,7 +120,7 @@ static inline void ip32_power_button(void) if (has_panicked) return; - if (shuting_down || kill_cad_pid(SIGINT, 1)) { + if (shuting_down || kill_proc(1, SIGINT, 1)) { /* No init process or button pressed twice. */ ip32_machine_power_off(); } diff --git a/trunk/arch/parisc/hpux/fs.c b/trunk/arch/parisc/hpux/fs.c index 6e79dbf3f6bd..d7c80edf4489 100644 --- a/trunk/arch/parisc/hpux/fs.c +++ b/trunk/arch/parisc/hpux/fs.c @@ -77,21 +77,17 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, { struct hpux_dirent * dirent; struct getdents_callback * buf = (struct getdents_callback *) __buf; - ino_t d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; if (dirent) put_user(offset, &dirent->d_off); dirent = buf->current_dir; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(reclen, &dirent->d_reclen); put_user(namlen, &dirent->d_namlen); copy_to_user(dirent->d_name, name, namlen); diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index 2e2dc4f2c853..cb69727027ae 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -266,21 +266,16 @@ static int hpux_uname(struct hpux_utsname *name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->release, &utsname()->release, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->release + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->version, &utsname()->version, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->version + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->machine, &utsname()->machine, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->machine + HPUX_UTSLEN - 1); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1); + error |= __put_user(0,name->sysname+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1); + error |= __put_user(0,name->nodename+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1); + error |= __put_user(0,name->release+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1); + error |= __put_user(0,name->version+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1); + error |= __put_user(0,name->machine+HPUX_UTSLEN-1); up_read(&uts_sem); @@ -378,8 +373,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about using this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(utsname()->sysname, ubuf, len)) { - utsname()->sysname[len] = 0; + if (!copy_from_user(system_utsname.sysname, ubuf, len)) { + system_utsname.sysname[len] = 0; error = 0; } up_write(&uts_sem); @@ -405,8 +400,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(utsname()->release, ubuf, len)) { - utsname()->release[len] = 0; + if (!copy_from_user(system_utsname.release, ubuf, len)) { + system_utsname.release[len] = 0; error = 0; } up_write(&uts_sem); @@ -427,13 +422,13 @@ int hpux_getdomainname(char *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; if (nlen < len) len = nlen; if(len > __NEW_UTS_LEN) goto done; - if(copy_to_user(name, utsname()->domainname, len)) + if(copy_to_user(name, system_utsname.domainname, len)) goto done; err = 0; done: diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index c2531ae032cf..4398d2a95789 100644 --- a/trunk/arch/parisc/kernel/firmware.c +++ b/trunk/arch/parisc/kernel/firmware.c @@ -1049,7 +1049,7 @@ void pdc_iodc_putc(unsigned char c) static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; unsigned int n; - unsigned long flags; + unsigned int flags; switch (c) { case '\n': @@ -1088,8 +1088,7 @@ void pdc_iodc_putc(unsigned char c) */ void pdc_iodc_outc(unsigned char c) { - unsigned int n; - unsigned long flags; + unsigned int n, flags; /* fill buffer with one caracter and print it */ static int __attribute__((aligned(8))) iodc_retbuf[32]; @@ -1114,7 +1113,7 @@ void pdc_iodc_outc(unsigned char c) */ int pdc_iodc_getc(void) { - unsigned long flags; + unsigned int flags; static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; int ch; diff --git a/trunk/arch/parisc/kernel/process.c b/trunk/arch/parisc/kernel/process.c index 2f9f9dfa66f7..0b485ef4be89 100644 --- a/trunk/arch/parisc/kernel/process.c +++ b/trunk/arch/parisc/kernel/process.c @@ -368,14 +368,7 @@ asmlinkage int sys_execve(struct pt_regs *regs) return error; } -extern int __execve(const char *filename, char *const argv[], - char *const envp[], struct task_struct *task); -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - return __execve(filename, argv, envp, current); -} - -unsigned long +unsigned long get_wchan(struct task_struct *p) { struct unwind_frame_info info; diff --git a/trunk/arch/parisc/kernel/sys_parisc32.c b/trunk/arch/parisc/kernel/sys_parisc32.c index e3b30bc36453..b74869803081 100644 --- a/trunk/arch/parisc/kernel/sys_parisc32.c +++ b/trunk/arch/parisc/kernel/sys_parisc32.c @@ -237,19 +237,14 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { - compat_ino_t ino; int err; if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) return -EOVERFLOW; - ino = stat->ino; - if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) - return -EOVERFLOW; - err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); - err |= put_user(ino, &statbuf->st_ino); + err |= put_user(stat->ino, &statbuf->st_ino); err |= put_user(stat->mode, &statbuf->st_mode); err |= put_user(stat->nlink, &statbuf->st_nlink); err |= put_user(0, &statbuf->st_reserved1); @@ -317,20 +312,16 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, struct linux32_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); - u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; if (dirent) put_user(offset, &dirent->d_off); dirent = buf->current_dir; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); put_user(0, dirent->d_name + namlen); @@ -380,16 +371,12 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent __user * dirent; - u32 d_ino; if (buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; buf->count++; dirent = buf->dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(offset, &dirent->d_offset); put_user(namlen, &dirent->d_namlen); copy_to_user(dirent->d_name, name, namlen); diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index ab641d67f551..700df10924dd 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -32,6 +32,9 @@ #include +/* xtime and wall_jiffies keep wall-clock time */ +extern unsigned long wall_jiffies; + static long clocktick __read_mostly; /* timer cycles per tick */ static long halftick __read_mostly; @@ -109,7 +112,7 @@ EXPORT_SYMBOL(profile_pc); /*** converted from ia64 ***/ /* * Return the number of micro-seconds that elapsed since the last - * update to wall time (aka xtime). The xtime_lock + * update to wall time (aka xtime aka wall_jiffies). The xtime_lock * must be at least read-locked when calling this routine. */ static inline unsigned long diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 032e6ab5d3c4..a0dd1b0ee483 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -1069,7 +1069,7 @@ source "arch/powerpc/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES + depends on PPC64 && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/powerpc/kernel/kprobes.c b/trunk/arch/powerpc/kernel/kprobes.c index 7b8d12b9026c..cd65c367b8b6 100644 --- a/trunk/arch/powerpc/kernel/kprobes.c +++ b/trunk/arch/powerpc/kernel/kprobes.c @@ -259,15 +259,14 @@ void kretprobe_trampoline_holder(void) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -278,20 +277,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -309,16 +308,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler - * to run (and have re-enabled preemption) - */ - return 1; + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler + * to run (and have re-enabled preemption) + */ + return 1; } /* diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 88fd73fdf048..58758d883361 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -843,7 +843,7 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr -_GLOBAL(kernel_execve) +_GLOBAL(execve) li r0,__NR_execve sc bnslr diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 9c54eccad993..e3ed21cd3d94 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -556,7 +556,7 @@ _GLOBAL(giveup_altivec) #endif /* CONFIG_ALTIVEC */ -_GLOBAL(kernel_execve) +_GLOBAL(execve) li r0,__NR_execve sc bnslr diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 7b2f6452ba72..a127a1e3c097 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs) printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %p TRAP: %04lx %s (%s)\n", - regs, regs->trap, print_tainted(), init_utsname()->release); + regs, regs->trap, print_tainted(), system_utsname.release); printk("MSR: "REG" ", regs->msr); printbits(regs->msr, msr_bits); printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index 79a17795d17b..e0df2ba1ab9f 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -67,6 +67,10 @@ int have_of = 1; dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY = 0x54; +#endif /* CONFIG_MAGIC_SYSRQ */ + #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; #endif diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index cda2dbe70a76..00d6b8addd78 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -93,6 +93,11 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY; +#endif /* CONFIG_MAGIC_SYSRQ */ + + #ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -414,7 +419,7 @@ void __init setup_system(void) smp_release_cpus(); #endif - printk("Starting Linux PPC64 %s\n", init_utsname()->version); + printk("Starting Linux PPC64 %s\n", system_utsname.version); printk("-----------------------------------------------------\n"); printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c index d15c33e95959..5e391fc25340 100644 --- a/trunk/arch/powerpc/kernel/sys_ppc32.c +++ b/trunk/arch/powerpc/kernel/sys_ppc32.c @@ -69,20 +69,16 @@ struct readdir_callback32 { }; static int fillonedir(void * __buf, const char * name, int namlen, - off_t offset, u64 ino, unsigned int d_type) + off_t offset, ino_t ino, unsigned int d_type) { struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; struct old_linux_dirent32 __user * dirent; - ino_t d_ino; if (buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; buf->count++; dirent = buf->dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(offset, &dirent->d_offset); put_user(namlen, &dirent->d_namlen); copy_to_user(dirent->d_name, name, namlen); @@ -124,20 +120,15 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { - compat_ino_t ino; long err; if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) return -EOVERFLOW; - ino = stat->ino; - if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) - return -EOVERFLOW; - err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); - err |= __put_user(ino, &statbuf->st_ino); + err |= __put_user(stat->ino, &statbuf->st_ino); err |= __put_user(stat->mode, &statbuf->st_mode); err |= __put_user(stat->nlink, &statbuf->st_nlink); err |= __put_user(stat->uid, &statbuf->st_uid); diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index d358866b880f..9b69d99a9103 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -260,7 +260,7 @@ long ppc_newuname(struct new_utsname __user * name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof(*name))) + if (copy_to_user(name, &system_utsname, sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -273,7 +273,7 @@ int sys_uname(struct old_utsname __user *name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof(*name))) + if (copy_to_user(name, &system_utsname, sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -289,19 +289,19 @@ int sys_olduname(struct oldold_utsname __user *name) return -EFAULT; down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, + error = __copy_to_user(&name->sysname, &system_utsname.sysname, __OLD_UTS_LEN); error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, + error |= __copy_to_user(&name->nodename, &system_utsname.nodename, __OLD_UTS_LEN); error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, + error |= __copy_to_user(&name->release, &system_utsname.release, __OLD_UTS_LEN); error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, + error |= __copy_to_user(&name->version, &system_utsname.version, __OLD_UTS_LEN); error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, + error |= __copy_to_user(&name->machine, &system_utsname.machine, __OLD_UTS_LEN); error |= override_machine(name->machine); up_read(&uts_sem); diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 8b278d85ca4e..71f71da98e7d 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -117,6 +117,8 @@ unsigned tb_to_ns_shift; struct gettimeofday_struct do_gtod; +extern unsigned long wall_jiffies; + extern struct timezone sys_tz; static long timezone_offset; @@ -814,6 +816,11 @@ int do_settimeofday(struct timespec *tv) /* * Subtract off the number of nanoseconds since the * beginning of the last tick. + * Note that since we don't increment jiffies_64 anywhere other + * than in do_timer (since we don't have a lost tick problem), + * wall_jiffies will always be the same as jiffies, + * and therefore the (jiffies - wall_jiffies) computation + * has been removed. */ tb_delta = tb_ticks_since(tb_last_jiffy); tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index 1983b640bac1..1a2c2a50f922 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg, */ static int shutdown(void) { - int rc = kill_cad_pid(SIGINT, 1); + int rc = kill_proc(1, SIGINT, 1); if (rc) { printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), " diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index 9d22361a26d6..d30466d74194 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -104,7 +104,7 @@ static void g5_smu_switch_volt(int speed_mode) { struct smu_simple_cmd cmd; - DECLARE_COMPLETION_ONSTACK(comp); + DECLARE_COMPLETION(comp); smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete, &comp, 'V', 'S', 'L', 'E', 'W', 0xff, g5_fvt_cur+1, speed_mode); diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index 692945c14919..6a36ea9bf673 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -195,7 +195,7 @@ static void pmu_nvram_complete(struct adb_request *req) static unsigned char pmu_nvram_read_byte(int addr) { struct adb_request req; - DECLARE_COMPLETION_ONSTACK(req_complete); + DECLARE_COMPLETION(req_complete); req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM, @@ -211,7 +211,7 @@ static unsigned char pmu_nvram_read_byte(int addr) static void pmu_nvram_write_byte(int addr, unsigned char val) { struct adb_request req; - DECLARE_COMPLETION_ONSTACK(req_complete); + DECLARE_COMPLETION(req_complete); req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM, diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 4f0097f31bdb..a6398fbe530d 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -342,7 +342,7 @@ static int __init pSeries_init_panel(void) { /* Manually leave the kernel version on the panel. */ ppc_md.progress("Linux ppc64\n", 0); - ppc_md.progress(init_utsname()->version, 0); + ppc_md.progress(system_utsname.release, 0); return 0; } diff --git a/trunk/arch/ppc/4xx_io/serial_sicc.c b/trunk/arch/ppc/4xx_io/serial_sicc.c index 87fe9a89dba7..b81a367dc278 100644 --- a/trunk/arch/ppc/4xx_io/serial_sicc.c +++ b/trunk/arch/ppc/4xx_io/serial_sicc.c @@ -1720,7 +1720,7 @@ static int siccuart_open(struct tty_struct *tty, struct file *filp) return 0; } -static const struct tty_operations sicc_ops = { +static struct tty_operations sicc_ops = { .open = siccuart_open, .close = siccuart_close, .write = siccuart_write, diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S index 5f6684012ded..50b4bbd06804 100644 --- a/trunk/arch/ppc/kernel/misc.S +++ b/trunk/arch/ppc/kernel/misc.S @@ -942,16 +942,20 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr -_GLOBAL(kernel_execve) - li r0,__NR_execve - sc - bnslr - neg r3,r3 - blr - /* * This routine is just here to keep GCC happy - sigh... */ _GLOBAL(__main) blr +#define SYSCALL(name) \ +_GLOBAL(name) \ + li r0,__NR_##name; \ + sc; \ + bnslr; \ + lis r4,errno@ha; \ + stw r3,errno@l(r4); \ + li r3,-1; \ + blr + +SYSCALL(execve) diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 75fe13815be2..5458ac5da7c3 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -86,6 +86,10 @@ int ppc_do_canonicalize_irqs; EXPORT_SYMBOL(ppc_do_canonicalize_irqs); #endif +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY = 0x54; +#endif /* CONFIG_MAGIC_SYSRQ */ + #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; #endif diff --git a/trunk/arch/ppc/kernel/time.c b/trunk/arch/ppc/kernel/time.c index 187388625a76..1e1f31554767 100644 --- a/trunk/arch/ppc/kernel/time.c +++ b/trunk/arch/ppc/kernel/time.c @@ -80,6 +80,8 @@ unsigned tb_to_us; unsigned tb_last_stamp; unsigned long tb_to_ns_scale; +extern unsigned long wall_jiffies; + /* used for timezone offset */ static long timezone_offset; @@ -171,7 +173,8 @@ void timer_interrupt(struct pt_regs * regs) */ if ( ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ) { + abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else @@ -197,7 +200,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned delta, usec, sec; + unsigned delta, lost_ticks, usec, sec; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -211,9 +214,10 @@ void do_gettimeofday(struct timeval *tv) if (!smp_tb_synchronized) delta = 0; #endif /* CONFIG_SMP */ + lost_ticks = jiffies - wall_jiffies; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - usec += mulhwu(tb_to_us, delta); + usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta); while (usec >= 1000000) { sec++; usec -= 1000000; @@ -254,6 +258,7 @@ int do_settimeofday(struct timespec *tv) * still reasonable when gettimeofday resolution is 1 jiffy. */ tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id())); + tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta); diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index cd702ae45d6d..813fc21358f9 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -134,20 +134,12 @@ static int hypfs_open(struct inode *inode, struct file *filp) return 0; } -static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t offset) +static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf, + size_t count, loff_t offset) { char *data; size_t len; struct file *filp = iocb->ki_filp; - /* XXX: temporary */ - char __user *buf = iov[0].iov_base; - size_t count = iov[0].iov_len; - - if (nr_segs != 1) { - count = -EINVAL; - goto out; - } data = filp->private_data; len = strlen(data); @@ -166,13 +158,12 @@ static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, out: return count; } -static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t offset) +static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf, + size_t count, loff_t pos) { int rc; struct super_block *sb; struct hypfs_sb_info *fs_info; - size_t count = iov_length(iov, nr_segs); sb = iocb->ki_filp->f_dentry->d_inode->i_sb; fs_info = sb->s_fs_info; diff --git a/trunk/arch/s390/kernel/compat_linux.c b/trunk/arch/s390/kernel/compat_linux.c index e15e1489aef5..c46e3d48e410 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -357,16 +357,11 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { - compat_ino_t ino; int err; if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) return -EOVERFLOW; - ino = stat->ino; - if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) - return -EOVERFLOW; - err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); err |= put_user(stat->ino, &statbuf->st_ino); err |= put_user(stat->mode, &statbuf->st_mode); diff --git a/trunk/arch/s390/kernel/head31.S b/trunk/arch/s390/kernel/head31.S index 1b952a3664e2..1fa9fa1ca740 100644 --- a/trunk/arch/s390/kernel/head31.S +++ b/trunk/arch/s390/kernel/head31.S @@ -254,16 +254,6 @@ startup_continue: oi 3(%r12),0x80 # set IDTE flag .Lchkidte: -# -# find out if the diag 0x9c is available -# - mvc __LC_PGM_NEW_PSW(8),.Lpcdiag9c-.LPG1(%r13) - stap __LC_CPUID+4 # store cpu address - lh %r1,__LC_CPUID+4 - diag %r1,0,0x9c # test diag 0x9c - oi 2(%r12),1 # set diag9c flag -.Lchkdiag9c: - lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, # virtual and never return ... .align 8 @@ -291,7 +281,6 @@ startup_continue: .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte -.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c .Lmemsize:.long memory_size .Lmchunk:.long memory_chunk .Lmflags:.long machine_flags diff --git a/trunk/arch/s390/kernel/head64.S b/trunk/arch/s390/kernel/head64.S index b30e5897cdf7..48998d50b00a 100644 --- a/trunk/arch/s390/kernel/head64.S +++ b/trunk/arch/s390/kernel/head64.S @@ -250,17 +250,6 @@ startup_continue: oi 7(%r12),0x80 # set IDTE flag 0: -# -# find out if the diag 0x9c is available -# - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - stap __LC_CPUID+4 # store cpu address - lh %r1,__LC_CPUID+4 - diag %r1,0,0x9c # test diag 0x9c - oi 6(%r12),1 # set diag9c flag -0: - # # find out if we have the MVCOS instruction # diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index 4d9ff5ce4cbd..ca28fb0b3790 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -369,12 +369,11 @@ void __kprobes kretprobe_trampoline_holder(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; + struct hlist_head *head; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -400,7 +399,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) { /* @@ -418,10 +417,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/trunk/arch/s390/kernel/sys_s390.c b/trunk/arch/s390/kernel/sys_s390.c index 584ed95f3380..e351780bb660 100644 --- a/trunk/arch/s390/kernel/sys_s390.c +++ b/trunk/arch/s390/kernel/sys_s390.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -267,22 +266,3 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register const char *__arg1 asm("2") = filename; - register char *const*__arg2 asm("3") = argv; - register char *const*__arg3 asm("4") = envp; - register long __svcres asm("2"); - asm volatile( - "svc %b1" - : "=d" (__svcres) - : "i" (__NR_execve), - "0" (__arg1), - "d" (__arg2), - "d" (__arg3) : "memory"); - return __svcres; -} diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index 4bf66cc4a267..abab42e9f5f8 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -53,6 +53,8 @@ static u64 init_timer_cc; static u64 jiffies_timer_cc; static u64 xtime_cc; +extern unsigned long wall_jiffies; + /* * Scheduler clock - returns current time in nanosec units. */ @@ -85,8 +87,9 @@ static inline unsigned long do_gettimeoffset(void) { __u64 now; - now = (get_clock() - jiffies_timer_cc) >> 12; - now -= (__u64) jiffies * USECS_PER_JIFFY; + now = (get_clock() - jiffies_timer_cc) >> 12; + /* We require the offset from the latest update of xtime */ + now -= (__u64) wall_jiffies*USECS_PER_JIFFY; return (unsigned long) now; } diff --git a/trunk/arch/s390/lib/spinlock.c b/trunk/arch/s390/lib/spinlock.c index 8d76403fcf89..b9b7958a226a 100644 --- a/trunk/arch/s390/lib/spinlock.c +++ b/trunk/arch/s390/lib/spinlock.c @@ -24,76 +24,57 @@ static int __init spin_retry_setup(char *str) } __setup("spin_retry=", spin_retry_setup); -static inline void _raw_yield(void) +static inline void +_diag44(void) { +#ifdef CONFIG_64BIT if (MACHINE_HAS_DIAG44) +#endif asm volatile("diag 0,0,0x44"); } -static inline void _raw_yield_cpu(int cpu) -{ - if (MACHINE_HAS_DIAG9C) - asm volatile("diag %0,0,0x9c" - : : "d" (__cpu_logical_map[cpu])); - else - _raw_yield(); -} - -void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) +void +_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) { int count = spin_retry; - unsigned int cpu = ~smp_processor_id(); while (1) { if (count-- <= 0) { - unsigned int owner = lp->owner_cpu; - if (owner != 0) - _raw_yield_cpu(~owner); + _diag44(); count = spin_retry; } if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { - lp->owner_pc = pc; + if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) return; - } } } EXPORT_SYMBOL(_raw_spin_lock_wait); -int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) +int +_raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) { - unsigned int cpu = ~smp_processor_id(); - int count; + int count = spin_retry; - for (count = spin_retry; count > 0; count--) { + while (count-- > 0) { if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { - lp->owner_pc = pc; + if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) return 1; - } } return 0; } EXPORT_SYMBOL(_raw_spin_trylock_retry); -void _raw_spin_relax(raw_spinlock_t *lock) -{ - unsigned int cpu = lock->owner_cpu; - if (cpu != 0) - _raw_yield_cpu(~cpu); -} -EXPORT_SYMBOL(_raw_spin_relax); - -void _raw_read_lock_wait(raw_rwlock_t *rw) +void +_raw_read_lock_wait(raw_rwlock_t *rw) { unsigned int old; int count = spin_retry; while (1) { if (count-- <= 0) { - _raw_yield(); + _diag44(); count = spin_retry; } if (!__raw_read_can_lock(rw)) @@ -105,7 +86,8 @@ void _raw_read_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_lock_wait); -int _raw_read_trylock_retry(raw_rwlock_t *rw) +int +_raw_read_trylock_retry(raw_rwlock_t *rw) { unsigned int old; int count = spin_retry; @@ -121,13 +103,14 @@ int _raw_read_trylock_retry(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_trylock_retry); -void _raw_write_lock_wait(raw_rwlock_t *rw) +void +_raw_write_lock_wait(raw_rwlock_t *rw) { int count = spin_retry; while (1) { if (count-- <= 0) { - _raw_yield(); + _diag44(); count = spin_retry; } if (!__raw_write_can_lock(rw)) @@ -138,7 +121,8 @@ void _raw_write_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_write_lock_wait); -int _raw_write_trylock_retry(raw_rwlock_t *rw) +int +_raw_write_trylock_retry(raw_rwlock_t *rw) { int count = spin_retry; diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 77491cf9b259..5f587332234a 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -459,7 +459,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "machine\t\t: %s\n", get_system_type()); seq_printf(m, "processor\t: %d\n", cpu); - seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); + seq_printf(m, "cpu family\t: %s\n", system_utsname.machine); seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); show_cpuflags(m); diff --git a/trunk/arch/sh/kernel/smp.c b/trunk/arch/sh/kernel/smp.c index dbebaddcfe39..6c0fb7c4af11 100644 --- a/trunk/arch/sh/kernel/smp.c +++ b/trunk/arch/sh/kernel/smp.c @@ -42,7 +42,6 @@ cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; -EXPORT_SYMBOL(cpu_online_map); static atomic_t cpus_booted = ATOMIC_INIT(0); /* These are defined by the board-specific code. */ diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c index 8fde95001c34..b68ff705f067 100644 --- a/trunk/arch/sh/kernel/sys_sh.c +++ b/trunk/arch/sh/kernel/sys_sh.c @@ -25,7 +25,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -282,7 +281,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -310,19 +309,3 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, (u64)len0 << 32 | len1, advice); #endif } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __sc0 __asm__ ("r3") = __NR_execve; - register long __sc4 __asm__ ("r4") = (long) filename; - register long __sc5 __asm__ ("r5") = (long) argv; - register long __sc6 __asm__ ("r6") = (long) envp; - __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0) - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) - : "memory"); - return __sc0; -} diff --git a/trunk/arch/sh/kernel/time.c b/trunk/arch/sh/kernel/time.c index 450c68f1df05..f664a196c4f5 100644 --- a/trunk/arch/sh/kernel/time.c +++ b/trunk/arch/sh/kernel/time.c @@ -18,6 +18,7 @@ #include #include +extern unsigned long wall_jiffies; struct sys_timer *sys_timer; /* Move this somewhere more sensible.. */ @@ -51,10 +52,16 @@ void do_gettimeofday(struct timeval *tv) { unsigned long seq; unsigned long usec, sec; + unsigned long lost; do { seq = read_seqbegin(&xtime_lock); usec = get_timer_offset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry(&xtime_lock, seq)); @@ -84,7 +91,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * get_timer_offset(); + nsec -= 1000 * (get_timer_offset() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/sh64/kernel/process.c b/trunk/arch/sh64/kernel/process.c index 525d0ec19b78..db475b7833fb 100644 --- a/trunk/arch/sh64/kernel/process.c +++ b/trunk/arch/sh64/kernel/process.c @@ -20,16 +20,261 @@ /* * This file handles the architecture-dependent parts of process handling.. */ + +/* Temporary flags/tests. All to be removed/undefined. BEGIN */ +#define IDLE_TRACE +#define VM_SHOW_TABLES +#define VM_TEST_FAULT +#define VM_TEST_RTLBMISS +#define VM_TEST_WTLBMISS + +#undef VM_SHOW_TABLES +#undef IDLE_TRACE +/* Temporary flags/tests. All to be removed/undefined. END */ + +#define __KERNEL_SYSCALLS__ +#include + +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include + #include #include +#include +#include +#include /* includes also */ +#include +#include +#include + +#include struct task_struct *last_task_used_math = NULL; +#ifdef IDLE_TRACE +#ifdef VM_SHOW_TABLES +/* For testing */ +static void print_PTE(long base) +{ + int i, skip=0; + long long x, y, *p = (long long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + x = (*p) >> 32; + y = (*p) & 0xffffffff; + printk("%08Lx%08Lx ", x, y); + if (!((i+1)&0x3)) printk("\n"); + } + } +} + +/* For testing */ +static void print_DIR(long base) +{ + int i, skip=0; + long *p = (long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + printk("%08lx ", *p); + if (!((i+1)&0x7)) printk("\n"); + } + } +} + +/* For testing */ +static void print_vmalloc_first_tables(void) +{ + +#define PRESENT 0x800 /* Bit 11 */ + + /* + * Do it really dirty by looking at raw addresses, + * raw offsets, no types. If we used pgtable/pgalloc + * macros/definitions we could hide potential bugs. + * + * Note that pointers are 32-bit for CDC. + */ + long pgdt, pmdt, ptet; + + pgdt = (long) &swapper_pg_dir; + printk("-->PGD (0x%08lx):\n", pgdt); + print_DIR(pgdt); + printk("\n"); + + /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */ + pgdt += 4; + pmdt = (long) (* (long *) pgdt); + if (!(pmdt & PRESENT)) { + printk("No PMD\n"); + return; + } else pmdt &= 0xfffff000; + + printk("-->PMD (0x%08lx):\n", pmdt); + print_DIR(pmdt); + printk("\n"); + + /* Get the pmdt displacement for 0xc0000000 */ + pmdt += 2048; + + /* just look at first two address ranges ... */ + /* ... 0xc0000000 ... */ + ptet = (long) (* (long *) pmdt); + if (!(ptet & PRESENT)) { + printk("No PTE0\n"); + return; + } else ptet &= 0xfffff000; + + printk("-->PTE0 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); + + /* ... 0xc0001000 ... */ + ptet += 4; + if (!(ptet & PRESENT)) { + printk("No PTE1\n"); + return; + } else ptet &= 0xfffff000; + printk("-->PTE1 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); +} +#else +#define print_vmalloc_first_tables() +#endif /* VM_SHOW_TABLES */ + +static void test_VM(void) +{ + void *a, *b, *c; + +#ifdef VM_SHOW_TABLES + printk("Initial PGD/PMD/PTE\n"); +#endif + print_vmalloc_first_tables(); + + printk("Allocating 2 bytes\n"); + a = vmalloc(2); + print_vmalloc_first_tables(); + + printk("Allocating 4100 bytes\n"); + b = vmalloc(4100); + print_vmalloc_first_tables(); + + printk("Allocating 20234 bytes\n"); + c = vmalloc(20234); + print_vmalloc_first_tables(); + +#ifdef VM_TEST_FAULT + /* Here you may want to fault ! */ + +#ifdef VM_TEST_RTLBMISS + printk("Ready to fault upon read.\n"); + if (* (char *) a) { + printk("RTLBMISSed on area a !\n"); + } + printk("RTLBMISSed on area a !\n"); +#endif + +#ifdef VM_TEST_WTLBMISS + printk("Ready to fault upon write.\n"); + *((char *) b) = 'L'; + printk("WTLBMISSed on area b !\n"); +#endif + +#endif /* VM_TEST_FAULT */ + + printk("Deallocating the 4100 byte chunk\n"); + vfree(b); + print_vmalloc_first_tables(); + + printk("Deallocating the 2 byte chunk\n"); + vfree(a); + print_vmalloc_first_tables(); + + printk("Deallocating the last chunk\n"); + vfree(c); + print_vmalloc_first_tables(); +} + +extern unsigned long volatile jiffies; +int once = 0; +unsigned long old_jiffies; +int pid = -1, pgid = -1; + +void idle_trace(void) +{ + + _syscall0(int, getpid) + _syscall1(int, getpgid, int, pid) + + if (!once) { + /* VM allocation/deallocation simple test */ + test_VM(); + pid = getpid(); + + printk("Got all through to Idle !!\n"); + printk("I'm now going to loop forever ...\n"); + printk("Any ! below is a timer tick.\n"); + printk("Any . below is a getpgid system call from pid = %d.\n", pid); + + + old_jiffies = jiffies; + once++; + } + + if (old_jiffies != jiffies) { + old_jiffies = jiffies - old_jiffies; + switch (old_jiffies) { + case 1: + printk("!"); + break; + case 2: + printk("!!"); + break; + case 3: + printk("!!!"); + break; + case 4: + printk("!!!!"); + break; + default: + printk("(%d!)", (int) old_jiffies); + } + old_jiffies = jiffies; + } + pgid = getpgid(pid); + printk("."); +} +#else +#define idle_trace() do { } while (0) +#endif /* IDLE_TRACE */ + static int hlt_counter = 1; #define HARD_IDLE_TIMEOUT (HZ / 3) @@ -78,6 +323,7 @@ void cpu_idle(void) local_irq_disable(); while (!need_resched()) { local_irq_enable(); + idle_trace(); hlt(); local_irq_disable(); } @@ -376,10 +622,6 @@ void free_task_struct(struct task_struct *p) /* * Create a kernel thread */ -ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) -{ - do_exit(fn(arg)); -} /* * This is the mechanism for creating a new kernel thread. @@ -391,17 +633,19 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - struct pt_regs regs; + /* A bit less processor dependent than older sh ... */ + unsigned int reply; - memset(®s, 0, sizeof(regs)); - regs.regs[2] = (unsigned long)arg; - regs.regs[3] = (unsigned long)fn; +static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) +static __inline__ _syscall1(int,exit,int,ret) - regs.pc = (unsigned long)kernel_thread_helper; - regs.sr = (1 << 30); + reply = clone(flags | CLONE_VM, 0); + if (!reply) { + /* Child */ + reply = exit(fn(arg)); + } - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, - ®s, 0, NULL, NULL); + return reply; } /* diff --git a/trunk/arch/sh64/kernel/sys_sh64.c b/trunk/arch/sh64/kernel/sys_sh64.c index ad0fa4e003e7..58ff7d522d81 100644 --- a/trunk/arch/sh64/kernel/sys_sh64.c +++ b/trunk/arch/sh64/kernel/sys_sh64.c @@ -32,7 +32,6 @@ #include #include #include -#include #define REG_3 3 @@ -280,25 +279,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); - register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; - register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv; - register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp; - __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)" - : "=r" (__sc0) - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); - __asm__ __volatile__ ("!dummy %0 %1 %2 %3" - : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory"); - return __sc0; -} diff --git a/trunk/arch/sh64/kernel/time.c b/trunk/arch/sh64/kernel/time.c index 9c4a38a8698c..3b61e06f9d72 100644 --- a/trunk/arch/sh64/kernel/time.c +++ b/trunk/arch/sh64/kernel/time.c @@ -107,6 +107,8 @@ #define TICK_SIZE (tick_nsec / 1000) +extern unsigned long wall_jiffies; + static unsigned long tmu_base, rtc_base; unsigned long cprc_base; @@ -192,6 +194,13 @@ void do_gettimeofday(struct timeval *tv) do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = usecs_since_tick(); + { + unsigned long lost = jiffies - wall_jiffies; + + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -220,7 +229,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * usecs_since_tick(); + nsec -= 1000 * (usecs_since_tick() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index edb6cc665f56..e19b1bad9bc5 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -765,6 +765,8 @@ static __inline__ unsigned long do_gettimeoffset(void) return count; } +extern unsigned long wall_jiffies; + static void pci_do_gettimeofday(struct timeval *tv) { unsigned long flags; @@ -773,17 +775,26 @@ static void pci_do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -808,7 +819,8 @@ static int pci_do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - tv->tv_nsec -= 1000 * do_gettimeoffset(); + tv->tv_nsec -= 1000 * (do_gettimeoffset() + + (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c index a954a0c00000..896863fb208a 100644 --- a/trunk/arch/sparc/kernel/sys_sparc.c +++ b/trunk/arch/sparc/kernel/sys_sparc.c @@ -24,7 +24,6 @@ #include #include -#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -476,38 +475,16 @@ asmlinkage int sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, utsname()->domainname, nlen)) + if (!copy_to_user(name, system_utsname.domainname, nlen)) err = 0; out: up_read(&uts_sem); return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - register long __g1 __asm__ ("g1") = __NR_execve; - register long __o0 __asm__ ("o0") = (long)(filename); - register long __o1 __asm__ ("o1") = (long)(argv); - register long __o2 __asm__ ("o2") = (long)(envp); - asm volatile ("t 0x10\n\t" - "bcc 1f\n\t" - "mov %%o0, %0\n\t" - "sub %%g0, %%o0, %0\n\t" - "1:\n\t" - : "=r" (__res), "=&r" (__o0) - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) - : "cc"); - return __res; -} diff --git a/trunk/arch/sparc/kernel/sys_sunos.c b/trunk/arch/sparc/kernel/sys_sunos.c index 6f3ac548ee66..aa0fb2efb615 100644 --- a/trunk/arch/sparc/kernel/sys_sunos.c +++ b/trunk/arch/sparc/kernel/sys_sunos.c @@ -325,25 +325,21 @@ struct sunos_dirent_callback { #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int sunos_filldir(void * __buf, const char * name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) + loff_t offset, ino_t ino, unsigned int d_type) { struct sunos_dirent __user *dirent; struct sunos_dirent_callback * buf = __buf; - unsigned long d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; if (dirent) put_user(offset, &dirent->d_off); dirent = buf->curr; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); @@ -410,23 +406,19 @@ struct sunos_direntry_callback { }; static int sunos_filldirentry(void * __buf, const char * name, int namlen, - loff_t offset, u64 ino, unsigned int d_type) + loff_t offset, ino_t ino, unsigned int d_type) { struct sunos_direntry __user *dirent; struct sunos_direntry_callback *buf = __buf; - unsigned long d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; dirent = buf->curr; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); @@ -491,18 +483,13 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], - sizeof(name->sname) - 1); + ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); if (!ret) { - ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0], - sizeof(name->nname) - 1); + ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= __put_user('\0', &name->nname[8]); - ret |= __copy_to_user(&name->rel[0], &utsname()->release[0], - sizeof(name->rel) - 1); - ret |= __copy_to_user(&name->ver[0], &utsname()->version[0], - sizeof(name->ver) - 1); - ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0], - sizeof(name->mach) - 1); + ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); + ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); + ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); } up_read(&uts_sem); return ret ? -EFAULT : 0; diff --git a/trunk/arch/sparc/kernel/time.c b/trunk/arch/sparc/kernel/time.c index e10dc831944d..6f84fa1b58e5 100644 --- a/trunk/arch/sparc/kernel/time.c +++ b/trunk/arch/sparc/kernel/time.c @@ -43,6 +43,8 @@ #include #include +extern unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); enum sparc_clock_type sp_clock_typ; DEFINE_SPINLOCK(mostek_lock); @@ -447,7 +449,7 @@ unsigned long long sched_clock(void) /* Ok, my cute asm atomicity trick doesn't work anymore. * There are just too many variables that need to be protected - * now (both members of xtime, et al.) + * now (both members of xtime, wall_jiffies, et al.) */ void do_gettimeofday(struct timeval *tv) { @@ -457,17 +459,26 @@ void do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -510,7 +521,8 @@ static int sbus_do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * do_gettimeoffset(); + nsec -= 1000 * (do_gettimeoffset() + + (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index b627f8dbcaad..8d8ca716f7a7 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -420,7 +420,7 @@ source "arch/sparc64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 0b9c70627ce4..e55466c77b61 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -4,6 +4,8 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#define __KERNEL_SYSCALLS__ + #include #include #include @@ -12,7 +14,6 @@ #include #include #include -#include #include #include @@ -97,7 +98,7 @@ static int powerd(void *__unused) /* Ok, down we go... */ button_pressed = 0; - if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { + if (execve("/sbin/shutdown", argv, envp) < 0) { printk("powerd: shutdown execution failed\n"); add_wait_queue(&powerd_wait, &wait); goto again; diff --git a/trunk/arch/sparc64/kernel/sys_sparc.c b/trunk/arch/sparc64/kernel/sys_sparc.c index a53d4abb4b49..c608c947e6c3 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc.c +++ b/trunk/arch/sparc64/kernel/sys_sparc.c @@ -31,7 +31,6 @@ #include #include #include -#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -713,13 +712,13 @@ asmlinkage long sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, utsname()->domainname, nlen)) + if (!copy_to_user(name, system_utsname.domainname, nlen)) err = 0; out: @@ -964,23 +963,3 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, }; return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - register long __g1 __asm__ ("g1") = __NR_execve; - register long __o0 __asm__ ("o0") = (long)(filename); - register long __o1 __asm__ ("o1") = (long)(argv); - register long __o2 __asm__ ("o2") = (long)(envp); - asm volatile ("t 0x6d\n\t" - "sub %%g0, %%o0, %0\n\t" - "movcc %%xcc, %%o0, %0\n\t" - : "=r" (__res), "=&r" (__o0) - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) - : "cc"); - return __res; -} diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index dbc6d1a3be1f..69444f266e2d 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -337,17 +337,12 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { - compat_ino_t ino; int err; if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) return -EOVERFLOW; - ino = stat->ino; - if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) - return -EOVERFLOW; - err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); err |= put_user(stat->ino, &statbuf->st_ino); err |= put_user(stat->mode, &statbuf->st_mode); diff --git a/trunk/arch/sparc64/kernel/sys_sunos32.c b/trunk/arch/sparc64/kernel/sys_sunos32.c index e414c8ef0225..87ebdf858a3a 100644 --- a/trunk/arch/sparc64/kernel/sys_sunos32.c +++ b/trunk/arch/sparc64/kernel/sys_sunos32.c @@ -280,20 +280,16 @@ static int sunos_filldir(void * __buf, const char * name, int namlen, struct sunos_dirent __user *dirent; struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); - u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; if (dirent) put_user(offset, &dirent->d_off); dirent = buf->curr; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); if (copy_to_user(dirent->d_name, name, namlen)) @@ -367,18 +363,14 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen, struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); - u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; - d_ino = ino; - if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) - return -EOVERFLOW; dirent = buf->previous; dirent = buf->curr; buf->previous = dirent; - put_user(d_ino, &dirent->d_ino); + put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); if (copy_to_user(dirent->d_name, name, namlen)) @@ -447,16 +439,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], + ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); - ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], + ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); - ret |= copy_to_user(&name->rel[0], &utsname()->release[0], + ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); - ret |= copy_to_user(&name->ver[0], &utsname()->version[0], + ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); - ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], + ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); up_read(&uts_sem); return (ret ? -EFAULT : 0); diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index 00f6fc4aaaff..ca1193482f07 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -53,6 +53,8 @@ void __iomem *mstk48t02_regs = NULL; unsigned long ds1287_regs = 0UL; #endif +extern unsigned long wall_jiffies; + static void __iomem *mstk48t08_regs; static void __iomem *mstk48t59_regs; diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c index 12a940cc791f..0f0eb6aa1c40 100644 --- a/trunk/arch/sparc64/solaris/fs.c +++ b/trunk/arch/sparc64/solaris/fs.c @@ -82,17 +82,12 @@ struct sol_stat64 { static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) { - u32 ino; - if (kbuf->size > MAX_NON_LFS || !sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev)) return -EOVERFLOW; - ino = kbuf->ino; - if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) - return -EOVERFLOW; if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || - __put_user (ino, &ubuf->st_ino) || + __put_user (kbuf->ino, &ubuf->st_ino) || __put_user (kbuf->mode, &ubuf->st_mode) || __put_user (kbuf->nlink, &ubuf->st_nlink) || __put_user (kbuf->uid, &ubuf->st_uid) || diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index 9ed997982f8d..9c581328e76a 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -249,7 +249,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) /* Let's cheat */ err = set_utsfield(v->sysname, "SunOS", 1, 0); down_read(&uts_sem); - err |= set_utsfield(v->nodename, utsname()->nodename, + err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1); up_read(&uts_sem); err |= set_utsfield(v->release, "2.6", 0, 0); @@ -273,7 +273,7 @@ asmlinkage int solaris_utsname(u32 buf) /* Why should we not lie a bit? */ down_read(&uts_sem); err = set_utsfield(v->sysname, "SunOS", 0, 0); - err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); + err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1); err |= set_utsfield(v->release, "5.6", 0, 0); err |= set_utsfield(v->version, "Generic", 0, 0); err |= set_utsfield(v->machine, machine(), 0, 0); @@ -305,7 +305,7 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) case SI_HOSTNAME: r = buffer + 256; down_read(&uts_sem); - for (p = utsname()->nodename, q = buffer; + for (p = system_utsname.nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); up_read(&uts_sem); *q = 0; diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 24747a413785..563ce7690a1e 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -642,9 +642,9 @@ int line_remove(struct line *lines, unsigned int num, int n) } struct tty_driver *line_register_devfs(struct lines *set, - struct line_driver *line_driver, - const struct tty_operations *ops, - struct line *lines, int nlines) + struct line_driver *line_driver, + struct tty_operations *ops, struct line *lines, + int nlines) { int i; struct tty_driver *driver = alloc_tty_driver(nlines); diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index a67dcbd78de4..773a134e7fdb 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req) { char version[256]; - sprintf(version, "%s %s %s %s %s", utsname()->sysname, - utsname()->nodename, utsname()->release, - utsname()->version, utsname()->machine); + sprintf(version, "%s %s %s %s %s", system_utsname.sysname, + system_utsname.nodename, system_utsname.release, + system_utsname.version, system_utsname.machine); mconsole_reply(req, version, 0, 0); } diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index fda4a3940698..5fa4c8e258a4 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -981,6 +981,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) __u64 offset; int len; + if(req->rq_status == RQ_INACTIVE) return(1); + /* This should be impossible now */ if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ printk("Write attempted on readonly ubd device %s\n", diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 7be24811bb30..642c9a0320f9 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -91,9 +91,10 @@ extern int line_setup_irq(int fd, int input, int output, struct line *line, void *data); extern void line_close_chan(struct line *line); extern struct tty_driver * line_register_devfs(struct lines *set, - struct line_driver *line_driver, - const struct tty_operations *driver, - struct line *lines, int nlines); + struct line_driver *line_driver, + struct tty_operations *driver, + struct line *lines, + int nlines); extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); extern void close_lines(struct line *lines, int nlines); diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c index f5ed8624648b..48cf88dd02d4 100644 --- a/trunk/arch/um/kernel/syscall.c +++ b/trunk/arch/um/kernel/syscall.c @@ -110,7 +110,7 @@ long sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -126,21 +126,21 @@ long sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, + error = __copy_to_user(&name->sysname,&system_utsname.sysname, __OLD_UTS_LEN); - error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename, __OLD_UTS_LEN); - error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release, __OLD_UTS_LEN); - error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version, __OLD_UTS_LEN); - error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine, __OLD_UTS_LEN); - error |= __put_user(0, name->machine + __OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); up_read(&uts_sem); @@ -164,16 +164,3 @@ int next_syscall_index(int limit) spin_unlock(&syscall_lock); return(ret); } - -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - mm_segment_t fs; - int ret; - - fs = get_fs(); - set_fs(KERNEL_DS); - ret = um_execve(filename, argv, envp); - set_fs(fs); - - return ret; -} diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 97d88e7902f7..55005710dcbb 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -167,7 +167,7 @@ static char *usage_string = static int __init uml_version_setup(char *line, int *add) { - printf("%s\n", init_utsname()->release); + printf("%s\n", system_utsname.release); exit(0); return 0; @@ -278,7 +278,7 @@ static int __init Usage(char *line, int *add) { const char **p; - printf(usage_string, init_utsname()->release); + printf(usage_string, system_utsname.release); p = &__uml_help_start; while (p < &__uml_help_end) { printf("%s", *p); @@ -403,7 +403,7 @@ int linux_main(int argc, char **argv) /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); - setup_machinename(init_utsname()->machine); + setup_machinename(system_utsname.machine); #ifdef CONFIG_CMDLINE_ON_HOST argv1_begin = argv[1]; diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index 51f0893640a6..ff203625a4bd 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "ptrace_user.h" #include "os.h" #include "user.h" @@ -141,9 +140,11 @@ void os_usr1_process(int pid) * syscalls, and also breaks with clone(), which does not unshare the TLS. */ +inline _syscall0(pid_t, getpid) + int os_getpid(void) { - return(syscall(__NR_getpid)); + return(getpid()); } int os_getpgrp(void) diff --git a/trunk/arch/um/os-Linux/sys-i386/tls.c b/trunk/arch/um/os-Linux/sys-i386/tls.c index 6e945ab45843..120abbe4e3ce 100644 --- a/trunk/arch/um/os-Linux/sys-i386/tls.c +++ b/trunk/arch/um/os-Linux/sys-i386/tls.c @@ -1,9 +1,10 @@ #include #include -#include #include "sysdep/tls.h" #include "user_util.h" +static _syscall1(int, get_thread_area, user_desc_t *, u_info); + /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ @@ -16,7 +17,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) { user_desc_t info; info.entry_number = val[i]; - if (syscall(__NR_get_thread_area, &info) == 0) { + if (get_thread_area(&info) == 0) { *tls_min = val[i]; *supports_tls = 1; return; diff --git a/trunk/arch/um/os-Linux/tls.c b/trunk/arch/um/os-Linux/tls.c index a2de2580b8af..9cb09a45546b 100644 --- a/trunk/arch/um/os-Linux/tls.c +++ b/trunk/arch/um/os-Linux/tls.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "sysdep/tls.h" #include "uml-config.h" @@ -49,11 +48,14 @@ int os_get_thread_area(user_desc_t *info, int pid) #ifdef UML_CONFIG_MODE_TT #include "linux/unistd.h" +static _syscall1(int, get_thread_area, user_desc_t *, u_info); +static _syscall1(int, set_thread_area, user_desc_t *, u_info); + int do_set_thread_area_tt(user_desc_t *info) { int ret; - ret = syscall(__NR_set_thread_area,info); + ret = set_thread_area(info); if (ret < 0) { ret = -errno; } @@ -64,7 +66,7 @@ int do_get_thread_area_tt(user_desc_t *info) { int ret; - ret = syscall(__NR_get_thread_area,info); + ret = get_thread_area(info); if (ret < 0) { ret = -errno; } diff --git a/trunk/arch/um/sys-i386/unmap.c b/trunk/arch/um/sys-i386/unmap.c index 8e55cd5d3d07..1b0ad0e4adcd 100644 --- a/trunk/arch/um/sys-i386/unmap.c +++ b/trunk/arch/um/sys-i386/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ + if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/um/sys-x86_64/syscalls.c b/trunk/arch/um/sys-x86_64/syscalls.c index 73ce4463f70c..6fce9f45dfdc 100644 --- a/trunk/arch/um/sys-x86_64/syscalls.c +++ b/trunk/arch/um/sys-x86_64/syscalls.c @@ -21,7 +21,7 @@ asmlinkage long sys_uname64(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/trunk/arch/um/sys-x86_64/sysrq.c b/trunk/arch/um/sys-x86_64/sysrq.c index ce3e07fcf283..d0a25af19a5b 100644 --- a/trunk/arch/um/sys-x86_64/sysrq.c +++ b/trunk/arch/um/sys-x86_64/sysrq.c @@ -16,7 +16,7 @@ void __show_regs(struct pt_regs * regs) printk("\n"); print_modules(); printk("Pid: %d, comm: %.20s %s %s\n", - current->pid, current->comm, print_tainted(), init_utsname()->release); + current->pid, current->comm, print_tainted(), system_utsname.release); printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, PT_REGS_RIP(regs)); printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), diff --git a/trunk/arch/um/sys-x86_64/unmap.c b/trunk/arch/um/sys-x86_64/unmap.c index 57c9286a701b..f4a4bffd8a18 100644 --- a/trunk/arch/um/sys-x86_64/unmap.c +++ b/trunk/arch/um/sys-x86_64/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/v850/kernel/memcons.c b/trunk/arch/v850/kernel/memcons.c index 92f514fdcc79..491614c435cd 100644 --- a/trunk/arch/v850/kernel/memcons.c +++ b/trunk/arch/v850/kernel/memcons.c @@ -30,7 +30,7 @@ static DEFINE_SPINLOCK(memcons_lock); static size_t write (const char *buf, size_t len) { - unsigned long flags; + int flags; char *point; spin_lock_irqsave (memcons_lock, flags); @@ -104,7 +104,7 @@ int memcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static const struct tty_operations ops = { +static struct tty_operations ops = { .open = memcons_tty_open, .write = memcons_tty_write, .write_room = memcons_tty_write_room, diff --git a/trunk/arch/v850/kernel/rte_cb_leds.c b/trunk/arch/v850/kernel/rte_cb_leds.c index 996bd4f33ecb..f654088b2760 100644 --- a/trunk/arch/v850/kernel/rte_cb_leds.c +++ b/trunk/arch/v850/kernel/rte_cb_leds.c @@ -42,7 +42,7 @@ do { \ len = LED_NUM_DIGITS - pos; \ \ if (len > 0) { \ - unsigned long _flags; \ + int _flags; \ const char *_end = buf + len; \ img_decl = &leds_image[pos]; \ \ diff --git a/trunk/arch/v850/kernel/rte_mb_a_pci.c b/trunk/arch/v850/kernel/rte_mb_a_pci.c index 35213fa9f7d8..f36b778f1432 100644 --- a/trunk/arch/v850/kernel/rte_mb_a_pci.c +++ b/trunk/arch/v850/kernel/rte_mb_a_pci.c @@ -365,7 +365,7 @@ static DEFINE_SPINLOCK(mb_sram_lock); static void *alloc_mb_sram (size_t size) { struct mb_sram_free_area *prev, *fa; - unsigned long flags; + int flags; void *mem = 0; spin_lock_irqsave (mb_sram_lock, flags); @@ -406,7 +406,7 @@ static void *alloc_mb_sram (size_t size) static void free_mb_sram (void *mem, size_t size) { struct mb_sram_free_area *prev, *fa, *new_fa; - unsigned long flags; + int flags; void *end = mem + size; spin_lock_irqsave (mb_sram_lock, flags); @@ -517,7 +517,7 @@ static DEFINE_SPINLOCK(dma_mappings_lock); static struct dma_mapping *new_dma_mapping (size_t size) { - unsigned long flags; + int flags; struct dma_mapping *mapping; void *mb_sram_block = alloc_mb_sram (size); @@ -575,7 +575,7 @@ static struct dma_mapping *new_dma_mapping (size_t size) static struct dma_mapping *find_dma_mapping (void *mb_sram_addr) { - unsigned long flags; + int flags; struct dma_mapping *mapping; spin_lock_irqsave (dma_mappings_lock, flags); @@ -592,7 +592,7 @@ static struct dma_mapping *find_dma_mapping (void *mb_sram_addr) static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr) { - unsigned long flags; + int flags; struct dma_mapping *mapping, *prev; spin_lock_irqsave (dma_mappings_lock, flags); @@ -622,7 +622,7 @@ static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr) static inline void free_dma_mapping (struct dma_mapping *mapping) { - unsigned long flags; + int flags; free_mb_sram (mapping->mb_sram_addr, mapping->size); diff --git a/trunk/arch/v850/kernel/simcons.c b/trunk/arch/v850/kernel/simcons.c index 9973596ae304..3975aa02cef8 100644 --- a/trunk/arch/v850/kernel/simcons.c +++ b/trunk/arch/v850/kernel/simcons.c @@ -77,7 +77,7 @@ int simcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static const struct tty_operations ops = { +static struct tty_operations ops = { .open = simcons_tty_open, .write = simcons_tty_write, .write_room = simcons_tty_write_room, diff --git a/trunk/arch/v850/kernel/syscalls.c b/trunk/arch/v850/kernel/syscalls.c index d2b1fb19d243..2ec0700fc46b 100644 --- a/trunk/arch/v850/kernel/syscalls.c +++ b/trunk/arch/v850/kernel/syscalls.c @@ -33,7 +33,6 @@ #include #include #include -#include /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. @@ -195,22 +194,3 @@ unsigned long sys_mmap (unsigned long addr, size_t len, out: return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register char *__a __asm__ ("r6") = filename; - register void *__b __asm__ ("r7") = argv; - register void *__c __asm__ ("r8") = envp; - register unsigned long __syscall __asm__ ("r12") = __NR_execve; - register unsigned long __ret __asm__ ("r10"); - __asm__ __volatile__ ("trap 0" - : "=r" (__ret), "=r" (__syscall) - : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) - : "r1", "r5", "r11", "r13", "r14", - "r15", "r16", "r17", "r18", "r19"); - return __ret; -} diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 0a5d8e659aa4..32ae1378f35c 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -367,10 +367,6 @@ config ARCH_FLATMEM_ENABLE source "mm/Kconfig" -config MEMORY_HOTPLUG_RESERVE - def_bool y - depends on (MEMORY_HOTPLUG && DISCONTIGMEM) - config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y depends on NUMA @@ -690,7 +686,7 @@ source "arch/x86_64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 4844b543bed0..647610ecb580 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,12 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git7 -# Wed Sep 27 21:53:10 2006 +# Linux kernel version: 2.6.18-git5 +# Tue Sep 26 09:30:47 2006 # CONFIG_X86_64=y CONFIG_64BIT=y CONFIG_X86=y -CONFIG_ZONE_DMA32=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -180,7 +179,6 @@ CONFIG_GENERIC_PENDING_IRQ=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_SOFTWARE_SUSPEND=y CONFIG_PM_STD_PARTITION="" CONFIG_SUSPEND_SMP=y @@ -253,7 +251,6 @@ CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_MSI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -1461,7 +1458,6 @@ CONFIG_KPROBES=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y diff --git a/trunk/arch/x86_64/ia32/sys_ia32.c b/trunk/arch/x86_64/ia32/sys_ia32.c index c9bac3af29d6..f280d3665f4b 100644 --- a/trunk/arch/x86_64/ia32/sys_ia32.c +++ b/trunk/arch/x86_64/ia32/sys_ia32.c @@ -76,8 +76,6 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) { - compat_ino_t ino; - typeof(ubuf->st_uid) uid = 0; typeof(ubuf->st_gid) gid = 0; SET_UID(uid, kbuf->uid); @@ -86,12 +84,9 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) return -EOVERFLOW; if (kbuf->size >= 0x7fffffff) return -EOVERFLOW; - ino = kbuf->ino; - if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) - return -EOVERFLOW; if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || - __put_user (ino, &ubuf->st_ino) || + __put_user (kbuf->ino, &ubuf->st_ino) || __put_user (kbuf->mode, &ubuf->st_mode) || __put_user (kbuf->nlink, &ubuf->st_nlink) || __put_user (uid, &ubuf->st_uid) || @@ -789,36 +784,36 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name) if (!name) return -EFAULT; - if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); - - err = __copy_to_user(&name->sysname,&utsname()->sysname, + + err = __copy_to_user(&name->sysname,&system_utsname.sysname, __OLD_UTS_LEN); err |= __put_user(0,name->sysname+__OLD_UTS_LEN); - err |= __copy_to_user(&name->nodename,&utsname()->nodename, + err |= __copy_to_user(&name->nodename,&system_utsname.nodename, __OLD_UTS_LEN); err |= __put_user(0,name->nodename+__OLD_UTS_LEN); - err |= __copy_to_user(&name->release,&utsname()->release, + err |= __copy_to_user(&name->release,&system_utsname.release, __OLD_UTS_LEN); err |= __put_user(0,name->release+__OLD_UTS_LEN); - err |= __copy_to_user(&name->version,&utsname()->version, + err |= __copy_to_user(&name->version,&system_utsname.version, __OLD_UTS_LEN); err |= __put_user(0,name->version+__OLD_UTS_LEN); - { - char *arch = "x86_64"; - if (personality(current->personality) == PER_LINUX32) - arch = "i686"; + { + char *arch = "x86_64"; + if (personality(current->personality) == PER_LINUX32) + arch = "i686"; - err |= __copy_to_user(&name->machine, arch, strlen(arch)+1); - } - - up_read(&uts_sem); - - err = err ? -EFAULT : 0; - - return err; + err |= __copy_to_user(&name->machine,arch,strlen(arch)+1); + } + + up_read(&uts_sem); + + err = err ? -EFAULT : 0; + + return err; } long sys32_uname(struct old_utsname __user * name) @@ -827,7 +822,7 @@ long sys32_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 6472e321cad7..135ff25e6b44 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,11 @@ int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; +static struct resource lapic_resource = { + .name = "Local APIC", + .flags = IORESOURCE_MEM | IORESOURCE_BUSY, +}; + /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -585,6 +591,40 @@ static int __init detect_init_APIC (void) return 0; } +#ifdef CONFIG_X86_IO_APIC +static struct resource * __init ioapic_setup_resources(void) +{ +#define IOAPIC_RESOURCE_NAME_SIZE 11 + unsigned long n; + struct resource *res; + char *mem; + int i; + + if (nr_ioapics <= 0) + return NULL; + + n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); + n *= nr_ioapics; + + res = alloc_bootmem(n); + + if (!res) + return NULL; + + memset(res, 0, n); + mem = (void *)&res[nr_ioapics]; + + for (i = 0; i < nr_ioapics; i++) { + res[i].name = mem; + res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; + snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); + mem += IOAPIC_RESOURCE_NAME_SIZE; + } + + return res; +} +#endif + void __init init_apic_mappings(void) { unsigned long apic_phys; @@ -604,6 +644,11 @@ void __init init_apic_mappings(void) apic_mapped = 1; apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); + /* Put local APIC into the resource map. */ + lapic_resource.start = apic_phys; + lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; + insert_resource(&iomem_resource, &lapic_resource); + /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). @@ -613,7 +658,9 @@ void __init init_apic_mappings(void) { unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; int i; + struct resource *ioapic_res; + ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; @@ -625,6 +672,13 @@ void __init init_apic_mappings(void) apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", __fix_to_virt(idx), ioapic_phys); idx++; + + if (ioapic_res) { + ioapic_res->start = ioapic_phys; + ioapic_res->end = ioapic_phys + (4 * 1024) - 1; + insert_resource(&iomem_resource, ioapic_res); + ioapic_res++; + } } } } diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index b8285cf1a9c3..2802524104f3 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -1023,7 +1023,7 @@ ENDPROC(child_rip) * do_sys_execve asm fallback arguments: * rdi: name, rsi: argv, rdx: envp, fake frame on the stack */ -ENTRY(kernel_execve) +ENTRY(execve) CFI_STARTPROC FAKE_STACK_FRAME $0 SAVE_ALL @@ -1036,7 +1036,7 @@ ENTRY(kernel_execve) UNFAKE_STACK_FRAME ret CFI_ENDPROC -ENDPROC(kernel_execve) +ENDPROC(execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault diff --git a/trunk/arch/x86_64/kernel/kprobes.c b/trunk/arch/x86_64/kernel/kprobes.c index ac241567e682..ffc73ac72485 100644 --- a/trunk/arch/x86_64/kernel/kprobes.c +++ b/trunk/arch/x86_64/kernel/kprobes.c @@ -270,19 +270,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; - struct kretprobe_instance *ri; + struct kretprobe_instance *ri; - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - add_rp_inst(ri); - } else { - rp->nmissed++; - } + + add_rp_inst(ri); + } else { + rp->nmissed++; + } } int __kprobes kprobe_handler(struct pt_regs *regs) @@ -404,15 +405,14 @@ int __kprobes kprobe_handler(struct pt_regs *regs) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -423,20 +423,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -454,16 +454,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler * to run (and have re-enabled preemption) - */ - return 1; + */ + return 1; } /* diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index b8d53dfa9931..20e88f4b564b 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -152,21 +152,6 @@ static void __init MP_bus_info (struct mpc_config_bus *m) } } -static int bad_ioapic(unsigned long address) -{ - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " - "(found %d)\n", MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); - } - if (!address) { - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" - " found in table, skipping!\n"); - return 1; - } - return 0; -} - static void __init MP_ioapic_info (struct mpc_config_ioapic *m) { if (!(m->mpc_flags & MPC_APIC_USABLE)) @@ -174,10 +159,16 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) printk("I/O APIC #%d at 0x%X.\n", m->mpc_apicid, m->mpc_apicaddr); - - if (bad_ioapic(m->mpc_apicaddr)) + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n", + MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); + } + if (!m->mpc_apicaddr) { + printk(KERN_ERR "WARNING: bogus zero I/O APIC address" + " found in MP table, skipping!\n"); return; - + } mp_ioapics[nr_ioapics] = *m; nr_ioapics++; } @@ -656,8 +647,16 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) { int idx = 0; - if (bad_ioapic(address)) + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " + "(found %d)\n", MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); + } + if (!address) { + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" + " found in MADT table, skipping!\n"); return; + } idx = nr_ioapics++; diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 7af9cb3e2d99..4d6fb047952e 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -28,10 +28,6 @@ #include #include -int unknown_nmi_panic; -int nmi_watchdog_enabled; -int panic_on_unrecovered_nmi; - /* perfctr_nmi_owner tracks the ownership of the perfctr registers: * evtsel_nmi_owner tracks the ownership of the event selection * - different performance counters/ event selection may be reserved for diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index f8d857453f8a..4dcb671bd19f 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -170,20 +170,8 @@ void dma_free_coherent(struct device *dev, size_t size, } EXPORT_SYMBOL(dma_free_coherent); -static int forbid_dac __read_mostly; - int dma_supported(struct device *dev, u64 mask) { -#ifdef CONFIG_PCI - if (mask > 0xffffffff && forbid_dac > 0) { - - - - printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id); - return 0; - } -#endif - if (dma_ops->dma_supported) return dma_ops->dma_supported(dev, mask); @@ -243,64 +231,57 @@ EXPORT_SYMBOL(dma_set_mask); allowed overwrite iommu off workarounds for specific chipsets. soft Use software bounce buffering (default for Intel machines) noaperture Don't touch the aperture for AGP. - allowdac Allow DMA >4GB - nodac Forbid DMA >4GB - panic Force panic when IOMMU overflows */ __init int iommu_setup(char *p) { - iommu_merge = 1; + iommu_merge = 1; if (!p) return -EINVAL; - while (*p) { - if (!strncmp(p,"off",3)) - no_iommu = 1; - /* gart_parse_options has more force support */ - if (!strncmp(p,"force",5)) - force_iommu = 1; - if (!strncmp(p,"noforce",7)) { - iommu_merge = 0; - force_iommu = 0; - } - - if (!strncmp(p, "biomerge",8)) { - iommu_bio_merge = 4096; - iommu_merge = 1; - force_iommu = 1; - } - if (!strncmp(p, "panic",5)) - panic_on_overflow = 1; - if (!strncmp(p, "nopanic",7)) - panic_on_overflow = 0; - if (!strncmp(p, "merge",5)) { - iommu_merge = 1; - force_iommu = 1; - } - if (!strncmp(p, "nomerge",7)) - iommu_merge = 0; - if (!strncmp(p, "forcesac",8)) - iommu_sac_force = 1; - if (!strncmp(p, "allowdac", 8)) - forbid_dac = 0; - if (!strncmp(p, "nodac", 5)) - forbid_dac = -1; + while (*p) { + if (!strncmp(p,"off",3)) + no_iommu = 1; + /* gart_parse_options has more force support */ + if (!strncmp(p,"force",5)) + force_iommu = 1; + if (!strncmp(p,"noforce",7)) { + iommu_merge = 0; + force_iommu = 0; + } + + if (!strncmp(p, "biomerge",8)) { + iommu_bio_merge = 4096; + iommu_merge = 1; + force_iommu = 1; + } + if (!strncmp(p, "panic",5)) + panic_on_overflow = 1; + if (!strncmp(p, "nopanic",7)) + panic_on_overflow = 0; + if (!strncmp(p, "merge",5)) { + iommu_merge = 1; + force_iommu = 1; + } + if (!strncmp(p, "nomerge",7)) + iommu_merge = 0; + if (!strncmp(p, "forcesac",8)) + iommu_sac_force = 1; #ifdef CONFIG_SWIOTLB - if (!strncmp(p, "soft",4)) - swiotlb = 1; + if (!strncmp(p, "soft",4)) + swiotlb = 1; #endif #ifdef CONFIG_IOMMU - gart_parse_options(p); + gart_parse_options(p); #endif - p += strcspn(p, ","); - if (*p == ',') - ++p; - } - return 0; + p += strcspn(p, ","); + if (*p == ',') + ++p; + } + return 0; } early_param("iommu", iommu_setup); diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index de10cb8a2c97..458006ae19f3 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -294,9 +294,9 @@ void __show_regs(struct pt_regs * regs) print_modules(); printk("Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); printk_address(regs->rip); printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index fc944b5e8f4a..0b00bb2ea576 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -123,6 +123,9 @@ struct resource standard_io_resources[] = { .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) struct resource data_resource = { @@ -169,6 +172,9 @@ static struct resource adapter_rom_resources[] = { .flags = IORESOURCE_ROM } }; +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + static struct resource video_rom_resource = { .name = "Video ROM", .start = 0xc0000, @@ -239,8 +245,7 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; - start += 2048) { + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -532,7 +537,7 @@ void __init setup_arch(char **cmdline_p) { unsigned i; /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); } diff --git a/trunk/arch/x86_64/kernel/sys_x86_64.c b/trunk/arch/x86_64/kernel/sys_x86_64.c index 76bf7c241fe4..6449ea8fe756 100644 --- a/trunk/arch/x86_64/kernel/sys_x86_64.c +++ b/trunk/arch/x86_64/kernel/sys_x86_64.c @@ -148,7 +148,7 @@ asmlinkage long sys_uname(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 557e92af7bea..7ea3bf2a858c 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -77,6 +77,7 @@ unsigned long long monotonic_base; struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */ volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; +unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES; struct timespec __xtime __section_xtime; struct timezone __sys_tz __section_sys_tz; @@ -118,7 +119,7 @@ unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; void do_gettimeofday(struct timeval *tv) { - unsigned long seq; + unsigned long seq, t; unsigned int sec, usec; do { @@ -135,7 +136,10 @@ void do_gettimeofday(struct timeval *tv) be found. Note when you fix it here you need to do the same in arch/x86_64/kernel/vsyscall.c and export all needed variables in vmlinux.lds. -AK */ - usec += do_gettimeoffset(); + + t = (jiffies - wall_jiffies) * USEC_PER_TICK + + do_gettimeoffset(); + usec += t; } while (read_seqretry(&xtime_lock, seq)); @@ -161,7 +165,8 @@ int do_settimeofday(struct timespec *tv) write_seqlock_irq(&xtime_lock); - nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= do_gettimeoffset() * NSEC_PER_USEC + + (jiffies - wall_jiffies) * NSEC_PER_TICK; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -1066,6 +1071,7 @@ static int timer_resume(struct sys_device *dev) vxtime.last_tsc = get_cycles_sync(); write_sequnlock_irqrestore(&xtime_lock,flags); jiffies += sleep_length; + wall_jiffies += sleep_length; monotonic_base += sleep_length * (NSEC_PER_SEC/HZ); touch_softlockup_watchdog(); return 0; diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index b9df2ab6529f..d0564f1bcb0b 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -67,6 +67,13 @@ SECTIONS _edata = .; /* End of data section */ + __bss_start = .; /* BSS */ + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + *(.bss.page_aligned) + *(.bss) + } + __bss_stop = .; + . = ALIGN(PAGE_SIZE); . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { @@ -101,6 +108,9 @@ SECTIONS .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } vgetcpu_mode = VVIRT(.vgetcpu_mode); + .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } + wall_jiffies = VVIRT(.wall_jiffies); + .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) } sys_tz = VVIRT(.sys_tz); @@ -219,13 +229,6 @@ SECTIONS . = ALIGN(4096); __nosave_end = .; - __bss_start = .; /* BSS */ - .bss : AT(ADDR(.bss) - LOAD_OFFSET) { - *(.bss.page_aligned) - *(.bss) - } - __bss_stop = .; - _end = . ; /* Sections to be discarded */ diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index a98b460af6a1..ac48c3857ddb 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -66,7 +66,8 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) sequence = read_seqbegin(&__xtime_lock); sec = __xtime.tv_sec; - usec = __xtime.tv_nsec / 1000; + usec = (__xtime.tv_nsec / 1000) + + (__jiffies - __wall_jiffies) * (1000000 / HZ); if (__vxtime.mode != VXTIME_HPET) { t = get_cycles_sync(); @@ -154,8 +155,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) We do this here because otherwise user space would do it on its own in a likely inferior way (no access to jiffies). If you don't like it pass NULL. */ - if (tcache && tcache->blob[0] == (j = __jiffies)) { - p = tcache->blob[1]; + if (tcache && tcache->t0 == (j = __jiffies)) { + p = tcache->t1; } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { /* Load per CPU data from RDTSCP */ rdtscp(dummy, dummy, p); @@ -164,8 +165,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); } if (tcache) { - tcache->blob[0] = j; - tcache->blob[1] = p; + tcache->t0 = j; + tcache->t1 = p; } if (cpu) *cpu = p & 0xfff; diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 19c72520a868..3e16fe08150e 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -462,6 +462,19 @@ void online_page(struct page *page) } #ifdef CONFIG_MEMORY_HOTPLUG +/* + * XXX: memory_add_physaddr_to_nid() is to find node id from physical address + * via probe interface of sysfs. If acpi notifies hot-add event, then it + * can tell node id by searching dsdt. But, probe interface doesn't have + * node id. So, return 0 as node id at this time. + */ +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 start) +{ + return 0; +} +#endif + /* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. @@ -474,12 +487,12 @@ int arch_add_memory(int nid, u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - init_memory_mapping(start, (start + size -1)); - ret = __add_pages(zone, start_pfn, nr_pages); if (ret) goto error; + init_memory_mapping(start, (start + size -1)); + return ret; error: printk("%s: Problem encountered in __add_pages!\n", __func__); @@ -493,24 +506,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#ifndef CONFIG_ACPI_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return 0; -} -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); -#endif - -#ifndef CONFIG_ACPI_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return 0; -} -#endif - -#endif /* CONFIG_MEMORY_HOTPLUG */ - -#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE +#else /* CONFIG_MEMORY_HOTPLUG */ /* * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, * just online the pages. @@ -536,7 +532,7 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) } return err; } -#endif +#endif /* CONFIG_MEMORY_HOTPLUG */ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; diff --git a/trunk/arch/x86_64/mm/ioremap.c b/trunk/arch/x86_64/mm/ioremap.c index c6e5e8d401a4..45d7d823c3b8 100644 --- a/trunk/arch/x86_64/mm/ioremap.c +++ b/trunk/arch/x86_64/mm/ioremap.c @@ -12,16 +12,117 @@ #include #include #include -#include +#include #include #include -#include #include +#include #include #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_GLOBAL | _PAGE_DIRTY | _PAGE_ACCESSED | flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PUD_MASK; + end = address + size; + if (end > PUD_SIZE) + end = PUD_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static inline int remap_area_pud(pud_t * pud, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pmd_t * pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + return -ENOMEM; + remap_area_pmd(pmd, address, end - address, address + phys_addr, flags); + address = (address + PUD_SIZE) & PUD_MASK; + pud++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t *pgd; + unsigned long end = address + size; + + phys_addr -= address; + pgd = pgd_offset_k(address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pud = pud_alloc(&init_mm, pgd, address); + error = -ENOMEM; + if (!pud) + break; + if (remap_area_pud(pud, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + pgd++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} + /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. @@ -64,7 +165,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -94,8 +194,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } #endif - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL - | _PAGE_DIRTY | _PAGE_ACCESSED | flags); /* * Mappings have to be page-aligned */ @@ -111,8 +209,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; area->phys_addr = phys_addr; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); return NULL; } diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 3cc0544e25f5..f8c04d6935c9 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -23,13 +23,22 @@ int acpi_numa __initdata; +#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ + defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ + && !defined(CONFIG_MEMORY_HOTPLUG) +#define RESERVE_HOTADD 1 +#endif + static struct acpi_table_slit *acpi_slit; static nodemask_t nodes_parsed __initdata; static struct bootnode nodes[MAX_NUMNODES] __initdata; -static struct bootnode nodes_add[MAX_NUMNODES]; +static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static int found_add_area __initdata; int hotadd_percent __initdata = 0; +#ifndef RESERVE_HOTADD +#define hotadd_percent 0 /* Ignore all settings */ +#endif /* Too small nodes confuse the VM badly. Usually they result from BIOS bugs. */ @@ -151,7 +160,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) pxm, pa->apic_id, node); } -#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE +#ifdef RESERVE_HOTADD /* * Protect against too large hotadd areas that would fill up memory. */ @@ -194,37 +203,15 @@ static int hotadd_enough_memory(struct bootnode *nd) return 1; } -static int update_end_of_memory(unsigned long end) -{ - found_add_area = 1; - if ((end >> PAGE_SHIFT) > end_pfn) - end_pfn = end >> PAGE_SHIFT; - return 1; -} - -static inline int save_add_info(void) -{ - return hotadd_percent > 0; -} -#else -int update_end_of_memory(unsigned long end) {return 0;} -static int hotadd_enough_memory(struct bootnode *nd) {return 1;} -#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE -static inline int save_add_info(void) {return 1;} -#else -static inline int save_add_info(void) {return 0;} -#endif -#endif /* - * Update nodes_add and decide if to include add are in the zone. - * Both SPARSE and RESERVE need nodes_add infomation. + * It is fine to add this area to the nodes data it will be used later * This code supports one contigious hot add area per node. */ static int reserve_hotadd(int node, unsigned long start, unsigned long end) { unsigned long s_pfn = start >> PAGE_SHIFT; unsigned long e_pfn = end >> PAGE_SHIFT; - int ret = 0, changed = 0; + int changed = 0; struct bootnode *nd = &nodes_add[node]; /* I had some trouble with strange memory hotadd regions breaking @@ -253,6 +240,7 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Looks good */ + found_add_area = 1; if (nd->start == nd->end) { nd->start = start; nd->end = end; @@ -270,12 +258,14 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); } - ret = update_end_of_memory(nd->end); + if ((nd->end >> PAGE_SHIFT) > end_pfn) + end_pfn = nd->end >> PAGE_SHIFT; if (changed) printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); - return ret; + return 0; } +#endif /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init @@ -294,7 +284,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) } if (ma->flags.enabled == 0) return; - if (ma->flags.hot_pluggable && !save_add_info()) + if (ma->flags.hot_pluggable && hotadd_percent == 0) return; start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); @@ -337,13 +327,15 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); - if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) { +#ifdef RESERVE_HOTADD + if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; if ((nd->start | nd->end) == 0) node_clear(node, nodes_parsed); } +#endif } /* Sanity check to catch more bad SRATs (they are amazingly common). @@ -359,6 +351,7 @@ static int nodes_cover_memory(void) unsigned long e = nodes[i].end >> PAGE_SHIFT; pxmram += e - s; pxmram -= absent_pages_in_range(s, e); + pxmram -= nodes_add[i].end - nodes_add[i].start; if ((long)pxmram < 0) pxmram = 0; } @@ -466,16 +459,3 @@ int __node_distance(int a, int b) } EXPORT_SYMBOL(__node_distance); - -int memory_add_physaddr_to_nid(u64 start) -{ - int i, ret = 0; - - for_each_node(i) - if (nodes_add[i].start <= start && nodes_add[i].end > start) - ret = i; - - return ret; -} -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); - diff --git a/trunk/arch/xtensa/kernel/syscalls.c b/trunk/arch/xtensa/kernel/syscalls.c index d9285d4d5565..4688ba2db84d 100644 --- a/trunk/arch/xtensa/kernel/syscalls.c +++ b/trunk/arch/xtensa/kernel/syscalls.c @@ -128,7 +128,7 @@ int sys_execve(struct pt_regs *regs) int sys_uname(struct old_utsname * name) { - if (name && !copy_to_user(name, utsname(), sizeof (*name))) + if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) return 0; return -EFAULT; } @@ -266,23 +266,3 @@ void system_call (struct pt_regs *regs) regs->areg[2] = res; do_syscall_trace(); } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ( - " mov a5, %2 \n" - " mov a4, %4 \n" - " mov a3, %3 \n" - " movi a2, %1 \n" - " syscall \n" - " mov %0, a2 \n" - : "=a" (__res) - : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp) - : "a2", "a3", "a4", "a5"); - return __res; -} diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index 37347e369987..241db201f40e 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -26,6 +26,8 @@ #include +extern volatile unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -108,6 +110,7 @@ int do_settimeofday(struct timespec *tv) */ ccount = get_ccount(); nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC; + nsec -= (jiffies - wall_jiffies) * CCOUNT_PER_JIFFY * CCOUNT_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -126,7 +129,7 @@ EXPORT_SYMBOL(do_settimeofday); void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, delta, seq; + unsigned long sec, usec, delta, lost, seq; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -134,9 +137,12 @@ void do_gettimeofday(struct timeval *tv) delta = get_ccount() - last_ccount_stamp; sec = xtime.tv_sec; usec = (xtime.tv_nsec / NSEC_PER_USEC); + + lost = jiffies - wall_jiffies; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - usec += (delta * CCOUNT_NSEC) / NSEC_PER_USEC; + usec += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC; for (; usec >= 1000000; sec++, usec -= 1000000) ; @@ -173,7 +179,8 @@ irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) if (ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) { + abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ && + jiffies - wall_jiffies == 1) { if (platform_set_rtc_time(xtime.tv_sec+1) == 0) last_rtc_update = xtime.tv_sec+1; diff --git a/trunk/arch/xtensa/platform-iss/console.c b/trunk/arch/xtensa/platform-iss/console.c index 5c947cae7520..22d3c571a7bc 100644 --- a/trunk/arch/xtensa/platform-iss/console.c +++ b/trunk/arch/xtensa/platform-iss/console.c @@ -191,7 +191,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index 83766a6bdee2..b6f5f0a79655 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -1,24 +1,6 @@ # # Block layer core configuration # -config BLOCK - bool "Enable the block layer" if EMBEDDED - default y - help - This permits the block layer to be removed from the kernel if it's not - needed (on some embedded devices for example). If this option is - disabled, then blockdev files will become unusable and some - filesystems (such as ext3) will become unavailable. - - This option will also disable SCSI character devices and USB storage - since they make use of various block layer definitions and - facilities. - - Say Y here unless you know you really don't want to mount disks and - suchlike. - -if BLOCK - #XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64 #for instance. config LBD @@ -51,6 +33,4 @@ config LSF If unsure, say Y. -endif - source block/Kconfig.iosched diff --git a/trunk/block/Kconfig.iosched b/trunk/block/Kconfig.iosched index 903f0d3b6852..48d090e266fc 100644 --- a/trunk/block/Kconfig.iosched +++ b/trunk/block/Kconfig.iosched @@ -1,4 +1,3 @@ -if BLOCK menu "IO Schedulers" @@ -68,5 +67,3 @@ config DEFAULT_IOSCHED default "noop" if DEFAULT_NOOP endmenu - -endif diff --git a/trunk/block/Makefile b/trunk/block/Makefile index 4b84d0d5947b..c05de0e0037f 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel block layer # -obj-$(CONFIG_BLOCK) := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o +obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o obj-$(CONFIG_IOSCHED_AS) += as-iosched.o diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 50b95e4c1425..5da56d48fbd3 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -1,7 +1,7 @@ /* * Anticipatory & deadline i/o scheduler. * - * Copyright (C) 2002 Jens Axboe + * Copyright (C) 2002 Jens Axboe * Nick Piggin * */ @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -92,8 +93,9 @@ struct as_data { struct rb_root sort_list[2]; struct list_head fifo_list[2]; - struct request *next_rq[2]; /* next in sort order */ + struct as_rq *next_arq[2]; /* next in sort order */ sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */ + struct hlist_head *hash; /* request hash */ unsigned long exit_prob; /* probability a task will exit while being waited on */ @@ -113,6 +115,7 @@ struct as_data { int write_batch_count; /* max # of reqs in a write batch */ int current_write_count; /* how many requests left this batch */ int write_batch_idled; /* has the write batch gone idle? */ + mempool_t *arq_pool; enum anticipation_status antic_status; unsigned long antic_start; /* jiffies: when it started */ @@ -130,6 +133,8 @@ struct as_data { unsigned long antic_expire; }; +#define list_entry_fifo(ptr) list_entry((ptr), struct as_rq, fifo) + /* * per-request data. */ @@ -145,14 +150,40 @@ enum arq_state { AS_RQ_POSTSCHED, /* when they shouldn't be */ }; -#define RQ_IOC(rq) ((struct io_context *) (rq)->elevator_private) -#define RQ_STATE(rq) ((enum arq_state)(rq)->elevator_private2) -#define RQ_SET_STATE(rq, state) ((rq)->elevator_private2 = (void *) state) +struct as_rq { + /* + * rbtree index, key is the starting offset + */ + struct rb_node rb_node; + sector_t rb_key; + + struct request *request; + + struct io_context *io_context; /* The submitting task */ + + /* + * request hash, key is the ending offset (for back merge lookup) + */ + struct hlist_node hash; + + /* + * expire fifo + */ + struct list_head fifo; + unsigned long expires; -static DEFINE_PER_CPU(unsigned long, ioc_count); + unsigned int is_sync; + enum arq_state state; +}; + +#define RQ_DATA(rq) ((struct as_rq *) (rq)->elevator_private) + +static kmem_cache_t *arq_pool; + +static atomic_t ioc_count = ATOMIC_INIT(0); static struct completion *ioc_gone; -static void as_move_to_dispatch(struct as_data *ad, struct request *rq); +static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); static void as_antic_stop(struct as_data *ad); /* @@ -163,8 +194,7 @@ static void as_antic_stop(struct as_data *ad); static void free_as_io_context(struct as_io_context *aic) { kfree(aic); - elv_ioc_count_dec(ioc_count); - if (ioc_gone && !elv_ioc_count_read(ioc_count)) + if (atomic_dec_and_test(&ioc_count) && ioc_gone) complete(ioc_gone); } @@ -200,7 +230,7 @@ static struct as_io_context *alloc_as_io_context(void) ret->seek_total = 0; ret->seek_samples = 0; ret->seek_mean = 0; - elv_ioc_count_inc(ioc_count); + atomic_inc(&ioc_count); } return ret; @@ -210,9 +240,9 @@ static struct as_io_context *alloc_as_io_context(void) * If the current task has no AS IO context then create one and initialise it. * Then take a ref on the task's io context and return it. */ -static struct io_context *as_get_io_context(int node) +static struct io_context *as_get_io_context(void) { - struct io_context *ioc = get_io_context(GFP_ATOMIC, node); + struct io_context *ioc = get_io_context(GFP_ATOMIC); if (ioc && !ioc->aic) { ioc->aic = alloc_as_io_context(); if (!ioc->aic) { @@ -223,43 +253,194 @@ static struct io_context *as_get_io_context(int node) return ioc; } -static void as_put_io_context(struct request *rq) +static void as_put_io_context(struct as_rq *arq) { struct as_io_context *aic; - if (unlikely(!RQ_IOC(rq))) + if (unlikely(!arq->io_context)) return; - aic = RQ_IOC(rq)->aic; + aic = arq->io_context->aic; - if (rq_is_sync(rq) && aic) { + if (arq->is_sync == REQ_SYNC && aic) { spin_lock(&aic->lock); set_bit(AS_TASK_IORUNNING, &aic->state); aic->last_end_request = jiffies; spin_unlock(&aic->lock); } - put_io_context(RQ_IOC(rq)); + put_io_context(arq->io_context); +} + +/* + * the back merge hash support functions + */ +static const int as_hash_shift = 6; +#define AS_HASH_BLOCK(sec) ((sec) >> 3) +#define AS_HASH_FN(sec) (hash_long(AS_HASH_BLOCK((sec)), as_hash_shift)) +#define AS_HASH_ENTRIES (1 << as_hash_shift) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) + +static inline void __as_del_arq_hash(struct as_rq *arq) +{ + hlist_del_init(&arq->hash); +} + +static inline void as_del_arq_hash(struct as_rq *arq) +{ + if (!hlist_unhashed(&arq->hash)) + __as_del_arq_hash(arq); +} + +static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq) +{ + struct request *rq = arq->request; + + BUG_ON(!hlist_unhashed(&arq->hash)); + + hlist_add_head(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]); +} + +/* + * move hot entry to front of chain + */ +static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq) +{ + struct request *rq = arq->request; + struct hlist_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))]; + + if (hlist_unhashed(&arq->hash)) { + WARN_ON(1); + return; + } + + if (&arq->hash != head->first) { + hlist_del(&arq->hash); + hlist_add_head(&arq->hash, head); + } +} + +static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset) +{ + struct hlist_head *hash_list = &ad->hash[AS_HASH_FN(offset)]; + struct hlist_node *entry, *next; + struct as_rq *arq; + + hlist_for_each_entry_safe(arq, entry, next, hash_list, hash) { + struct request *__rq = arq->request; + + BUG_ON(hlist_unhashed(&arq->hash)); + + if (!rq_mergeable(__rq)) { + as_del_arq_hash(arq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; } /* * rb tree support functions */ -#define RQ_RB_ROOT(ad, rq) (&(ad)->sort_list[rq_is_sync((rq))]) +#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node) +#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync]) +#define rq_rb_key(rq) (rq)->sector + +/* + * as_find_first_arq finds the first (lowest sector numbered) request + * for the specified data_dir. Used to sweep back to the start of the disk + * (1-way elevator) after we process the last (highest sector) request. + */ +static struct as_rq *as_find_first_arq(struct as_data *ad, int data_dir) +{ + struct rb_node *n = ad->sort_list[data_dir].rb_node; + + if (n == NULL) + return NULL; + + for (;;) { + if (n->rb_left == NULL) + return rb_entry_arq(n); + + n = n->rb_left; + } +} + +/* + * Add the request to the rb tree if it is unique. If there is an alias (an + * existing request against the same sector), which can happen when using + * direct IO, then return the alias. + */ +static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq) +{ + struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node; + struct rb_node *parent = NULL; + struct as_rq *__arq; + struct request *rq = arq->request; + + arq->rb_key = rq_rb_key(rq); + + while (*p) { + parent = *p; + __arq = rb_entry_arq(parent); + + if (arq->rb_key < __arq->rb_key) + p = &(*p)->rb_left; + else if (arq->rb_key > __arq->rb_key) + p = &(*p)->rb_right; + else + return __arq; + } + + rb_link_node(&arq->rb_node, parent, p); + rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq)); + + return NULL; +} -static void as_add_rq_rb(struct as_data *ad, struct request *rq) +static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq) { - struct request *alias; + struct as_rq *alias; - while ((unlikely(alias = elv_rb_add(RQ_RB_ROOT(ad, rq), rq)))) { + while ((unlikely(alias = __as_add_arq_rb(ad, arq)))) { as_move_to_dispatch(ad, alias); as_antic_stop(ad); } } -static inline void as_del_rq_rb(struct as_data *ad, struct request *rq) +static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq) +{ + if (!RB_EMPTY_NODE(&arq->rb_node)) { + WARN_ON(1); + return; + } + + rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq)); + RB_CLEAR_NODE(&arq->rb_node); +} + +static struct request * +as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir) { - elv_rb_del(RQ_RB_ROOT(ad, rq), rq); + struct rb_node *n = ad->sort_list[data_dir].rb_node; + struct as_rq *arq; + + while (n) { + arq = rb_entry_arq(n); + + if (sector < arq->rb_key) + n = n->rb_left; + else if (sector > arq->rb_key) + n = n->rb_right; + else + return arq->request; + } + + return NULL; } /* @@ -277,26 +458,26 @@ static inline void as_del_rq_rb(struct as_data *ad, struct request *rq) * as_choose_req selects the preferred one of two requests of the same data_dir * ignoring time - eg. timeouts, which is the job of as_dispatch_request */ -static struct request * -as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2) +static struct as_rq * +as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2) { int data_dir; sector_t last, s1, s2, d1, d2; int r1_wrap=0, r2_wrap=0; /* requests are behind the disk head */ const sector_t maxback = MAXBACK; - if (rq1 == NULL || rq1 == rq2) - return rq2; - if (rq2 == NULL) - return rq1; + if (arq1 == NULL || arq1 == arq2) + return arq2; + if (arq2 == NULL) + return arq1; - data_dir = rq_is_sync(rq1); + data_dir = arq1->is_sync; last = ad->last_sector[data_dir]; - s1 = rq1->sector; - s2 = rq2->sector; + s1 = arq1->request->sector; + s2 = arq2->request->sector; - BUG_ON(data_dir != rq_is_sync(rq2)); + BUG_ON(data_dir != arq2->is_sync); /* * Strict one way elevator _except_ in the case where we allow @@ -323,58 +504,61 @@ as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2) /* Found required data */ if (!r1_wrap && r2_wrap) - return rq1; + return arq1; else if (!r2_wrap && r1_wrap) - return rq2; + return arq2; else if (r1_wrap && r2_wrap) { /* both behind the head */ if (s1 <= s2) - return rq1; + return arq1; else - return rq2; + return arq2; } /* Both requests in front of the head */ if (d1 < d2) - return rq1; + return arq1; else if (d2 < d1) - return rq2; + return arq2; else { if (s1 >= s2) - return rq1; + return arq1; else - return rq2; + return arq2; } } /* - * as_find_next_rq finds the next request after @prev in elevator order. + * as_find_next_arq finds the next request after @prev in elevator order. * this with as_choose_req form the basis for how the scheduler chooses * what request to process next. Anticipation works on top of this. */ -static struct request * -as_find_next_rq(struct as_data *ad, struct request *last) +static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last) { + const int data_dir = last->is_sync; + struct as_rq *ret; struct rb_node *rbnext = rb_next(&last->rb_node); struct rb_node *rbprev = rb_prev(&last->rb_node); - struct request *next = NULL, *prev = NULL; + struct as_rq *arq_next, *arq_prev; - BUG_ON(RB_EMPTY_NODE(&last->rb_node)); + BUG_ON(!RB_EMPTY_NODE(&last->rb_node)); if (rbprev) - prev = rb_entry_rq(rbprev); + arq_prev = rb_entry_arq(rbprev); + else + arq_prev = NULL; if (rbnext) - next = rb_entry_rq(rbnext); + arq_next = rb_entry_arq(rbnext); else { - const int data_dir = rq_is_sync(last); - - rbnext = rb_first(&ad->sort_list[data_dir]); - if (rbnext && rbnext != &last->rb_node) - next = rb_entry_rq(rbnext); + arq_next = as_find_first_arq(ad, data_dir); + if (arq_next == last) + arq_next = NULL; } - return as_choose_req(ad, next, prev); + ret = as_choose_req(ad, arq_next, arq_prev); + + return ret; } /* @@ -528,7 +712,8 @@ static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq) { - int data_dir = rq_is_sync(rq); + struct as_rq *arq = RQ_DATA(rq); + int data_dir = arq->is_sync; unsigned long thinktime = 0; sector_t seek_dist; @@ -567,11 +752,11 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, * previous one issued. */ static int as_close_req(struct as_data *ad, struct as_io_context *aic, - struct request *rq) + struct as_rq *arq) { unsigned long delay; /* milliseconds */ sector_t last = ad->last_sector[ad->batch_data_dir]; - sector_t next = rq->sector; + sector_t next = arq->request->sector; sector_t delta; /* acceptable close offset (in sectors) */ sector_t s; @@ -628,7 +813,7 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic, * * If this task has queued some other IO, do not enter enticipation. */ -static int as_can_break_anticipation(struct as_data *ad, struct request *rq) +static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) { struct io_context *ioc; struct as_io_context *aic; @@ -636,7 +821,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) ioc = ad->io_context; BUG_ON(!ioc); - if (rq && ioc == RQ_IOC(rq)) { + if (arq && ioc == arq->io_context) { /* request from same process */ return 1; } @@ -663,7 +848,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) return 1; } - if (rq && rq_is_sync(rq) && as_close_req(ad, aic, rq)) { + if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) { /* * Found a close request that is not one of ours. * @@ -679,7 +864,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) ad->exit_no_coop = (7*ad->exit_no_coop)/8; } - as_update_iohist(ad, aic, rq); + as_update_iohist(ad, aic, arq->request); return 1; } @@ -706,10 +891,10 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) } /* - * as_can_anticipate indicates whether we should either run rq + * as_can_anticipate indicates whether we should either run arq * or keep anticipating a better request. */ -static int as_can_anticipate(struct as_data *ad, struct request *rq) +static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) { if (!ad->io_context) /* @@ -723,7 +908,7 @@ static int as_can_anticipate(struct as_data *ad, struct request *rq) */ return 0; - if (as_can_break_anticipation(ad, rq)) + if (as_can_break_anticipation(ad, arq)) /* * This request is a good candidate. Don't keep anticipating, * run it. @@ -741,16 +926,16 @@ static int as_can_anticipate(struct as_data *ad, struct request *rq) } /* - * as_update_rq must be called whenever a request (rq) is added to + * as_update_arq must be called whenever a request (arq) is added to * the sort_list. This function keeps caches up to date, and checks if the * request might be one we are "anticipating" */ -static void as_update_rq(struct as_data *ad, struct request *rq) +static void as_update_arq(struct as_data *ad, struct as_rq *arq) { - const int data_dir = rq_is_sync(rq); + const int data_dir = arq->is_sync; - /* keep the next_rq cache up to date */ - ad->next_rq[data_dir] = as_choose_req(ad, rq, ad->next_rq[data_dir]); + /* keep the next_arq cache up to date */ + ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]); /* * have we been anticipating this request? @@ -759,7 +944,7 @@ static void as_update_rq(struct as_data *ad, struct request *rq) */ if (ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT) { - if (as_can_break_anticipation(ad, rq)) + if (as_can_break_anticipation(ad, arq)) as_antic_stop(ad); } } @@ -799,11 +984,12 @@ static void update_write_batch(struct as_data *ad) static void as_completed_request(request_queue_t *q, struct request *rq) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); WARN_ON(!list_empty(&rq->queuelist)); - if (RQ_STATE(rq) != AS_RQ_REMOVED) { - printk("rq->state %d\n", RQ_STATE(rq)); + if (arq->state != AS_RQ_REMOVED) { + printk("arq->state %d\n", arq->state); WARN_ON(1); goto out; } @@ -823,14 +1009,14 @@ static void as_completed_request(request_queue_t *q, struct request *rq) * actually serviced. This should help devices with big TCQ windows * and writeback caches */ - if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) { + if (ad->new_batch && ad->batch_data_dir == arq->is_sync) { update_write_batch(ad); ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; ad->new_batch = 0; } - if (ad->io_context == RQ_IOC(rq) && ad->io_context) { + if (ad->io_context == arq->io_context && ad->io_context) { ad->antic_start = jiffies; ad->ioc_finished = 1; if (ad->antic_status == ANTIC_WAIT_REQ) { @@ -842,9 +1028,9 @@ static void as_completed_request(request_queue_t *q, struct request *rq) } } - as_put_io_context(rq); + as_put_io_context(arq); out: - RQ_SET_STATE(rq, AS_RQ_POSTSCHED); + arq->state = AS_RQ_POSTSCHED; } /* @@ -855,27 +1041,27 @@ static void as_completed_request(request_queue_t *q, struct request *rq) */ static void as_remove_queued_request(request_queue_t *q, struct request *rq) { - const int data_dir = rq_is_sync(rq); + struct as_rq *arq = RQ_DATA(rq); + const int data_dir = arq->is_sync; struct as_data *ad = q->elevator->elevator_data; - struct io_context *ioc; - WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED); + WARN_ON(arq->state != AS_RQ_QUEUED); - ioc = RQ_IOC(rq); - if (ioc && ioc->aic) { - BUG_ON(!atomic_read(&ioc->aic->nr_queued)); - atomic_dec(&ioc->aic->nr_queued); + if (arq->io_context && arq->io_context->aic) { + BUG_ON(!atomic_read(&arq->io_context->aic->nr_queued)); + atomic_dec(&arq->io_context->aic->nr_queued); } /* - * Update the "next_rq" cache if we are about to remove its + * Update the "next_arq" cache if we are about to remove its * entry */ - if (ad->next_rq[data_dir] == rq) - ad->next_rq[data_dir] = as_find_next_rq(ad, rq); + if (ad->next_arq[data_dir] == arq) + ad->next_arq[data_dir] = as_find_next_arq(ad, arq); - rq_fifo_clear(rq); - as_del_rq_rb(ad, rq); + list_del_init(&arq->fifo); + as_del_arq_hash(arq); + as_del_arq_rb(ad, arq); } /* @@ -888,7 +1074,7 @@ static void as_remove_queued_request(request_queue_t *q, struct request *rq) */ static int as_fifo_expired(struct as_data *ad, int adir) { - struct request *rq; + struct as_rq *arq; long delta_jif; delta_jif = jiffies - ad->last_check_fifo[adir]; @@ -902,9 +1088,9 @@ static int as_fifo_expired(struct as_data *ad, int adir) if (list_empty(&ad->fifo_list[adir])) return 0; - rq = rq_entry_fifo(ad->fifo_list[adir].next); + arq = list_entry_fifo(ad->fifo_list[adir].next); - return time_after(jiffies, rq_fifo_time(rq)); + return time_after(jiffies, arq->expires); } /* @@ -927,25 +1113,25 @@ static inline int as_batch_expired(struct as_data *ad) /* * move an entry to dispatch queue */ -static void as_move_to_dispatch(struct as_data *ad, struct request *rq) +static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) { - const int data_dir = rq_is_sync(rq); + struct request *rq = arq->request; + const int data_dir = arq->is_sync; - BUG_ON(RB_EMPTY_NODE(&rq->rb_node)); + BUG_ON(!RB_EMPTY_NODE(&arq->rb_node)); as_antic_stop(ad); ad->antic_status = ANTIC_OFF; /* * This has to be set in order to be correctly updated by - * as_find_next_rq + * as_find_next_arq */ ad->last_sector[data_dir] = rq->sector + rq->nr_sectors; if (data_dir == REQ_SYNC) { - struct io_context *ioc = RQ_IOC(rq); /* In case we have to anticipate after this */ - copy_io_context(&ad->io_context, &ioc); + copy_io_context(&ad->io_context, &arq->io_context); } else { if (ad->io_context) { put_io_context(ad->io_context); @@ -957,19 +1143,19 @@ static void as_move_to_dispatch(struct as_data *ad, struct request *rq) } ad->ioc_finished = 0; - ad->next_rq[data_dir] = as_find_next_rq(ad, rq); + ad->next_arq[data_dir] = as_find_next_arq(ad, arq); /* * take it off the sort and fifo list, add to dispatch queue */ as_remove_queued_request(ad->q, rq); - WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED); + WARN_ON(arq->state != AS_RQ_QUEUED); elv_dispatch_sort(ad->q, rq); - RQ_SET_STATE(rq, AS_RQ_DISPATCHED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched); + arq->state = AS_RQ_DISPATCHED; + if (arq->io_context && arq->io_context->aic) + atomic_inc(&arq->io_context->aic->nr_dispatched); ad->nr_dispatched++; } @@ -981,9 +1167,9 @@ static void as_move_to_dispatch(struct as_data *ad, struct request *rq) static int as_dispatch_request(request_queue_t *q, int force) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq; const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]); const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]); - struct request *rq; if (unlikely(force)) { /* @@ -999,14 +1185,14 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 0; ad->new_batch = 0; - while (ad->next_rq[REQ_SYNC]) { - as_move_to_dispatch(ad, ad->next_rq[REQ_SYNC]); + while (ad->next_arq[REQ_SYNC]) { + as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); dispatched++; } ad->last_check_fifo[REQ_SYNC] = jiffies; - while (ad->next_rq[REQ_ASYNC]) { - as_move_to_dispatch(ad, ad->next_rq[REQ_ASYNC]); + while (ad->next_arq[REQ_ASYNC]) { + as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); dispatched++; } ad->last_check_fifo[REQ_ASYNC] = jiffies; @@ -1030,19 +1216,19 @@ static int as_dispatch_request(request_queue_t *q, int force) /* * batch is still running or no reads or no writes */ - rq = ad->next_rq[ad->batch_data_dir]; + arq = ad->next_arq[ad->batch_data_dir]; if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) { if (as_fifo_expired(ad, REQ_SYNC)) goto fifo_expired; - if (as_can_anticipate(ad, rq)) { + if (as_can_anticipate(ad, arq)) { as_antic_waitreq(ad); return 0; } } - if (rq) { + if (arq) { /* we have a "next request" */ if (reads && !writes) ad->current_batch_expires = @@ -1070,7 +1256,7 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 1; } ad->batch_data_dir = REQ_SYNC; - rq = rq_entry_fifo(ad->fifo_list[REQ_SYNC].next); + arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); ad->last_check_fifo[ad->batch_data_dir] = jiffies; goto dispatch_request; } @@ -1096,7 +1282,7 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->batch_data_dir = REQ_ASYNC; ad->current_write_count = ad->write_batch_count; ad->write_batch_idled = 0; - rq = ad->next_rq[ad->batch_data_dir]; + arq = ad->next_arq[ad->batch_data_dir]; goto dispatch_request; } @@ -1110,7 +1296,8 @@ static int as_dispatch_request(request_queue_t *q, int force) if (as_fifo_expired(ad, ad->batch_data_dir)) { fifo_expired: - rq = rq_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); + arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); + BUG_ON(arq == NULL); } if (ad->changed_batch) { @@ -1129,58 +1316,70 @@ static int as_dispatch_request(request_queue_t *q, int force) } /* - * rq is the selected appropriate request. + * arq is the selected appropriate request. */ - as_move_to_dispatch(ad, rq); + as_move_to_dispatch(ad, arq); return 1; } /* - * add rq to rbtree and fifo + * add arq to rbtree and fifo */ static void as_add_request(request_queue_t *q, struct request *rq) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); int data_dir; - RQ_SET_STATE(rq, AS_RQ_NEW); + arq->state = AS_RQ_NEW; - data_dir = rq_is_sync(rq); + if (rq_data_dir(arq->request) == READ + || (arq->request->flags & REQ_RW_SYNC)) + arq->is_sync = 1; + else + arq->is_sync = 0; + data_dir = arq->is_sync; - rq->elevator_private = as_get_io_context(q->node); + arq->io_context = as_get_io_context(); - if (RQ_IOC(rq)) { - as_update_iohist(ad, RQ_IOC(rq)->aic, rq); - atomic_inc(&RQ_IOC(rq)->aic->nr_queued); + if (arq->io_context) { + as_update_iohist(ad, arq->io_context->aic, arq->request); + atomic_inc(&arq->io_context->aic->nr_queued); } - as_add_rq_rb(ad, rq); + as_add_arq_rb(ad, arq); + if (rq_mergeable(arq->request)) + as_add_arq_hash(ad, arq); /* * set expire time (only used for reads) and add to fifo list */ - rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]); - list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]); + arq->expires = jiffies + ad->fifo_expire[data_dir]; + list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]); - as_update_rq(ad, rq); /* keep state machine up to date */ - RQ_SET_STATE(rq, AS_RQ_QUEUED); + as_update_arq(ad, arq); /* keep state machine up to date */ + arq->state = AS_RQ_QUEUED; } static void as_activate_request(request_queue_t *q, struct request *rq) { - WARN_ON(RQ_STATE(rq) != AS_RQ_DISPATCHED); - RQ_SET_STATE(rq, AS_RQ_REMOVED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_dec(&RQ_IOC(rq)->aic->nr_dispatched); + struct as_rq *arq = RQ_DATA(rq); + + WARN_ON(arq->state != AS_RQ_DISPATCHED); + arq->state = AS_RQ_REMOVED; + if (arq->io_context && arq->io_context->aic) + atomic_dec(&arq->io_context->aic->nr_dispatched); } static void as_deactivate_request(request_queue_t *q, struct request *rq) { - WARN_ON(RQ_STATE(rq) != AS_RQ_REMOVED); - RQ_SET_STATE(rq, AS_RQ_DISPATCHED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched); + struct as_rq *arq = RQ_DATA(rq); + + WARN_ON(arq->state != AS_RQ_REMOVED); + arq->state = AS_RQ_DISPATCHED; + if (arq->io_context && arq->io_context->aic) + atomic_inc(&arq->io_context->aic->nr_dispatched); } /* @@ -1197,35 +1396,93 @@ static int as_queue_empty(request_queue_t *q) && list_empty(&ad->fifo_list[REQ_SYNC]); } +static struct request *as_former_request(request_queue_t *q, + struct request *rq) +{ + struct as_rq *arq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&arq->rb_node); + struct request *ret = NULL; + + if (rbprev) + ret = rb_entry_arq(rbprev)->request; + + return ret; +} + +static struct request *as_latter_request(request_queue_t *q, + struct request *rq) +{ + struct as_rq *arq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&arq->rb_node); + struct request *ret = NULL; + + if (rbnext) + ret = rb_entry_arq(rbnext)->request; + + return ret; +} + static int as_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct as_data *ad = q->elevator->elevator_data; sector_t rb_key = bio->bi_sector + bio_sectors(bio); struct request *__rq; + int ret; + + /* + * see if the merge hash can satisfy a back merge + */ + __rq = as_find_arq_hash(ad, bio->bi_sector); + if (__rq) { + BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } + } /* * check for front merge */ - __rq = elv_rb_find(&ad->sort_list[bio_data_dir(bio)], rb_key); - if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_FRONT_MERGE; + __rq = as_find_arq_rb(ad, rb_key, bio_data_dir(bio)); + if (__rq) { + BUG_ON(rb_key != rq_rb_key(__rq)); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_FRONT_MERGE; + goto out; + } } return ELEVATOR_NO_MERGE; +out: + if (ret) { + if (rq_mergeable(__rq)) + as_hot_arq_hash(ad, RQ_DATA(__rq)); + } + *req = __rq; + return ret; } -static void as_merged_request(request_queue_t *q, struct request *req, int type) +static void as_merged_request(request_queue_t *q, struct request *req) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(req); + + /* + * hash always needs to be repositioned, key is end sector + */ + as_del_arq_hash(arq); + as_add_arq_hash(ad, arq); /* * if the merge was a front merge, we need to reposition request */ - if (type == ELEVATOR_FRONT_MERGE) { - as_del_rq_rb(ad, req); - as_add_rq_rb(ad, req); + if (rq_rb_key(req) != arq->rb_key) { + as_del_arq_rb(ad, arq); + as_add_arq_rb(ad, arq); /* * Note! At this stage of this and the next function, our next * request may not be optimal - eg the request may have "grown" @@ -1237,22 +1494,38 @@ static void as_merged_request(request_queue_t *q, struct request *req, int type) static void as_merged_requests(request_queue_t *q, struct request *req, struct request *next) { + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(req); + struct as_rq *anext = RQ_DATA(next); + + BUG_ON(!arq); + BUG_ON(!anext); + /* - * if next expires before rq, assign its expire time to arq - * and move into next position (next will be deleted) in fifo + * reposition arq (this is the merged request) in hash, and in rbtree + * in case of a front merge */ - if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { - if (time_before(rq_fifo_time(next), rq_fifo_time(req))) { - struct io_context *rioc = RQ_IOC(req); - struct io_context *nioc = RQ_IOC(next); + as_del_arq_hash(arq); + as_add_arq_hash(ad, arq); + + if (rq_rb_key(req) != arq->rb_key) { + as_del_arq_rb(ad, arq); + as_add_arq_rb(ad, arq); + } - list_move(&req->queuelist, &next->queuelist); - rq_set_fifo_time(req, rq_fifo_time(next)); + /* + * if anext expires before arq, assign its expire time to arq + * and move into anext position (anext will be deleted) in fifo + */ + if (!list_empty(&arq->fifo) && !list_empty(&anext->fifo)) { + if (time_before(anext->expires, arq->expires)) { + list_move(&arq->fifo, &anext->fifo); + arq->expires = anext->expires; /* * Don't copy here but swap, because when anext is * removed below, it must contain the unused context */ - swap_io_context(&rioc, &nioc); + swap_io_context(&arq->io_context, &anext->io_context); } } @@ -1260,9 +1533,9 @@ static void as_merged_requests(request_queue_t *q, struct request *req, * kill knowledge of next, this one is a goner */ as_remove_queued_request(q, next); - as_put_io_context(next); + as_put_io_context(anext); - RQ_SET_STATE(next, AS_RQ_MERGED); + anext->state = AS_RQ_MERGED; } /* @@ -1280,18 +1553,61 @@ static void as_work_handler(void *data) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - blk_start_queueing(q); + if (!as_queue_empty(q)) + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } -static int as_may_queue(request_queue_t *q, int rw) +static void as_put_request(request_queue_t *q, struct request *rq) +{ + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); + + if (!arq) { + WARN_ON(1); + return; + } + + if (unlikely(arq->state != AS_RQ_POSTSCHED && + arq->state != AS_RQ_PRESCHED && + arq->state != AS_RQ_MERGED)) { + printk("arq->state %d\n", arq->state); + WARN_ON(1); + } + + mempool_free(arq, ad->arq_pool); + rq->elevator_private = NULL; +} + +static int as_set_request(request_queue_t *q, struct request *rq, + struct bio *bio, gfp_t gfp_mask) +{ + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask); + + if (arq) { + memset(arq, 0, sizeof(*arq)); + RB_CLEAR_NODE(&arq->rb_node); + arq->request = rq; + arq->state = AS_RQ_PRESCHED; + arq->io_context = NULL; + INIT_HLIST_NODE(&arq->hash); + INIT_LIST_HEAD(&arq->fifo); + rq->elevator_private = arq; + return 0; + } + + return 1; +} + +static int as_may_queue(request_queue_t *q, int rw, struct bio *bio) { int ret = ELV_MQUEUE_MAY; struct as_data *ad = q->elevator->elevator_data; struct io_context *ioc; if (ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT) { - ioc = as_get_io_context(q->node); + ioc = as_get_io_context(); if (ad->io_context == ioc) ret = ELV_MQUEUE_MUST; put_io_context(ioc); @@ -1310,16 +1626,23 @@ static void as_exit_queue(elevator_t *e) BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC])); BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC])); + mempool_destroy(ad->arq_pool); put_io_context(ad->io_context); + kfree(ad->hash); kfree(ad); } /* - * initialize elevator private data (as_data). + * initialize elevator private data (as_data), and alloc a arq for + * each request on the free lists */ static void *as_init_queue(request_queue_t *q, elevator_t *e) { struct as_data *ad; + int i; + + if (!arq_pool) + return NULL; ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); if (!ad) @@ -1328,12 +1651,30 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) ad->q = q; /* Identify what queue the data belongs to */ + ad->hash = kmalloc_node(sizeof(struct hlist_head)*AS_HASH_ENTRIES, + GFP_KERNEL, q->node); + if (!ad->hash) { + kfree(ad); + return NULL; + } + + ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, + mempool_free_slab, arq_pool, q->node); + if (!ad->arq_pool) { + kfree(ad->hash); + kfree(ad); + return NULL; + } + /* anticipatory scheduling helpers */ ad->antic_timer.function = as_antic_timeout; ad->antic_timer.data = (unsigned long)q; init_timer(&ad->antic_timer); INIT_WORK(&ad->antic_work, as_work_handler, q); + for (i = 0; i < AS_HASH_ENTRIES; i++) + INIT_HLIST_HEAD(&ad->hash[i]); + INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]); INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]); ad->sort_list[REQ_SYNC] = RB_ROOT; @@ -1446,8 +1787,10 @@ static struct elevator_type iosched_as = { .elevator_deactivate_req_fn = as_deactivate_request, .elevator_queue_empty_fn = as_queue_empty, .elevator_completed_req_fn = as_completed_request, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = as_former_request, + .elevator_latter_req_fn = as_latter_request, + .elevator_set_req_fn = as_set_request, + .elevator_put_req_fn = as_put_request, .elevator_may_queue_fn = as_may_queue, .elevator_init_fn = as_init_queue, .elevator_exit_fn = as_exit_queue, @@ -1463,6 +1806,11 @@ static int __init as_init(void) { int ret; + arq_pool = kmem_cache_create("as_arq", sizeof(struct as_rq), + 0, 0, NULL, NULL); + if (!arq_pool) + return -ENOMEM; + ret = elv_register(&iosched_as); if (!ret) { /* @@ -1474,19 +1822,21 @@ static int __init as_init(void) return 0; } + kmem_cache_destroy(arq_pool); return ret; } static void __exit as_exit(void) { - DECLARE_COMPLETION_ONSTACK(all_gone); + DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_as); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (elv_ioc_count_read(ioc_count)) + if (atomic_read(&ioc_count)) wait_for_completion(ioc_gone); synchronize_rcu(); + kmem_cache_destroy(arq_pool); } module_init(as_init); diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index 135593c8e45b..8ff33441d8a2 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Jens Axboe + * Copyright (C) 2006 Jens Axboe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -69,7 +69,7 @@ static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK /* * Bio action bits of interest */ -static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD), 0, 0, 0, BLK_TC_ACT(BLK_TC_META) }; +static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD) }; /* * More could be added as needed, taking care to increment the decrementer @@ -81,8 +81,6 @@ static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_AC (((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1)) #define trace_ahead_bit(rw) \ (((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD)) -#define trace_meta_bit(rw) \ - (((rw) & (1 << BIO_RW_META)) >> (BIO_RW_META - 3)) /* * The worker for the various blk_add_trace*() types. Fills out a @@ -105,7 +103,6 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= bio_act[trace_barrier_bit(rw)]; what |= bio_act[trace_sync_bit(rw)]; what |= bio_act[trace_ahead_bit(rw)]; - what |= bio_act[trace_meta_bit(rw)]; pid = tsk->pid; if (unlikely(act_log_check(bt, what, sector, pid))) @@ -476,9 +473,6 @@ static void blk_check_time(unsigned long long *t) *t -= (a + b) / 2; } -/* - * calibrate our inter-CPU timings - */ static void blk_trace_check_cpu_time(void *data) { unsigned long long *t; @@ -496,6 +490,20 @@ static void blk_trace_check_cpu_time(void *data) put_cpu(); } +/* + * Call blk_trace_check_cpu_time() on each CPU to calibrate our inter-CPU + * timings + */ +static void blk_trace_calibrate_offsets(void) +{ + unsigned long flags; + + smp_call_function(blk_trace_check_cpu_time, NULL, 1, 1); + local_irq_save(flags); + blk_trace_check_cpu_time(NULL); + local_irq_restore(flags); +} + static void blk_trace_set_ht_offsets(void) { #if defined(CONFIG_SCHED_SMT) @@ -524,7 +532,7 @@ static void blk_trace_set_ht_offsets(void) static __init int blk_trace_init(void) { mutex_init(&blk_tree_mutex); - on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1); + blk_trace_calibrate_offsets(); blk_trace_set_ht_offsets(); return 0; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index d3d76136f53a..3a3aee08ec5f 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -4,7 +4,7 @@ * Based on ideas from a previously unfinished io * scheduler (round robin per-process disk scheduling) and Andrea Arcangeli. * - * Copyright (C) 2003 Jens Axboe + * Copyright (C) 2003 Jens Axboe */ #include #include @@ -17,6 +17,7 @@ * tunables */ static const int cfq_quantum = 4; /* max queue in one round of service */ +static const int cfq_queued = 8; /* minimum rq allocate limit per-queue*/ static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; static const int cfq_back_max = 16 * 1024; /* maximum backwards seek, in KiB */ static const int cfq_back_penalty = 2; /* penalty of a backwards seek */ @@ -31,6 +32,8 @@ static int cfq_slice_idle = HZ / 125; #define CFQ_KEY_ASYNC (0) +static DEFINE_SPINLOCK(cfq_exit_lock); + /* * for the hash of cfqq inside the cfqd */ @@ -38,19 +41,37 @@ static int cfq_slice_idle = HZ / 125; #define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT) #define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash) +/* + * for the hash of crq inside the cfqq + */ +#define CFQ_MHASH_SHIFT 6 +#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3) +#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT) +#define CFQ_MHASH_FN(sec) hash_long(CFQ_MHASH_BLOCK(sec), CFQ_MHASH_SHIFT) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) +#define list_entry_hash(ptr) hlist_entry((ptr), struct cfq_rq, hash) + #define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list) +#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist) -#define RQ_CIC(rq) ((struct cfq_io_context*)(rq)->elevator_private) -#define RQ_CFQQ(rq) ((rq)->elevator_private2) +#define RQ_DATA(rq) (rq)->elevator_private +/* + * rb-tree defines + */ +#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node) +#define rq_rb_key(rq) (rq)->sector + +static kmem_cache_t *crq_pool; static kmem_cache_t *cfq_pool; static kmem_cache_t *cfq_ioc_pool; -static DEFINE_PER_CPU(unsigned long, ioc_count); +static atomic_t ioc_count = ATOMIC_INIT(0); static struct completion *ioc_gone; #define CFQ_PRIO_LISTS IOPRIO_BE_NR #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) +#define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE) #define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT) #define ASYNC (0) @@ -81,14 +102,29 @@ struct cfq_data { struct list_head idle_rr; unsigned int busy_queues; + /* + * non-ordered list of empty cfqq's + */ + struct list_head empty_list; + /* * cfqq lookup hash */ struct hlist_head *cfq_hash; + /* + * global crq hash for all queues + */ + struct hlist_head *crq_hash; + + mempool_t *crq_pool; + int rq_in_driver; int hw_tag; + /* + * schedule slice state info + */ /* * idle window management */ @@ -105,10 +141,13 @@ struct cfq_data { sector_t last_sector; unsigned long last_end_request; + unsigned int rq_starved; + /* * tunables, see top of file */ unsigned int cfq_quantum; + unsigned int cfq_queued; unsigned int cfq_fifo_expire[2]; unsigned int cfq_back_penalty; unsigned int cfq_back_max; @@ -131,24 +170,23 @@ struct cfq_queue { struct hlist_node cfq_hash; /* hash key */ unsigned int key; - /* member of the rr/busy/cur/idle cfqd list */ + /* on either rr or empty list of cfqd */ struct list_head cfq_list; /* sorted list of pending requests */ struct rb_root sort_list; /* if fifo isn't expired, next request to serve */ - struct request *next_rq; + struct cfq_rq *next_crq; /* requests queued in sort_list */ int queued[2]; /* currently allocated requests */ int allocated[2]; - /* pending metadata requests */ - int meta_pending; /* fifo list of requests in sort_list */ struct list_head fifo; unsigned long slice_start; unsigned long slice_end; unsigned long slice_left; + unsigned long service_last; /* number of requests that are on the dispatch list */ int on_dispatch[2]; @@ -161,6 +199,18 @@ struct cfq_queue { unsigned int flags; }; +struct cfq_rq { + struct rb_node rb_node; + sector_t rb_key; + struct request *request; + struct hlist_node hash; + + struct cfq_queue *cfq_queue; + struct cfq_io_context *io_context; + + unsigned int crq_flags; +}; + enum cfqq_state_flags { CFQ_CFQQ_FLAG_on_rr = 0, CFQ_CFQQ_FLAG_wait_request, @@ -170,7 +220,6 @@ enum cfqq_state_flags { CFQ_CFQQ_FLAG_fifo_expire, CFQ_CFQQ_FLAG_idle_window, CFQ_CFQQ_FLAG_prio_changed, - CFQ_CFQQ_FLAG_queue_new, }; #define CFQ_CFQQ_FNS(name) \ @@ -195,13 +244,69 @@ CFQ_CFQQ_FNS(must_dispatch); CFQ_CFQQ_FNS(fifo_expire); CFQ_CFQQ_FNS(idle_window); CFQ_CFQQ_FNS(prio_changed); -CFQ_CFQQ_FNS(queue_new); #undef CFQ_CFQQ_FNS +enum cfq_rq_state_flags { + CFQ_CRQ_FLAG_is_sync = 0, +}; + +#define CFQ_CRQ_FNS(name) \ +static inline void cfq_mark_crq_##name(struct cfq_rq *crq) \ +{ \ + crq->crq_flags |= (1 << CFQ_CRQ_FLAG_##name); \ +} \ +static inline void cfq_clear_crq_##name(struct cfq_rq *crq) \ +{ \ + crq->crq_flags &= ~(1 << CFQ_CRQ_FLAG_##name); \ +} \ +static inline int cfq_crq_##name(const struct cfq_rq *crq) \ +{ \ + return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \ +} + +CFQ_CRQ_FNS(is_sync); +#undef CFQ_CRQ_FNS + static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short); -static void cfq_dispatch_insert(request_queue_t *, struct request *); +static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *); static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask); +/* + * lots of deadline iosched dupes, can be abstracted later... + */ +static inline void cfq_del_crq_hash(struct cfq_rq *crq) +{ + hlist_del_init(&crq->hash); +} + +static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq) +{ + const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request)); + + hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]); +} + +static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset) +{ + struct hlist_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)]; + struct hlist_node *entry, *next; + + hlist_for_each_safe(entry, next, hash_list) { + struct cfq_rq *crq = list_entry_hash(entry); + struct request *__rq = crq->request; + + if (!rq_mergeable(__rq)) { + cfq_del_crq_hash(crq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; +} + /* * scheduler run of queue, if there are requests pending and no one in the * driver that will restart queueing @@ -228,12 +333,12 @@ static inline pid_t cfq_queue_pid(struct task_struct *task, int rw) } /* - * Lifted from AS - choose which of rq1 and rq2 that is best served now. + * Lifted from AS - choose which of crq1 and crq2 that is best served now. * We choose the request that is closest to the head right now. Distance * behind the head is penalized and only allowed to a certain extent. */ -static struct request * -cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) +static struct cfq_rq * +cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) { sector_t last, s1, s2, d1 = 0, d2 = 0; unsigned long back_max; @@ -241,22 +346,18 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) #define CFQ_RQ2_WRAP 0x02 /* request 2 wraps */ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ - if (rq1 == NULL || rq1 == rq2) - return rq2; - if (rq2 == NULL) - return rq1; + if (crq1 == NULL || crq1 == crq2) + return crq2; + if (crq2 == NULL) + return crq1; - if (rq_is_sync(rq1) && !rq_is_sync(rq2)) - return rq1; - else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) - return rq2; - if (rq_is_meta(rq1) && !rq_is_meta(rq2)) - return rq1; - else if (rq_is_meta(rq2) && !rq_is_meta(rq1)) - return rq2; + if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2)) + return crq1; + else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1)) + return crq2; - s1 = rq1->sector; - s2 = rq2->sector; + s1 = crq1->request->sector; + s2 = crq2->request->sector; last = cfqd->last_sector; @@ -291,23 +392,23 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) * check two variables for all permutations: --> faster! */ switch (wrap) { - case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ + case 0: /* common case for CFQ: crq1 and crq2 not wrapped */ if (d1 < d2) - return rq1; + return crq1; else if (d2 < d1) - return rq2; + return crq2; else { if (s1 >= s2) - return rq1; + return crq1; else - return rq2; + return crq2; } case CFQ_RQ2_WRAP: - return rq1; + return crq1; case CFQ_RQ1_WRAP: - return rq2; - case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both rqs wrapped */ + return crq2; + case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both crqs wrapped */ default: /* * Since both rqs are wrapped, @@ -316,43 +417,50 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) * since back seek takes more time than forward. */ if (s1 <= s2) - return rq1; + return crq1; else - return rq2; + return crq2; } } /* * would be nice to take fifo expire time into account as well */ -static struct request * -cfq_find_next_rq(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *last) +static struct cfq_rq * +cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *last) { - struct rb_node *rbnext = rb_next(&last->rb_node); - struct rb_node *rbprev = rb_prev(&last->rb_node); - struct request *next = NULL, *prev = NULL; + struct cfq_rq *crq_next = NULL, *crq_prev = NULL; + struct rb_node *rbnext, *rbprev; - BUG_ON(RB_EMPTY_NODE(&last->rb_node)); + if (!(rbnext = rb_next(&last->rb_node))) { + rbnext = rb_first(&cfqq->sort_list); + if (rbnext == &last->rb_node) + rbnext = NULL; + } - if (rbprev) - prev = rb_entry_rq(rbprev); + rbprev = rb_prev(&last->rb_node); + if (rbprev) + crq_prev = rb_entry_crq(rbprev); if (rbnext) - next = rb_entry_rq(rbnext); - else { - rbnext = rb_first(&cfqq->sort_list); - if (rbnext && rbnext != &last->rb_node) - next = rb_entry_rq(rbnext); - } + crq_next = rb_entry_crq(rbnext); - return cfq_choose_req(cfqd, next, prev); + return cfq_choose_req(cfqd, crq_next, crq_prev); +} + +static void cfq_update_next_crq(struct cfq_rq *crq) +{ + struct cfq_queue *cfqq = crq->cfq_queue; + + if (cfqq->next_crq == crq) + cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq); } static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) { struct cfq_data *cfqd = cfqq->cfqd; - struct list_head *list; + struct list_head *list, *entry; BUG_ON(!cfq_cfqq_on_rr(cfqq)); @@ -377,26 +485,31 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) } /* - * If this queue was preempted or is new (never been serviced), let - * it be added first for fairness but beind other new queues. - * Otherwise, just add to the back of the list. + * if queue was preempted, just add to front to be fair. busy_rr + * isn't sorted, but insert at the back for fairness. */ - if (preempted || cfq_cfqq_queue_new(cfqq)) { - struct list_head *n = list; - struct cfq_queue *__cfqq; + if (preempted || list == &cfqd->busy_rr) { + if (preempted) + list = list->prev; - while (n->next != list) { - __cfqq = list_entry_cfqq(n->next); - if (!cfq_cfqq_queue_new(__cfqq)) - break; + list_add_tail(&cfqq->cfq_list, list); + return; + } - n = n->next; - } + /* + * sort by when queue was last serviced + */ + entry = list; + while ((entry = entry->prev) != list) { + struct cfq_queue *__cfqq = list_entry_cfqq(entry); - list = n; + if (!__cfqq->service_last) + break; + if (time_before(__cfqq->service_last, cfqq->service_last)) + break; } - list_add_tail(&cfqq->cfq_list, list); + list_add(&cfqq->cfq_list, entry); } /* @@ -418,7 +531,7 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) { BUG_ON(!cfq_cfqq_on_rr(cfqq)); cfq_clear_cfqq_on_rr(cfqq); - list_del_init(&cfqq->cfq_list); + list_move(&cfqq->cfq_list, &cfqd->empty_list); BUG_ON(!cfqd->busy_queues); cfqd->busy_queues--; @@ -427,43 +540,81 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) /* * rb tree support functions */ -static inline void cfq_del_rq_rb(struct request *rq) +static inline void cfq_del_crq_rb(struct cfq_rq *crq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - const int sync = rq_is_sync(rq); + const int sync = cfq_crq_is_sync(crq); BUG_ON(!cfqq->queued[sync]); cfqq->queued[sync]--; - elv_rb_del(&cfqq->sort_list, rq); + cfq_update_next_crq(crq); + + rb_erase(&crq->rb_node, &cfqq->sort_list); if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) cfq_del_cfqq_rr(cfqd, cfqq); } -static void cfq_add_rq_rb(struct request *rq) +static struct cfq_rq * +__cfq_add_crq_rb(struct cfq_rq *crq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct rb_node **p = &crq->cfq_queue->sort_list.rb_node; + struct rb_node *parent = NULL; + struct cfq_rq *__crq; + + while (*p) { + parent = *p; + __crq = rb_entry_crq(parent); + + if (crq->rb_key < __crq->rb_key) + p = &(*p)->rb_left; + else if (crq->rb_key > __crq->rb_key) + p = &(*p)->rb_right; + else + return __crq; + } + + rb_link_node(&crq->rb_node, parent, p); + return NULL; +} + +static void cfq_add_crq_rb(struct cfq_rq *crq) +{ + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - struct request *__alias; + struct request *rq = crq->request; + struct cfq_rq *__alias; - cfqq->queued[rq_is_sync(rq)]++; + crq->rb_key = rq_rb_key(rq); + cfqq->queued[cfq_crq_is_sync(crq)]++; /* * looks a little odd, but the first insert might return an alias. * if that happens, put the alias on the dispatch list */ - while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL) + while ((__alias = __cfq_add_crq_rb(crq)) != NULL) cfq_dispatch_insert(cfqd->queue, __alias); + + rb_insert_color(&crq->rb_node, &cfqq->sort_list); + + if (!cfq_cfqq_on_rr(cfqq)) + cfq_add_cfqq_rr(cfqd, cfqq); + + /* + * check if this request is a better next-serve candidate + */ + cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); } static inline void -cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq) +cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq) { - elv_rb_del(&cfqq->sort_list, rq); - cfqq->queued[rq_is_sync(rq)]--; - cfq_add_rq_rb(rq); + rb_erase(&crq->rb_node, &cfqq->sort_list); + cfqq->queued[cfq_crq_is_sync(crq)]--; + + cfq_add_crq_rb(crq); } static struct request * @@ -472,14 +623,27 @@ cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio) struct task_struct *tsk = current; pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio)); struct cfq_queue *cfqq; + struct rb_node *n; + sector_t sector; cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio); - if (cfqq) { - sector_t sector = bio->bi_sector + bio_sectors(bio); + if (!cfqq) + goto out; + + sector = bio->bi_sector + bio_sectors(bio); + n = cfqq->sort_list.rb_node; + while (n) { + struct cfq_rq *crq = rb_entry_crq(n); - return elv_rb_find(&cfqq->sort_list, sector); + if (sector < crq->rb_key) + n = n->rb_left; + else if (sector > crq->rb_key) + n = n->rb_right; + else + return crq->request; } +out: return NULL; } @@ -509,18 +673,11 @@ static void cfq_deactivate_request(request_queue_t *q, struct request *rq) static void cfq_remove_request(struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); - - if (cfqq->next_rq == rq) - cfqq->next_rq = cfq_find_next_rq(cfqq->cfqd, cfqq, rq); + struct cfq_rq *crq = RQ_DATA(rq); list_del_init(&rq->queuelist); - cfq_del_rq_rb(rq); - - if (rq_is_meta(rq)) { - WARN_ON(!cfqq->meta_pending); - cfqq->meta_pending--; - } + cfq_del_crq_rb(crq); + cfq_del_crq_hash(crq); } static int @@ -528,23 +685,39 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct cfq_data *cfqd = q->elevator->elevator_data; struct request *__rq; + int ret; + + __rq = cfq_find_rq_hash(cfqd, bio->bi_sector); + if (__rq && elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } __rq = cfq_find_rq_fmerge(cfqd, bio); if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_FRONT_MERGE; + ret = ELEVATOR_FRONT_MERGE; + goto out; } return ELEVATOR_NO_MERGE; +out: + *req = __rq; + return ret; } -static void cfq_merged_request(request_queue_t *q, struct request *req, - int type) +static void cfq_merged_request(request_queue_t *q, struct request *req) { - if (type == ELEVATOR_FRONT_MERGE) { - struct cfq_queue *cfqq = RQ_CFQQ(req); + struct cfq_data *cfqd = q->elevator->elevator_data; + struct cfq_rq *crq = RQ_DATA(req); + + cfq_del_crq_hash(crq); + cfq_add_crq_hash(cfqd, crq); + + if (rq_rb_key(req) != crq->rb_key) { + struct cfq_queue *cfqq = crq->cfq_queue; - cfq_reposition_rq_rb(cfqq, req); + cfq_update_next_crq(crq); + cfq_reposition_crq_rb(cfqq, crq); } } @@ -552,6 +725,8 @@ static void cfq_merged_requests(request_queue_t *q, struct request *rq, struct request *next) { + cfq_merged_request(q, rq); + /* * reposition in fifo if next is older than rq */ @@ -593,12 +768,13 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cfq_cfqq_wait_request(cfqq)) del_timer(&cfqd->idle_slice_timer); - if (!preempted && !cfq_cfqq_dispatched(cfqq)) + if (!preempted && !cfq_cfqq_dispatched(cfqq)) { + cfqq->service_last = now; cfq_schedule_dispatch(cfqd); + } cfq_clear_cfqq_must_dispatch(cfqq); cfq_clear_cfqq_wait_request(cfqq); - cfq_clear_cfqq_queue_new(cfqq); /* * store what was left of this slice, if the queue idled out @@ -692,25 +868,26 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd) { struct cfq_queue *cfqq = NULL; - if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1) { - /* - * if current list is non-empty, grab first entry. if it is - * empty, get next prio level and grab first entry then if any - * are spliced - */ + /* + * if current list is non-empty, grab first entry. if it is empty, + * get next prio level and grab first entry then if any are spliced + */ + if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1) cfqq = list_entry_cfqq(cfqd->cur_rr.next); - } else if (!list_empty(&cfqd->busy_rr)) { - /* - * If no new queues are available, check if the busy list has - * some before falling back to idle io. - */ + + /* + * If no new queues are available, check if the busy list has some + * before falling back to idle io. + */ + if (!cfqq && !list_empty(&cfqd->busy_rr)) cfqq = list_entry_cfqq(cfqd->busy_rr.next); - } else if (!list_empty(&cfqd->idle_rr)) { - /* - * if we have idle queues and no rt or be queues had pending - * requests, either allow immediate service if the grace period - * has passed or arm the idle grace timer - */ + + /* + * if we have idle queues and no rt or be queues had pending + * requests, either allow immediate service if the grace period + * has passed or arm the idle grace timer + */ + if (!cfqq && !list_empty(&cfqd->idle_rr)) { unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE; if (time_after_eq(jiffies, end)) @@ -765,14 +942,16 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) return 1; } -static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) +static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_queue *cfqq = crq->cfq_queue; + struct request *rq; - cfq_remove_request(rq); - cfqq->on_dispatch[rq_is_sync(rq)]++; - elv_dispatch_sort(q, rq); + cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq); + cfq_remove_request(crq->request); + cfqq->on_dispatch[cfq_crq_is_sync(crq)]++; + elv_dispatch_sort(q, crq->request); rq = list_entry(q->queue_head.prev, struct request, queuelist); cfqd->last_sector = rq->sector + rq->nr_sectors; @@ -781,23 +960,24 @@ static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) /* * return expired entry, or NULL to just start from scratch in rbtree */ -static inline struct request *cfq_check_fifo(struct cfq_queue *cfqq) +static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq) { struct cfq_data *cfqd = cfqq->cfqd; struct request *rq; - int fifo; + struct cfq_rq *crq; if (cfq_cfqq_fifo_expire(cfqq)) return NULL; - if (list_empty(&cfqq->fifo)) - return NULL; - fifo = cfq_cfqq_class_sync(cfqq); - rq = rq_entry_fifo(cfqq->fifo.next); + if (!list_empty(&cfqq->fifo)) { + int fifo = cfq_cfqq_class_sync(cfqq); - if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) { - cfq_mark_cfqq_fifo_expire(cfqq); - return rq; + crq = RQ_DATA(list_entry_fifo(cfqq->fifo.next)); + rq = crq->request; + if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) { + cfq_mark_cfqq_fifo_expire(cfqq); + return crq; + } } return NULL; @@ -883,25 +1063,25 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); do { - struct request *rq; + struct cfq_rq *crq; /* * follow expired path, else get first next available */ - if ((rq = cfq_check_fifo(cfqq)) == NULL) - rq = cfqq->next_rq; + if ((crq = cfq_check_fifo(cfqq)) == NULL) + crq = cfqq->next_crq; /* * finally, insert request into driver dispatch list */ - cfq_dispatch_insert(cfqd->queue, rq); + cfq_dispatch_insert(cfqd->queue, crq); cfqd->dispatch_slice++; dispatched++; if (!cfqd->active_cic) { - atomic_inc(&RQ_CIC(rq)->ioc->refcount); - cfqd->active_cic = RQ_CIC(rq); + atomic_inc(&crq->io_context->ioc->refcount); + cfqd->active_cic = crq->io_context; } if (RB_EMPTY_ROOT(&cfqq->sort_list)) @@ -932,12 +1112,13 @@ static int cfq_forced_dispatch_cfqqs(struct list_head *list) { struct cfq_queue *cfqq, *next; + struct cfq_rq *crq; int dispatched; dispatched = 0; list_for_each_entry_safe(cfqq, next, list, cfq_list) { - while (cfqq->next_rq) { - cfq_dispatch_insert(cfqq->cfqd->queue, cfqq->next_rq); + while ((crq = cfqq->next_crq)) { + cfq_dispatch_insert(cfqq->cfqd->queue, crq); dispatched++; } BUG_ON(!list_empty(&cfqq->fifo)); @@ -1013,8 +1194,8 @@ cfq_dispatch_requests(request_queue_t *q, int force) } /* - * task holds one reference to the queue, dropped when task exits. each rq - * in-flight on this queue also holds a reference, dropped when rq is freed. + * task holds one reference to the queue, dropped when task exits. each crq + * in-flight on this queue also holds a reference, dropped when crq is freed. * * queue lock must be held here. */ @@ -1042,7 +1223,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) kmem_cache_free(cfq_pool, cfqq); } -static struct cfq_queue * +static inline struct cfq_queue * __cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio, const int hashval) { @@ -1079,63 +1260,62 @@ static void cfq_free_io_context(struct io_context *ioc) freed++; } - elv_ioc_count_mod(ioc_count, -freed); - - if (ioc_gone && !elv_ioc_count_read(ioc_count)) + if (atomic_sub_and_test(freed, &ioc_count) && ioc_gone) complete(ioc_gone); } -static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) +static void cfq_trim(struct io_context *ioc) { - if (unlikely(cfqq == cfqd->active_queue)) - __cfq_slice_expired(cfqd, cfqq, 0); - - cfq_put_queue(cfqq); + ioc->set_ioprio = NULL; + cfq_free_io_context(ioc); } -static void __cfq_exit_single_io_context(struct cfq_data *cfqd, - struct cfq_io_context *cic) +/* + * Called with interrupts disabled + */ +static void cfq_exit_single_io_context(struct cfq_io_context *cic) { - list_del_init(&cic->queue_list); - smp_wmb(); - cic->key = NULL; + struct cfq_data *cfqd = cic->key; + request_queue_t *q; + + if (!cfqd) + return; + + q = cfqd->queue; + + WARN_ON(!irqs_disabled()); + + spin_lock(q->queue_lock); if (cic->cfqq[ASYNC]) { - cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]); + if (unlikely(cic->cfqq[ASYNC] == cfqd->active_queue)) + __cfq_slice_expired(cfqd, cic->cfqq[ASYNC], 0); + cfq_put_queue(cic->cfqq[ASYNC]); cic->cfqq[ASYNC] = NULL; } if (cic->cfqq[SYNC]) { - cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]); + if (unlikely(cic->cfqq[SYNC] == cfqd->active_queue)) + __cfq_slice_expired(cfqd, cic->cfqq[SYNC], 0); + cfq_put_queue(cic->cfqq[SYNC]); cic->cfqq[SYNC] = NULL; } -} - -/* - * Called with interrupts disabled - */ -static void cfq_exit_single_io_context(struct cfq_io_context *cic) -{ - struct cfq_data *cfqd = cic->key; - - if (cfqd) { - request_queue_t *q = cfqd->queue; - - spin_lock_irq(q->queue_lock); - __cfq_exit_single_io_context(cfqd, cic); - spin_unlock_irq(q->queue_lock); - } + cic->key = NULL; + list_del_init(&cic->queue_list); + spin_unlock(q->queue_lock); } static void cfq_exit_io_context(struct io_context *ioc) { struct cfq_io_context *__cic; + unsigned long flags; struct rb_node *n; /* * put the reference this task is holding to the various queues */ + spin_lock_irqsave(&cfq_exit_lock, flags); n = rb_first(&ioc->cic_root); while (n != NULL) { @@ -1144,21 +1324,22 @@ static void cfq_exit_io_context(struct io_context *ioc) cfq_exit_single_io_context(__cic); n = rb_next(n); } + + spin_unlock_irqrestore(&cfq_exit_lock, flags); } static struct cfq_io_context * cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) { - struct cfq_io_context *cic; + struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask); - cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask, cfqd->queue->node); if (cic) { memset(cic, 0, sizeof(*cic)); cic->last_end_request = jiffies; INIT_LIST_HEAD(&cic->queue_list); cic->dtor = cfq_free_io_context; cic->exit = cfq_exit_io_context; - elv_ioc_count_inc(ioc_count); + atomic_inc(&ioc_count); } return cic; @@ -1239,12 +1420,15 @@ static inline void changed_ioprio(struct cfq_io_context *cic) spin_unlock(cfqd->queue->queue_lock); } -static void cfq_ioc_set_ioprio(struct io_context *ioc) +/* + * callback from sys_ioprio_set, irqs are disabled + */ +static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio) { struct cfq_io_context *cic; struct rb_node *n; - ioc->ioprio_changed = 0; + spin_lock(&cfq_exit_lock); n = rb_first(&ioc->cic_root); while (n != NULL) { @@ -1253,6 +1437,10 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc) changed_ioprio(cic); n = rb_next(n); } + + spin_unlock(&cfq_exit_lock); + + return 0; } static struct cfq_queue * @@ -1272,18 +1460,12 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, cfqq = new_cfqq; new_cfqq = NULL; } else if (gfp_mask & __GFP_WAIT) { - /* - * Inform the allocator of the fact that we will - * just repeat this allocation if it fails, to allow - * the allocator to do whatever it needs to attempt to - * free memory. - */ spin_unlock_irq(cfqd->queue->queue_lock); - new_cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask|__GFP_NOFAIL, cfqd->queue->node); + new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); spin_lock_irq(cfqd->queue->queue_lock); goto retry; } else { - cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask, cfqd->queue->node); + cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); if (!cfqq) goto out; } @@ -1298,13 +1480,13 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]); atomic_set(&cfqq->ref, 0); cfqq->cfqd = cfqd; + cfqq->service_last = 0; /* * set ->slice_left to allow preemption for a new process */ cfqq->slice_left = 2 * cfqd->cfq_slice_idle; cfq_mark_cfqq_idle_window(cfqq); cfq_mark_cfqq_prio_changed(cfqq); - cfq_mark_cfqq_queue_new(cfqq); cfq_init_prio_data(cfqq); } @@ -1320,10 +1502,12 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, static void cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) { - WARN_ON(!list_empty(&cic->queue_list)); + spin_lock(&cfq_exit_lock); rb_erase(&cic->rb_node, &ioc->cic_root); + list_del_init(&cic->queue_list); + spin_unlock(&cfq_exit_lock); kmem_cache_free(cfq_ioc_pool, cic); - elv_ioc_count_dec(ioc_count); + atomic_dec(&ioc_count); } static struct cfq_io_context * @@ -1367,6 +1551,7 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, cic->ioc = ioc; cic->key = cfqd; + ioc->set_ioprio = cfq_ioc_set_ioprio; restart: parent = NULL; p = &ioc->cic_root.rb_node; @@ -1388,12 +1573,11 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, BUG(); } + spin_lock(&cfq_exit_lock); rb_link_node(&cic->rb_node, parent, p); rb_insert_color(&cic->rb_node, &ioc->cic_root); - - spin_lock_irq(cfqd->queue->queue_lock); list_add(&cic->queue_list, &cfqd->cic_list); - spin_unlock_irq(cfqd->queue->queue_lock); + spin_unlock(&cfq_exit_lock); } /* @@ -1409,7 +1593,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) might_sleep_if(gfp_mask & __GFP_WAIT); - ioc = get_io_context(gfp_mask, cfqd->queue->node); + ioc = get_io_context(gfp_mask); if (!ioc) return NULL; @@ -1423,10 +1607,6 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) cfq_cic_link(cfqd, ioc, cic); out: - smp_read_barrier_depends(); - if (unlikely(ioc->ioprio_changed)) - cfq_ioc_set_ioprio(ioc); - return cic; err: put_io_context(ioc); @@ -1460,15 +1640,15 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic) static void cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, - struct request *rq) + struct cfq_rq *crq) { sector_t sdist; u64 total; - if (cic->last_request_pos < rq->sector) - sdist = rq->sector - cic->last_request_pos; + if (cic->last_request_pos < crq->request->sector) + sdist = crq->request->sector - cic->last_request_pos; else - sdist = cic->last_request_pos - rq->sector; + sdist = cic->last_request_pos - crq->request->sector; /* * Don't allow the seek distance to get too large from the @@ -1519,7 +1699,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ static int cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, - struct request *rq) + struct cfq_rq *crq) { struct cfq_queue *cfqq = cfqd->active_queue; @@ -1538,17 +1718,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ if (new_cfqq->slice_left < cfqd->cfq_slice_idle) return 0; - /* - * if the new request is sync, but the currently running queue is - * not, let the sync request have priority. - */ - if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) - return 1; - /* - * So both queues are sync. Let the new request get disk time if - * it's a metadata request and the current queue is doing regular IO. - */ - if (rq_is_meta(rq) && !cfqq->meta_pending) + if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq)) return 1; return 0; @@ -1560,45 +1730,47 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - cfq_slice_expired(cfqd, 1); + struct cfq_queue *__cfqq, *next; + + list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list) + cfq_resort_rr_list(__cfqq, 1); if (!cfqq->slice_left) cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2; - /* - * Put the new queue at the front of the of the current list, - * so we know that it will be selected next. - */ - BUG_ON(!cfq_cfqq_on_rr(cfqq)); - list_move(&cfqq->cfq_list, &cfqd->cur_rr); - cfqq->slice_end = cfqq->slice_left + jiffies; + cfq_slice_expired(cfqd, 1); + __cfq_set_active_queue(cfqd, cfqq); } /* - * Called when a new fs request (rq) is added (to cfqq). Check if there's - * something we should do about it + * should really be a ll_rw_blk.c helper */ -static void -cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *rq) +static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - struct cfq_io_context *cic = RQ_CIC(rq); + request_queue_t *q = cfqd->queue; - if (rq_is_meta(rq)) - cfqq->meta_pending++; + if (!blk_queue_plugged(q)) + q->request_fn(q); + else + __generic_unplug_device(q); +} - /* - * check if this request is a better next-serve candidate)) { - */ - cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); - BUG_ON(!cfqq->next_rq); +/* + * Called when a new fs request (crq) is added (to cfqq). Check if there's + * something we should do about it + */ +static void +cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *crq) +{ + struct cfq_io_context *cic = crq->io_context; /* * we never wait for an async request and we don't allow preemption * of an async request. so just return early */ - if (!rq_is_sync(rq)) { + if (!cfq_crq_is_sync(crq)) { /* * sync process issued an async request, if it's waiting * then expire it and kick rq handling. @@ -1606,17 +1778,17 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cic == cfqd->active_cic && del_timer(&cfqd->idle_slice_timer)) { cfq_slice_expired(cfqd, 0); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } return; } cfq_update_io_thinktime(cfqd, cic); - cfq_update_io_seektime(cfqd, cic, rq); + cfq_update_io_seektime(cfqd, cic, crq); cfq_update_idle_window(cfqd, cfqq, cic); cic->last_queue = jiffies; - cic->last_request_pos = rq->sector + rq->nr_sectors; + cic->last_request_pos = crq->request->sector + crq->request->nr_sectors; if (cfqq == cfqd->active_queue) { /* @@ -1627,9 +1799,9 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cfq_cfqq_wait_request(cfqq)) { cfq_mark_cfqq_must_dispatch(cfqq); del_timer(&cfqd->idle_slice_timer); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } - } else if (cfq_should_preempt(cfqd, cfqq, rq)) { + } else if (cfq_should_preempt(cfqd, cfqq, crq)) { /* * not the active queue - expire current slice if it is * idle and has expired it's mean thinktime or this new queue @@ -1637,32 +1809,34 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ cfq_preempt_queue(cfqd, cfqq); cfq_mark_cfqq_must_dispatch(cfqq); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } } static void cfq_insert_request(request_queue_t *q, struct request *rq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = crq->cfq_queue; cfq_init_prio_data(cfqq); - cfq_add_rq_rb(rq); - - if (!cfq_cfqq_on_rr(cfqq)) - cfq_add_cfqq_rr(cfqd, cfqq); + cfq_add_crq_rb(crq); list_add_tail(&rq->queuelist, &cfqq->fifo); - cfq_rq_enqueued(cfqd, cfqq, rq); + if (rq_mergeable(rq)) + cfq_add_crq_hash(cfqd, crq); + + cfq_crq_enqueued(cfqd, cfqq, crq); } static void cfq_completed_request(request_queue_t *q, struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - const int sync = rq_is_sync(rq); + const int sync = cfq_crq_is_sync(crq); unsigned long now; now = jiffies; @@ -1675,11 +1849,15 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) if (!cfq_class_idle(cfqq)) cfqd->last_end_request = now; - if (!cfq_cfqq_dispatched(cfqq) && cfq_cfqq_on_rr(cfqq)) - cfq_resort_rr_list(cfqq, 0); + if (!cfq_cfqq_dispatched(cfqq)) { + if (cfq_cfqq_on_rr(cfqq)) { + cfqq->service_last = now; + cfq_resort_rr_list(cfqq, 0); + } + } if (sync) - RQ_CIC(rq)->last_end_request = now; + crq->io_context->last_end_request = now; /* * If this is the active queue, check if it needs to be expired, @@ -1695,6 +1873,30 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) } } +static struct request * +cfq_former_request(request_queue_t *q, struct request *rq) +{ + struct cfq_rq *crq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&crq->rb_node); + + if (rbprev) + return rb_entry_crq(rbprev)->request; + + return NULL; +} + +static struct request * +cfq_latter_request(request_queue_t *q, struct request *rq) +{ + struct cfq_rq *crq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&crq->rb_node); + + if (rbnext) + return rb_entry_crq(rbnext)->request; + + return NULL; +} + /* * we temporarily boost lower priority queues if they are holding fs exclusive * resources. they are boosted to normal prio (CLASS_BE/4) @@ -1731,7 +1933,9 @@ static void cfq_prio_boost(struct cfq_queue *cfqq) cfq_resort_rr_list(cfqq, 0); } -static inline int __cfq_may_queue(struct cfq_queue *cfqq) +static inline int +__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct task_struct *task, int rw) { if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) && !cfq_cfqq_must_alloc_slice(cfqq)) { @@ -1742,7 +1946,7 @@ static inline int __cfq_may_queue(struct cfq_queue *cfqq) return ELV_MQUEUE_MAY; } -static int cfq_may_queue(request_queue_t *q, int rw) +static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -1759,30 +1963,48 @@ static int cfq_may_queue(request_queue_t *q, int rw) cfq_init_prio_data(cfqq); cfq_prio_boost(cfqq); - return __cfq_may_queue(cfqq); + return __cfq_may_queue(cfqd, cfqq, tsk, rw); } return ELV_MQUEUE_MAY; } +static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq) +{ + struct cfq_data *cfqd = q->elevator->elevator_data; + + if (unlikely(cfqd->rq_starved)) { + struct request_list *rl = &q->rq; + + smp_mb(); + if (waitqueue_active(&rl->wait[READ])) + wake_up(&rl->wait[READ]); + if (waitqueue_active(&rl->wait[WRITE])) + wake_up(&rl->wait[WRITE]); + } +} + /* * queue lock held here */ static void cfq_put_request(request_queue_t *q, struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_data *cfqd = q->elevator->elevator_data; + struct cfq_rq *crq = RQ_DATA(rq); - if (cfqq) { + if (crq) { + struct cfq_queue *cfqq = crq->cfq_queue; const int rw = rq_data_dir(rq); BUG_ON(!cfqq->allocated[rw]); cfqq->allocated[rw]--; - put_io_context(RQ_CIC(rq)->ioc); + put_io_context(crq->io_context->ioc); + mempool_free(crq, cfqd->crq_pool); rq->elevator_private = NULL; - rq->elevator_private2 = NULL; + cfq_check_waiters(q, cfqq); cfq_put_queue(cfqq); } } @@ -1791,7 +2013,8 @@ static void cfq_put_request(request_queue_t *q, struct request *rq) * Allocate cfq data structures associated with this request. */ static int -cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) +cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -1799,6 +2022,7 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) const int rw = rq_data_dir(rq); pid_t key = cfq_queue_pid(tsk, rw); struct cfq_queue *cfqq; + struct cfq_rq *crq; unsigned long flags; int is_sync = key != CFQ_KEY_ASYNC; @@ -1822,18 +2046,42 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) cfqq->allocated[rw]++; cfq_clear_cfqq_must_alloc(cfqq); + cfqd->rq_starved = 0; atomic_inc(&cfqq->ref); - spin_unlock_irqrestore(q->queue_lock, flags); - rq->elevator_private = cic; - rq->elevator_private2 = cfqq; - return 0; + crq = mempool_alloc(cfqd->crq_pool, gfp_mask); + if (crq) { + RB_CLEAR_NODE(&crq->rb_node); + crq->rb_key = 0; + crq->request = rq; + INIT_HLIST_NODE(&crq->hash); + crq->cfq_queue = cfqq; + crq->io_context = cic; + + if (is_sync) + cfq_mark_crq_is_sync(crq); + else + cfq_clear_crq_is_sync(crq); + rq->elevator_private = crq; + return 0; + } + + spin_lock_irqsave(q->queue_lock, flags); + cfqq->allocated[rw]--; + if (!(cfqq->allocated[0] + cfqq->allocated[1])) + cfq_mark_cfqq_must_alloc(cfqq); + cfq_put_queue(cfqq); queue_fail: if (cic) put_io_context(cic->ioc); - + /* + * mark us rq allocation starved. we need to kickstart the process + * ourselves if there are no pending requests that can do it for us. + * that would be an extremely rare OOM situation + */ + cfqd->rq_starved = 1; cfq_schedule_dispatch(cfqd); spin_unlock_irqrestore(q->queue_lock, flags); return 1; @@ -1842,10 +2090,27 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) static void cfq_kick_queue(void *data) { request_queue_t *q = data; + struct cfq_data *cfqd = q->elevator->elevator_data; unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - blk_start_queueing(q); + + if (cfqd->rq_starved) { + struct request_list *rl = &q->rq; + + /* + * we aren't guaranteed to get a request after this, but we + * have to be opportunistic + */ + smp_mb(); + if (waitqueue_active(&rl->wait[READ])) + wake_up(&rl->wait[READ]); + if (waitqueue_active(&rl->wait[WRITE])) + wake_up(&rl->wait[WRITE]); + } + + blk_remove_plug(q); + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -1928,6 +2193,7 @@ static void cfq_exit_queue(elevator_t *e) cfq_shutdown_timer_wq(cfqd); + spin_lock(&cfq_exit_lock); spin_lock_irq(q->queue_lock); if (cfqd->active_queue) @@ -1937,14 +2203,25 @@ static void cfq_exit_queue(elevator_t *e) struct cfq_io_context *cic = list_entry(cfqd->cic_list.next, struct cfq_io_context, queue_list); - - __cfq_exit_single_io_context(cfqd, cic); + if (cic->cfqq[ASYNC]) { + cfq_put_queue(cic->cfqq[ASYNC]); + cic->cfqq[ASYNC] = NULL; + } + if (cic->cfqq[SYNC]) { + cfq_put_queue(cic->cfqq[SYNC]); + cic->cfqq[SYNC] = NULL; + } + cic->key = NULL; + list_del_init(&cic->queue_list); } spin_unlock_irq(q->queue_lock); + spin_unlock(&cfq_exit_lock); cfq_shutdown_timer_wq(cfqd); + mempool_destroy(cfqd->crq_pool); + kfree(cfqd->crq_hash); kfree(cfqd->cfq_hash); kfree(cfqd); } @@ -1954,7 +2231,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) struct cfq_data *cfqd; int i; - cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL, q->node); + cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); if (!cfqd) return NULL; @@ -1966,12 +2243,23 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) INIT_LIST_HEAD(&cfqd->busy_rr); INIT_LIST_HEAD(&cfqd->cur_rr); INIT_LIST_HEAD(&cfqd->idle_rr); + INIT_LIST_HEAD(&cfqd->empty_list); INIT_LIST_HEAD(&cfqd->cic_list); - cfqd->cfq_hash = kmalloc_node(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL, q->node); + cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL); + if (!cfqd->crq_hash) + goto out_crqhash; + + cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL); if (!cfqd->cfq_hash) - goto out_free; + goto out_cfqhash; + + cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool); + if (!cfqd->crq_pool) + goto out_crqpool; + for (i = 0; i < CFQ_MHASH_ENTRIES; i++) + INIT_HLIST_HEAD(&cfqd->crq_hash[i]); for (i = 0; i < CFQ_QHASH_ENTRIES; i++) INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); @@ -1987,6 +2275,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q); + cfqd->cfq_queued = cfq_queued; cfqd->cfq_quantum = cfq_quantum; cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1]; @@ -1998,13 +2287,19 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->cfq_slice_idle = cfq_slice_idle; return cfqd; -out_free: +out_crqpool: + kfree(cfqd->cfq_hash); +out_cfqhash: + kfree(cfqd->crq_hash); +out_crqhash: kfree(cfqd); return NULL; } static void cfq_slab_kill(void) { + if (crq_pool) + kmem_cache_destroy(crq_pool); if (cfq_pool) kmem_cache_destroy(cfq_pool); if (cfq_ioc_pool) @@ -2013,6 +2308,11 @@ static void cfq_slab_kill(void) static int __init cfq_slab_setup(void) { + crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0, + NULL, NULL); + if (!crq_pool) + goto fail; + cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0, NULL, NULL); if (!cfq_pool) @@ -2058,6 +2358,7 @@ static ssize_t __FUNC(elevator_t *e, char *page) \ return cfq_var_show(__data, (page)); \ } SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum, 0); +SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued, 0); SHOW_FUNCTION(cfq_fifo_expire_sync_show, cfqd->cfq_fifo_expire[1], 1); SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1); SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0); @@ -2085,6 +2386,7 @@ static ssize_t __FUNC(elevator_t *e, const char *page, size_t count) \ return ret; \ } STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0); +STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_fifo_expire_async_store, &cfqd->cfq_fifo_expire[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_back_seek_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0); @@ -2100,6 +2402,7 @@ STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(quantum), + CFQ_ATTR(queued), CFQ_ATTR(fifo_expire_sync), CFQ_ATTR(fifo_expire_async), CFQ_ATTR(back_seek_max), @@ -2122,14 +2425,14 @@ static struct elevator_type iosched_cfq = { .elevator_deactivate_req_fn = cfq_deactivate_request, .elevator_queue_empty_fn = cfq_queue_empty, .elevator_completed_req_fn = cfq_completed_request, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = cfq_former_request, + .elevator_latter_req_fn = cfq_latter_request, .elevator_set_req_fn = cfq_set_request, .elevator_put_req_fn = cfq_put_request, .elevator_may_queue_fn = cfq_may_queue, .elevator_init_fn = cfq_init_queue, .elevator_exit_fn = cfq_exit_queue, - .trim = cfq_free_io_context, + .trim = cfq_trim, }, .elevator_attrs = cfq_attrs, .elevator_name = "cfq", @@ -2160,12 +2463,12 @@ static int __init cfq_init(void) static void __exit cfq_exit(void) { - DECLARE_COMPLETION_ONSTACK(all_gone); + DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_cfq); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (elv_ioc_count_read(ioc_count)) + if (atomic_read(&ioc_count)) wait_for_completion(ioc_gone); synchronize_rcu(); cfq_slab_kill(); diff --git a/trunk/block/deadline-iosched.c b/trunk/block/deadline-iosched.c index b7c5b34cb7b4..c7ca9f0b6498 100644 --- a/trunk/block/deadline-iosched.c +++ b/trunk/block/deadline-iosched.c @@ -1,7 +1,7 @@ /* * Deadline i/o scheduler. * - * Copyright (C) 2002 Jens Axboe + * Copyright (C) 2002 Jens Axboe */ #include #include @@ -12,6 +12,7 @@ #include #include #include +#include #include /* @@ -23,6 +24,13 @@ static const int writes_starved = 2; /* max times reads can starve a write */ static const int fifo_batch = 16; /* # of sequential requests treated as one by the above parameters. For throughput. */ +static const int deadline_hash_shift = 5; +#define DL_HASH_BLOCK(sec) ((sec) >> 3) +#define DL_HASH_FN(sec) (hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift)) +#define DL_HASH_ENTRIES (1 << deadline_hash_shift) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) +#define ON_HASH(drq) (!hlist_unhashed(&(drq)->hash)) + struct deadline_data { /* * run time data @@ -37,7 +45,8 @@ struct deadline_data { /* * next in sort order. read, write or both are NULL */ - struct request *next_rq[2]; + struct deadline_rq *next_drq[2]; + struct hlist_head *hash; /* request hash */ unsigned int batching; /* number of sequential requests made */ sector_t last_sector; /* head position */ unsigned int starved; /* times reads have starved writes */ @@ -49,69 +58,240 @@ struct deadline_data { int fifo_batch; int writes_starved; int front_merges; + + mempool_t *drq_pool; }; -static void deadline_move_request(struct deadline_data *, struct request *); +/* + * pre-request data. + */ +struct deadline_rq { + /* + * rbtree index, key is the starting offset + */ + struct rb_node rb_node; + sector_t rb_key; + + struct request *request; + + /* + * request hash, key is the ending offset (for back merge lookup) + */ + struct hlist_node hash; + + /* + * expire fifo + */ + struct list_head fifo; + unsigned long expires; +}; + +static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq); + +static kmem_cache_t *drq_pool; + +#define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private) -#define RQ_RB_ROOT(dd, rq) (&(dd)->sort_list[rq_data_dir((rq))]) +/* + * the back merge hash support functions + */ +static inline void __deadline_del_drq_hash(struct deadline_rq *drq) +{ + hlist_del_init(&drq->hash); +} + +static inline void deadline_del_drq_hash(struct deadline_rq *drq) +{ + if (ON_HASH(drq)) + __deadline_del_drq_hash(drq); +} + +static inline void +deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct request *rq = drq->request; + + BUG_ON(ON_HASH(drq)); + + hlist_add_head(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]); +} + +/* + * move hot entry to front of chain + */ +static inline void +deadline_hot_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct request *rq = drq->request; + struct hlist_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))]; + + if (ON_HASH(drq) && &drq->hash != head->first) { + hlist_del(&drq->hash); + hlist_add_head(&drq->hash, head); + } +} + +static struct request * +deadline_find_drq_hash(struct deadline_data *dd, sector_t offset) +{ + struct hlist_head *hash_list = &dd->hash[DL_HASH_FN(offset)]; + struct hlist_node *entry, *next; + struct deadline_rq *drq; + + hlist_for_each_entry_safe(drq, entry, next, hash_list, hash) { + struct request *__rq = drq->request; + + BUG_ON(!ON_HASH(drq)); + + if (!rq_mergeable(__rq)) { + __deadline_del_drq_hash(drq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; +} + +/* + * rb tree support functions + */ +#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node) +#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)]) +#define rq_rb_key(rq) (rq)->sector + +static struct deadline_rq * +__deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct rb_node **p = &DRQ_RB_ROOT(dd, drq)->rb_node; + struct rb_node *parent = NULL; + struct deadline_rq *__drq; + + while (*p) { + parent = *p; + __drq = rb_entry_drq(parent); + + if (drq->rb_key < __drq->rb_key) + p = &(*p)->rb_left; + else if (drq->rb_key > __drq->rb_key) + p = &(*p)->rb_right; + else + return __drq; + } + + rb_link_node(&drq->rb_node, parent, p); + return NULL; +} static void -deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) +deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) { - struct rb_root *root = RQ_RB_ROOT(dd, rq); - struct request *__alias; + struct deadline_rq *__alias; + + drq->rb_key = rq_rb_key(drq->request); retry: - __alias = elv_rb_add(root, rq); - if (unlikely(__alias)) { - deadline_move_request(dd, __alias); - goto retry; + __alias = __deadline_add_drq_rb(dd, drq); + if (!__alias) { + rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); + return; } + + deadline_move_request(dd, __alias); + goto retry; } static inline void -deadline_del_rq_rb(struct deadline_data *dd, struct request *rq) +deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) { - const int data_dir = rq_data_dir(rq); + const int data_dir = rq_data_dir(drq->request); - if (dd->next_rq[data_dir] == rq) { - struct rb_node *rbnext = rb_next(&rq->rb_node); + if (dd->next_drq[data_dir] == drq) { + struct rb_node *rbnext = rb_next(&drq->rb_node); - dd->next_rq[data_dir] = NULL; + dd->next_drq[data_dir] = NULL; if (rbnext) - dd->next_rq[data_dir] = rb_entry_rq(rbnext); + dd->next_drq[data_dir] = rb_entry_drq(rbnext); + } + + BUG_ON(!RB_EMPTY_NODE(&drq->rb_node)); + rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); + RB_CLEAR_NODE(&drq->rb_node); +} + +static struct request * +deadline_find_drq_rb(struct deadline_data *dd, sector_t sector, int data_dir) +{ + struct rb_node *n = dd->sort_list[data_dir].rb_node; + struct deadline_rq *drq; + + while (n) { + drq = rb_entry_drq(n); + + if (sector < drq->rb_key) + n = n->rb_left; + else if (sector > drq->rb_key) + n = n->rb_right; + else + return drq->request; } - elv_rb_del(RQ_RB_ROOT(dd, rq), rq); + return NULL; } /* - * add rq to rbtree and fifo + * deadline_find_first_drq finds the first (lowest sector numbered) request + * for the specified data_dir. Used to sweep back to the start of the disk + * (1-way elevator) after we process the last (highest sector) request. + */ +static struct deadline_rq * +deadline_find_first_drq(struct deadline_data *dd, int data_dir) +{ + struct rb_node *n = dd->sort_list[data_dir].rb_node; + + for (;;) { + if (n->rb_left == NULL) + return rb_entry_drq(n); + + n = n->rb_left; + } +} + +/* + * add drq to rbtree and fifo */ static void deadline_add_request(struct request_queue *q, struct request *rq) { struct deadline_data *dd = q->elevator->elevator_data; - const int data_dir = rq_data_dir(rq); + struct deadline_rq *drq = RQ_DATA(rq); - deadline_add_rq_rb(dd, rq); + const int data_dir = rq_data_dir(drq->request); + deadline_add_drq_rb(dd, drq); /* * set expire time (only used for reads) and add to fifo list */ - rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]); - list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); + drq->expires = jiffies + dd->fifo_expire[data_dir]; + list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]); + + if (rq_mergeable(rq)) + deadline_add_drq_hash(dd, drq); } /* - * remove rq from rbtree and fifo. + * remove rq from rbtree, fifo, and hash */ static void deadline_remove_request(request_queue_t *q, struct request *rq) { + struct deadline_rq *drq = RQ_DATA(rq); struct deadline_data *dd = q->elevator->elevator_data; - rq_fifo_clear(rq); - deadline_del_rq_rb(dd, rq); + list_del_init(&drq->fifo); + deadline_del_drq_rb(dd, drq); + deadline_del_drq_hash(drq); } static int @@ -121,15 +301,28 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) struct request *__rq; int ret; + /* + * see if the merge hash can satisfy a back merge + */ + __rq = deadline_find_drq_hash(dd, bio->bi_sector); + if (__rq) { + BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } + } + /* * check for front merge */ if (dd->front_merges) { - sector_t sector = bio->bi_sector + bio_sectors(bio); + sector_t rb_key = bio->bi_sector + bio_sectors(bio); - __rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector); + __rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio)); if (__rq) { - BUG_ON(sector != __rq->sector); + BUG_ON(rb_key != rq_rb_key(__rq)); if (elv_rq_merge_ok(__rq, bio)) { ret = ELEVATOR_FRONT_MERGE; @@ -140,21 +333,29 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) return ELEVATOR_NO_MERGE; out: + if (ret) + deadline_hot_drq_hash(dd, RQ_DATA(__rq)); *req = __rq; return ret; } -static void deadline_merged_request(request_queue_t *q, struct request *req, - int type) +static void deadline_merged_request(request_queue_t *q, struct request *req) { struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(req); + + /* + * hash always needs to be repositioned, key is end sector + */ + deadline_del_drq_hash(drq); + deadline_add_drq_hash(dd, drq); /* * if the merge was a front merge, we need to reposition request */ - if (type == ELEVATOR_FRONT_MERGE) { - elv_rb_del(RQ_RB_ROOT(dd, req), req); - deadline_add_rq_rb(dd, req); + if (rq_rb_key(req) != drq->rb_key) { + deadline_del_drq_rb(dd, drq); + deadline_add_drq_rb(dd, drq); } } @@ -162,14 +363,33 @@ static void deadline_merged_requests(request_queue_t *q, struct request *req, struct request *next) { + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(req); + struct deadline_rq *dnext = RQ_DATA(next); + + BUG_ON(!drq); + BUG_ON(!dnext); + /* - * if next expires before rq, assign its expire time to rq - * and move into next position (next will be deleted) in fifo + * reposition drq (this is the merged request) in hash, and in rbtree + * in case of a front merge */ - if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { - if (time_before(rq_fifo_time(next), rq_fifo_time(req))) { - list_move(&req->queuelist, &next->queuelist); - rq_set_fifo_time(req, rq_fifo_time(next)); + deadline_del_drq_hash(drq); + deadline_add_drq_hash(dd, drq); + + if (rq_rb_key(req) != drq->rb_key) { + deadline_del_drq_rb(dd, drq); + deadline_add_drq_rb(dd, drq); + } + + /* + * if dnext expires before drq, assign its expire time to drq + * and move into dnext position (dnext will be deleted) in fifo + */ + if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) { + if (time_before(dnext->expires, drq->expires)) { + list_move(&drq->fifo, &dnext->fifo); + drq->expires = dnext->expires; } } @@ -183,50 +403,52 @@ deadline_merged_requests(request_queue_t *q, struct request *req, * move request from sort list to dispatch queue. */ static inline void -deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq) +deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq) { - request_queue_t *q = rq->q; + request_queue_t *q = drq->request->q; - deadline_remove_request(q, rq); - elv_dispatch_add_tail(q, rq); + deadline_remove_request(q, drq->request); + elv_dispatch_add_tail(q, drq->request); } /* * move an entry to dispatch queue */ static void -deadline_move_request(struct deadline_data *dd, struct request *rq) +deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq) { - const int data_dir = rq_data_dir(rq); - struct rb_node *rbnext = rb_next(&rq->rb_node); + const int data_dir = rq_data_dir(drq->request); + struct rb_node *rbnext = rb_next(&drq->rb_node); - dd->next_rq[READ] = NULL; - dd->next_rq[WRITE] = NULL; + dd->next_drq[READ] = NULL; + dd->next_drq[WRITE] = NULL; if (rbnext) - dd->next_rq[data_dir] = rb_entry_rq(rbnext); + dd->next_drq[data_dir] = rb_entry_drq(rbnext); - dd->last_sector = rq->sector + rq->nr_sectors; + dd->last_sector = drq->request->sector + drq->request->nr_sectors; /* * take it off the sort and fifo list, move * to dispatch queue */ - deadline_move_to_dispatch(dd, rq); + deadline_move_to_dispatch(dd, drq); } +#define list_entry_fifo(ptr) list_entry((ptr), struct deadline_rq, fifo) + /* * deadline_check_fifo returns 0 if there are no expired reads on the fifo, * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) */ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) { - struct request *rq = rq_entry_fifo(dd->fifo_list[ddir].next); + struct deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next); /* - * rq is expired! + * drq is expired! */ - if (time_after(jiffies, rq_fifo_time(rq))) + if (time_after(jiffies, drq->expires)) return 1; return 0; @@ -241,21 +463,21 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) struct deadline_data *dd = q->elevator->elevator_data; const int reads = !list_empty(&dd->fifo_list[READ]); const int writes = !list_empty(&dd->fifo_list[WRITE]); - struct request *rq; + struct deadline_rq *drq; int data_dir; /* * batches are currently reads XOR writes */ - if (dd->next_rq[WRITE]) - rq = dd->next_rq[WRITE]; + if (dd->next_drq[WRITE]) + drq = dd->next_drq[WRITE]; else - rq = dd->next_rq[READ]; + drq = dd->next_drq[READ]; - if (rq) { + if (drq) { /* we have a "next request" */ - if (dd->last_sector != rq->sector) + if (dd->last_sector != drq->request->sector) /* end the batch on a non sequential request */ dd->batching += dd->fifo_batch; @@ -304,33 +526,30 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) if (deadline_check_fifo(dd, data_dir)) { /* An expired request exists - satisfy it */ dd->batching = 0; - rq = rq_entry_fifo(dd->fifo_list[data_dir].next); + drq = list_entry_fifo(dd->fifo_list[data_dir].next); - } else if (dd->next_rq[data_dir]) { + } else if (dd->next_drq[data_dir]) { /* * The last req was the same dir and we have a next request in * sort order. No expired requests so continue on from here. */ - rq = dd->next_rq[data_dir]; + drq = dd->next_drq[data_dir]; } else { - struct rb_node *node; /* * The last req was the other direction or we have run out of * higher-sectored requests. Go back to the lowest sectored * request (1 way elevator) and start a new batch. */ dd->batching = 0; - node = rb_first(&dd->sort_list[data_dir]); - if (node) - rq = rb_entry_rq(node); + drq = deadline_find_first_drq(dd, data_dir); } dispatch_request: /* - * rq is the selected appropriate request. + * drq is the selected appropriate request. */ dd->batching++; - deadline_move_request(dd, rq); + deadline_move_request(dd, drq); return 1; } @@ -343,6 +562,30 @@ static int deadline_queue_empty(request_queue_t *q) && list_empty(&dd->fifo_list[READ]); } +static struct request * +deadline_former_request(request_queue_t *q, struct request *rq) +{ + struct deadline_rq *drq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&drq->rb_node); + + if (rbprev) + return rb_entry_drq(rbprev)->request; + + return NULL; +} + +static struct request * +deadline_latter_request(request_queue_t *q, struct request *rq) +{ + struct deadline_rq *drq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&drq->rb_node); + + if (rbnext) + return rb_entry_drq(rbnext)->request; + + return NULL; +} + static void deadline_exit_queue(elevator_t *e) { struct deadline_data *dd = e->elevator_data; @@ -350,21 +593,46 @@ static void deadline_exit_queue(elevator_t *e) BUG_ON(!list_empty(&dd->fifo_list[READ])); BUG_ON(!list_empty(&dd->fifo_list[WRITE])); + mempool_destroy(dd->drq_pool); + kfree(dd->hash); kfree(dd); } /* - * initialize elevator private data (deadline_data). + * initialize elevator private data (deadline_data), and alloc a drq for + * each request on the free lists */ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) { struct deadline_data *dd; + int i; + + if (!drq_pool) + return NULL; dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); if (!dd) return NULL; memset(dd, 0, sizeof(*dd)); + dd->hash = kmalloc_node(sizeof(struct hlist_head)*DL_HASH_ENTRIES, + GFP_KERNEL, q->node); + if (!dd->hash) { + kfree(dd); + return NULL; + } + + dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, + mempool_free_slab, drq_pool, q->node); + if (!dd->drq_pool) { + kfree(dd->hash); + kfree(dd); + return NULL; + } + + for (i = 0; i < DL_HASH_ENTRIES; i++) + INIT_HLIST_HEAD(&dd->hash[i]); + INIT_LIST_HEAD(&dd->fifo_list[READ]); INIT_LIST_HEAD(&dd->fifo_list[WRITE]); dd->sort_list[READ] = RB_ROOT; @@ -377,6 +645,39 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) return dd; } +static void deadline_put_request(request_queue_t *q, struct request *rq) +{ + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(rq); + + mempool_free(drq, dd->drq_pool); + rq->elevator_private = NULL; +} + +static int +deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) +{ + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq; + + drq = mempool_alloc(dd->drq_pool, gfp_mask); + if (drq) { + memset(drq, 0, sizeof(*drq)); + RB_CLEAR_NODE(&drq->rb_node); + drq->request = rq; + + INIT_HLIST_NODE(&drq->hash); + + INIT_LIST_HEAD(&drq->fifo); + + rq->elevator_private = drq; + return 0; + } + + return 1; +} + /* * sysfs parts below */ @@ -456,8 +757,10 @@ static struct elevator_type iosched_deadline = { .elevator_dispatch_fn = deadline_dispatch_requests, .elevator_add_req_fn = deadline_add_request, .elevator_queue_empty_fn = deadline_queue_empty, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = deadline_former_request, + .elevator_latter_req_fn = deadline_latter_request, + .elevator_set_req_fn = deadline_set_request, + .elevator_put_req_fn = deadline_put_request, .elevator_init_fn = deadline_init_queue, .elevator_exit_fn = deadline_exit_queue, }, @@ -469,11 +772,24 @@ static struct elevator_type iosched_deadline = { static int __init deadline_init(void) { - return elv_register(&iosched_deadline); + int ret; + + drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq), + 0, 0, NULL, NULL); + + if (!drq_pool) + return -ENOMEM; + + ret = elv_register(&iosched_deadline); + if (ret) + kmem_cache_destroy(drq_pool); + + return ret; } static void __exit deadline_exit(void) { + kmem_cache_destroy(drq_pool); elv_unregister(&iosched_deadline); } diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 487dd3da8853..9b72dc7c8a5c 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -3,7 +3,7 @@ * * Copyright (C) 2000 Andrea Arcangeli SuSE * - * 30042000 Jens Axboe : + * 30042000 Jens Axboe : * * Split the elevator a bit so that it is possible to choose a different * one or even write a new "plug in". There are three pieces: @@ -33,23 +33,12 @@ #include #include #include -#include #include static DEFINE_SPINLOCK(elv_list_lock); static LIST_HEAD(elv_list); -/* - * Merge hash stuff. - */ -static const int elv_hash_shift = 6; -#define ELV_HASH_BLOCK(sec) ((sec) >> 3) -#define ELV_HASH_FN(sec) (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift)) -#define ELV_HASH_ENTRIES (1 << elv_hash_shift) -#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) -#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) - /* * can we safely merge with this request? */ @@ -67,7 +56,8 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) /* * same device and no special stuff set, merge is ok */ - if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special) + if (rq->rq_disk == bio->bi_bdev->bd_disk && + !rq->waiting && !rq->special) return 1; return 0; @@ -161,44 +151,27 @@ __setup("elevator=", elevator_setup); static struct kobj_type elv_ktype; -static elevator_t *elevator_alloc(request_queue_t *q, struct elevator_type *e) -{ - elevator_t *eq; - int i; - - eq = kmalloc_node(sizeof(elevator_t), GFP_KERNEL, q->node); - if (unlikely(!eq)) - goto err; - - memset(eq, 0, sizeof(*eq)); - eq->ops = &e->ops; - eq->elevator_type = e; - kobject_init(&eq->kobj); - snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched"); - eq->kobj.ktype = &elv_ktype; - mutex_init(&eq->sysfs_lock); - - eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, - GFP_KERNEL, q->node); - if (!eq->hash) - goto err; - - for (i = 0; i < ELV_HASH_ENTRIES; i++) - INIT_HLIST_HEAD(&eq->hash[i]); - +static elevator_t *elevator_alloc(struct elevator_type *e) +{ + elevator_t *eq = kmalloc(sizeof(elevator_t), GFP_KERNEL); + if (eq) { + memset(eq, 0, sizeof(*eq)); + eq->ops = &e->ops; + eq->elevator_type = e; + kobject_init(&eq->kobj); + snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched"); + eq->kobj.ktype = &elv_ktype; + mutex_init(&eq->sysfs_lock); + } else { + elevator_put(e); + } return eq; -err: - kfree(eq); - elevator_put(e); - return NULL; } static void elevator_release(struct kobject *kobj) { elevator_t *e = container_of(kobj, elevator_t, kobj); - elevator_put(e->elevator_type); - kfree(e->hash); kfree(e); } @@ -225,7 +198,7 @@ int elevator_init(request_queue_t *q, char *name) e = elevator_get("noop"); } - eq = elevator_alloc(q, e); + eq = elevator_alloc(e); if (!eq) return -ENOMEM; @@ -239,8 +212,6 @@ int elevator_init(request_queue_t *q, char *name) return ret; } -EXPORT_SYMBOL(elevator_init); - void elevator_exit(elevator_t *e) { mutex_lock(&e->sysfs_lock); @@ -252,118 +223,10 @@ void elevator_exit(elevator_t *e) kobject_put(&e->kobj); } -EXPORT_SYMBOL(elevator_exit); - -static inline void __elv_rqhash_del(struct request *rq) -{ - hlist_del_init(&rq->hash); -} - -static void elv_rqhash_del(request_queue_t *q, struct request *rq) -{ - if (ELV_ON_HASH(rq)) - __elv_rqhash_del(rq); -} - -static void elv_rqhash_add(request_queue_t *q, struct request *rq) -{ - elevator_t *e = q->elevator; - - BUG_ON(ELV_ON_HASH(rq)); - hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]); -} - -static void elv_rqhash_reposition(request_queue_t *q, struct request *rq) -{ - __elv_rqhash_del(rq); - elv_rqhash_add(q, rq); -} - -static struct request *elv_rqhash_find(request_queue_t *q, sector_t offset) -{ - elevator_t *e = q->elevator; - struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)]; - struct hlist_node *entry, *next; - struct request *rq; - - hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) { - BUG_ON(!ELV_ON_HASH(rq)); - - if (unlikely(!rq_mergeable(rq))) { - __elv_rqhash_del(rq); - continue; - } - - if (rq_hash_key(rq) == offset) - return rq; - } - - return NULL; -} - -/* - * RB-tree support functions for inserting/lookup/removal of requests - * in a sorted RB tree. - */ -struct request *elv_rb_add(struct rb_root *root, struct request *rq) -{ - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct request *__rq; - - while (*p) { - parent = *p; - __rq = rb_entry(parent, struct request, rb_node); - - if (rq->sector < __rq->sector) - p = &(*p)->rb_left; - else if (rq->sector > __rq->sector) - p = &(*p)->rb_right; - else - return __rq; - } - - rb_link_node(&rq->rb_node, parent, p); - rb_insert_color(&rq->rb_node, root); - return NULL; -} - -EXPORT_SYMBOL(elv_rb_add); - -void elv_rb_del(struct rb_root *root, struct request *rq) -{ - BUG_ON(RB_EMPTY_NODE(&rq->rb_node)); - rb_erase(&rq->rb_node, root); - RB_CLEAR_NODE(&rq->rb_node); -} - -EXPORT_SYMBOL(elv_rb_del); - -struct request *elv_rb_find(struct rb_root *root, sector_t sector) -{ - struct rb_node *n = root->rb_node; - struct request *rq; - - while (n) { - rq = rb_entry(n, struct request, rb_node); - - if (sector < rq->sector) - n = n->rb_left; - else if (sector > rq->sector) - n = n->rb_right; - else - return rq; - } - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_find); - /* * Insert rq into dispatch queue of q. Queue lock must be held on - * entry. rq is sort insted into the dispatch queue. To be used by - * specific elevators. + * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be + * appended to the dispatch queue. To be used by specific elevators. */ void elv_dispatch_sort(request_queue_t *q, struct request *rq) { @@ -372,9 +235,6 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) if (q->last_merge == rq) q->last_merge = NULL; - - elv_rqhash_del(q, rq); - q->nr_sorted--; boundary = q->end_sector; @@ -382,7 +242,7 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); - if (pos->cmd_flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) + if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) break; if (rq->sector >= boundary) { if (pos->sector < boundary) @@ -398,38 +258,11 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) list_add(&rq->queuelist, entry); } -EXPORT_SYMBOL(elv_dispatch_sort); - -/* - * Insert rq into dispatch queue of q. Queue lock must be held on - * entry. rq is added to the back of the dispatch queue. To be used by - * specific elevators. - */ -void elv_dispatch_add_tail(struct request_queue *q, struct request *rq) -{ - if (q->last_merge == rq) - q->last_merge = NULL; - - elv_rqhash_del(q, rq); - - q->nr_sorted--; - - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - list_add_tail(&rq->queuelist, &q->queue_head); -} - -EXPORT_SYMBOL(elv_dispatch_add_tail); - int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) { elevator_t *e = q->elevator; - struct request *__rq; int ret; - /* - * First try one-hit cache. - */ if (q->last_merge) { ret = elv_try_merge(q->last_merge, bio); if (ret != ELEVATOR_NO_MERGE) { @@ -438,30 +271,18 @@ int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) } } - /* - * See if our hash lookup can find a potential backmerge. - */ - __rq = elv_rqhash_find(q, bio->bi_sector); - if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_BACK_MERGE; - } - if (e->ops->elevator_merge_fn) return e->ops->elevator_merge_fn(q, req, bio); return ELEVATOR_NO_MERGE; } -void elv_merged_request(request_queue_t *q, struct request *rq, int type) +void elv_merged_request(request_queue_t *q, struct request *rq) { elevator_t *e = q->elevator; if (e->ops->elevator_merged_fn) - e->ops->elevator_merged_fn(q, rq, type); - - if (type == ELEVATOR_BACK_MERGE) - elv_rqhash_reposition(q, rq); + e->ops->elevator_merged_fn(q, rq); q->last_merge = rq; } @@ -473,11 +294,8 @@ void elv_merge_requests(request_queue_t *q, struct request *rq, if (e->ops->elevator_merge_req_fn) e->ops->elevator_merge_req_fn(q, rq, next); - - elv_rqhash_reposition(q, rq); - elv_rqhash_del(q, next); - q->nr_sorted--; + q->last_merge = rq; } @@ -495,7 +313,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) e->ops->elevator_deactivate_req_fn(q, rq); } - rq->cmd_flags &= ~REQ_STARTED; + rq->flags &= ~REQ_STARTED; elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); } @@ -526,13 +344,13 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) switch (where) { case ELEVATOR_INSERT_FRONT: - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; list_add(&rq->queuelist, &q->queue_head); break; case ELEVATOR_INSERT_BACK: - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; elv_drain_elevator(q); list_add_tail(&rq->queuelist, &q->queue_head); /* @@ -551,14 +369,10 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) case ELEVATOR_INSERT_SORT: BUG_ON(!blk_fs_request(rq)); - rq->cmd_flags |= REQ_SORTED; + rq->flags |= REQ_SORTED; q->nr_sorted++; - if (rq_mergeable(rq)) { - elv_rqhash_add(q, rq); - if (!q->last_merge) - q->last_merge = rq; - } - + if (q->last_merge == NULL && rq_mergeable(rq)) + q->last_merge = rq; /* * Some ioscheds (cfq) run q->request_fn directly, so * rq cannot be accessed after calling @@ -573,7 +387,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) * insertion; otherwise, requests should be requeued * in ordseq order. */ - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; if (q->ordseq == 0) { list_add(&rq->queuelist, &q->queue_head); @@ -615,9 +429,9 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { if (q->ordcolor) - rq->cmd_flags |= REQ_ORDERED_COLOR; + rq->flags |= REQ_ORDERED_COLOR; - if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { + if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { /* * toggle ordered color */ @@ -638,7 +452,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, q->end_sector = rq_end_sector(rq); q->boundary_rq = rq; } - } else if (!(rq->cmd_flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) where = ELEVATOR_INSERT_BACK; if (plug) @@ -647,8 +461,6 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, elv_insert(q, rq, where); } -EXPORT_SYMBOL(__elv_add_request); - void elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { @@ -659,8 +471,6 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where, spin_unlock_irqrestore(q->queue_lock, flags); } -EXPORT_SYMBOL(elv_add_request); - static inline struct request *__elv_next_request(request_queue_t *q) { struct request *rq; @@ -683,7 +493,7 @@ struct request *elv_next_request(request_queue_t *q) int ret; while ((rq = __elv_next_request(q)) != NULL) { - if (!(rq->cmd_flags & REQ_STARTED)) { + if (!(rq->flags & REQ_STARTED)) { elevator_t *e = q->elevator; /* @@ -700,7 +510,7 @@ struct request *elv_next_request(request_queue_t *q) * it, a request that has been delayed should * not be passed by new incoming requests */ - rq->cmd_flags |= REQ_STARTED; + rq->flags |= REQ_STARTED; blk_add_trace_rq(q, rq, BLK_TA_ISSUE); } @@ -709,7 +519,7 @@ struct request *elv_next_request(request_queue_t *q) q->boundary_rq = NULL; } - if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) + if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) break; ret = q->prep_rq_fn(q, rq); @@ -731,7 +541,7 @@ struct request *elv_next_request(request_queue_t *q) nr_bytes = rq->data_len; blkdev_dequeue_request(rq); - rq->cmd_flags |= REQ_QUIET; + rq->flags |= REQ_QUIET; end_that_request_chunk(rq, 0, nr_bytes); end_that_request_last(rq, 0); } else { @@ -744,12 +554,9 @@ struct request *elv_next_request(request_queue_t *q) return rq; } -EXPORT_SYMBOL(elv_next_request); - void elv_dequeue_request(request_queue_t *q, struct request *rq) { BUG_ON(list_empty(&rq->queuelist)); - BUG_ON(ELV_ON_HASH(rq)); list_del_init(&rq->queuelist); @@ -762,8 +569,6 @@ void elv_dequeue_request(request_queue_t *q, struct request *rq) q->in_flight++; } -EXPORT_SYMBOL(elv_dequeue_request); - int elv_queue_empty(request_queue_t *q) { elevator_t *e = q->elevator; @@ -777,8 +582,6 @@ int elv_queue_empty(request_queue_t *q) return 1; } -EXPORT_SYMBOL(elv_queue_empty); - struct request *elv_latter_request(request_queue_t *q, struct request *rq) { elevator_t *e = q->elevator; @@ -797,12 +600,13 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq) return NULL; } -int elv_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) +int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) { elevator_t *e = q->elevator; if (e->ops->elevator_set_req_fn) - return e->ops->elevator_set_req_fn(q, rq, gfp_mask); + return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask); rq->elevator_private = NULL; return 0; @@ -816,12 +620,12 @@ void elv_put_request(request_queue_t *q, struct request *rq) e->ops->elevator_put_req_fn(q, rq); } -int elv_may_queue(request_queue_t *q, int rw) +int elv_may_queue(request_queue_t *q, int rw, struct bio *bio) { elevator_t *e = q->elevator; if (e->ops->elevator_may_queue_fn) - return e->ops->elevator_may_queue_fn(q, rw); + return e->ops->elevator_may_queue_fn(q, rw, bio); return ELV_MQUEUE_MAY; } @@ -988,7 +792,7 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) /* * Allocate new elevator */ - e = elevator_alloc(q, new_e); + e = elevator_alloc(new_e); if (!e) return 0; @@ -1104,26 +908,11 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) return len; } -struct request *elv_rb_former_request(request_queue_t *q, struct request *rq) -{ - struct rb_node *rbprev = rb_prev(&rq->rb_node); - - if (rbprev) - return rb_entry_rq(rbprev); - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_former_request); - -struct request *elv_rb_latter_request(request_queue_t *q, struct request *rq) -{ - struct rb_node *rbnext = rb_next(&rq->rb_node); - - if (rbnext) - return rb_entry_rq(rbnext); - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_latter_request); +EXPORT_SYMBOL(elv_dispatch_sort); +EXPORT_SYMBOL(elv_add_request); +EXPORT_SYMBOL(__elv_add_request); +EXPORT_SYMBOL(elv_next_request); +EXPORT_SYMBOL(elv_dequeue_request); +EXPORT_SYMBOL(elv_queue_empty); +EXPORT_SYMBOL(elevator_exit); +EXPORT_SYMBOL(elevator_init); diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index 58aab630dfc1..309760b7e37f 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -199,8 +199,8 @@ static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, return -ENOIOCTLCMD; } -int blkdev_driver_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned cmd, unsigned long arg) +static int blkdev_driver_ioctl(struct inode *inode, struct file *file, + struct gendisk *disk, unsigned cmd, unsigned long arg) { int ret; if (disk->fops->unlocked_ioctl) @@ -215,7 +215,6 @@ int blkdev_driver_ioctl(struct inode *inode, struct file *file, return -ENOTTY; } -EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 83425fb3c8db..51dc0edf76e0 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -39,7 +39,6 @@ static void blk_unplug_timeout(unsigned long data); static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io); static void init_request_from_bio(struct request *req, struct bio *bio); static int __make_request(request_queue_t *q, struct bio *bio); -static struct io_context *current_io_context(gfp_t gfp_flags, int node); /* * For the allocated request tables @@ -278,19 +277,19 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) EXPORT_SYMBOL(blk_queue_make_request); -static void rq_init(request_queue_t *q, struct request *rq) +static inline void rq_init(request_queue_t *q, struct request *rq) { INIT_LIST_HEAD(&rq->queuelist); INIT_LIST_HEAD(&rq->donelist); rq->errors = 0; + rq->rq_status = RQ_ACTIVE; rq->bio = rq->biotail = NULL; - INIT_HLIST_NODE(&rq->hash); - RB_CLEAR_NODE(&rq->rb_node); rq->ioprio = 0; rq->buffer = NULL; rq->ref_count = 1; rq->q = q; + rq->waiting = NULL; rq->special = NULL; rq->data_len = 0; rq->data = NULL; @@ -383,8 +382,8 @@ unsigned blk_ordered_req_seq(struct request *rq) if (rq == &q->post_flush_rq) return QUEUE_ORDSEQ_POSTFLUSH; - if ((rq->cmd_flags & REQ_ORDERED_COLOR) == - (q->orig_bar_rq->cmd_flags & REQ_ORDERED_COLOR)) + if ((rq->flags & REQ_ORDERED_COLOR) == + (q->orig_bar_rq->flags & REQ_ORDERED_COLOR)) return QUEUE_ORDSEQ_DRAIN; else return QUEUE_ORDSEQ_DONE; @@ -447,11 +446,11 @@ static void queue_flush(request_queue_t *q, unsigned which) end_io = post_flush_end_io; } - rq->cmd_flags = REQ_HARDBARRIER; rq_init(q, rq); + rq->flags = REQ_HARDBARRIER; rq->elevator_private = NULL; - rq->elevator_private2 = NULL; rq->rq_disk = q->bar_rq.rq_disk; + rq->rl = NULL; rq->end_io = end_io; q->prepare_flush_fn(q, rq); @@ -472,13 +471,11 @@ static inline struct request *start_ordered(request_queue_t *q, blkdev_dequeue_request(rq); q->orig_bar_rq = rq; rq = &q->bar_rq; - rq->cmd_flags = 0; rq_init(q, rq); - if (bio_data_dir(q->orig_bar_rq->bio) == WRITE) - rq->cmd_flags |= REQ_RW; - rq->cmd_flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; + rq->flags = bio_data_dir(q->orig_bar_rq->bio); + rq->flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; rq->elevator_private = NULL; - rq->elevator_private2 = NULL; + rq->rl = NULL; init_request_from_bio(rq, q->orig_bar_rq->bio); rq->end_io = bar_end_io; @@ -590,8 +587,8 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) return 0; } -static int ordered_bio_endio(struct request *rq, struct bio *bio, - unsigned int nbytes, int error) +static inline int ordered_bio_endio(struct request *rq, struct bio *bio, + unsigned int nbytes, int error) { request_queue_t *q = rq->q; bio_end_io_t *endio; @@ -1127,7 +1124,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) } list_del_init(&rq->queuelist); - rq->cmd_flags &= ~REQ_QUEUED; + rq->flags &= ~REQ_QUEUED; rq->tag = -1; if (unlikely(bqt->tag_index[tag] == NULL)) @@ -1163,7 +1160,7 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) struct blk_queue_tag *bqt = q->queue_tags; int tag; - if (unlikely((rq->cmd_flags & REQ_QUEUED))) { + if (unlikely((rq->flags & REQ_QUEUED))) { printk(KERN_ERR "%s: request %p for device [%s] already tagged %d", __FUNCTION__, rq, @@ -1171,18 +1168,13 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) BUG(); } - /* - * Protect against shared tag maps, as we may not have exclusive - * access to the tag map. - */ - do { - tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); - if (tag >= bqt->max_depth) - return 1; + tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); + if (tag >= bqt->max_depth) + return 1; - } while (test_and_set_bit(tag, bqt->tag_map)); + __set_bit(tag, bqt->tag_map); - rq->cmd_flags |= REQ_QUEUED; + rq->flags |= REQ_QUEUED; rq->tag = tag; bqt->tag_index[tag] = rq; blkdev_dequeue_request(rq); @@ -1218,31 +1210,65 @@ void blk_queue_invalidate_tags(request_queue_t *q) printk(KERN_ERR "%s: bad tag found on list\n", __FUNCTION__); list_del_init(&rq->queuelist); - rq->cmd_flags &= ~REQ_QUEUED; + rq->flags &= ~REQ_QUEUED; } else blk_queue_end_tag(q, rq); - rq->cmd_flags &= ~REQ_STARTED; + rq->flags &= ~REQ_STARTED; __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0); } } EXPORT_SYMBOL(blk_queue_invalidate_tags); +static const char * const rq_flags[] = { + "REQ_RW", + "REQ_FAILFAST", + "REQ_SORTED", + "REQ_SOFTBARRIER", + "REQ_HARDBARRIER", + "REQ_FUA", + "REQ_CMD", + "REQ_NOMERGE", + "REQ_STARTED", + "REQ_DONTPREP", + "REQ_QUEUED", + "REQ_ELVPRIV", + "REQ_PC", + "REQ_BLOCK_PC", + "REQ_SENSE", + "REQ_FAILED", + "REQ_QUIET", + "REQ_SPECIAL", + "REQ_DRIVE_CMD", + "REQ_DRIVE_TASK", + "REQ_DRIVE_TASKFILE", + "REQ_PREEMPT", + "REQ_PM_SUSPEND", + "REQ_PM_RESUME", + "REQ_PM_SHUTDOWN", + "REQ_ORDERED_COLOR", +}; + void blk_dump_rq_flags(struct request *rq, char *msg) { int bit; - printk("%s: dev %s: type=%x, flags=%x\n", msg, - rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type, - rq->cmd_flags); + printk("%s: dev %s: flags = ", msg, + rq->rq_disk ? rq->rq_disk->disk_name : "?"); + bit = 0; + do { + if (rq->flags & (1 << bit)) + printk("%s ", rq_flags[bit]); + bit++; + } while (bit < __REQ_NR_BITS); printk("\nsector %llu, nr/cnr %lu/%u\n", (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); printk("bio %p, biotail %p, buffer %p, data %p, len %u\n", rq->bio, rq->biotail, rq->buffer, rq->data, rq->data_len); - if (blk_pc_request(rq)) { + if (rq->flags & (REQ_BLOCK_PC | REQ_PC)) { printk("cdb: "); for (bit = 0; bit < sizeof(rq->cmd); bit++) printk("%02x ", rq->cmd[bit]); @@ -1415,7 +1441,7 @@ static inline int ll_new_mergeable(request_queue_t *q, int nr_phys_segs = bio_phys_segments(q, bio); if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1438,7 +1464,7 @@ static inline int ll_new_hw_segment(request_queue_t *q, if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1465,7 +1491,7 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req, max_sectors = q->max_sectors; if (req->nr_sectors + bio_sectors(bio) > max_sectors) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1504,7 +1530,7 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req, if (req->nr_sectors + bio_sectors(bio) > max_sectors) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -2003,13 +2029,14 @@ EXPORT_SYMBOL(blk_get_queue); static inline void blk_free_request(request_queue_t *q, struct request *rq) { - if (rq->cmd_flags & REQ_ELVPRIV) + if (rq->flags & REQ_ELVPRIV) elv_put_request(q, rq); mempool_free(rq, q->rq.rq_pool); } -static struct request * -blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask) +static inline struct request * +blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, + int priv, gfp_t gfp_mask) { struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); @@ -2017,17 +2044,17 @@ blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask) return NULL; /* - * first three bits are identical in rq->cmd_flags and bio->bi_rw, + * first three bits are identical in rq->flags and bio->bi_rw, * see bio.h and blkdev.h */ - rq->cmd_flags = rw | REQ_ALLOCED; + rq->flags = rw; if (priv) { - if (unlikely(elv_set_request(q, rq, gfp_mask))) { + if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) { mempool_free(rq, q->rq.rq_pool); return NULL; } - rq->cmd_flags |= REQ_ELVPRIV; + rq->flags |= REQ_ELVPRIV; } return rq; @@ -2114,13 +2141,13 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, struct io_context *ioc = NULL; int may_queue, priv; - may_queue = elv_may_queue(q, rw); + may_queue = elv_may_queue(q, rw, bio); if (may_queue == ELV_MQUEUE_NO) goto rq_starved; if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) { if (rl->count[rw]+1 >= q->nr_requests) { - ioc = current_io_context(GFP_ATOMIC, q->node); + ioc = current_io_context(GFP_ATOMIC); /* * The queue will fill after this allocation, so set * it as full, and mark this process as "batching". @@ -2162,7 +2189,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, spin_unlock_irq(q->queue_lock); - rq = blk_alloc_request(q, rw, priv, gfp_mask); + rq = blk_alloc_request(q, rw, bio, priv, gfp_mask); if (unlikely(!rq)) { /* * Allocation failed presumably due to memory. Undo anything @@ -2198,6 +2225,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, ioc->nr_batch_requests--; rq_init(q, rq); + rq->rl = rl; blk_add_trace_generic(q, bio, rw, BLK_TA_GETRQ); out: @@ -2240,7 +2268,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw, * up to a big batch of them for a small period time. * See ioc_batching, ioc_set_batching */ - ioc = current_io_context(GFP_NOIO, q->node); + ioc = current_io_context(GFP_NOIO); ioc_set_batching(q, ioc); spin_lock_irq(q->queue_lock); @@ -2271,25 +2299,6 @@ struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask) } EXPORT_SYMBOL(blk_get_request); -/** - * blk_start_queueing - initiate dispatch of requests to device - * @q: request queue to kick into gear - * - * This is basically a helper to remove the need to know whether a queue - * is plugged or not if someone just wants to initiate dispatch of requests - * for this queue. - * - * The queue lock must be held with interrupts disabled. - */ -void blk_start_queueing(request_queue_t *q) -{ - if (!blk_queue_plugged(q)) - q->request_fn(q); - else - __generic_unplug_device(q); -} -EXPORT_SYMBOL(blk_start_queueing); - /** * blk_requeue_request - put a request back on queue * @q: request queue where request should be inserted @@ -2342,8 +2351,7 @@ void blk_insert_request(request_queue_t *q, struct request *rq, * must not attempt merges on this) and that it acts as a soft * barrier */ - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SPECIAL | REQ_SOFTBARRIER; rq->special = data; @@ -2357,7 +2365,11 @@ void blk_insert_request(request_queue_t *q, struct request *rq, drive_stat_acct(rq, rq->nr_sectors, 1); __elv_add_request(q, rq, where, 0); - blk_start_queueing(q); + + if (blk_queue_plugged(q)) + __generic_unplug_device(q); + else + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -2546,7 +2558,7 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk, int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; rq->rq_disk = bd_disk; - rq->cmd_flags |= REQ_NOMERGE; + rq->flags |= REQ_NOMERGE; rq->end_io = done; WARN_ON(irqs_disabled()); spin_lock_irq(q->queue_lock); @@ -2586,9 +2598,10 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk, rq->sense_len = 0; } - rq->end_io_data = &wait; + rq->waiting = &wait; blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq); wait_for_completion(&wait); + rq->waiting = NULL; if (rq->errors) err = -EIO; @@ -2697,6 +2710,8 @@ EXPORT_SYMBOL_GPL(disk_round_stats); */ void __blk_put_request(request_queue_t *q, struct request *req) { + struct request_list *rl = req->rl; + if (unlikely(!q)) return; if (unlikely(--req->ref_count)) @@ -2704,16 +2719,18 @@ void __blk_put_request(request_queue_t *q, struct request *req) elv_completed_request(q, req); + req->rq_status = RQ_INACTIVE; + req->rl = NULL; + /* * Request may not have originated from ll_rw_blk. if not, * it didn't come out of our reserved rq pools */ - if (req->cmd_flags & REQ_ALLOCED) { + if (rl) { int rw = rq_data_dir(req); - int priv = req->cmd_flags & REQ_ELVPRIV; + int priv = req->flags & REQ_ELVPRIV; BUG_ON(!list_empty(&req->queuelist)); - BUG_ON(!hlist_unhashed(&req->hash)); blk_free_request(q, req); freed_request(q, rw, priv); @@ -2747,9 +2764,9 @@ EXPORT_SYMBOL(blk_put_request); */ void blk_end_sync_rq(struct request *rq, int error) { - struct completion *waiting = rq->end_io_data; + struct completion *waiting = rq->waiting; - rq->end_io_data = NULL; + rq->waiting = NULL; __blk_put_request(rq->q, rq); /* @@ -2812,7 +2829,7 @@ static int attempt_merge(request_queue_t *q, struct request *req, if (rq_data_dir(req) != rq_data_dir(next) || req->rq_disk != next->rq_disk - || next->special) + || next->waiting || next->special) return 0; /* @@ -2873,24 +2890,22 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq) static void init_request_from_bio(struct request *req, struct bio *bio) { - req->cmd_type = REQ_TYPE_FS; + req->flags |= REQ_CMD; /* * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) */ if (bio_rw_ahead(bio) || bio_failfast(bio)) - req->cmd_flags |= REQ_FAILFAST; + req->flags |= REQ_FAILFAST; /* * REQ_BARRIER implies no merging, but lets make it explicit */ if (unlikely(bio_barrier(bio))) - req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE); + req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); if (bio_sync(bio)) - req->cmd_flags |= REQ_RW_SYNC; - if (bio_rw_meta(bio)) - req->cmd_flags |= REQ_RW_META; + req->flags |= REQ_RW_SYNC; req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; @@ -2899,6 +2914,7 @@ static void init_request_from_bio(struct request *req, struct bio *bio) req->nr_phys_segments = bio_phys_segments(req->q, bio); req->nr_hw_segments = bio_hw_segments(req->q, bio); req->buffer = bio_data(bio); /* see ->buffer comment above */ + req->waiting = NULL; req->bio = req->biotail = bio; req->ioprio = bio_prio(bio); req->rq_disk = bio->bi_bdev->bd_disk; @@ -2908,11 +2924,17 @@ static void init_request_from_bio(struct request *req, struct bio *bio) static int __make_request(request_queue_t *q, struct bio *bio) { struct request *req; - int el_ret, nr_sectors, barrier, err; - const unsigned short prio = bio_prio(bio); - const int sync = bio_sync(bio); + int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; + unsigned short prio; + sector_t sector; + sector = bio->bi_sector; nr_sectors = bio_sectors(bio); + cur_nr_sectors = bio_cur_sectors(bio); + prio = bio_prio(bio); + + rw = bio_data_dir(bio); + sync = bio_sync(bio); /* * low level driver can indicate that it wants pages above a @@ -2921,6 +2943,8 @@ static int __make_request(request_queue_t *q, struct bio *bio) */ blk_queue_bounce(q, &bio); + spin_lock_prefetch(q->queue_lock); + barrier = bio_barrier(bio); if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) { err = -EOPNOTSUPP; @@ -2948,7 +2972,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) req->ioprio = ioprio_best(req->ioprio, prio); drive_stat_acct(req, nr_sectors, 0); if (!attempt_back_merge(q, req)) - elv_merged_request(q, req, el_ret); + elv_merged_request(q, req); goto out; case ELEVATOR_FRONT_MERGE: @@ -2968,14 +2992,14 @@ static int __make_request(request_queue_t *q, struct bio *bio) * not touch req->buffer either... */ req->buffer = bio_data(bio); - req->current_nr_sectors = bio_cur_sectors(bio); - req->hard_cur_sectors = req->current_nr_sectors; - req->sector = req->hard_sector = bio->bi_sector; + req->current_nr_sectors = cur_nr_sectors; + req->hard_cur_sectors = cur_nr_sectors; + req->sector = req->hard_sector = sector; req->nr_sectors = req->hard_nr_sectors += nr_sectors; req->ioprio = ioprio_best(req->ioprio, prio); drive_stat_acct(req, nr_sectors, 0); if (!attempt_front_merge(q, req)) - elv_merged_request(q, req, el_ret); + elv_merged_request(q, req); goto out; /* ELV_NO_MERGE: elevator says don't/can't merge. */ @@ -2988,7 +3012,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) * Grab a free request. This is might sleep but can not fail. * Returns with the queue unlocked. */ - req = get_request_wait(q, bio_data_dir(bio), bio); + req = get_request_wait(q, rw, bio); /* * After dropping the lock and possibly sleeping here, our request @@ -3282,7 +3306,7 @@ static int __end_that_request_first(struct request *req, int uptodate, req->errors = 0; if (!uptodate) { - if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET)) + if (blk_fs_request(req) && !(req->flags & REQ_QUIET)) printk("end_request: I/O error, dev %s, sector %llu\n", req->rq_disk ? req->rq_disk->disk_name : "?", (unsigned long long)req->sector); @@ -3545,8 +3569,8 @@ EXPORT_SYMBOL(end_request); void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio) { - /* first two bits are identical in rq->cmd_flags and bio->bi_rw */ - rq->cmd_flags |= (bio->bi_rw & 3); + /* first two bits are identical in rq->flags and bio->bi_rw */ + rq->flags |= (bio->bi_rw & 3); rq->nr_phys_segments = bio_phys_segments(q, bio); rq->nr_hw_segments = bio_hw_segments(q, bio); @@ -3634,22 +3658,25 @@ EXPORT_SYMBOL(put_io_context); /* Called by the exitting task */ void exit_io_context(void) { + unsigned long flags; struct io_context *ioc; struct cfq_io_context *cic; + local_irq_save(flags); task_lock(current); ioc = current->io_context; current->io_context = NULL; + ioc->task = NULL; task_unlock(current); + local_irq_restore(flags); - ioc->task = NULL; if (ioc->aic && ioc->aic->exit) ioc->aic->exit(ioc->aic); if (ioc->cic_root.rb_node != NULL) { cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node); cic->exit(ioc); } - + put_io_context(ioc); } @@ -3661,7 +3688,7 @@ void exit_io_context(void) * but since the current task itself holds a reference, the context can be * used in general code, so long as it stays within `current` context. */ -static struct io_context *current_io_context(gfp_t gfp_flags, int node) +struct io_context *current_io_context(gfp_t gfp_flags) { struct task_struct *tsk = current; struct io_context *ret; @@ -3670,11 +3697,11 @@ static struct io_context *current_io_context(gfp_t gfp_flags, int node) if (likely(ret)) return ret; - ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node); + ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); if (ret) { atomic_set(&ret->refcount, 1); ret->task = current; - ret->ioprio_changed = 0; + ret->set_ioprio = NULL; ret->last_waited = jiffies; /* doesn't matter... */ ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; @@ -3694,10 +3721,10 @@ EXPORT_SYMBOL(current_io_context); * * This is always called in the context of the task which submitted the I/O. */ -struct io_context *get_io_context(gfp_t gfp_flags, int node) +struct io_context *get_io_context(gfp_t gfp_flags) { struct io_context *ret; - ret = current_io_context(gfp_flags, node); + ret = current_io_context(gfp_flags); if (likely(ret)) atomic_inc(&ret->refcount); return ret; @@ -3810,6 +3837,9 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count) ssize_t ret = queue_var_store(&ra_kb, page, count); spin_lock_irq(q->queue_lock); + if (ra_kb > (q->max_sectors >> 1)) + ra_kb = (q->max_sectors >> 1); + q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); spin_unlock_irq(q->queue_lock); diff --git a/trunk/block/noop-iosched.c b/trunk/block/noop-iosched.c index 79af43179421..56a7c620574f 100644 --- a/trunk/block/noop-iosched.c +++ b/trunk/block/noop-iosched.c @@ -69,7 +69,7 @@ static void *noop_init_queue(request_queue_t *q, elevator_t *e) { struct noop_data *nd; - nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node); + nd = kmalloc(sizeof(*nd), GFP_KERNEL); if (!nd) return NULL; INIT_LIST_HEAD(&nd->queue); diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 2dc326421a24..b33eda26e205 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -294,7 +294,7 @@ static int sg_io(struct file *file, request_queue_t *q, rq->sense = sense; rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; bio = rq->bio; /* @@ -470,7 +470,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q, memset(sense, 0, sizeof(sense)); rq->sense = sense; rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; blk_execute_rq(q, disk, rq, 0); @@ -502,7 +502,7 @@ static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int c int err; rq = blk_get_request(q, WRITE, __GFP_WAIT); - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; rq->data = NULL; rq->data_len = 0; rq->timeout = BLK_DEFAULT_TIMEOUT; diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 98099de59b45..1dda370f402b 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -238,10 +238,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) num_enabled++; continue; } - - if (node < 0) - node = memory_add_physaddr_to_nid(info->start_addr); - result = add_memory(node, info->start_addr, info->length); if (result) continue; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 0a395fca843b..71066066d626 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -38,7 +38,6 @@ #include #include #include /* need_resched() */ -#include #include #include @@ -454,8 +453,7 @@ static void acpi_processor_idle(void) */ if (cx->promotion.state && ((cx->promotion.state - pr->power.states) <= max_cstate)) { - if (sleep_ticks > cx->promotion.threshold.ticks && - cx->promotion.state->latency <= system_latency_constraint()) { + if (sleep_ticks > cx->promotion.threshold.ticks) { cx->promotion.count++; cx->demotion.count = 0; if (cx->promotion.count >= @@ -496,10 +494,8 @@ static void acpi_processor_idle(void) end: /* * Demote if current state exceeds max_cstate - * or if the latency of the current state is unacceptable */ - if ((pr->power.state - pr->power.states) > max_cstate || - pr->power.state->latency > system_latency_constraint()) { + if ((pr->power.state - pr->power.states) > max_cstate) { if (cx->demotion.state) next_state = cx->demotion.state; } @@ -1013,11 +1009,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "active state: C%zd\n" "max_cstate: C%d\n" - "bus master activity: %08x\n" - "maximum allowed latency: %d usec\n", + "bus master activity: %08x\n", pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, (unsigned)pr->power.bm_activity, - system_latency_constraint()); + max_cstate, (unsigned)pr->power.bm_activity); seq_puts(seq, "states:\n"); @@ -1083,28 +1077,6 @@ static const struct file_operations acpi_processor_power_fops = { .release = single_release, }; -static void smp_callback(void *v) -{ - /* we already woke the CPU up, nothing more to do */ -} - -/* - * This function gets called when a part of the kernel has a new latency - * requirement. This means we need to get all processors out of their C-state, - * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that - * wakes them all right up. - */ -static int acpi_processor_latency_notify(struct notifier_block *b, - unsigned long l, void *v) -{ - smp_call_function(smp_callback, NULL, 0, 1); - return NOTIFY_OK; -} - -static struct notifier_block acpi_processor_latency_notifier = { - .notifier_call = acpi_processor_latency_notify, -}; - int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) { @@ -1121,7 +1093,6 @@ int acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; - register_latency_notifier(&acpi_processor_latency_notifier); } if (!pr) @@ -1193,7 +1164,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, * copies of pm_idle before proceeding. */ cpu_idle_wait(); - unregister_latency_notifier(&acpi_processor_latency_notifier); } return 0; diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index 8c757438f350..cf656ecbe507 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -429,7 +429,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* PCI clocking determines the ATA timing values to use */ /* info_hpt366 is safe against re-entry so we can scribble on it */ - switch((reg1 & 0x700) >> 8) { + switch(reg1 & 0x700) { case 5: info_hpt366.private_data = &hpt366_40; break; diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index 7bbb9eeda235..b539e5e75b56 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -8,7 +8,7 @@ obj-y += power/ obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o -obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o +obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o obj-$(CONFIG_SMP) += topology.o obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index b3f639fbf220..a360215dbce7 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -770,7 +770,7 @@ static void DAC960_P_QueueCommand(DAC960_Command_T *Command) static void DAC960_ExecuteCommand(DAC960_Command_T *Command) { DAC960_Controller_T *Controller = Command->Controller; - DECLARE_COMPLETION_ONSTACK(Completion); + DECLARE_COMPLETION(Completion); unsigned long flags; Command->Completion = &Completion; @@ -3331,7 +3331,7 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_ Command->DmaDirection = PCI_DMA_TODEVICE; Command->CommandType = DAC960_WriteCommand; } - Command->Completion = Request->end_io_data; + Command->Completion = Request->waiting; Command->LogicalDriveNumber = (long)Request->rq_disk->private_data; Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors; diff --git a/trunk/drivers/block/DAC960.h b/trunk/drivers/block/DAC960.h index f9217c34bc2b..a82f37f749a5 100644 --- a/trunk/drivers/block/DAC960.h +++ b/trunk/drivers/block/DAC960.h @@ -71,7 +71,7 @@ Define a Boolean data type. */ -typedef bool boolean; +typedef enum { false, true } __attribute__ ((packed)) boolean; /* diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 422e31d5f8e5..b5382cedf0c0 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -2,8 +2,6 @@ # Block device driver configuration # -if BLOCK - menu "Block devices" config BLK_DEV_FD @@ -470,5 +468,3 @@ config ATA_OVER_ETH devices like the Coraid EtherDrive (R) Storage Blade. endmenu - -endif diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 99f87efe0f58..2cd3391ff878 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -144,13 +144,13 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all); -static void cciss_read_capacity(int ctlr, int logvol, int withirq, - sector_t *total_size, unsigned int *block_size); -static void cciss_read_capacity_16(int ctlr, int logvol, int withirq, - sector_t *total_size, unsigned int *block_size); -static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, sector_t total_size, - unsigned int block_size, InquiryData_struct *inq_buff, +static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, + int withirq, unsigned int *total_size, + unsigned int *block_size); +static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq, + unsigned int total_size, + unsigned int block_size, + InquiryData_struct *inq_buff, drive_info_struct *drv); static void cciss_getgeometry(int cntl_num); static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, @@ -879,7 +879,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, char *buff = NULL; u64bit temp64; unsigned long flags; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); if (!arg) return -EINVAL; @@ -997,7 +997,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, BYTE sg_used = 0; int status = 0; int i; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); __u32 left; __u32 sz; BYTE __user *data_ptr; @@ -1229,6 +1229,7 @@ static inline void complete_buffers(struct bio *bio, int status) int nr_sectors = bio_sectors(bio); bio->bi_next = NULL; + blk_finished_io(len); bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); bio = xbh; } @@ -1325,9 +1326,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index) { ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; + ReadCapdata_struct *size_buff = NULL; InquiryData_struct *inq_buff = NULL; unsigned int block_size; - sector_t total_size; + unsigned int total_size; unsigned long flags = 0; int ret = 0; @@ -1346,25 +1348,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index) return; /* Get information about the disk and modify the driver structure */ + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) + goto mem_msg; inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) goto mem_msg; - cciss_read_capacity(ctlr, drv_index, 1, + cciss_read_capacity(ctlr, drv_index, size_buff, 1, &total_size, &block_size); - - /* total size = last LBA + 1 */ - /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */ - /* so we assume this volume this must be >2TB in size */ - if (total_size == (__u32) 0) { - cciss_read_capacity_16(ctlr, drv_index, 1, - &total_size, &block_size); - h->cciss_read = CCISS_READ_16; - h->cciss_write = CCISS_WRITE_16; - } else { - h->cciss_read = CCISS_READ_10; - h->cciss_write = CCISS_WRITE_10; - } cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, inq_buff, &h->drv[drv_index]); @@ -1400,6 +1392,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) } freeret: + kfree(size_buff); kfree(inq_buff); return; mem_msg: @@ -1724,22 +1717,6 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ c->Request.Timeout = 0; c->Request.CDB[0] = cmd; break; - case CCISS_READ_CAPACITY_16: - c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID; - c->Header.LUN.LogDev.Mode = 1; - c->Request.CDBLen = 16; - c->Request.Type.Attribute = ATTR_SIMPLE; - c->Request.Type.Direction = XFER_READ; - c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; - c->Request.CDB[1] = 0x10; - c->Request.CDB[10] = (size >> 24) & 0xFF; - c->Request.CDB[11] = (size >> 16) & 0xFF; - c->Request.CDB[12] = (size >> 8) & 0xFF; - c->Request.CDB[13] = size & 0xFF; - c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; - break; case CCISS_CACHE_FLUSH: c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1773,7 +1750,6 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); c->Request.CDB[0] = cmd; /* reset */ c->Request.CDB[1] = 0x04; /* reset a LUN */ - break; case 3: /* No-Op message */ c->Request.CDBLen = 1; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1816,7 +1792,7 @@ static int sendcmd_withirq(__u8 cmd, u64bit buff_dma_handle; unsigned long flags; int return_status; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); if ((c = cmd_alloc(h, 0)) == NULL) return -ENOMEM; @@ -1917,15 +1893,12 @@ static int sendcmd_withirq(__u8 cmd, } static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, sector_t total_size, + int withirq, unsigned int total_size, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv) { int return_code; - unsigned long t; - unsigned long rem; - memset(inq_buff, 0, sizeof(InquiryData_struct)); if (withirq) return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, @@ -1944,10 +1917,10 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->nr_blocks = total_size; drv->heads = 255; drv->sectors = 32; // Sectors per track - t = drv->heads * drv->sectors; - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); + drv->cylinders = total_size / 255 / 32; } else { + unsigned int t; + drv->block_size = block_size; drv->nr_blocks = total_size; drv->heads = inq_buff->data_byte[6]; @@ -1957,84 +1930,42 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->raid_level = inq_buff->data_byte[8]; t = drv->heads * drv->sectors; if (t > 1) { - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); + drv->cylinders = total_size / t; } } } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); } - printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n", + printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n", drv->heads, drv->sectors, drv->cylinders); } static void -cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, +cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, + int withirq, unsigned int *total_size, unsigned int *block_size) { - ReadCapdata_struct *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (buf == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); - return; - } - memset(buf, 0, sizeof(ReadCapdata_struct)); + memset(buf, 0, sizeof(*buf)); if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(ReadCapdata_struct), - 1, logvol, 0, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, + logvol, 0, TYPE_CMD); else return_code = sendcmd(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(ReadCapdata_struct), - 1, logvol, 0, NULL, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, logvol, 0, + NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1; - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); + *total_size = + be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; + *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0])); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } - if (*total_size != (__u32) 0) - printk(KERN_INFO " blocks= %lld block_size= %d\n", - *total_size, *block_size); - kfree(buf); - return; -} - -static void -cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size) -{ - ReadCapdata_struct_16 *buf; - int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); - if (buf == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); - return; - } - memset(buf, 0, sizeof(ReadCapdata_struct_16)); - if (withirq) { - return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, - ctlr, buf, sizeof(ReadCapdata_struct_16), - 1, logvol, 0, TYPE_CMD); - } - else { - return_code = sendcmd(CCISS_READ_CAPACITY_16, - ctlr, buf, sizeof(ReadCapdata_struct_16), - 1, logvol, 0, NULL, TYPE_CMD); - } - if (return_code == IO_OK) { - *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1; - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); - } else { /* read capacity command failed */ - printk(KERN_WARNING "cciss: read capacity failed\n"); - *total_size = 0; - *block_size = BLOCK_SIZE; - } - printk(KERN_INFO " blocks= %lld block_size= %d\n", + printk(KERN_INFO " blocks= %u block_size= %d\n", *total_size, *block_size); - kfree(buf); return; } @@ -2045,7 +1976,8 @@ static int cciss_revalidate(struct gendisk *disk) int logvol; int FOUND = 0; unsigned int block_size; - sector_t total_size; + unsigned int total_size; + ReadCapdata_struct *size_buff = NULL; InquiryData_struct *inq_buff = NULL; for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { @@ -2058,24 +1990,27 @@ static int cciss_revalidate(struct gendisk *disk) if (!FOUND) return 1; + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) { + printk(KERN_WARNING "cciss: out of memory\n"); + return 1; + } inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { printk(KERN_WARNING "cciss: out of memory\n"); + kfree(size_buff); return 1; } - if (h->cciss_read == CCISS_READ_10) { - cciss_read_capacity(h->ctlr, logvol, 1, - &total_size, &block_size); - } else { - cciss_read_capacity_16(h->ctlr, logvol, 1, - &total_size, &block_size); - } + + cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, + &block_size); cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); blk_queue_hardsect_size(drv->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); + kfree(size_buff); kfree(inq_buff); return 0; } @@ -2484,8 +2419,7 @@ static void do_cciss_request(request_queue_t *q) { ctlr_info_t *h = q->queuedata; CommandList_struct *c; - sector_t start_blk; - int seg; + int start_blk, seg; struct request *creq; u64bit temp64; struct scatterlist tmp_sg[MAXSGENTRIES]; @@ -2529,10 +2463,10 @@ static void do_cciss_request(request_queue_t *q) c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = - (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; + (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; c->Request.Timeout = 0; // Don't time out c->Request.CDB[0] = - (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; + (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; start_blk = creq->sector; #ifdef CCISS_DEBUG printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, @@ -2566,33 +2500,15 @@ static void do_cciss_request(request_queue_t *q) #endif /* CCISS_DEBUG */ c->Header.SGList = c->Header.SGTotal = seg; - if(h->cciss_read == CCISS_READ_10) { - c->Request.CDB[1] = 0; - c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB - c->Request.CDB[3] = (start_blk >> 16) & 0xff; - c->Request.CDB[4] = (start_blk >> 8) & 0xff; - c->Request.CDB[5] = start_blk & 0xff; - c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB - c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[8] = creq->nr_sectors & 0xff; - c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; - } else { - c->Request.CDBLen = 16; - c->Request.CDB[1]= 0; - c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB - c->Request.CDB[3]= (start_blk >> 48) & 0xff; - c->Request.CDB[4]= (start_blk >> 40) & 0xff; - c->Request.CDB[5]= (start_blk >> 32) & 0xff; - c->Request.CDB[6]= (start_blk >> 24) & 0xff; - c->Request.CDB[7]= (start_blk >> 16) & 0xff; - c->Request.CDB[8]= (start_blk >> 8) & 0xff; - c->Request.CDB[9]= start_blk & 0xff; - c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; - c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; - c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[13]= creq->nr_sectors & 0xff; - c->Request.CDB[14] = c->Request.CDB[15] = 0; - } + c->Request.CDB[1] = 0; + c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB + c->Request.CDB[3] = (start_blk >> 16) & 0xff; + c->Request.CDB[4] = (start_blk >> 8) & 0xff; + c->Request.CDB[5] = start_blk & 0xff; + c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB + c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; + c->Request.CDB[8] = creq->nr_sectors & 0xff; + c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; spin_lock_irq(q->queue_lock); @@ -2602,9 +2518,9 @@ static void do_cciss_request(request_queue_t *q) h->maxQsinceinit = h->Qdepth; goto queue; -full: + full: blk_stop_queue(q); -startio: + startio: /* We will already have the driver lock here so not need * to lock it. */ @@ -3032,23 +2948,31 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) static void cciss_getgeometry(int cntl_num) { ReportLunData_struct *ld_buff; + ReadCapdata_struct *size_buff; InquiryData_struct *inq_buff; int return_code; int i; int listlength = 0; __u32 lunid = 0; int block_size; - sector_t total_size; + int total_size; ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); if (ld_buff == NULL) { printk(KERN_ERR "cciss: out of memory\n"); return; } + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) { + printk(KERN_ERR "cciss: out of memory\n"); + kfree(ld_buff); + return; + } inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { printk(KERN_ERR "cciss: out of memory\n"); kfree(ld_buff); + kfree(size_buff); return; } /* Get the firmware version */ @@ -3103,6 +3027,7 @@ static void cciss_getgeometry(int cntl_num) #endif /* CCISS_DEBUG */ hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; +// for(i=0; i< hba[cntl_num]->num_luns; i++) for (i = 0; i < CISS_MAX_LUN; i++) { if (i < hba[cntl_num]->num_luns) { lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) @@ -3121,26 +3046,8 @@ static void cciss_getgeometry(int cntl_num) ld_buff->LUN[i][2], ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID); #endif /* CCISS_DEBUG */ - - /* testing to see if 16-byte CDBs are already being used */ - if(hba[cntl_num]->cciss_read == CCISS_READ_16) { - cciss_read_capacity_16(cntl_num, i, 0, + cciss_read_capacity(cntl_num, i, size_buff, 0, &total_size, &block_size); - goto geo_inq; - } - cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); - - /* total_size = last LBA + 1 */ - if(total_size == (__u32) 0) { - cciss_read_capacity_16(cntl_num, i, 0, - &total_size, &block_size); - hba[cntl_num]->cciss_read = CCISS_READ_16; - hba[cntl_num]->cciss_write = CCISS_WRITE_16; - } else { - hba[cntl_num]->cciss_read = CCISS_READ_10; - hba[cntl_num]->cciss_write = CCISS_WRITE_10; - } -geo_inq: cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size, inq_buff, &hba[cntl_num]->drv[i]); @@ -3150,6 +3057,7 @@ static void cciss_getgeometry(int cntl_num) } } kfree(ld_buff); + kfree(size_buff); kfree(inq_buff); } diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 562235c1445a..868e0d862b0d 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -76,9 +76,6 @@ struct ctlr_info unsigned int intr[4]; unsigned int msix_vector; unsigned int msi_vector; - BYTE cciss_read; - BYTE cciss_write; - BYTE cciss_read_capacity; // information about each logical volume drive_info_struct drv[CISS_MAX_LUN]; diff --git a/trunk/drivers/block/cciss_cmd.h b/trunk/drivers/block/cciss_cmd.h index 4af7c4c0c7af..53fea549ba8b 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -118,34 +118,11 @@ typedef struct _ReadCapdata_struct BYTE block_size[4]; // Size of blocks in bytes } ReadCapdata_struct; -#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */ - -/* service action to differentiate a 16 byte read capacity from - other commands that use the 0x9e SCSI op code */ - -#define CCISS_READ_CAPACITY_16_SERVICE_ACT 0x10 - -typedef struct _ReadCapdata_struct_16 -{ - BYTE total_size[8]; /* Total size in blocks */ - BYTE block_size[4]; /* Size of blocks in bytes */ - BYTE prot_en:1; /* protection enable bit */ - BYTE rto_en:1; /* reference tag own enable bit */ - BYTE reserved:6; /* reserved bits */ - BYTE reserved2[18]; /* reserved bytes per spec */ -} ReadCapdata_struct_16; - -/* Define the supported read/write commands for cciss based controllers */ - -#define CCISS_READ_10 0x28 /* Read(10) */ -#define CCISS_WRITE_10 0x2a /* Write(10) */ -#define CCISS_READ_16 0x88 /* Read(16) */ -#define CCISS_WRITE_16 0x8a /* Write(16) */ - -/* Define the CDB lengths supported by cciss based controllers */ - -#define CDB_LEN10 10 -#define CDB_LEN16 16 +// 12 byte commands not implemented in firmware yet. +// #define CCISS_READ 0xa8 // Read(12) +// #define CCISS_WRITE 0xaa // Write(12) + #define CCISS_READ 0x28 // Read(10) + #define CCISS_WRITE 0x2a // Write(10) // BMIC commands #define BMIC_READ 0x26 diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index bb15051ffbe0..05f79d7393f7 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -766,7 +766,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c, int direction) { unsigned long flags; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl cp->scsi_cmd = NULL; diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index 4abc193314ee..78082edc14b4 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -989,6 +989,7 @@ static inline void complete_buffers(struct bio *bio, int ok) xbh = bio->bi_next; bio->bi_next = NULL; + blk_finished_io(nr_sectors); bio_endio(bio, nr_sectors << 9, ok ? 0 : -EIO); bio = xbh; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 629c5769d994..ad1d7065a1b2 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -2991,8 +2991,8 @@ static void do_fd_request(request_queue_t * q) if (usage_count == 0) { printk("warning: usage count=0, current_req=%p exiting\n", current_req); - printk("sect=%ld type=%x flags=%x\n", (long)current_req->sector, - current_req->cmd_type, current_req->cmd_flags); + printk("sect=%ld flags=%lx\n", (long)current_req->sector, + current_req->flags); return; } if (test_bit(0, &fdc_busy)) { diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index d6bb8da955a2..68b0471ad5a6 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -66,7 +66,6 @@ #include #include #include -#include #include #include #include /* for invalidate_bdev() */ @@ -1166,162 +1165,6 @@ static int lo_ioctl(struct inode * inode, struct file * file, return err; } -#ifdef CONFIG_COMPAT -struct compat_loop_info { - compat_int_t lo_number; /* ioctl r/o */ - compat_dev_t lo_device; /* ioctl r/o */ - compat_ulong_t lo_inode; /* ioctl r/o */ - compat_dev_t lo_rdevice; /* ioctl r/o */ - compat_int_t lo_offset; - compat_int_t lo_encrypt_type; - compat_int_t lo_encrypt_key_size; /* ioctl w/o */ - compat_int_t lo_flags; /* ioctl r/o */ - char lo_name[LO_NAME_SIZE]; - unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ - compat_ulong_t lo_init[2]; - char reserved[4]; -}; - -/* - * Transfer 32-bit compatibility structure in userspace to 64-bit loop info - * - noinlined to reduce stack space usage in main part of driver - */ -static noinline int -loop_info64_from_compat(const struct compat_loop_info *arg, - struct loop_info64 *info64) -{ - struct compat_loop_info info; - - if (copy_from_user(&info, arg, sizeof(info))) - return -EFAULT; - - memset(info64, 0, sizeof(*info64)); - info64->lo_number = info.lo_number; - info64->lo_device = info.lo_device; - info64->lo_inode = info.lo_inode; - info64->lo_rdevice = info.lo_rdevice; - info64->lo_offset = info.lo_offset; - info64->lo_sizelimit = 0; - info64->lo_encrypt_type = info.lo_encrypt_type; - info64->lo_encrypt_key_size = info.lo_encrypt_key_size; - info64->lo_flags = info.lo_flags; - info64->lo_init[0] = info.lo_init[0]; - info64->lo_init[1] = info.lo_init[1]; - if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) - memcpy(info64->lo_crypt_name, info.lo_name, LO_NAME_SIZE); - else - memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE); - memcpy(info64->lo_encrypt_key, info.lo_encrypt_key, LO_KEY_SIZE); - return 0; -} - -/* - * Transfer 64-bit loop info to 32-bit compatibility structure in userspace - * - noinlined to reduce stack space usage in main part of driver - */ -static noinline int -loop_info64_to_compat(const struct loop_info64 *info64, - struct compat_loop_info __user *arg) -{ - struct compat_loop_info info; - - memset(&info, 0, sizeof(info)); - info.lo_number = info64->lo_number; - info.lo_device = info64->lo_device; - info.lo_inode = info64->lo_inode; - info.lo_rdevice = info64->lo_rdevice; - info.lo_offset = info64->lo_offset; - info.lo_encrypt_type = info64->lo_encrypt_type; - info.lo_encrypt_key_size = info64->lo_encrypt_key_size; - info.lo_flags = info64->lo_flags; - info.lo_init[0] = info64->lo_init[0]; - info.lo_init[1] = info64->lo_init[1]; - if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) - memcpy(info.lo_name, info64->lo_crypt_name, LO_NAME_SIZE); - else - memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE); - memcpy(info.lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE); - - /* error in case values were truncated */ - if (info.lo_device != info64->lo_device || - info.lo_rdevice != info64->lo_rdevice || - info.lo_inode != info64->lo_inode || - info.lo_offset != info64->lo_offset || - info.lo_init[0] != info64->lo_init[0] || - info.lo_init[1] != info64->lo_init[1]) - return -EOVERFLOW; - - if (copy_to_user(arg, &info, sizeof(info))) - return -EFAULT; - return 0; -} - -static int -loop_set_status_compat(struct loop_device *lo, - const struct compat_loop_info __user *arg) -{ - struct loop_info64 info64; - int ret; - - ret = loop_info64_from_compat(arg, &info64); - if (ret < 0) - return ret; - return loop_set_status(lo, &info64); -} - -static int -loop_get_status_compat(struct loop_device *lo, - struct compat_loop_info __user *arg) -{ - struct loop_info64 info64; - int err = 0; - - if (!arg) - err = -EINVAL; - if (!err) - err = loop_get_status(lo, &info64); - if (!err) - err = loop_info64_to_compat(&info64, arg); - return err; -} - -static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; - int err; - - lock_kernel(); - switch(cmd) { - case LOOP_SET_STATUS: - mutex_lock(&lo->lo_ctl_mutex); - err = loop_set_status_compat( - lo, (const struct compat_loop_info __user *) arg); - mutex_unlock(&lo->lo_ctl_mutex); - break; - case LOOP_GET_STATUS: - mutex_lock(&lo->lo_ctl_mutex); - err = loop_get_status_compat( - lo, (struct compat_loop_info __user *) arg); - mutex_unlock(&lo->lo_ctl_mutex); - break; - case LOOP_CLR_FD: - case LOOP_GET_STATUS64: - case LOOP_SET_STATUS64: - arg = (unsigned long) compat_ptr(arg); - case LOOP_SET_FD: - case LOOP_CHANGE_FD: - err = lo_ioctl(inode, file, cmd, arg); - break; - default: - err = -ENOIOCTLCMD; - break; - } - unlock_kernel(); - return err; -} -#endif - static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; @@ -1349,9 +1192,6 @@ static struct block_device_operations lo_fops = { .open = lo_open, .release = lo_release, .ioctl = lo_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = lo_compat_ioctl, -#endif }; /* diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 9d1035e8d9d8..bdbade9a5cf5 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -407,10 +407,10 @@ static void do_nbd_request(request_queue_t * q) struct nbd_device *lo; blkdev_dequeue_request(req); - dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n", - req->rq_disk->disk_name, req, req->cmd_type); + dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n", + req->rq_disk->disk_name, req, req->flags); - if (!blk_fs_request(req)) + if (!(req->flags & REQ_CMD)) goto error_out; lo = req->rq_disk->private_data; @@ -489,7 +489,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, switch (cmd) { case NBD_DISCONNECT: printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name); - sreq.cmd_type = REQ_TYPE_SPECIAL; + sreq.flags = REQ_SPECIAL; nbd_cmd(&sreq) = NBD_CMD_DISC; /* * Set these to sane values in case server implementation diff --git a/trunk/drivers/block/paride/pd.c b/trunk/drivers/block/paride/pd.c index 40a11e567970..2403721f9db1 100644 --- a/trunk/drivers/block/paride/pd.c +++ b/trunk/drivers/block/paride/pd.c @@ -437,7 +437,7 @@ static char *pd_buf; /* buffer for request in progress */ static enum action do_pd_io_start(void) { - if (blk_special_request(pd_req)) { + if (pd_req->flags & REQ_SPECIAL) { phase = pd_special; return pd_special(); } @@ -713,18 +713,20 @@ static void do_pd_request(request_queue_t * q) static int pd_special_command(struct pd_unit *disk, enum action (*func)(struct pd_unit *disk)) { - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); struct request rq; int err = 0; memset(&rq, 0, sizeof(rq)); rq.errors = 0; + rq.rq_status = RQ_ACTIVE; rq.rq_disk = disk->gd; rq.ref_count = 1; - rq.end_io_data = &wait; + rq.waiting = &wait; rq.end_io = blk_end_sync_rq; blk_insert_request(disk->gd->queue, &rq, 0, func); wait_for_completion(&wait); + rq.waiting = NULL; if (rq.errors) err = -EIO; blk_put_request(&rq); diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index a6b2aa67c9b2..451b996bba91 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -348,7 +348,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * char sense[SCSI_SENSE_BUFFERSIZE]; request_queue_t *q; struct request *rq; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); int err = 0; q = bdev_get_queue(pd->bdev); @@ -365,17 +365,17 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * rq->sense = sense; memset(sense, 0, sizeof(sense)); rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_HARDBARRIER; + rq->flags |= REQ_BLOCK_PC | REQ_HARDBARRIER; if (cgc->quiet) - rq->cmd_flags |= REQ_QUIET; + rq->flags |= REQ_QUIET; memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); rq->ref_count++; - rq->end_io_data = &wait; + rq->flags |= REQ_NOMERGE; + rq->waiting = &wait; rq->end_io = blk_end_sync_rq; elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); generic_unplug_device(q); diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index f2305ee792a1..cc42e762396f 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -319,8 +319,8 @@ static void start_request(struct floppy_state *fs) printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", req->rq_disk->disk_name, req->cmd, (long)req->sector, req->nr_sectors, req->buffer); - printk(" errors=%d current_nr_sectors=%ld\n", - req->errors, req->current_nr_sectors); + printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", + req->rq_status, req->errors, req->current_nr_sectors); #endif if (req->sector < 0 || req->sector >= fs->total_secs) { diff --git a/trunk/drivers/block/swim_iop.c b/trunk/drivers/block/swim_iop.c index dfda796eba56..89e3c2f8b776 100644 --- a/trunk/drivers/block/swim_iop.c +++ b/trunk/drivers/block/swim_iop.c @@ -529,8 +529,8 @@ static void start_request(struct floppy_state *fs) printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", CURRENT->rq_disk->disk_name, CURRENT->cmd, CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer); - printk(" errors=%d current_nr_sectors=%ld\n", - CURRENT->errors, CURRENT->current_nr_sectors); + printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", + CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors); #endif if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) { diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index cbb9d0f21acc..5d8925bd9045 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -552,8 +552,7 @@ static void process_page(unsigned long data) static int mm_make_request(request_queue_t *q, struct bio *bio) { struct cardinfo *card = q->queuedata; - pr_debug("mm_make_request %llu %u\n", - (unsigned long long)bio->bi_sector, bio->bi_size); + pr_debug("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size); bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/ spin_lock_irq(&card->lock); diff --git a/trunk/drivers/block/xd.c b/trunk/drivers/block/xd.c index ebf3025721d1..e828e4cbd3e1 100644 --- a/trunk/drivers/block/xd.c +++ b/trunk/drivers/block/xd.c @@ -313,7 +313,7 @@ static void do_xd_request (request_queue_t * q) int res = 0; int retry; - if (!blk_fs_request(req)) { + if (!(req->flags & REQ_CMD)) { end_request(req, 0); continue; } diff --git a/trunk/drivers/cdrom/Kconfig b/trunk/drivers/cdrom/Kconfig index 4b12e9031fb3..ff5652d40619 100644 --- a/trunk/drivers/cdrom/Kconfig +++ b/trunk/drivers/cdrom/Kconfig @@ -3,7 +3,7 @@ # menu "Old CD-ROM drivers (not SCSI, not IDE)" - depends on ISA && BLOCK + depends on ISA config CD_NO_IDESCSI bool "Support non-SCSI/IDE/ATAPI CDROM drives" diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index b38c84a7a8e3..d239cf8b20bd 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -2129,7 +2129,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, rq->cmd[9] = 0xf8; rq->cmd_len = 12; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; rq->timeout = 60 * HZ; bio = rq->bio; diff --git a/trunk/drivers/cdrom/cdu31a.c b/trunk/drivers/cdrom/cdu31a.c index ccd91c1a84bd..37bdb0163f0d 100644 --- a/trunk/drivers/cdrom/cdu31a.c +++ b/trunk/drivers/cdrom/cdu31a.c @@ -1338,10 +1338,8 @@ static void do_cdu31a_request(request_queue_t * q) } /* WTF??? */ - if (!blk_fs_request(req)) { - end_request(req, 0); + if (!(req->flags & REQ_CMD)) continue; - } if (rq_data_dir(req) == WRITE) { end_request(req, 0); continue; diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index bde1c665d9f4..4cc619edf424 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -1006,7 +1006,6 @@ config GPIO_VR41XX config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)" - depends on BLOCK help The raw driver permits block devices to be bound to /dev/raw/rawN. Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index 00b17ae39736..8cd52984cda5 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -409,7 +409,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) int i; unsigned size = amd64_fetch_size(); printk(KERN_INFO "Setting up ULi AGP.\n"); - dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0)); + dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0)); if (dev1 == NULL) { printk(KERN_INFO PFX "Detected a ULi chipset, " "but could not fine the secondary device.\n"); @@ -442,8 +442,6 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) enuscr= httfea+ (size * 1024 * 1024) - 1; pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea); pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr); - - pci_dev_put(dev1); return 0; } @@ -468,7 +466,7 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); - dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0)); + dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0)); if (dev1 == NULL) { printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " "nForce3 chipset, but could not find " @@ -512,8 +510,6 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase); pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit); - pci_dev_put(dev1); - return 0; } diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index c39200161688..0dcdb363923f 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -581,21 +581,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_ * If not, we fall back to x4 mode. */ if ((*bridge_agpstat & AGPSTAT3_8X) && (*vga_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode " - "supported by bridge & card (x8).\n"); + printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode supported by bridge & card (x8).\n"); *bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); *vga_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); } else { printk(KERN_INFO PFX "Fell back to AGPx4 mode because"); if (!(*bridge_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n", - *bridge_agpstat, origbridge); + printk("bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n", *bridge_agpstat, origbridge); *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); *bridge_agpstat |= AGPSTAT3_4X; } if (!(*vga_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n", - *vga_agpstat, origvga); + printk("graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n", *vga_agpstat, origvga); *vga_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); *vga_agpstat |= AGPSTAT3_4X; } diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index d0e92ed0a367..9d6713a93ed7 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -1958,7 +1958,7 @@ static void show_serial_version(void) } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index f85b4eb16618..c1c67281750d 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -5205,7 +5205,7 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, extra ports are ignored. */ -static const struct tty_operations cy_ops = { +static struct tty_operations cy_ops = { .open = cy_open, .close = cy_close, .write = cy_write, diff --git a/trunk/drivers/char/drm/Kconfig b/trunk/drivers/char/drm/Kconfig index ef833a1c27eb..5278c388d3e7 100644 --- a/trunk/drivers/char/drm/Kconfig +++ b/trunk/drivers/char/drm/Kconfig @@ -60,9 +60,7 @@ config DRM_I830 Choose this option if you have a system that has Intel 830M, 845G, 852GM, 855GM or 865G integrated graphics. If M is selected, the module will be called i830. AGP support is required for this driver - to work. This driver is used by the older X releases X.org 6.7 and - XFree86 4.3. If unsure, build this and i915 as modules and the X server - will load the correct one. + to work. This driver will eventually be replaced by the i915 one. config DRM_I915 tristate "i915 driver" @@ -70,9 +68,8 @@ config DRM_I915 Choose this option if you have a system that has Intel 830M, 845G, 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the module will be called i915. AGP support is required for this driver - to work. This driver is used by the Intel driver in X.org 6.8 and - XFree86 4.4 and above. If unsure, build this and i830 as modules and - the X server will load the correct one. + to work. This driver will eventually replace the I830 driver, when + later release of X start to use the new DDX and DRI. endchoice diff --git a/trunk/drivers/char/drm/Makefile b/trunk/drivers/char/drm/Makefile index 3ad0f648c6b2..9d180c42816c 100644 --- a/trunk/drivers/char/drm/Makefile +++ b/trunk/drivers/char/drm/Makefile @@ -6,7 +6,7 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o + drm_sysfs.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o @@ -16,9 +16,9 @@ i830-objs := i830_drv.o i830_dma.o i830_irq.o i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o ffb-objs := ffb_drv.o ffb_context.o -sis-objs := sis_drv.o sis_mm.o +sis-objs := sis_drv.o sis_ds.o sis_mm.o savage-objs := savage_drv.o savage_bci.o savage_state.o -via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o +via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o ifeq ($(CONFIG_COMPAT),y) drm-objs += drm_ioc32.o diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index 7690a59ace04..d2a56182bc35 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -79,7 +79,6 @@ #define __OS_HAS_MTRR (defined(CONFIG_MTRR)) #include "drm_os_linux.h" -#include "drm_hashtab.h" /***********************************************************************/ /** \name DRM template customization defaults */ @@ -105,7 +104,7 @@ #define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then also include looping detection. */ -#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ +#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */ #define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ #define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ #define DRM_LOOPING_LIMIT 5000000 @@ -135,12 +134,19 @@ #define DRM_MEM_CTXBITMAP 18 #define DRM_MEM_STUB 19 #define DRM_MEM_SGLISTS 20 -#define DRM_MEM_CTXLIST 21 -#define DRM_MEM_MM 22 -#define DRM_MEM_HASHTAB 23 +#define DRM_MEM_CTXLIST 21 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) -#define DRM_MAP_HASH_OFFSET 0x10000000 + +/*@}*/ + +/***********************************************************************/ +/** \name Backward compatibility section */ +/*@{*/ + +#define DRM_RPR_ARG(vma) vma, + +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) /*@}*/ @@ -205,6 +211,8 @@ /*@{*/ #define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) +#define DRM_MIN(a,b) min(a,b) +#define DRM_MAX(a,b) max(a,b) #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) @@ -278,8 +286,7 @@ typedef struct drm_devstate { } drm_devstate_t; typedef struct drm_magic_entry { - drm_hash_item_t hash_item; - struct list_head head; + drm_magic_t magic; struct drm_file *priv; struct drm_magic_entry *next; } drm_magic_entry_t; @@ -486,7 +493,6 @@ typedef struct drm_sigdata { */ typedef struct drm_map_list { struct list_head head; /**< list head */ - drm_hash_item_t hash; drm_map_t *map; /**< mapping */ unsigned int user_token; } drm_map_list_t; @@ -521,22 +527,6 @@ typedef struct ati_pcigart_info { drm_local_map_t mapping; } drm_ati_pcigart_info; -/* - * Generic memory manager structs - */ -typedef struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; - int free; - unsigned long start; - unsigned long size; - void *private; -} drm_mm_node_t; - -typedef struct drm_mm { - drm_mm_node_t root_node; -} drm_mm_t; - /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -656,15 +646,13 @@ typedef struct drm_device { /*@{ */ drm_file_t *file_first; /**< file list head */ drm_file_t *file_last; /**< file list tail */ - drm_open_hash_t magiclist; /**< magic hash table */ - struct list_head magicfree; + drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ /*@} */ /** \name Memory management */ /*@{ */ drm_map_list_t *maplist; /**< Linked list of regions */ int map_count; /**< Number of mappable regions */ - drm_open_hash_t map_hash; /**< User token hash table for maps */ /** \name Context handle management */ /*@{ */ @@ -723,8 +711,10 @@ typedef struct drm_device { drm_agp_head_t *agp; /**< AGP data */ struct pci_dev *pdev; /**< PCI device structure */ - int pci_vendor; /**< PCI vendor id */ - int pci_device; /**< PCI device id */ + int pci_domain; /**< PCI bus domain number */ + int pci_bus; /**< PCI bus number */ + int pci_slot; /**< PCI slot number */ + int pci_func; /**< PCI function number */ #ifdef __alpha__ struct pci_controller *hose; #endif @@ -746,12 +736,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } -#ifdef __alpha__ -#define drm_get_pci_domain(dev) dev->hose->bus->number -#else -#define drm_get_pci_domain(dev) 0 -#endif - #if __OS_HAS_AGP static inline int drm_core_has_AGP(struct drm_device *dev) { @@ -1027,18 +1011,6 @@ extern struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head); extern void drm_sysfs_device_remove(struct class_device *class_dev); -/* - * Basic memory manager support (drm_mm.c) - */ -extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, - unsigned long size, - unsigned alignment); -extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); -extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, - unsigned alignment, int best_match); -extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); -extern void drm_mm_takedown(drm_mm_t *mm); - /* Inline replacements for DRM_IOREMAP macros */ static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) diff --git a/trunk/drivers/char/drm/drm_auth.c b/trunk/drivers/char/drm/drm_auth.c index c7b19d35bcd6..2a37586a7ee8 100644 --- a/trunk/drivers/char/drm/drm_auth.c +++ b/trunk/drivers/char/drm/drm_auth.c @@ -35,6 +35,20 @@ #include "drmP.h" +/** + * Generate a hash key from a magic. + * + * \param magic magic. + * \return hash key. + * + * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be + * a power of 2. + */ +static int drm_hash_magic(drm_magic_t magic) +{ + return magic & (DRM_HASH_SIZE - 1); +} + /** * Find the file with the given magic number. * @@ -49,12 +63,14 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) { drm_file_t *retval = NULL; drm_magic_entry_t *pt; - drm_hash_item_t *hash; + int hash = drm_hash_magic(magic); mutex_lock(&dev->struct_mutex); - if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); - retval = pt->priv; + for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { + if (pt->magic == magic) { + retval = pt->priv; + break; + } } mutex_unlock(&dev->struct_mutex); return retval; @@ -74,20 +90,28 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, drm_magic_t magic) { + int hash; drm_magic_entry_t *entry; DRM_DEBUG("%d\n", magic); + hash = drm_hash_magic(magic); entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); if (!entry) return -ENOMEM; memset(entry, 0, sizeof(*entry)); + entry->magic = magic; entry->priv = priv; + entry->next = NULL; - entry->hash_item.key = (unsigned long)magic; mutex_lock(&dev->struct_mutex); - drm_ht_insert_item(&dev->magiclist, &entry->hash_item); - list_add_tail(&entry->head, &dev->magicfree); + if (dev->magiclist[hash].tail) { + dev->magiclist[hash].tail->next = entry; + dev->magiclist[hash].tail = entry; + } else { + dev->magiclist[hash].head = entry; + dev->magiclist[hash].tail = entry; + } mutex_unlock(&dev->struct_mutex); return 0; @@ -104,24 +128,34 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, */ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) { + drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; - drm_hash_item_t *hash; + int hash; DRM_DEBUG("%d\n", magic); + hash = drm_hash_magic(magic); mutex_lock(&dev->struct_mutex); - if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; + for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { + if (pt->magic == magic) { + if (dev->magiclist[hash].head == pt) { + dev->magiclist[hash].head = pt->next; + } + if (dev->magiclist[hash].tail == pt) { + dev->magiclist[hash].tail = prev; + } + if (prev) { + prev->next = pt->next; + } + mutex_unlock(&dev->struct_mutex); + return 0; + } } - pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); - drm_ht_remove_item(&dev->magiclist, hash); - list_del(&pt->head); mutex_unlock(&dev->struct_mutex); drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); - return 0; + return -EINVAL; } /** diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 029baea33b62..006b06d29727 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -65,29 +65,43 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, return NULL; } -static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, - unsigned long user_token, int hashed_handle) +/* + * Used to allocate 32-bit handles for mappings. + */ +#define START_RANGE 0x10000000 +#define END_RANGE 0x40000000 + +#ifdef _LP64 +static __inline__ unsigned int HandleID(unsigned long lhandle, + drm_device_t *dev) { - int use_hashed_handle; -#if (BITS_PER_LONG == 64) - use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); -#elif (BITS_PER_LONG == 32) - use_hashed_handle = hashed_handle; -#else -#error Unsupported long size. Neither 64 nor 32 bits. -#endif + static unsigned int map32_handle = START_RANGE; + unsigned int hash; + + if (lhandle & 0xffffffff00000000) { + hash = map32_handle; + map32_handle += PAGE_SIZE; + if (map32_handle > END_RANGE) + map32_handle = START_RANGE; + } else + hash = lhandle; + + while (1) { + drm_map_list_t *_entry; + list_for_each_entry(_entry, &dev->maplist->head, head) { + if (_entry->user_token == hash) + break; + } + if (&_entry->head == &dev->maplist->head) + return hash; - if (!use_hashed_handle) { - int ret; - hash->key = user_token; - ret = drm_ht_insert_item(&dev->map_hash, hash); - if (ret != -EINVAL) - return ret; + hash += PAGE_SIZE; + map32_handle += PAGE_SIZE; } - return drm_ht_just_insert_please(&dev->map_hash, hash, - user_token, 32 - PAGE_SHIFT - 3, - PAGE_SHIFT, DRM_MAP_HASH_OFFSET); } +#else +# define HandleID(x,dev) (unsigned int)(x) +#endif /** * Ioctl to specify a range of memory that is available for mapping by a non-root process. @@ -109,8 +123,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, drm_map_t *map; drm_map_list_t *list; drm_dma_handle_t *dmah; - unsigned long user_token; - int ret; map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); if (!map) @@ -245,20 +257,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, mutex_lock(&dev->struct_mutex); list_add(&list->head, &dev->maplist->head); - /* Assign a 32-bit handle */ /* We do it here so that dev->struct_mutex protects the increment */ - user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : - map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0); - if (ret) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - drm_free(list, sizeof(*list), DRM_MEM_MAPS); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - list->user_token = list->hash.key; + list->user_token = HandleID(map->type == _DRM_SHM + ? (unsigned long)map->handle + : map->offset, dev); mutex_unlock(&dev->struct_mutex); *maplist = list; @@ -343,7 +346,6 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) if (r_list->map == map) { list_del(list); - drm_ht_remove_key(&dev->map_hash, r_list->user_token); drm_free(list, sizeof(*list), DRM_MEM_MAPS); break; } @@ -439,10 +441,8 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) { - mutex_unlock(&dev->struct_mutex); + if (!map) return -EINVAL; - } /* Register and framebuffer maps are permanent */ if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c index b366c5b1bd16..3c0b882a8e72 100644 --- a/trunk/drivers/char/drm/drm_drv.c +++ b/trunk/drivers/char/drm/drm_drv.c @@ -118,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, }; -#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) +#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) /** * Take down the DRM device. @@ -155,13 +155,12 @@ int drm_lastclose(drm_device_t * dev) del_timer(&dev->timer); /* Clear pid list */ - if (dev->magicfree.next) { - list_for_each_entry_safe(pt, next, &dev->magicfree, head) { - list_del(&pt->head); - drm_ht_remove_item(&dev->magiclist, &pt->hash_item); + for (i = 0; i < DRM_HASH_SIZE; i++) { + for (pt = dev->magiclist[i].head; pt; pt = next) { + next = pt->next; drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); } - drm_ht_remove(&dev->magiclist); + dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } /* Clear AGP information */ @@ -300,7 +299,6 @@ static void drm_cleanup(drm_device_t * dev) if (dev->maplist) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; - drm_ht_remove(&dev->map_hash); } drm_ctxbitmap_cleanup(dev); diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c index 898f47dafec0..b7f7951c4587 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -53,8 +53,6 @@ static int drm_setup(drm_device_t * dev) return ret; } - dev->magicfree.next = NULL; - /* prebuild the SAREA */ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); if (i != 0) @@ -71,11 +69,13 @@ static int drm_setup(drm_device_t * dev) return i; } - for (i = 0; i < ARRAY_SIZE(dev->counts); i++) + for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); - drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); - INIT_LIST_HEAD(&dev->magicfree); + for (i = 0; i < DRM_HASH_SIZE; i++) { + dev->magiclist[i].head = NULL; + dev->magiclist[i].tail = NULL; + } dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); if (dev->ctxlist == NULL) diff --git a/trunk/drivers/char/drm/drm_hashtab.c b/trunk/drivers/char/drm/drm_hashtab.c deleted file mode 100644 index a0b2d6802ae4..000000000000 --- a/trunk/drivers/char/drm/drm_hashtab.c +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "drm_hashtab.h" -#include - -int drm_ht_create(drm_open_hash_t *ht, unsigned int order) -{ - unsigned int i; - - ht->size = 1 << order; - ht->order = order; - ht->fill = 0; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); - if (!ht->table) { - DRM_ERROR("Out of memory for hash table\n"); - return -ENOMEM; - } - for (i=0; i< ht->size; ++i) { - INIT_HLIST_HEAD(&ht->table[i]); - } - return 0; -} - -void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - int count = 0; - - hashed_key = hash_long(key, ht->order); - DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); - } -} - -static struct hlist_node *drm_ht_find_key(drm_open_hash_t *ht, - unsigned long key) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - if (entry->key == key) - return list; - if (entry->key > key) - break; - } - return NULL; -} - - -int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list, *parent; - unsigned int hashed_key; - unsigned long key = item->key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - parent = NULL; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - if (entry->key == key) - return -EINVAL; - if (entry->key > key) - break; - parent = list; - } - if (parent) { - hlist_add_after(parent, &item->head); - } else { - hlist_add_head(&item->head, h_list); - } - return 0; -} - -/* - * Just insert an item and return any "bits" bit key that hasn't been - * used before. - */ -int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, - unsigned long seed, int bits, int shift, - unsigned long add) -{ - int ret; - unsigned long mask = (1 << bits) - 1; - unsigned long first, unshifted_key; - - unshifted_key = hash_long(seed, bits); - first = unshifted_key; - do { - item->key = (unshifted_key << shift) + add; - ret = drm_ht_insert_item(ht, item); - if (ret) - unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); - - if (ret) { - DRM_ERROR("Available key bit space exhausted\n"); - return -EINVAL; - } - return 0; -} - -int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, - drm_hash_item_t **item) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (!list) - return -EINVAL; - - *item = hlist_entry(list, drm_hash_item_t, head); - return 0; -} - -int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (list) { - hlist_del_init(list); - ht->fill--; - return 0; - } - return -EINVAL; -} - -int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) -{ - hlist_del_init(&item->head); - ht->fill--; - return 0; -} - -void drm_ht_remove(drm_open_hash_t *ht) -{ - if (ht->table) { - vfree(ht->table); - ht->table = NULL; - } -} - diff --git a/trunk/drivers/char/drm/drm_hashtab.h b/trunk/drivers/char/drm/drm_hashtab.h deleted file mode 100644 index 40afec05bff8..000000000000 --- a/trunk/drivers/char/drm/drm_hashtab.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_HASHTAB_H -#define DRM_HASHTAB_H - -#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) - -typedef struct drm_hash_item{ - struct hlist_node head; - unsigned long key; -} drm_hash_item_t; - -typedef struct drm_open_hash{ - unsigned int size; - unsigned int order; - unsigned int fill; - struct hlist_head *table; -} drm_open_hash_t; - - -extern int drm_ht_create(drm_open_hash_t *ht, unsigned int order); -extern int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item); -extern int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, - unsigned long seed, int bits, int shift, - unsigned long add); -extern int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, drm_hash_item_t **item); - -extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key); -extern int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key); -extern int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item); -extern void drm_ht_remove(drm_open_hash_t *ht); - - -#endif - diff --git a/trunk/drivers/char/drm/drm_ioc32.c b/trunk/drivers/char/drm/drm_ioc32.c index d4f874520082..e9e2db18952d 100644 --- a/trunk/drivers/char/drm/drm_ioc32.c +++ b/trunk/drivers/char/drm/drm_ioc32.c @@ -1051,7 +1051,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) drm_ioctl_compat_t *fn; int ret; - if (nr >= ARRAY_SIZE(drm_compat_ioctls)) + if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls)) return -ENOTTY; fn = drm_compat_ioctls[nr]; diff --git a/trunk/drivers/char/drm/drm_ioctl.c b/trunk/drivers/char/drm/drm_ioctl.c index 565895547d75..555f323b8a32 100644 --- a/trunk/drivers/char/drm/drm_ioctl.c +++ b/trunk/drivers/char/drm/drm_ioctl.c @@ -127,10 +127,9 @@ int drm_setunique(struct inode *inode, struct file *filp, domain = bus >> 8; bus &= 0xff; - if ((domain != drm_get_pci_domain(dev)) || - (bus != dev->pdev->bus->number) || - (slot != PCI_SLOT(dev->pdev->devfn)) || - (func != PCI_FUNC(dev->pdev->devfn))) + if ((domain != dev->pci_domain) || + (bus != dev->pci_bus) || + (slot != dev->pci_slot) || (func != dev->pci_func)) return -EINVAL; return 0; @@ -141,17 +140,15 @@ static int drm_set_busid(drm_device_t * dev) int len; if (dev->unique != NULL) - return 0; + return EBUSY; dev->unique_len = 40; dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); if (dev->unique == NULL) - return -ENOMEM; + return ENOMEM; len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", - drm_get_pci_domain(dev), dev->pdev->bus->number, - PCI_SLOT(dev->pdev->devfn), - PCI_FUNC(dev->pdev->devfn)); + dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); if (len > dev->unique_len) DRM_ERROR("Unique buffer overflowed\n"); @@ -160,7 +157,7 @@ static int drm_set_busid(drm_device_t * dev) drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, DRM_MEM_DRIVER); if (dev->devname == NULL) - return -ENOMEM; + return ENOMEM; sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); @@ -333,32 +330,27 @@ int drm_setversion(DRM_IOCTL_ARGS) drm_set_version_t retv; int if_version; drm_set_version_t __user *argp = (void __user *)data; - int ret; - if (copy_from_user(&sv, argp, sizeof(sv))) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_minor = DRM_IF_MINOR; retv.drm_dd_major = dev->driver->major; retv.drm_dd_minor = dev->driver->minor; - if (copy_to_user(argp, &retv, sizeof(retv))) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); if (sv.drm_di_major != -1) { if (sv.drm_di_major != DRM_IF_MAJOR || sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) - return -EINVAL; + return EINVAL; if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor); - dev->if_version = max(if_version, dev->if_version); + dev->if_version = DRM_MAX(if_version, dev->if_version); if (sv.drm_di_minor >= 1) { /* * Version 1.1 includes tying of DRM to specific device */ - ret = drm_set_busid(dev); - if (ret) - return ret; + drm_set_busid(dev); } } @@ -366,7 +358,7 @@ int drm_setversion(DRM_IOCTL_ARGS) if (sv.drm_dd_major != dev->driver->major || sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver->minor) - return -EINVAL; + return EINVAL; if (dev->driver->set_version) dev->driver->set_version(dev, &sv); diff --git a/trunk/drivers/char/drm/drm_irq.c b/trunk/drivers/char/drm/drm_irq.c index 4553a3a1e496..ebdb7182c4fd 100644 --- a/trunk/drivers/char/drm/drm_irq.c +++ b/trunk/drivers/char/drm/drm_irq.c @@ -64,9 +64,9 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, if (copy_from_user(&p, argp, sizeof(p))) return -EFAULT; - if ((p.busnum >> 8) != drm_get_pci_domain(dev) || - (p.busnum & 0xff) != dev->pdev->bus->number || - p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn)) + if ((p.busnum >> 8) != dev->pci_domain || + (p.busnum & 0xff) != dev->pci_bus || + p.devnum != dev->pci_slot || p.funcnum != dev->pci_func) return -EINVAL; p.irq = dev->irq; @@ -255,8 +255,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) if (!dev->irq) return -EINVAL; - if (copy_from_user(&vblwait, argp, sizeof(vblwait))) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait)); switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) { case _DRM_VBLANK_RELATIVE: @@ -330,8 +329,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) } done: - if (copy_to_user(argp, &vblwait, sizeof(vblwait))) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait)); return ret; } diff --git a/trunk/drivers/char/drm/drm_mm.c b/trunk/drivers/char/drm/drm_mm.c deleted file mode 100644 index 617526bd5b0c..000000000000 --- a/trunk/drivers/char/drm/drm_mm.c +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" - -drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, - unsigned long size, unsigned alignment) -{ - - drm_mm_node_t *child; - - if (alignment) - size += alignment - 1; - - if (parent->size == size) { - list_del_init(&parent->fl_entry); - parent->free = 0; - return parent; - } else { - child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return NULL; - - INIT_LIST_HEAD(&child->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - child->free = 0; - child->size = size; - child->start = parent->start; - - list_add_tail(&child->ml_entry, &parent->ml_entry); - parent->size -= size; - parent->start += size; - } - return child; -} - -/* - * Put a block. Merge with the previous and / or next block if they are free. - * Otherwise add to the free stack. - */ - -void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) -{ - - drm_mm_node_t *list_root = &mm->root_node; - struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &list_root->ml_entry; - drm_mm_node_t *prev_node = NULL; - drm_mm_node_t *next_node; - - int merged = 0; - - if (cur_head->prev != root_head) { - prev_node = list_entry(cur_head->prev, drm_mm_node_t, ml_entry); - if (prev_node->free) { - prev_node->size += cur->size; - merged = 1; - } - } - if (cur_head->next != root_head) { - next_node = list_entry(cur_head->next, drm_mm_node_t, ml_entry); - if (next_node->free) { - if (merged) { - prev_node->size += next_node->size; - list_del(&next_node->ml_entry); - list_del(&next_node->fl_entry); - drm_free(next_node, sizeof(*next_node), - DRM_MEM_MM); - } else { - next_node->size += cur->size; - next_node->start = cur->start; - merged = 1; - } - } - } - if (!merged) { - cur->free = 1; - list_add(&cur->fl_entry, &list_root->fl_entry); - } else { - list_del(&cur->ml_entry); - drm_free(cur, sizeof(*cur), DRM_MEM_MM); - } -} - -drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, - unsigned long size, - unsigned alignment, int best_match) -{ - struct list_head *list; - const struct list_head *free_stack = &mm->root_node.fl_entry; - drm_mm_node_t *entry; - drm_mm_node_t *best; - unsigned long best_size; - - best = NULL; - best_size = ~0UL; - - if (alignment) - size += alignment - 1; - - list_for_each(list, free_stack) { - entry = list_entry(list, drm_mm_node_t, fl_entry); - if (entry->size >= size) { - if (!best_match) - return entry; - if (size < best_size) { - best = entry; - best_size = entry->size; - } - } - } - - return best; -} - -int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) -{ - drm_mm_node_t *child; - - INIT_LIST_HEAD(&mm->root_node.ml_entry); - INIT_LIST_HEAD(&mm->root_node.fl_entry); - child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return -ENOMEM; - - INIT_LIST_HEAD(&child->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - child->start = start; - child->size = size; - child->free = 1; - - list_add(&child->fl_entry, &mm->root_node.fl_entry); - list_add(&child->ml_entry, &mm->root_node.ml_entry); - - return 0; -} - -EXPORT_SYMBOL(drm_mm_init); - -void drm_mm_takedown(drm_mm_t * mm) -{ - struct list_head *bnode = mm->root_node.fl_entry.next; - drm_mm_node_t *entry; - - entry = list_entry(bnode, drm_mm_node_t, fl_entry); - - if (entry->ml_entry.next != &mm->root_node.ml_entry || - entry->fl_entry.next != &mm->root_node.fl_entry) { - DRM_ERROR("Memory manager not clean. Delaying takedown\n"); - return; - } - - list_del(&entry->fl_entry); - list_del(&entry->ml_entry); - - drm_free(entry, sizeof(*entry), DRM_MEM_MM); -} - -EXPORT_SYMBOL(drm_mm_takedown); diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index 09398d5fbd3f..b1bb3c7b568d 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -3,13 +3,13 @@ Please contact dri-devel@lists.sf.net to add new cards to this list */ #define radeon_PCI_IDS \ - {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ - {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ + {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ + {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ @@ -25,35 +25,35 @@ {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ + {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ + {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ + {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ @@ -62,16 +62,16 @@ {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ + {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ @@ -80,59 +80,59 @@ {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ - {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ + {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ + {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ {0, 0, 0} #define r128_PCI_IDS \ @@ -209,7 +209,6 @@ {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} @@ -228,10 +227,6 @@ {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} #define i810_PCI_IDS \ @@ -290,9 +285,5 @@ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} diff --git a/trunk/drivers/char/drm/drm_proc.c b/trunk/drivers/char/drm/drm_proc.c index 62d5fe15f046..362a270af0f1 100644 --- a/trunk/drivers/char/drm/drm_proc.c +++ b/trunk/drivers/char/drm/drm_proc.c @@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, vma->vm_flags & VM_MAYSHARE ? 's' : 'p', vma->vm_flags & VM_LOCKED ? 'l' : '-', vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_pgoff << PAGE_SHIFT); + VM_OFFSET(vma)); #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); diff --git a/trunk/drivers/char/drm/drm_sman.c b/trunk/drivers/char/drm/drm_sman.c deleted file mode 100644 index 425c82336ee0..000000000000 --- a/trunk/drivers/char/drm/drm_sman.c +++ /dev/null @@ -1,352 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Simple memory manager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#include "drm_sman.h" - -typedef struct drm_owner_item { - drm_hash_item_t owner_hash; - struct list_head sman_list; - struct list_head mem_blocks; -} drm_owner_item_t; - -void drm_sman_takedown(drm_sman_t * sman) -{ - drm_ht_remove(&sman->user_hash_tab); - drm_ht_remove(&sman->owner_hash_tab); - if (sman->mm) - drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm), - DRM_MEM_MM); -} - -EXPORT_SYMBOL(drm_sman_takedown); - -int -drm_sman_init(drm_sman_t * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order) -{ - int ret = 0; - - sman->mm = (drm_sman_mm_t *) drm_calloc(num_managers, sizeof(*sman->mm), - DRM_MEM_MM); - if (!sman->mm) { - ret = -ENOMEM; - goto out; - } - sman->num_managers = num_managers; - INIT_LIST_HEAD(&sman->owner_items); - ret = drm_ht_create(&sman->owner_hash_tab, owner_order); - if (ret) - goto out1; - ret = drm_ht_create(&sman->user_hash_tab, user_order); - if (!ret) - goto out; - - drm_ht_remove(&sman->owner_hash_tab); -out1: - drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM); -out: - return ret; -} - -EXPORT_SYMBOL(drm_sman_init); - -static void *drm_sman_mm_allocate(void *private, unsigned long size, - unsigned alignment) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_node_t *tmp; - - tmp = drm_mm_search_free(mm, size, alignment, 1); - if (!tmp) { - return NULL; - } - tmp = drm_mm_get_block(tmp, size, alignment); - return tmp; -} - -static void drm_sman_mm_free(void *private, void *ref) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_node_t *node = (drm_mm_node_t *) ref; - - drm_mm_put_block(mm, node); -} - -static void drm_sman_mm_destroy(void *private) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_takedown(mm); - drm_free(mm, sizeof(*mm), DRM_MEM_MM); -} - -static unsigned long drm_sman_mm_offset(void *private, void *ref) -{ - drm_mm_node_t *node = (drm_mm_node_t *) ref; - return node->start; -} - -int -drm_sman_set_range(drm_sman_t * sman, unsigned int manager, - unsigned long start, unsigned long size) -{ - drm_sman_mm_t *sman_mm; - drm_mm_t *mm; - int ret; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM); - if (!mm) { - return -ENOMEM; - } - sman_mm->private = mm; - ret = drm_mm_init(mm, start, size); - - if (ret) { - drm_free(mm, sizeof(*mm), DRM_MEM_MM); - return ret; - } - - sman_mm->allocate = drm_sman_mm_allocate; - sman_mm->free = drm_sman_mm_free; - sman_mm->destroy = drm_sman_mm_destroy; - sman_mm->offset = drm_sman_mm_offset; - - return 0; -} - -EXPORT_SYMBOL(drm_sman_set_range); - -int -drm_sman_set_manager(drm_sman_t * sman, unsigned int manager, - drm_sman_mm_t * allocator) -{ - BUG_ON(manager >= sman->num_managers); - sman->mm[manager] = *allocator; - - return 0; -} - -static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman, - unsigned long owner) -{ - int ret; - drm_hash_item_t *owner_hash_item; - drm_owner_item_t *owner_item; - - ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item); - if (!ret) { - return drm_hash_entry(owner_hash_item, drm_owner_item_t, - owner_hash); - } - - owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM); - if (!owner_item) - goto out; - - INIT_LIST_HEAD(&owner_item->mem_blocks); - owner_item->owner_hash.key = owner; - if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash)) - goto out1; - - list_add_tail(&owner_item->sman_list, &sman->owner_items); - return owner_item; - -out1: - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -out: - return NULL; -} - -drm_memblock_item_t *drm_sman_alloc(drm_sman_t *sman, unsigned int manager, - unsigned long size, unsigned alignment, - unsigned long owner) -{ - void *tmp; - drm_sman_mm_t *sman_mm; - drm_owner_item_t *owner_item; - drm_memblock_item_t *memblock; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - tmp = sman_mm->allocate(sman_mm->private, size, alignment); - - if (!tmp) { - return NULL; - } - - memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM); - - if (!memblock) - goto out; - - memblock->mm_info = tmp; - memblock->mm = sman_mm; - memblock->sman = sman; - - if (drm_ht_just_insert_please - (&sman->user_hash_tab, &memblock->user_hash, - (unsigned long)memblock, 32, 0, 0)) - goto out1; - - owner_item = drm_sman_get_owner_item(sman, owner); - if (!owner_item) - goto out2; - - list_add_tail(&memblock->owner_list, &owner_item->mem_blocks); - - return memblock; - -out2: - drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); -out1: - drm_free(memblock, sizeof(*memblock), DRM_MEM_MM); -out: - sman_mm->free(sman_mm->private, tmp); - - return NULL; -} - -EXPORT_SYMBOL(drm_sman_alloc); - -static void drm_sman_free(drm_memblock_item_t *item) -{ - drm_sman_t *sman = item->sman; - - list_del(&item->owner_list); - drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); - item->mm->free(item->mm->private, item->mm_info); - drm_free(item, sizeof(*item), DRM_MEM_MM); -} - -int drm_sman_free_key(drm_sman_t *sman, unsigned int key) -{ - drm_hash_item_t *hash_item; - drm_memblock_item_t *memblock_item; - - if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item)) - return -EINVAL; - - memblock_item = drm_hash_entry(hash_item, drm_memblock_item_t, user_hash); - drm_sman_free(memblock_item); - return 0; -} - -EXPORT_SYMBOL(drm_sman_free_key); - -static void drm_sman_remove_owner(drm_sman_t *sman, - drm_owner_item_t *owner_item) -{ - list_del(&owner_item->sman_list); - drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -} - -int drm_sman_owner_clean(drm_sman_t *sman, unsigned long owner) -{ - - drm_hash_item_t *hash_item; - drm_owner_item_t *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - return -1; - } - - owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash); - if (owner_item->mem_blocks.next == &owner_item->mem_blocks) { - drm_sman_remove_owner(sman, owner_item); - return -1; - } - - return 0; -} - -EXPORT_SYMBOL(drm_sman_owner_clean); - -static void drm_sman_do_owner_cleanup(drm_sman_t *sman, - drm_owner_item_t *owner_item) -{ - drm_memblock_item_t *entry, *next; - - list_for_each_entry_safe(entry, next, &owner_item->mem_blocks, - owner_list) { - drm_sman_free(entry); - } - drm_sman_remove_owner(sman, owner_item); -} - -void drm_sman_owner_cleanup(drm_sman_t *sman, unsigned long owner) -{ - - drm_hash_item_t *hash_item; - drm_owner_item_t *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - - return; - } - - owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash); - drm_sman_do_owner_cleanup(sman, owner_item); -} - -EXPORT_SYMBOL(drm_sman_owner_cleanup); - -void drm_sman_cleanup(drm_sman_t *sman) -{ - drm_owner_item_t *entry, *next; - unsigned int i; - drm_sman_mm_t *sman_mm; - - list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) { - drm_sman_do_owner_cleanup(sman, entry); - } - if (sman->mm) { - for (i = 0; i < sman->num_managers; ++i) { - sman_mm = &sman->mm[i]; - if (sman_mm->private) { - sman_mm->destroy(sman_mm->private); - sman_mm->private = NULL; - } - } - } -} - -EXPORT_SYMBOL(drm_sman_cleanup); diff --git a/trunk/drivers/char/drm/drm_sman.h b/trunk/drivers/char/drm/drm_sman.h deleted file mode 100644 index ddc732a1bf27..000000000000 --- a/trunk/drivers/char/drm/drm_sman.h +++ /dev/null @@ -1,176 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple memory MANager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_SMAN_H -#define DRM_SMAN_H - -#include "drmP.h" -#include "drm_hashtab.h" - -/* - * A class that is an abstration of a simple memory allocator. - * The sman implementation provides a default such allocator - * using the drm_mm.c implementation. But the user can replace it. - * See the SiS implementation, which may use the SiS FB kernel module - * for memory management. - */ - -typedef struct drm_sman_mm { - /* private info. If allocated, needs to be destroyed by the destroy - function */ - void *private; - - /* Allocate a memory block with given size and alignment. - Return an opaque reference to the memory block */ - - void *(*allocate) (void *private, unsigned long size, - unsigned alignment); - - /* Free a memory block. "ref" is the opaque reference that we got from - the "alloc" function */ - - void (*free) (void *private, void *ref); - - /* Free all resources associated with this allocator */ - - void (*destroy) (void *private); - - /* Return a memory offset from the opaque reference returned from the - "alloc" function */ - - unsigned long (*offset) (void *private, void *ref); -} drm_sman_mm_t; - -typedef struct drm_memblock_item { - struct list_head owner_list; - drm_hash_item_t user_hash; - void *mm_info; - drm_sman_mm_t *mm; - struct drm_sman *sman; -} drm_memblock_item_t; - -typedef struct drm_sman { - drm_sman_mm_t *mm; - int num_managers; - drm_open_hash_t owner_hash_tab; - drm_open_hash_t user_hash_tab; - struct list_head owner_items; -} drm_sman_t; - -/* - * Take down a memory manager. This function should only be called after a - * successful init and after a call to drm_sman_cleanup. - */ - -extern void drm_sman_takedown(drm_sman_t * sman); - -/* - * Allocate structures for a manager. - * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) - * user_order is the log2 of the number of buckets in the user hash table. - * set this to approximately log2 of the max number of memory regions - * that will be allocated for _all_ pools together. - * owner_order is the log2 of the number of buckets in the owner hash table. - * set this to approximately log2 of - * the number of client file connections that will - * be using the manager. - * - */ - -extern int drm_sman_init(drm_sman_t * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order); - -/* - * Initialize a drm_mm.c allocator. Should be called only once for each - * manager unless a customized allogator is used. - */ - -extern int drm_sman_set_range(drm_sman_t * sman, unsigned int manager, - unsigned long start, unsigned long size); - -/* - * Initialize a customized allocator for one of the managers. - * (See the SiS module). The object pointed to by "allocator" is copied, - * so it can be destroyed after this call. - */ - -extern int drm_sman_set_manager(drm_sman_t * sman, unsigned int mananger, - drm_sman_mm_t * allocator); - -/* - * Allocate a memory block. Aligment is not implemented yet. - */ - -extern drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman, - unsigned int manager, - unsigned long size, - unsigned alignment, - unsigned long owner); -/* - * Free a memory block identified by its user hash key. - */ - -extern int drm_sman_free_key(drm_sman_t * sman, unsigned int key); - -/* - * returns 1 iff there are no stale memory blocks associated with this owner. - * Typically called to determine if we need to idle the hardware and call - * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all - * resources associated with owner. - */ - -extern int drm_sman_owner_clean(drm_sman_t * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with this owner. Note that this - * requires that the hardware is finished with all blocks, so the graphics engine - * should be idled before this call is made. This function also frees - * any resources associated with "owner" and should be called when owner - * is not going to be referenced anymore. - */ - -extern void drm_sman_owner_cleanup(drm_sman_t * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with the memory manager. - * See idling above. - */ - -extern void drm_sman_cleanup(drm_sman_t * sman); - -#endif diff --git a/trunk/drivers/char/drm/drm_stub.c b/trunk/drivers/char/drm/drm_stub.c index 7b1d4e8659ba..9a842a36bb27 100644 --- a/trunk/drivers/char/drm/drm_stub.c +++ b/trunk/drivers/char/drm/drm_stub.c @@ -65,22 +65,22 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, mutex_init(&dev->ctxlist_mutex); dev->pdev = pdev; - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; #ifdef __alpha__ dev->hose = pdev->sysdata; + dev->pci_domain = dev->hose->bus->number; +#else + dev->pci_domain = 0; #endif + dev->pci_bus = pdev->bus->number; + dev->pci_slot = PCI_SLOT(pdev->devfn); + dev->pci_func = PCI_FUNC(pdev->devfn); dev->irq = pdev->irq; dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); if (dev->maplist == NULL) return -ENOMEM; INIT_LIST_HEAD(&dev->maplist->head); - if (drm_ht_create(&dev->map_hash, 12)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - return -ENOMEM; - } /* the DRM has 6 basic counters */ dev->counters = 6; diff --git a/trunk/drivers/char/drm/drm_vm.c b/trunk/drivers/char/drm/drm_vm.c index b40ae438f531..ffd0800ed601 100644 --- a/trunk/drivers/char/drm/drm_vm.c +++ b/trunk/drivers/char/drm/drm_vm.c @@ -59,7 +59,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; drm_map_list_t *r_list; - drm_hash_item_t *hash; + struct list_head *list; /* * Find the right map @@ -70,11 +70,14 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, if (!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) - goto vm_nopage_error; - - r_list = drm_hash_entry(hash, drm_map_list_t, hash); - map = r_list->map; + list_for_each(list, &dev->maplist->head) { + r_list = list_entry(list, drm_map_list_t, head); + map = r_list->map; + if (!map) + continue; + if (r_list->user_token == VM_OFFSET(vma)) + break; + } if (map && map->type == _DRM_AGP) { unsigned long offset = address - vma->vm_start; @@ -464,7 +467,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) dev = priv->head->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { @@ -518,11 +521,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; + drm_map_list_t *r_list; unsigned long offset = 0; - drm_hash_item_t *hash; + struct list_head *list; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); if (!priv->authenticated) return -EACCES; @@ -531,7 +535,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) * the AGP mapped at physical address 0 * --BenH. */ - if (!(vma->vm_pgoff << PAGE_SHIFT) + if (!VM_OFFSET(vma) #if __OS_HAS_AGP && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) @@ -539,12 +543,23 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { - DRM_ERROR("Could not find map\n"); - return -EINVAL; + /* A sequential search of a linked list is + fine here because: 1) there will only be + about 5-10 entries in the list and, 2) a + DRI client only has to do this mapping + once, so it doesn't have to be optimized + for performance, even if the list was a + bit longer. */ + list_for_each(list, &dev->maplist->head) { + + r_list = list_entry(list, drm_map_list_t, head); + map = r_list->map; + if (!map) + continue; + if (r_list->user_token == VM_OFFSET(vma)) + break; } - map = drm_hash_entry(hash, drm_map_list_t, hash)->map; if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -605,7 +620,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) offset = dev->driver->get_reg_ofs(dev); #ifdef __sparc__ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - if (io_remap_pfn_range(vma, vma->vm_start, + if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, (map->offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c index fa2de70f7401..c658dde3633b 100644 --- a/trunk/drivers/char/drm/i810_dma.c +++ b/trunk/drivers/char/drm/i810_dma.c @@ -106,7 +106,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, + VM_OFFSET(vma) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -141,10 +141,10 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp) MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; - if (IS_ERR(buf_priv->virtual)) { + if ((unsigned long)buf_priv->virtual > -1024UL) { /* Real error */ DRM_ERROR("mmap error\n"); - retcode = PTR_ERR(buf_priv->virtual); + retcode = (signed int)buf_priv->virtual; buf_priv->virtual = NULL; } up_write(¤t->mm->mmap_sem); @@ -808,7 +808,7 @@ static void i810_dma_dispatch_vertex(drm_device_t * dev, ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); if (used & 4) { - *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; + *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0; used += 4; } @@ -1166,7 +1166,7 @@ static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used, if (buf_priv->currently_mapped == I810_BUF_MAPPED) { if (used & 4) { - *(u32 *) ((char *) buf_priv->virtual + used) = 0; + *(u32 *) ((u32) buf_priv->virtual + used) = 0; used += 4; } diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c index 4f0e5746ab33..b0f815d8cea8 100644 --- a/trunk/drivers/char/drm/i830_dma.c +++ b/trunk/drivers/char/drm/i830_dma.c @@ -108,7 +108,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, + VM_OFFSET(vma) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -146,7 +146,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp) if (IS_ERR((void *)virtual)) { /* ugh */ /* Real error */ DRM_ERROR("mmap error\n"); - retcode = PTR_ERR((void *)virtual); + retcode = virtual; buf_priv->virtual = NULL; } else { buf_priv->virtual = (void __user *)virtual; diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index fb7913ff5286..a94233bdbc0e 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -31,11 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2) - /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time * the head pointer changes, so that EBUSY only happens if the ring @@ -260,7 +255,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_resume(dev); break; default: - retcode = DRM_ERR(EINVAL); + retcode = -EINVAL; break; } @@ -352,7 +347,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) return DRM_ERR(EINVAL); - BEGIN_LP_RING((dwords+1)&~1); + BEGIN_LP_RING(((dwords+1)&~1)); for (i = 0; i < dwords;) { int cmd, sz; @@ -391,7 +386,7 @@ static int i915_emit_box(drm_device_t * dev, RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return DRM_ERR(EFAULT); + return EFAULT; } if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { @@ -400,40 +395,24 @@ static int i915_emit_box(drm_device_t * dev, return DRM_ERR(EINVAL); } - if (IS_I965G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(6); - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(DR1); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - OUT_RING(0); - ADVANCE_LP_RING(); - } + BEGIN_LP_RING(6); + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(DR1); + OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); + OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); + OUT_RING(DR4); + OUT_RING(0); + ADVANCE_LP_RING(); return 0; } -/* XXX: Emitting the counter should really be moved to part of the IRQ - * emit. For now, do it in both places: - */ - static void i915_emit_breadcrumb(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; BEGIN_LP_RING(4); OUT_RING(CMD_STORE_DWORD_IDX); diff --git a/trunk/drivers/char/drm/i915_drm.h b/trunk/drivers/char/drm/i915_drm.h index 6af83e613f27..5aa3e0e3bb45 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -98,12 +98,6 @@ typedef struct _drm_i915_sarea { int rotated_size; int rotated_pitch; int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; } drm_i915_sarea_t; /* Flags for perf_boxes diff --git a/trunk/drivers/char/drm/i915_drv.h b/trunk/drivers/char/drm/i915_drv.h index fdc2bf192714..2d565031c002 100644 --- a/trunk/drivers/char/drm/i915_drv.h +++ b/trunk/drivers/char/drm/i915_drv.h @@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev, #define BEGIN_LP_RING(n) do { \ if (I915_VERBOSE) \ DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - (n), __FUNCTION__); \ - if (dev_priv->ring.space < (n)*4) \ - i915_wait_ring(dev, (n)*4, __FUNCTION__); \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i915_wait_ring(dev, n*4, __FUNCTION__); \ outcount = 0; \ outring = dev_priv->ring.tail; \ ringmask = dev_priv->ring.tail_mask; \ @@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev, #define OUT_RING(n) do { \ if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = (n); \ + *(volatile unsigned int *)(virt + outring) = n; \ outcount++; \ outring += 4; \ outring &= ringmask; \ @@ -254,8 +254,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) - #define MI_BATCH_BUFFER ((0x30<<23)|1) #define MI_BATCH_BUFFER_START (0x31<<23) #define MI_BATCH_BUFFER_END (0xA<<23) diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index 0d4a162aa385..cd96cfa430db 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -71,27 +71,21 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) static int i915_emit_irq(drm_device_t * dev) { drm_i915_private_t *dev_priv = dev->dev_private; + u32 ret; RING_LOCALS; i915_kernel_lost_context(dev); DRM_DEBUG("%s\n", __FUNCTION__); - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + ret = dev_priv->counter; - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; - - BEGIN_LP_RING(6); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); + BEGIN_LP_RING(2); OUT_RING(0); OUT_RING(GFX_OP_USER_INTERRUPT); ADVANCE_LP_RING(); - - return dev_priv->counter; + + return ret; } static int i915_wait_irq(drm_device_t * dev, int irq_nr) diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 5ed965688293..5ad43ba7b5aa 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -864,13 +864,13 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); + tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT); + tmp |= RADEON_RB2D_DC_FLUSH_ALL; + RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp); for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) - & RADEON_RB3D_DC_BUSY)) { + if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT) + & RADEON_RB2D_DC_BUSY)) { return 0; } DRM_UDELAY(1); @@ -1130,7 +1130,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | (dev_priv->fb_location >> 16)); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); RADEON_WRITE(RADEON_MC_AGP_LOCATION, (((dev_priv->gart_vm_start - 1 + @@ -1158,7 +1158,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, dev_priv->ring.tail = cur_read_ptr; #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1258,13 +1258,6 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) dev_priv->writeback_works = 0; DRM_INFO("writeback forced off\n"); } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); - } } /* Enable or disable PCI-E GART on the chip */ @@ -1302,7 +1295,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; - if (dev_priv->flags & RADEON_IS_PCIE) { + if (dev_priv->flags & CHIP_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; } @@ -1340,22 +1333,20 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_DEBUG("\n"); /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); + if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap) + { + DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { + if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) + { DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; + dev_priv->flags &= ~CHIP_IS_AGP; } - if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { + if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); @@ -1498,7 +1489,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) init->sarea_priv_offset); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { drm_core_ioremap(dev_priv->cp_ring, dev); drm_core_ioremap(dev_priv->ring_rptr, dev); drm_core_ioremap(dev->agp_buffer_map, dev); @@ -1557,7 +1548,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) * align it down. */ #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { base = dev->agp->base; /* Check if valid */ if ((base + dev_priv->gart_size) > dev_priv->fb_location && @@ -1587,7 +1578,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) } #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) + if (dev_priv->flags & CHIP_IS_AGP) dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1613,7 +1604,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -1633,7 +1624,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->gart_info.mapping.handle; dev_priv->gart_info.is_pcie = - !!(dev_priv->flags & RADEON_IS_PCIE); + !!(dev_priv->flags & CHIP_IS_PCIE); dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; @@ -1645,7 +1636,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { + if (dev_priv->flags & CHIP_IS_PCIE) { DRM_ERROR ("Cannot use PCI Express without GART in FB memory\n"); radeon_do_cleanup_cp(dev); @@ -1687,7 +1678,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) drm_irq_uninstall(dev); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { if (dev_priv->cp_ring != NULL) { drm_core_ioremapfree(dev_priv->cp_ring, dev); dev_priv->cp_ring = NULL; @@ -1742,7 +1733,7 @@ static int radeon_do_resume_cp(drm_device_t * dev) DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -2186,15 +2177,13 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; dev_priv->flags = flags; - switch (flags & RADEON_FAMILY_MASK) { + switch (flags & CHIP_FAMILY_MASK) { case CHIP_R100: case CHIP_RV200: case CHIP_R200: case CHIP_R300: - case CHIP_R350: case CHIP_R420: - case CHIP_RV410: - dev_priv->flags |= RADEON_HAS_HIERZ; + dev_priv->flags |= CHIP_HAS_HIERZ; break; default: /* all other chips have no hierarchical z buffer */ @@ -2202,14 +2191,13 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) } if (drm_device_is_agp(dev)) - dev_priv->flags |= RADEON_IS_AGP; - else if (drm_device_is_pcie(dev)) - dev_priv->flags |= RADEON_IS_PCIE; - else - dev_priv->flags |= RADEON_IS_PCI; + dev_priv->flags |= CHIP_IS_AGP; + + if (drm_device_is_pcie(dev)) + dev_priv->flags |= CHIP_IS_PCIE; DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); + ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); return ret; } diff --git a/trunk/drivers/char/drm/radeon_drv.c b/trunk/drivers/char/drm/radeon_drv.c index 2eb652ec6745..eb985c2a31e9 100644 --- a/trunk/drivers/char/drm/radeon_drv.c +++ b/trunk/drivers/char/drm/radeon_drv.c @@ -44,7 +44,7 @@ module_param_named(no_wb, radeon_no_wb, int, 0444); static int dri_library_name(struct drm_device *dev, char *buf) { drm_radeon_private_t *dev_priv = dev->dev_private; - int family = dev_priv->flags & RADEON_FAMILY_MASK; + int family = dev_priv->flags & CHIP_FAMILY_MASK; return snprintf(buf, PAGE_SIZE, "%s\n", (family < CHIP_R200) ? "radeon" : diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index f45cd7f147a5..e5a256f5429c 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -133,16 +133,15 @@ enum radeon_cp_microcode_version { * Chip flags */ enum radeon_chip_flags { - RADEON_FAMILY_MASK = 0x0000ffffUL, - RADEON_FLAGS_MASK = 0xffff0000UL, - RADEON_IS_MOBILITY = 0x00010000UL, - RADEON_IS_IGP = 0x00020000UL, - RADEON_SINGLE_CRTC = 0x00040000UL, - RADEON_IS_AGP = 0x00080000UL, - RADEON_HAS_HIERZ = 0x00100000UL, - RADEON_IS_PCIE = 0x00200000UL, - RADEON_NEW_MEMMAP = 0x00400000UL, - RADEON_IS_PCI = 0x00800000UL, + CHIP_FAMILY_MASK = 0x0000ffffUL, + CHIP_FLAGS_MASK = 0xffff0000UL, + CHIP_IS_MOBILITY = 0x00010000UL, + CHIP_IS_IGP = 0x00020000UL, + CHIP_SINGLE_CRTC = 0x00040000UL, + CHIP_IS_AGP = 0x00080000UL, + CHIP_HAS_HIERZ = 0x00100000UL, + CHIP_IS_PCIE = 0x00200000UL, + CHIP_NEW_MEMMAP = 0x00400000UL, }; #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ @@ -425,8 +424,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_RB3D_COLOROFFSET 0x1c40 #define RADEON_RB3D_COLORPITCH 0x1c48 -#define RADEON_SRC_X_Y 0x1590 - #define RADEON_DP_GUI_MASTER_CNTL 0x146c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) # define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) @@ -444,7 +441,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, # define RADEON_ROP3_S 0x00cc0000 # define RADEON_ROP3_P 0x00f00000 #define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_SRC_PITCH_OFFSET 0x1428 #define RADEON_DST_PITCH_OFFSET 0x142c #define RADEON_DST_PITCH_OFFSET_C 0x1c80 # define RADEON_DST_TILE_LINEAR (0 << 30) @@ -549,11 +545,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, # define RADEON_RB3D_ZC_FREE (1 << 2) # define RADEON_RB3D_ZC_FLUSH_ALL 0x5 # define RADEON_RB3D_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c # define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4) @@ -690,7 +681,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_CNTL 0x0704 # define RADEON_BUF_SWAP_32BIT (2 << 16) -# define RADEON_RB_NO_UPDATE (1 << 27) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -996,13 +986,13 @@ do { \ } while (0) #define RADEON_FLUSH_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH ); \ } while (0) #define RADEON_PURGE_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ } while (0) #define RADEON_FLUSH_ZCACHE() do { \ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index feac5f005d47..39a7f685e3fd 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -42,11 +42,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * drm_file_t * filp_priv, u32 *offset) { - u64 off = *offset; - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; + u32 off = *offset; struct drm_radeon_driver_file_fields *radeon_priv; /* Hrm ... the story of the offset ... So this function converts @@ -66,8 +62,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * /* First, the best case, the offset already lands in either the * framebuffer or the GART mapped space */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) + if ((off >= dev_priv->fb_location && + off < (dev_priv->fb_location + dev_priv->fb_size)) || + (off >= dev_priv->gart_vm_start && + off < (dev_priv->gart_vm_start + dev_priv->gart_size))) return 0; /* Ok, that didn't happen... now check if we have a zero based @@ -80,13 +78,16 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * } /* Finally, assume we aimed at a GART offset if beyond the fb */ - if (off > fb_end) - off = off - fb_end - 1 + gart_start; + if (off > (dev_priv->fb_location + dev_priv->fb_size)) + off = off - (dev_priv->fb_location + dev_priv->fb_size) + + dev_priv->gart_vm_start; /* Now recheck and fail if out of bounds */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) { - DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); + if ((off >= dev_priv->fb_location && + off < (dev_priv->fb_location + dev_priv->fb_size)) || + (off >= dev_priv->gart_vm_start && + off < (dev_priv->gart_vm_start + dev_priv->gart_size))) { + DRM_DEBUG("offset fixed up to 0x%x\n", off); *offset = off; return 0; } @@ -868,7 +869,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, */ dev_priv->sarea_priv->ctx_owner = 0; - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { /* FIXME : reverse engineer that for Rx00 cards */ /* FIXME : the mask supposedly contains low-res z values. So can't set @@ -913,7 +914,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, for (i = 0; i < nbox; i++) { int tileoffset, nrtilesx, nrtilesy, j; /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && !(dev_priv->microcode_version == UCODE_R200)) { /* FIXME : figure this out for r200 (when hierz is enabled). Or maybe r200 actually doesn't need to put the low-res z value into @@ -997,7 +998,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, } /* TODO don't always clear all hi-level z tiles */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version == UCODE_R200) && (flags & RADEON_USE_HIERZ)) /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ @@ -1269,9 +1270,9 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h); - BEGIN_RING(9); + BEGIN_RING(7); - OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0)); + OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | @@ -1283,7 +1284,6 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) /* Make this work even if front & back are flipped: */ - OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); if (dev_priv->current_page == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); @@ -1292,7 +1292,6 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) OUT_RING(dev_priv->back_pitch_offset); } - OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2)); OUT_RING((x << 16) | y); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); @@ -2988,21 +2987,16 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) case RADEON_PARAM_GART_TEX_HANDLE: value = dev_priv->gart_textures_offset; break; - case RADEON_PARAM_SCRATCH_OFFSET: - if (!dev_priv->writeback_works) - return DRM_ERR(EINVAL); - value = RADEON_SCRATCH_REG_OFFSET; - break; + case RADEON_PARAM_CARD_TYPE: - if (dev_priv->flags & RADEON_IS_PCIE) + if (dev_priv->flags & CHIP_IS_PCIE) value = RADEON_CARD_PCIE; - else if (dev_priv->flags & RADEON_IS_AGP) + else if (dev_priv->flags & CHIP_IS_AGP) value = RADEON_CARD_AGP; else value = RADEON_CARD_PCI; break; default: - DRM_DEBUG("Invalid parameter %d\n", param.param); return DRM_ERR(EINVAL); } diff --git a/trunk/drivers/char/drm/sis_drv.c b/trunk/drivers/char/drm/sis_drv.c index 3d5b3218b6ff..5e9dc86f2956 100644 --- a/trunk/drivers/char/drm/sis_drv.c +++ b/trunk/drivers/char/drm/sis_drv.c @@ -35,44 +35,11 @@ static struct pci_device_id pciidlist[] = { sisdrv_PCI_IDS }; -static int sis_driver_load(drm_device_t *dev, unsigned long chipset) -{ - drm_sis_private_t *dev_priv; - int ret; - - dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - - dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; - ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); - if (ret) { - drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER); - } - - return ret; -} - -static int sis_driver_unload(drm_device_t *dev) -{ - drm_sis_private_t *dev_priv = dev->dev_private; - - drm_sman_takedown(&dev_priv->sman); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); - - return 0; -} - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, - .load = sis_driver_load, - .unload = sis_driver_unload, - .context_dtor = NULL, - .dma_quiescent = sis_idle, - .reclaim_buffers = NULL, - .reclaim_buffers_locked = sis_reclaim_buffers_locked, - .lastclose = sis_lastclose, + .context_ctor = sis_init_context, + .context_dtor = sis_final_context, + .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, .ioctls = sis_ioctls, diff --git a/trunk/drivers/char/drm/sis_drv.h b/trunk/drivers/char/drm/sis_drv.h index 2b8d6f6ed7c0..e218e5269503 100644 --- a/trunk/drivers/char/drm/sis_drv.h +++ b/trunk/drivers/char/drm/sis_drv.h @@ -31,39 +31,23 @@ /* General customization: */ -#define DRIVER_AUTHOR "SIS, Tungsten Graphics" +#define DRIVER_AUTHOR "SIS" #define DRIVER_NAME "sis" #define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20060704" +#define DRIVER_DATE "20030826" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_MINOR 1 +#define DRIVER_PATCHLEVEL 0 -enum sis_family { - SIS_OTHER = 0, - SIS_CHIP_315 = 1, -}; - -#include "drm_sman.h" - -#define SIS_BASE (dev_priv->mmio) -#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); -#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val); +#include "sis_ds.h" typedef struct drm_sis_private { - drm_local_map_t *mmio; - unsigned int idle_fault; - drm_sman_t sman; - unsigned int chipset; - int vram_initialized; - int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; + memHeap_t *AGPHeap; + memHeap_t *FBHeap; } drm_sis_private_t; -extern int sis_idle(drm_device_t *dev); -extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); -extern void sis_lastclose(drm_device_t *dev); +extern int sis_init_context(drm_device_t * dev, int context); +extern int sis_final_context(drm_device_t * dev, int context); extern drm_ioctl_desc_t sis_ioctls[]; extern int sis_max_ioctl; diff --git a/trunk/drivers/char/drm/sis_ds.c b/trunk/drivers/char/drm/sis_ds.c new file mode 100644 index 000000000000..2e485d482943 --- /dev/null +++ b/trunk/drivers/char/drm/sis_ds.c @@ -0,0 +1,299 @@ +/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin + * + */ + +#include "drmP.h" +#include "drm.h" +#include "sis_ds.h" + +/* Set Data Structure, not check repeated value + * temporarily used + */ + +set_t *setInit(void) +{ + int i; + set_t *set; + + set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER); + if (set != NULL) { + for (i = 0; i < SET_SIZE; i++) { + set->list[i].free_next = i + 1; + set->list[i].alloc_next = -1; + } + set->list[SET_SIZE - 1].free_next = -1; + set->free = 0; + set->alloc = -1; + set->trace = -1; + } + return set; +} + +int setAdd(set_t * set, ITEM_TYPE item) +{ + int free = set->free; + + if (free != -1) { + set->list[free].val = item; + set->free = set->list[free].free_next; + } else { + return 0; + } + + set->list[free].alloc_next = set->alloc; + set->alloc = free; + set->list[free].free_next = -1; + + return 1; +} + +int setDel(set_t * set, ITEM_TYPE item) +{ + int alloc = set->alloc; + int prev = -1; + + while (alloc != -1) { + if (set->list[alloc].val == item) { + if (prev != -1) + set->list[prev].alloc_next = + set->list[alloc].alloc_next; + else + set->alloc = set->list[alloc].alloc_next; + break; + } + prev = alloc; + alloc = set->list[alloc].alloc_next; + } + + if (alloc == -1) + return 0; + + set->list[alloc].free_next = set->free; + set->free = alloc; + set->list[alloc].alloc_next = -1; + + return 1; +} + +/* setFirst -> setAdd -> setNext is wrong */ + +int setFirst(set_t * set, ITEM_TYPE * item) +{ + if (set->alloc == -1) + return 0; + + *item = set->list[set->alloc].val; + set->trace = set->list[set->alloc].alloc_next; + + return 1; +} + +int setNext(set_t * set, ITEM_TYPE * item) +{ + if (set->trace == -1) + return 0; + + *item = set->list[set->trace].val; + set->trace = set->list[set->trace].alloc_next; + + return 1; +} + +int setDestroy(set_t * set) +{ + drm_free(set, sizeof(set_t), DRM_MEM_DRIVER); + + return 1; +} + +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#define ISFREE(bptr) ((bptr)->free) + +memHeap_t *mmInit(int ofs, int size) +{ + PMemBlock blocks; + + if (size <= 0) + return NULL; + + blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); + if (blocks != NULL) { + blocks->ofs = ofs; + blocks->size = size; + blocks->free = 1; + return (memHeap_t *) blocks; + } else + return NULL; +} + +/* Checks if a pointer 'b' is part of the heap 'heap' */ +int mmBlockInHeap(memHeap_t * heap, PMemBlock b) +{ + TMemBlock *p; + + if (heap == NULL || b == NULL) + return 0; + + p = heap; + while (p != NULL && p != b) { + p = p->next; + } + if (p == b) + return 1; + else + return 0; +} + +static TMemBlock *SliceBlock(TMemBlock * p, + int startofs, int size, + int reserved, int alignment) +{ + TMemBlock *newblock; + + /* break left */ + if (startofs > p->ofs) { + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->next = p->next; + p->size -= newblock->size; + p->next = newblock; + p = newblock; + } + + /* break right */ + if (size < p->size) { + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->next = p->next; + p->size = size; + p->next = newblock; + } + + /* p = middle block */ + p->align = alignment; + p->free = 0; + p->reserved = reserved; + return p; +} + +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch) +{ + int mask, startofs, endofs; + TMemBlock *p; + + if (heap == NULL || align2 < 0 || size <= 0) + return NULL; + + mask = (1 << align2) - 1; + startofs = 0; + p = (TMemBlock *) heap; + while (p != NULL) { + if (ISFREE(p)) { + startofs = (p->ofs + mask) & ~mask; + if (startofs < startSearch) { + startofs = startSearch; + } + endofs = startofs + size; + if (endofs <= (p->ofs + p->size)) + break; + } + p = p->next; + } + if (p == NULL) + return NULL; + p = SliceBlock(p, startofs, size, 0, mask + 1); + p->heap = heap; + return p; +} + +static __inline__ int Join2Blocks(TMemBlock * p) +{ + if (p->free && p->next && p->next->free) { + TMemBlock *q = p->next; + p->size += q->size; + p->next = q->next; + drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER); + return 1; + } + return 0; +} + +int mmFreeMem(PMemBlock b) +{ + TMemBlock *p, *prev; + + if (b == NULL) + return 0; + if (b->heap == NULL) + return -1; + + p = b->heap; + prev = NULL; + while (p != NULL && p != b) { + prev = p; + p = p->next; + } + if (p == NULL || p->free || p->reserved) + return -1; + + p->free = 1; + Join2Blocks(p); + if (prev) + Join2Blocks(prev); + return 0; +} diff --git a/trunk/drivers/char/drm/sis_ds.h b/trunk/drivers/char/drm/sis_ds.h new file mode 100644 index 000000000000..94f2b4728b63 --- /dev/null +++ b/trunk/drivers/char/drm/sis_ds.h @@ -0,0 +1,146 @@ +/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + */ +/* + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin + * + */ + +#ifndef __SIS_DS_H__ +#define __SIS_DS_H__ + +/* Set Data Structure */ + +#define SET_SIZE 5000 + +typedef unsigned long ITEM_TYPE; + +typedef struct { + ITEM_TYPE val; + int alloc_next, free_next; +} list_item_t; + +typedef struct { + int alloc; + int free; + int trace; + list_item_t list[SET_SIZE]; +} set_t; + +set_t *setInit(void); +int setAdd(set_t * set, ITEM_TYPE item); +int setDel(set_t * set, ITEM_TYPE item); +int setFirst(set_t * set, ITEM_TYPE * item); +int setNext(set_t * set, ITEM_TYPE * item); +int setDestroy(set_t * set); + +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +struct mem_block_t { + struct mem_block_t *next; + struct mem_block_t *heap; + int ofs, size; + int align; + unsigned int free:1; + unsigned int reserved:1; +}; +typedef struct mem_block_t TMemBlock; +typedef struct mem_block_t *PMemBlock; + +/* a heap is just the first block in a chain */ +typedef struct mem_block_t memHeap_t; + +static __inline__ int mmBlockSize(PMemBlock b) +{ + return b->size; +} + +static __inline__ int mmOffset(PMemBlock b) +{ + return b->ofs; +} + +static __inline__ void mmMarkReserved(PMemBlock b) +{ + b->reserved = 1; +} + +/* + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +memHeap_t *mmInit(int ofs, int size); + +/* + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch); + +/* + * Returns 1 if the block 'b' is part of the heap 'heap' + */ +int mmBlockInHeap(PMemBlock heap, PMemBlock b); + +/* + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +int mmFreeMem(PMemBlock b); + +/* For debuging purpose. */ +void mmDumpMemInfo(memHeap_t * mmInit); + +#endif /* __SIS_DS_H__ */ diff --git a/trunk/drivers/char/drm/sis_mm.c b/trunk/drivers/char/drm/sis_mm.c index d26f5dbb7853..5e9936bc307f 100644 --- a/trunk/drivers/char/drm/sis_mm.c +++ b/trunk/drivers/char/drm/sis_mm.c @@ -1,348 +1,414 @@ -/************************************************************************** +/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * - * - **************************************************************************/ - -/* * Authors: - * Thomas Hellström + * Sung-Ching Lin + * */ #include "drmP.h" #include "sis_drm.h" #include "sis_drv.h" - +#include "sis_ds.h" +#if defined(__linux__) && defined(CONFIG_FB_SIS) #include