]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 31 Oct 2005 01:48:00 +0000 (17:48 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 31 Oct 2005 01:48:00 +0000 (17:48 -0800)
558 files changed:
Documentation/RCU/torture.txt [new file with mode: 0644]
Documentation/cpusets.txt
Documentation/firmware_class/firmware_sample_driver.c
Documentation/firmware_class/firmware_sample_firmware_class.c
Documentation/i2c/writing-clients
Documentation/keys.txt
MAINTAINERS
README
arch/alpha/kernel/time.c
arch/arm/common/amba.c
arch/arm/common/scoop.c
arch/arm/kernel/arthur.c
arch/arm/kernel/ptrace.c
arch/arm/kernel/time.c
arch/arm/mach-imx/generic.c
arch/arm/mach-integrator/clock.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/lm.c
arch/arm/mach-iop3xx/iq31244-pci.c
arch/arm/mach-iop3xx/iq80321-pci.c
arch/arm/mach-iop3xx/iq80331-pci.c
arch/arm/mach-iop3xx/iq80332-pci.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-versatile/clock.c
arch/arm/plat-omap/clock.c
arch/arm26/kernel/ptrace.c
arch/arm26/kernel/time.c
arch/cris/arch-v10/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/kernel/time.c
arch/frv/kernel/ptrace.c
arch/frv/kernel/time.c
arch/h8300/kernel/ptrace.c
arch/h8300/kernel/time.c
arch/i386/Kconfig
arch/i386/Kconfig.cpu [new file with mode: 0644]
arch/i386/Makefile
arch/i386/Makefile.cpu [new file with mode: 0644]
arch/i386/kernel/apic.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/intel_cacheinfo.c
arch/i386/kernel/cpu/mcheck/p6.c
arch/i386/kernel/cpu/mtrr/if.c
arch/i386/kernel/cpu/proc.c
arch/i386/kernel/crash.c
arch/i386/kernel/i8259.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/mpparse.c
arch/i386/kernel/nmi.c
arch/i386/kernel/ptrace.c
arch/i386/kernel/reboot_fixups.c
arch/i386/kernel/setup.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/srat.c
arch/i386/kernel/time.c
arch/i386/kernel/time_hpet.c
arch/i386/kernel/timers/timer_hpet.c
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/traps.c
arch/i386/mach-es7000/es7000.h
arch/i386/mach-es7000/es7000plat.c
arch/i386/mm/fault.c
arch/i386/pci/irq.c
arch/i386/power/cpu.c
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/cyclone.c
arch/ia64/kernel/time.c
arch/m32r/kernel/entry.S
arch/m32r/kernel/io_m32700ut.c
arch/m32r/kernel/io_mappi.c
arch/m32r/kernel/io_mappi2.c
arch/m32r/kernel/io_mappi3.c
arch/m32r/kernel/io_oaks32r.c
arch/m32r/kernel/io_opsput.c
arch/m32r/kernel/io_usrv.c
arch/m32r/kernel/ptrace.c
arch/m32r/kernel/setup.c
arch/m32r/kernel/time.c
arch/m32r/lib/csum_partial_copy.c
arch/m68k/kernel/ptrace.c
arch/m68k/kernel/time.c
arch/m68knommu/kernel/ptrace.c
arch/m68knommu/kernel/time.c
arch/mips/kernel/irixelf.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/time.c
arch/mips/sgi-ip27/ip27-berr.c
arch/parisc/kernel/ioctl32.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/time.c
arch/ppc/kernel/ptrace.c
arch/ppc/kernel/time.c
arch/ppc/platforms/hdpu.c
arch/ppc/syslib/of_device.c
arch/ppc64/kernel/hvcserver.c
arch/ppc64/kernel/ioctl32.c
arch/ppc64/kernel/of_device.c
arch/ppc64/kernel/ptrace.c
arch/ppc64/kernel/time.c
arch/ppc64/lib/locks.c
arch/s390/kernel/compat_ioctl.c
arch/s390/kernel/head.S
arch/s390/kernel/head64.S
arch/s390/kernel/setup.c
arch/s390/kernel/time.c
arch/s390/kernel/vtime.c
arch/sh/drivers/dma/dma-sysfs.c
arch/sh/kernel/cpufreq.c
arch/sh/kernel/ptrace.c
arch/sh/kernel/time.c
arch/sh64/kernel/ptrace.c
arch/sh64/kernel/time.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/time.c
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/time.c
arch/um/Kconfig
arch/um/Kconfig.x86_64
arch/um/Makefile-i386
arch/um/include/sysdep-i386/syscalls.h
arch/um/kernel/time_kern.c
arch/v850/kernel/ptrace.c
arch/v850/kernel/time.c
arch/x86_64/ia32/ia32_ioctl.c
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/suspend.c
arch/x86_64/kernel/time.c
arch/xtensa/kernel/platform.c
arch/xtensa/kernel/ptrace.c
arch/xtensa/kernel/time.c
drivers/acpi/processor_idle.c
drivers/acpi/sleep/main.c
drivers/base/class.c
drivers/base/cpu.c
drivers/base/firmware_class.c
drivers/base/platform.c
drivers/base/sys.c
drivers/block/Kconfig.iosched
drivers/block/as-iosched.c
drivers/block/cciss_scsi.c
drivers/block/cfq-iosched.c
drivers/block/elevator.c
drivers/block/paride/paride.c
drivers/block/paride/pf.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/agp/Kconfig
drivers/char/agp/ali-agp.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/ati-agp.c
drivers/char/agp/i460-agp.c
drivers/char/agp/isoch.c
drivers/char/agp/sworks-agp.c
drivers/char/cyclades.c
drivers/char/drm/drm_sysfs.c
drivers/char/epca.c
drivers/char/hangcheck-timer.c
drivers/char/hpet.c
drivers/char/mwave/3780i.c
drivers/char/rocket.c
drivers/char/ser_a2232.c
drivers/char/specialix.c
drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/char/tlclk.c [new file with mode: 0644]
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_infineon.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tty_io.c
drivers/char/vt_ioctl.c
drivers/char/watchdog/cpu5wdt.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/wdt_pci.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_stats.c
drivers/crypto/Kconfig
drivers/firmware/Kconfig
drivers/ide/ide-cd.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/sa_query.c
drivers/infiniband/hw/mthca/mthca_av.c
drivers/infiniband/hw/mthca/mthca_mad.c
drivers/infiniband/hw/mthca/mthca_mcg.c
drivers/infiniband/hw/mthca/mthca_profile.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_reset.c
drivers/infiniband/hw/mthca/mthca_uar.c
drivers/input/gameport/gameport.c
drivers/input/joystick/a3d.c
drivers/input/joystick/adi.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/interact.c
drivers/input/joystick/joydump.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/tmdc.c
drivers/input/misc/Kconfig
drivers/input/serio/hp_sdc_mlc.c
drivers/isdn/capi/capifs.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/macintosh/macio_asic.c
drivers/mca/mca-device.c
drivers/media/common/ir-common.c
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/bcm3510.c
drivers/media/dvb/frontends/dib3000mb.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/lgdt330x.c
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/mt352.c
drivers/media/dvb/frontends/nxt2002.c
drivers/media/dvb/frontends/or51132.c
drivers/media/dvb/frontends/or51211.c
drivers/media/dvb/frontends/s5h1420.c
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda8083.c
drivers/media/radio/miropcm20-rds.c
drivers/message/i2o/debug.c
drivers/message/i2o/device.c
drivers/message/i2o/driver.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/iop.c
drivers/mmc/mmc_block.c
drivers/mmc/pxamci.c
drivers/mtd/chips/jedec.c
drivers/mtd/devices/lart.c
drivers/mtd/devices/phram.c
drivers/mtd/maps/bast-flash.c
drivers/mtd/maps/ceiva.c
drivers/mtd/maps/dc21285.c
drivers/mtd/maps/dilnetpc.c
drivers/mtd/maps/epxa10db-flash.c
drivers/mtd/maps/fortunet.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lubbock-flash.c
drivers/mtd/maps/mainstone-flash.c
drivers/mtd/maps/omap-toto-flash.c
drivers/mtd/maps/omap_nor.c
drivers/mtd/maps/pci.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/tqm8xxl.c
drivers/mtd/mtdblock.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdconcat.c
drivers/mtd/nand/s3c2410.c
drivers/net/eepro.c
drivers/net/irda/smsc-ircc2.c
drivers/net/skfp/smt.c
drivers/net/smc91x.h
drivers/net/wireless/prism54/islpci_mgt.c
drivers/pci/hotplug/cpcihp_generic.c
drivers/pci/hotplug/cpcihp_zt5550.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/ibmphp_core.c
drivers/pci/hotplug/pciehp_pci.c
drivers/pci/hotplug/pciehprm_nonacpi.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp_pci.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchprm_nonacpi.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/quirks.c
drivers/pci/rom.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pnp/manager.c
drivers/pnp/pnpbios/rsparser.c
drivers/s390/char/con3270.c
drivers/s390/char/fs3270.c
drivers/s390/char/raw3270.c
drivers/s390/char/raw3270.h
drivers/s390/char/tty3270.c
drivers/s390/cio/cmf.c
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/scsi/ahci.c
drivers/scsi/ata_piix.c
drivers/scsi/ide-scsi.c
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/scsi/mesh.c
drivers/scsi/pdc_adma.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_nv.c
drivers/scsi/sata_promise.c
drivers/scsi/sata_qstor.c
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sis.c
drivers/scsi/sata_svw.c
drivers/scsi/sata_sx4.c
drivers/scsi/sata_uli.c
drivers/scsi/sata_via.c
drivers/scsi/sata_vsc.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/scsi/sym53c8xx_2/sym_hipd.h
drivers/serial/ioc4_serial.c
drivers/serial/mpsc.c
drivers/sh/superhyway/superhyway.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/input/pid.c
drivers/video/Kconfig
drivers/video/console/Kconfig
drivers/video/console/vgacon.c
drivers/w1/w1_family.c
drivers/zorro/zorro-sysfs.c
drivers/zorro/zorro.c
fs/Kconfig
fs/Kconfig.binfmt
fs/attr.c
fs/binfmt_elf.c
fs/buffer.c
fs/compat_ioctl.c
fs/dquot.c
fs/exec.c
fs/ext2/inode.c
fs/ext3/balloc.c
fs/ext3/bitmap.c
fs/ext3/bitmap.h [new file with mode: 0644]
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/namei.h [new file with mode: 0644]
fs/ext3/resize.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/fat/dir.c
fs/file_table.c
fs/filesystems.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/fuse_i.h
fs/inode.c
fs/jffs2/background.c
fs/jffs2/wbuf.c
fs/msdos/namei.c
fs/namei.c
fs/nfs/inode.c
fs/proc/generic.c
fs/proc/inode.c
fs/reiserfs/super.c
fs/reiserfs/xattr_acl.c
fs/super.c
fs/vfat/namei.c
fs/xattr.c
include/asm-alpha/semaphore.h
include/asm-arm/pgtable.h
include/asm-arm/semaphore.h
include/asm-arm/unistd.h
include/asm-arm26/pgtable.h
include/asm-arm26/semaphore.h
include/asm-arm26/unistd.h
include/asm-cris/semaphore.h
include/asm-cris/unistd.h
include/asm-frv/pgtable.h
include/asm-frv/semaphore.h
include/asm-h8300/semaphore.h
include/asm-h8300/unistd.h
include/asm-i386/apic.h
include/asm-i386/desc.h
include/asm-i386/hw_irq.h
include/asm-i386/mach-default/smpboot_hooks.h
include/asm-i386/mach-es7000/mach_mpparse.h
include/asm-i386/mach-visws/smpboot_hooks.h
include/asm-i386/pgtable-2level.h
include/asm-i386/pgtable-3level.h
include/asm-i386/pgtable.h
include/asm-i386/semaphore.h
include/asm-i386/system.h
include/asm-i386/unistd.h
include/asm-ia64/pgtable.h
include/asm-ia64/semaphore.h
include/asm-ia64/unistd.h
include/asm-m32r/pgtable.h
include/asm-m32r/semaphore.h
include/asm-m32r/thread_info.h
include/asm-m32r/unistd.h
include/asm-m68k/semaphore.h
include/asm-m68k/sun3xflop.h
include/asm-m68k/unistd.h
include/asm-m68knommu/ide.h
include/asm-m68knommu/semaphore.h
include/asm-m68knommu/unistd.h
include/asm-mips/pgtable-64.h
include/asm-mips/pgtable.h
include/asm-mips/semaphore.h
include/asm-mips/unistd.h
include/asm-parisc/ide.h
include/asm-parisc/semaphore.h
include/asm-parisc/unistd.h
include/asm-ppc/semaphore.h
include/asm-ppc/unistd.h
include/asm-ppc64/semaphore.h
include/asm-ppc64/unistd.h
include/asm-s390/semaphore.h
include/asm-s390/setup.h
include/asm-s390/unistd.h
include/asm-sh/pgtable.h
include/asm-sh/semaphore.h
include/asm-sh/unistd.h
include/asm-sh64/pgtable.h
include/asm-sh64/semaphore.h
include/asm-sparc/floppy.h
include/asm-sparc/pgtable.h
include/asm-sparc/semaphore.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/semaphore.h
include/asm-um/cache.h
include/asm-um/linkage.h
include/asm-v850/semaphore.h
include/asm-v850/unistd.h
include/asm-x86_64/mtrr.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/semaphore.h
include/asm-x86_64/unistd.h
include/asm-xtensa/semaphore.h
include/keys/user-type.h [new file with mode: 0644]
include/linux/bitmap.h
include/linux/buffer_head.h
include/linux/cpu.h
include/linux/cpufreq.h
include/linux/cpumask.h
include/linux/dmi.h
include/linux/fs.h
include/linux/fuse.h
include/linux/gameport.h
include/linux/i2c.h
include/linux/i2o.h
include/linux/kernel.h
include/linux/key-ui.h
include/linux/key.h
include/linux/kobj_map.h
include/linux/kthread.h
include/linux/libata.h
include/linux/mempolicy.h
include/linux/module.h
include/linux/msdos_fs.h
include/linux/mtd/map.h
include/linux/nodemask.h
include/linux/pm.h
include/linux/rcupdate.h
include/linux/sched.h
include/linux/security.h
include/linux/serial.h
include/linux/signal.h
include/linux/spinlock.h
include/linux/suspend.h
include/linux/syscalls.h
include/linux/textsearch.h
include/linux/timer.h
include/linux/timex.h
include/pcmcia/ss.h
include/scsi/scsi_cmnd.h
include/scsi/scsi_transport_fc.h
init/Kconfig
init/main.c
kernel/Makefile
kernel/cpu.c
kernel/cpuset.c
kernel/exit.c
kernel/kallsyms.c
kernel/kmod.c
kernel/kprobes.c
kernel/kthread.c
kernel/params.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/power/Makefile
kernel/power/disk.c
kernel/power/main.c
kernel/power/power.h
kernel/power/snapshot.c [new file with mode: 0644]
kernel/power/swsusp.c
kernel/printk.c
kernel/ptrace.c
kernel/rcupdate.c
kernel/rcutorture.c [new file with mode: 0644]
kernel/sched.c
kernel/signal.c
kernel/time.c
kernel/timer.c
kernel/workqueue.c
lib/Kconfig.debug
lib/bitmap.c
lib/extable.c
lib/idr.c
lib/kobject.c
lib/smp_processor_id.c
lib/sort.c
lib/string.c
lib/vsprintf.c
mm/filemap.c
mm/mempolicy.c
mm/mmap.c
mm/pdflush.c
mm/swap.c
mm/tiny-shmem.c
mm/truncate.c
net/ipv4/netfilter/ipt_addrtype.c
scripts/kconfig/Makefile
scripts/kconfig/lkc.h
scripts/kconfig/mconf.c
security/dummy.c
security/keys/key.c
security/keys/keyctl.c
security/keys/keyring.c
security/keys/permission.c
security/keys/process_keys.c
security/keys/user_defined.c
security/selinux/hooks.c
security/selinux/netif.c
security/selinux/selinuxfs.c
security/selinux/ss/conditional.c
security/selinux/ss/ebitmap.c
security/selinux/ss/hashtab.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
sound/oss/ac97_codec.c
sound/oss/awe_wave.c
sound/oss/cs4232.c
sound/oss/wavfront.c

diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
new file mode 100644 (file)
index 0000000..e4c3815
--- /dev/null
@@ -0,0 +1,122 @@
+RCU Torture Test Operation
+
+
+CONFIG_RCU_TORTURE_TEST
+
+The CONFIG_RCU_TORTURE_TEST config option is available for all RCU
+implementations.  It creates an rcutorture kernel module that can
+be loaded to run a torture test.  The test periodically outputs
+status messages via printk(), which can be examined via the dmesg
+command (perhaps grepping for "rcutorture").  The test is started
+when the module is loaded, and stops when the module is unloaded.
+
+However, actually setting this config option to "y" results in the system
+running the test immediately upon boot, and ending only when the system
+is taken down.  Normally, one will instead want to build the system
+with CONFIG_RCU_TORTURE_TEST=m and to use modprobe and rmmod to control
+the test, perhaps using a script similar to the one shown at the end of
+this document.  Note that you will need CONFIG_MODULE_UNLOAD in order
+to be able to end the test.
+
+
+MODULE PARAMETERS
+
+This module has the following parameters:
+
+nreaders       This is the number of RCU reading threads supported.
+               The default is twice the number of CPUs.  Why twice?
+               To properly exercise RCU implementations with preemptible
+               read-side critical sections.
+
+stat_interval  The number of seconds between output of torture
+               statistics (via printk()).  Regardless of the interval,
+               statistics are printed when the module is unloaded.
+               Setting the interval to zero causes the statistics to
+               be printed -only- when the module is unloaded, and this
+               is the default.
+
+verbose                Enable debug printk()s.  Default is disabled.
+
+
+OUTPUT
+
+The statistics output is as follows:
+
+       rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0
+       rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915
+       rcutorture: Reader Pipe:  1466408 9747 0 0 0 0 0 0 0 0 0
+       rcutorture: Reader Batch:  1464477 11678 0 0 0 0 0 0 0 0
+       rcutorture: Free-Block Circulation:  1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0
+       rcutorture: --- End of test
+
+The command "dmesg | grep rcutorture:" will extract this information on
+most systems.  On more esoteric configurations, it may be necessary to
+use other commands to access the output of the printk()s used by
+the RCU torture test.  The printk()s use KERN_ALERT, so they should
+be evident.  ;-)
+
+The entries are as follows:
+
+o      "ggp": The number of counter flips (or batches) since boot.
+
+o      "rtc": The hexadecimal address of the structure currently visible
+       to readers.
+
+o      "ver": The number of times since boot that the rcutw writer task
+       has changed the structure visible to readers.
+
+o      "tfle": If non-zero, indicates that the "torture freelist"
+       containing structure to be placed into the "rtc" area is empty.
+       This condition is important, since it can fool you into thinking
+       that RCU is working when it is not.  :-/
+
+o      "rta": Number of structures allocated from the torture freelist.
+
+o      "rtaf": Number of allocations from the torture freelist that have
+       failed due to the list being empty.
+
+o      "rtf": Number of frees into the torture freelist.
+
+o      "Reader Pipe": Histogram of "ages" of structures seen by readers.
+       If any entries past the first two are non-zero, RCU is broken.
+       And rcutorture prints the error flag string "!!!" to make sure
+       you notice.  The age of a newly allocated structure is zero,
+       it becomes one when removed from reader visibility, and is
+       incremented once per grace period subsequently -- and is freed
+       after passing through (RCU_TORTURE_PIPE_LEN-2) grace periods.
+
+       The output displayed above was taken from a correctly working
+       RCU.  If you want to see what it looks like when broken, break
+       it yourself.  ;-)
+
+o      "Reader Batch": Another histogram of "ages" of structures seen
+       by readers, but in terms of counter flips (or batches) rather
+       than in terms of grace periods.  The legal number of non-zero
+       entries is again two.  The reason for this separate view is
+       that it is easier to get the third entry to show up in the
+       "Reader Batch" list than in the "Reader Pipe" list.
+
+o      "Free-Block Circulation": Shows the number of torture structures
+       that have reached a given point in the pipeline.  The first element
+       should closely correspond to the number of structures allocated,
+       the second to the number that have been removed from reader view,
+       and all but the last remaining to the corresponding number of
+       passes through a grace period.  The last entry should be zero,
+       as it is only incremented if a torture structure's counter
+       somehow gets incremented farther than it should.
+
+
+USAGE
+
+The following script may be used to torture RCU:
+
+       #!/bin/sh
+
+       modprobe rcutorture
+       sleep 100
+       rmmod rcutorture
+       dmesg | grep rcutorture:
+
+The output can be manually inspected for the error flag of "!!!".
+One could of course create a more elaborate script that automatically
+checked for such errors.
index d17b7d2dd771e6c0eeeda4b93c372840209f014d..a09a8eb80665ed5d1eadc4eee0cf935d4e689c5d 100644 (file)
@@ -94,7 +94,7 @@ the available CPU and Memory resources amongst the requesting tasks.
 But larger systems, which benefit more from careful processor and
 memory placement to reduce memory access times and contention,
 and which typically represent a larger investment for the customer,
-can benefit from explictly placing jobs on properly sized subsets of
+can benefit from explicitly placing jobs on properly sized subsets of
 the system.
 
 This can be especially valuable on:
index 4bef8c25172c8e472b09f068e0a34e2e5e8b08ee..d3ad2c24490aa4361ad83d841aca57607f83e5db 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/string.h>
 
 #include "linux/firmware.h"
 
index 09eab2f1b3735f0f9ff6feb193bba7b70c72130f..57b956aecbc52c0d4c7402611edc83304870dad0 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/firmware.h>
 
 
index e94d9c6cc522a9166664dbaca099fd721cb36afe..cff7b652588a6c1153c5d49f048db20ff1d3efcf 100644 (file)
@@ -273,6 +273,7 @@ For now, you can ignore the `flags' parameter. It is there for future use.
     if (is_isa) {
 
       /* Discard immediately if this ISA range is already used */
+      /* FIXME: never use check_region(), only request_region() */
       if (check_region(address,FOO_EXTENT))
         goto ERROR0;
 
index 4afe03a58c5ba912d6977d38a76314fe34d7bf66..31154882000a594c599c224c48a1d0f2569b6bc8 100644 (file)
@@ -196,7 +196,7 @@ KEY ACCESS PERMISSIONS
 
 Keys have an owner user ID, a group access ID, and a permissions mask. The mask
 has up to eight bits each for possessor, user, group and other access. Only
-five of each set of eight bits are defined. These permissions granted are:
+six of each set of eight bits are defined. These permissions granted are:
 
  (*) View
 
@@ -224,6 +224,10 @@ five of each set of eight bits are defined. These permissions granted are:
      keyring to a key, a process must have Write permission on the keyring and
      Link permission on the key.
 
+ (*) Set Attribute
+
+     This permits a key's UID, GID and permissions mask to be changed.
+
 For changing the ownership, group ID or permissions mask, being the owner of
 the key or having the sysadmin capability is sufficient.
 
@@ -242,15 +246,15 @@ about the status of the key service:
      this way:
 
        SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
-       00000001 I-----    39 perm 1f1f0000     0     0 keyring   _uid_ses.0: 1/4
-       00000002 I-----     2 perm 1f1f0000     0     0 keyring   _uid.0: empty
-       00000007 I-----     1 perm 1f1f0000     0     0 keyring   _pid.1: empty
-       0000018d I-----     1 perm 1f1f0000     0     0 keyring   _pid.412: empty
-       000004d2 I--Q--     1 perm 1f1f0000    32    -1 keyring   _uid.32: 1/4
-       000004d3 I--Q--     3 perm 1f1f0000    32    -1 keyring   _uid_ses.32: empty
+       00000001 I-----    39 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
+       00000002 I-----     2 perm 1f3f0000     0     0 keyring   _uid.0: empty
+       00000007 I-----     1 perm 1f3f0000     0     0 keyring   _pid.1: empty
+       0000018d I-----     1 perm 1f3f0000     0     0 keyring   _pid.412: empty
+       000004d2 I--Q--     1 perm 1f3f0000    32    -1 keyring   _uid.32: 1/4
+       000004d3 I--Q--     3 perm 1f3f0000    32    -1 keyring   _uid_ses.32: empty
        00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
-       00000893 I--Q-N     1  35s 1f1f0000     0     0 user      metal:silver: 0
-       00000894 I--Q--     1  10h 001f0000     0     0 user      metal:gold: 0
+       00000893 I--Q-N     1  35s 1f3f0000     0     0 user      metal:silver: 0
+       00000894 I--Q--     1  10h 003f0000     0     0 user      metal:gold: 0
 
      The flags are:
 
index e88d193d42f8f7031b86900cb215806753991b52..983f9e9aed617130bbd97c5bde4f11933b452049 100644 (file)
@@ -2286,6 +2286,11 @@ W:       http://tpmdd.sourceforge.net
 L:     tpmdd-devel@lists.sourceforge.net
 S:     Maintained
 
+Telecom Clock Driver for MCPL0010
+P: Mark Gross
+M: mark.gross@intel.com
+S: Supported
+
 TENSILICA XTENSA PORT (xtensa):
 P:     Chris Zankel
 M:     chris@zankel.net
diff --git a/README b/README
index d1edcc7adabe4a1dfd8efbdb3d26777a8526b044..4ee7dda88ba3956f0bea64072ee456ddf27fe8f9 100644 (file)
--- a/README
+++ b/README
@@ -54,6 +54,10 @@ INSTALLING the kernel:
 
                gzip -cd linux-2.6.XX.tar.gz | tar xvf -
 
+   or
+               bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
+
+
    Replace "XX" with the version number of the latest kernel.
 
    Do NOT use the /usr/src/linux area! This area has a (usually
index 67be50b7d80afba730e18746ad8e8ac63acc6068..6b2921be19090c9a5a0a6a85a87f4e6d525ff258 100644 (file)
 #include "proto.h"
 #include "irq_impl.h"
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 extern unsigned long wall_jiffies;     /* kernel/timer.c */
 
 static int set_rtc_mmss(unsigned long);
index c6beb751f2a93b4057a49df188d8522e1809dcdc..e1013112c354b4ab22bda4fa11968d5d93dee910 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index e8356b76d7c6e1fcaf3155b886085ef64c5c6e64..4af0cf5f3bfbc8d4f8fce84fc508f465c6ddf10a 100644 (file)
@@ -12,6 +12,9 @@
  */
 
 #include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
 #include <asm/io.h>
 #include <asm/hardware/scoop.h>
 
index a418dad6692c754b54504e54dcf86eb8d69dcaa3..0ee2e98196313a6dffaf46e38faaf5b426d80144 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/stddef.h>
 #include <linux/signal.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 
 #include <asm/ptrace.h>
 
index cd99b83f14c275ce9de09384b981472c4baf80b9..9bd8609a2926d29f12913c28705f9175d6e2a420 100644 (file)
@@ -782,7 +782,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
        return ret;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index 69449a818dccecd78ac290032124c9998e746d4a..fc4729106a3262cd4709f8f822673952205098c8 100644 (file)
 #include <asm/thread_info.h>
 #include <asm/mach/time.h>
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /*
  * Our system timer.
  */
index cb14b0682cef09892d9035b0ebd6f1bb02b43730..837d7f0bda4c8f9b610064551414e66f1cf5a213 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/string.h>
+
 #include <asm/arch/imxfb.h>
 #include <asm/hardware.h>
 #include <asm/arch/imx-regs.h>
index 56200594db3c2898255c281960014cbd709f817a..73c360685cad5eac086d56e03243620ee83a7ac7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <asm/semaphore.h>
 #include <asm/hardware/clock.h>
index f368b85f0447c220b601f44b68db2beef8a67612..764ceb49470a88975044d383cfe90e083fd77c70 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
+#include <asm/param.h>         /* HZ */
 #include <asm/mach-types.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/amba_kmi.h>
index c5f19d160598694c32a165b3611bf0e6e7e670c5..5b41e3a724e1d34f35aacd1a94372781a2c4710a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <asm/arch/lm.h>
 
index f997daa800bf5d196ce0e71bf61e0601656dffd6..c6a973ba8fc6f9aff7af143be17f4fdd95427720 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index 79fea3d20b66d53b0072543267e998845ef39493..802f6d091b75ec5b4f407fa2a3ffc6e7dedd2f22 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index f37a0e26b4663e521ae8683dcfa668e75f3e15c2..654e450a131170a28997f1a674bbff09c0cd160a 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index b9807aa2aade264b69ec48d5fc482cfdb6d59ae0..65951ffe4631261485c2ab1c64655426ba771c89 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index 3248bc9b94955ba934c914c6aef4763ae4e9a1c2..9c0289333301e9c5f0c0dc252c9990fbd20a8646 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/device.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
+#include <linux/string.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index f94b0fbcdcc86af73db3a3f4091318b620519e16..83eba8b54816681f217807dd2ef0dccd76d10288 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/pm.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
+#include <linux/sched.h>       /* just for sched_clock() - funny that */
 
 #include <asm/div64.h>
 #include <asm/hardware.h>
index 48025c2b99873ba1d3b67660081ad0d40546d11c..b96a2ea15d41b61b517204c770cfe9cc4d19ec7c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <asm/semaphore.h>
 #include <asm/hardware/clock.h>
index 52a58b2da2882553121810e75ba9aa1d168674b0..a020fe16428fecbd430989927da27ca7d174f53f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <asm/io.h>
 #include <asm/semaphore.h>
index 8a52124de0e1e6a188446594f9be2eff7aeb5f05..cf7e977d18c850eb4aba0bd3a2975cf48e85d525 100644 (file)
@@ -665,7 +665,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
        return ret;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index e66aedd02fad7c2eccf15259efb97c162e3dec5a..335525339ad6f4e107689ca26d047eb7b4a89330 100644 (file)
 #include <asm/irq.h>
 #include <asm/ioc.h>
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 extern unsigned long wall_jiffies;
 
 /* this needs a better home */
index 11ab3836aac65102d87b97429bdceb25e14e0218..56b038c8d48202f916b1eb06fc217a8ecb66afd6 100644 (file)
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/concat.h>
 #include <linux/mtd/map.h>
index 78ed52b1cdacfe5c7846da2d5eff686b851a24e3..b679f983b90a6edd5c05e5a2602fdace3d4b83f0 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/concat.h>
 #include <linux/mtd/map.h>
index a2d99b4aedcda34f22a5c1ec10fc4f3250050b0c..66ba8898db07ba0facf5a1edb86b31bb48a4f874 100644 (file)
 #include <linux/timex.h>
 #include <linux/init.h>
 #include <linux/profile.h>
-
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
+#include <linux/sched.h>       /* just for sched_clock() - funny that */
 
 int have_rtc;  /* used to remember if we have an RTC or not */;
 
index cbe03cba9f02a08dca3b7f59413df2aabf118a82..cb335a14a315ae3d18ac319939754725f4b89b67 100644 (file)
@@ -106,7 +106,7 @@ void ptrace_enable(struct task_struct *child)
        child->thread.frame0->__status |= REG__STATUS_STEP;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        unsigned long tmp;
index f43b734482e3aea84c5de5547f3ab31d102f6470..2e9741227b739161bd57b5f4b2d47593971da0b2 100644 (file)
@@ -34,9 +34,6 @@
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
 unsigned long __nongprelbss __clkin_clock_speed_HZ;
 unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
 unsigned long __nongprelbss __res_bus_clock_speed_HZ;
index 05c15e869777fc3225ca7fb400fb306556c5385f..a569fe4aa2842c34271174a0dfedecc232ff986e 100644 (file)
@@ -57,7 +57,7 @@ void ptrace_disable(struct task_struct *child)
        h8300_disable_trace(child);
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index af8c5d2057dd56ed6fa30257cd9ab2cd5c521bcb..688a5100604c943c614e5ffeb8fef25ba5c9b2fd 100644 (file)
 
 #define        TICK_SIZE (tick_nsec / 1000)
 
-u64 jiffies_64;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
index d2703cda61ea36db794b75c0e8d6f01a6ca0e048..5383e5e2d9b7e564f675516f69b477b280989e02 100644 (file)
@@ -5,7 +5,7 @@
 
 mainmenu "Linux Kernel Configuration"
 
-config X86
+config X86_32
        bool
        default y
        help
@@ -18,6 +18,10 @@ config SEMAPHORE_SLEEPERS
        bool
        default y
 
+config X86
+       bool
+       default y
+
 config MMU
        bool
        default y
@@ -151,304 +155,7 @@ config ES7000_CLUSTERED_APIC
        default y
        depends on SMP && X86_ES7000 && MPENTIUMIII
 
-if !X86_ELAN
-
-choice
-       prompt "Processor family"
-       default M686
-
-config M386
-       bool "386"
-       ---help---
-         This is the processor type of your CPU. This information is used for
-         optimizing purposes. In order to compile a kernel that can run on
-         all x86 CPU types (albeit not optimally fast), you can specify
-         "386" here.
-
-         The kernel will not necessarily run on earlier architectures than
-         the one you have chosen, e.g. a Pentium optimized kernel will run on
-         a PPro, but not necessarily on a i486.
-
-         Here are the settings recommended for greatest speed:
-         - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
-         486DLC/DLC2, UMC 486SX-S and NexGen Nx586.  Only "386" kernels
-         will run on a 386 class machine.
-         - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
-         SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
-         - "586" for generic Pentium CPUs lacking the TSC
-         (time stamp counter) register.
-         - "Pentium-Classic" for the Intel Pentium.
-         - "Pentium-MMX" for the Intel Pentium MMX.
-         - "Pentium-Pro" for the Intel Pentium Pro.
-         - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
-         - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
-         - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
-         - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
-         - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
-         - "Crusoe" for the Transmeta Crusoe series.
-         - "Efficeon" for the Transmeta Efficeon series.
-         - "Winchip-C6" for original IDT Winchip.
-         - "Winchip-2" for IDT Winchip 2.
-         - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
-         - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
-         - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
-         - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
-
-         If you don't know what to do, choose "386".
-
-config M486
-       bool "486"
-       help
-         Select this for a 486 series processor, either Intel or one of the
-         compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
-         DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
-         U5S.
-
-config M586
-       bool "586/K5/5x86/6x86/6x86MX"
-       help
-         Select this for an 586 or 686 series processor such as the AMD K5,
-         the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
-         assume the RDTSC (Read Time Stamp Counter) instruction.
-
-config M586TSC
-       bool "Pentium-Classic"
-       help
-         Select this for a Pentium Classic processor with the RDTSC (Read
-         Time Stamp Counter) instruction for benchmarking.
-
-config M586MMX
-       bool "Pentium-MMX"
-       help
-         Select this for a Pentium with the MMX graphics/multimedia
-         extended instructions.
-
-config M686
-       bool "Pentium-Pro"
-       help
-         Select this for Intel Pentium Pro chips.  This enables the use of
-         Pentium Pro extended instructions, and disables the init-time guard
-         against the f00f bug found in earlier Pentiums.
-
-config MPENTIUMII
-       bool "Pentium-II/Celeron(pre-Coppermine)"
-       help
-         Select this for Intel chips based on the Pentium-II and
-         pre-Coppermine Celeron core.  This option enables an unaligned
-         copy optimization, compiles the kernel with optimization flags
-         tailored for the chip, and applies any applicable Pentium Pro
-         optimizations.
-
-config MPENTIUMIII
-       bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
-       help
-         Select this for Intel chips based on the Pentium-III and
-         Celeron-Coppermine core.  This option enables use of some
-         extended prefetch instructions in addition to the Pentium II
-         extensions.
-
-config MPENTIUMM
-       bool "Pentium M"
-       help
-         Select this for Intel Pentium M (not Pentium-4 M)
-         notebook chips.
-
-config MPENTIUM4
-       bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
-       help
-         Select this for Intel Pentium 4 chips.  This includes the
-         Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
-         (not Pentium M) chips.  This option enables compile flags
-         optimized for the chip, uses the correct cache shift, and
-         applies any applicable Pentium III optimizations.
-
-config MK6
-       bool "K6/K6-II/K6-III"
-       help
-         Select this for an AMD K6-family processor.  Enables use of
-         some extended instructions, and passes appropriate optimization
-         flags to GCC.
-
-config MK7
-       bool "Athlon/Duron/K7"
-       help
-         Select this for an AMD Athlon K7-family processor.  Enables use of
-         some extended instructions, and passes appropriate optimization
-         flags to GCC.
-
-config MK8
-       bool "Opteron/Athlon64/Hammer/K8"
-       help
-         Select this for an AMD Opteron or Athlon64 Hammer-family processor.  Enables
-         use of some extended instructions, and passes appropriate optimization
-         flags to GCC.
-
-config MCRUSOE
-       bool "Crusoe"
-       help
-         Select this for a Transmeta Crusoe processor.  Treats the processor
-         like a 586 with TSC, and sets some GCC optimization flags (like a
-         Pentium Pro with no alignment requirements).
-
-config MEFFICEON
-       bool "Efficeon"
-       help
-         Select this for a Transmeta Efficeon processor.
-
-config MWINCHIPC6
-       bool "Winchip-C6"
-       help
-         Select this for an IDT Winchip C6 chip.  Linux and GCC
-         treat this chip as a 586TSC with some extended instructions
-         and alignment requirements.
-
-config MWINCHIP2
-       bool "Winchip-2"
-       help
-         Select this for an IDT Winchip-2.  Linux and GCC
-         treat this chip as a 586TSC with some extended instructions
-         and alignment requirements.
-
-config MWINCHIP3D
-       bool "Winchip-2A/Winchip-3"
-       help
-         Select this for an IDT Winchip-2A or 3.  Linux and GCC
-         treat this chip as a 586TSC with some extended instructions
-         and alignment reqirements.  Also enable out of order memory
-         stores for this CPU, which can increase performance of some
-         operations.
-
-config MGEODEGX1
-       bool "GeodeGX1"
-       help
-         Select this for a Geode GX1 (Cyrix MediaGX) chip.
-
-config MCYRIXIII
-       bool "CyrixIII/VIA-C3"
-       help
-         Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
-         treat this chip as a generic 586. Whilst the CPU is 686 class,
-         it lacks the cmov extension which gcc assumes is present when
-         generating 686 code.
-         Note that Nehemiah (Model 9) and above will not boot with this
-         kernel due to them lacking the 3DNow! instructions used in earlier
-         incarnations of the CPU.
-
-config MVIAC3_2
-       bool "VIA C3-2 (Nehemiah)"
-       help
-         Select this for a VIA C3 "Nehemiah". Selecting this enables usage
-         of SSE and tells gcc to treat the CPU as a 686.
-         Note, this kernel will not boot on older (pre model 9) C3s.
-
-endchoice
-
-config X86_GENERIC
-       bool "Generic x86 support"
-       help
-         Instead of just including optimizations for the selected
-         x86 variant (e.g. PII, Crusoe or Athlon), include some more
-         generic optimizations as well. This will make the kernel
-         perform better on x86 CPUs other than that selected.
-
-         This is really intended for distributors who need more
-         generic optimizations.
-
-endif
-
-#
-# Define implied options from the CPU selection here
-#
-config X86_CMPXCHG
-       bool
-       depends on !M386
-       default y
-
-config X86_XADD
-       bool
-       depends on !M386
-       default y
-
-config X86_L1_CACHE_SHIFT
-       int
-       default "7" if MPENTIUM4 || X86_GENERIC
-       default "4" if X86_ELAN || M486 || M386
-       default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
-       default "6" if MK7 || MK8 || MPENTIUMM
-
-config RWSEM_GENERIC_SPINLOCK
-       bool
-       depends on M386
-       default y
-
-config RWSEM_XCHGADD_ALGORITHM
-       bool
-       depends on !M386
-       default y
-
-config GENERIC_CALIBRATE_DELAY
-       bool
-       default y
-
-config X86_PPRO_FENCE
-       bool
-       depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
-       default y
-
-config X86_F00F_BUG
-       bool
-       depends on M586MMX || M586TSC || M586 || M486 || M386
-       default y
-
-config X86_WP_WORKS_OK
-       bool
-       depends on !M386
-       default y
-
-config X86_INVLPG
-       bool
-       depends on !M386
-       default y
-
-config X86_BSWAP
-       bool
-       depends on !M386
-       default y
-
-config X86_POPAD_OK
-       bool
-       depends on !M386
-       default y
-
-config X86_ALIGNMENT_16
-       bool
-       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
-       default y
-
-config X86_GOOD_APIC
-       bool
-       depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
-       default y
-
-config X86_INTEL_USERCOPY
-       bool
-       depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
-       default y
-
-config X86_USE_PPRO_CHECKSUM
-       bool
-       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
-       default y
-
-config X86_USE_3DNOW
-       bool
-       depends on MCYRIXIII || MK7
-       default y
-
-config X86_OOSTORE
-       bool
-       depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
-       default y
+source "arch/i386/Kconfig.cpu"
 
 config HPET_TIMER
        bool "HPET Timer Support"
@@ -561,11 +268,6 @@ config X86_VISWS_APIC
        depends on X86_VISWS
        default y
 
-config X86_TSC
-       bool
-       depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
-       default y
-
 config X86_MCE
        bool "Machine Check Exception"
        depends on !X86_VOYAGER
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
new file mode 100644 (file)
index 0000000..53bbb3c
--- /dev/null
@@ -0,0 +1,309 @@
+# Put here option for CPU selection and depending optimization
+if !X86_ELAN
+
+choice
+       prompt "Processor family"
+       default M686
+
+config M386
+       bool "386"
+       ---help---
+         This is the processor type of your CPU. This information is used for
+         optimizing purposes. In order to compile a kernel that can run on
+         all x86 CPU types (albeit not optimally fast), you can specify
+         "386" here.
+
+         The kernel will not necessarily run on earlier architectures than
+         the one you have chosen, e.g. a Pentium optimized kernel will run on
+         a PPro, but not necessarily on a i486.
+
+         Here are the settings recommended for greatest speed:
+         - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI
+         486DLC/DLC2, UMC 486SX-S and NexGen Nx586.  Only "386" kernels
+         will run on a 386 class machine.
+         - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or
+         SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S.
+         - "586" for generic Pentium CPUs lacking the TSC
+         (time stamp counter) register.
+         - "Pentium-Classic" for the Intel Pentium.
+         - "Pentium-MMX" for the Intel Pentium MMX.
+         - "Pentium-Pro" for the Intel Pentium Pro.
+         - "Pentium-II" for the Intel Pentium II or pre-Coppermine Celeron.
+         - "Pentium-III" for the Intel Pentium III or Coppermine Celeron.
+         - "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
+         - "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
+         - "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
+         - "Crusoe" for the Transmeta Crusoe series.
+         - "Efficeon" for the Transmeta Efficeon series.
+         - "Winchip-C6" for original IDT Winchip.
+         - "Winchip-2" for IDT Winchip 2.
+         - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
+         - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+         - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+         - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
+
+         If you don't know what to do, choose "386".
+
+config M486
+       bool "486"
+       help
+         Select this for a 486 series processor, either Intel or one of the
+         compatible processors from AMD, Cyrix, IBM, or Intel.  Includes DX,
+         DX2, and DX4 variants; also SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or
+         U5S.
+
+config M586
+       bool "586/K5/5x86/6x86/6x86MX"
+       help
+         Select this for an 586 or 686 series processor such as the AMD K5,
+         the Cyrix 5x86, 6x86 and 6x86MX.  This choice does not
+         assume the RDTSC (Read Time Stamp Counter) instruction.
+
+config M586TSC
+       bool "Pentium-Classic"
+       help
+         Select this for a Pentium Classic processor with the RDTSC (Read
+         Time Stamp Counter) instruction for benchmarking.
+
+config M586MMX
+       bool "Pentium-MMX"
+       help
+         Select this for a Pentium with the MMX graphics/multimedia
+         extended instructions.
+
+config M686
+       bool "Pentium-Pro"
+       help
+         Select this for Intel Pentium Pro chips.  This enables the use of
+         Pentium Pro extended instructions, and disables the init-time guard
+         against the f00f bug found in earlier Pentiums.
+
+config MPENTIUMII
+       bool "Pentium-II/Celeron(pre-Coppermine)"
+       help
+         Select this for Intel chips based on the Pentium-II and
+         pre-Coppermine Celeron core.  This option enables an unaligned
+         copy optimization, compiles the kernel with optimization flags
+         tailored for the chip, and applies any applicable Pentium Pro
+         optimizations.
+
+config MPENTIUMIII
+       bool "Pentium-III/Celeron(Coppermine)/Pentium-III Xeon"
+       help
+         Select this for Intel chips based on the Pentium-III and
+         Celeron-Coppermine core.  This option enables use of some
+         extended prefetch instructions in addition to the Pentium II
+         extensions.
+
+config MPENTIUMM
+       bool "Pentium M"
+       help
+         Select this for Intel Pentium M (not Pentium-4 M)
+         notebook chips.
+
+config MPENTIUM4
+       bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon"
+       help
+         Select this for Intel Pentium 4 chips.  This includes the
+         Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
+         (not Pentium M) chips.  This option enables compile flags
+         optimized for the chip, uses the correct cache shift, and
+         applies any applicable Pentium III optimizations.
+
+config MK6
+       bool "K6/K6-II/K6-III"
+       help
+         Select this for an AMD K6-family processor.  Enables use of
+         some extended instructions, and passes appropriate optimization
+         flags to GCC.
+
+config MK7
+       bool "Athlon/Duron/K7"
+       help
+         Select this for an AMD Athlon K7-family processor.  Enables use of
+         some extended instructions, and passes appropriate optimization
+         flags to GCC.
+
+config MK8
+       bool "Opteron/Athlon64/Hammer/K8"
+       help
+         Select this for an AMD Opteron or Athlon64 Hammer-family processor.  Enables
+         use of some extended instructions, and passes appropriate optimization
+         flags to GCC.
+
+config MCRUSOE
+       bool "Crusoe"
+       help
+         Select this for a Transmeta Crusoe processor.  Treats the processor
+         like a 586 with TSC, and sets some GCC optimization flags (like a
+         Pentium Pro with no alignment requirements).
+
+config MEFFICEON
+       bool "Efficeon"
+       help
+         Select this for a Transmeta Efficeon processor.
+
+config MWINCHIPC6
+       bool "Winchip-C6"
+       help
+         Select this for an IDT Winchip C6 chip.  Linux and GCC
+         treat this chip as a 586TSC with some extended instructions
+         and alignment requirements.
+
+config MWINCHIP2
+       bool "Winchip-2"
+       help
+         Select this for an IDT Winchip-2.  Linux and GCC
+         treat this chip as a 586TSC with some extended instructions
+         and alignment requirements.
+
+config MWINCHIP3D
+       bool "Winchip-2A/Winchip-3"
+       help
+         Select this for an IDT Winchip-2A or 3.  Linux and GCC
+         treat this chip as a 586TSC with some extended instructions
+         and alignment reqirements.  Also enable out of order memory
+         stores for this CPU, which can increase performance of some
+         operations.
+
+config MGEODEGX1
+       bool "GeodeGX1"
+       help
+         Select this for a Geode GX1 (Cyrix MediaGX) chip.
+
+config MCYRIXIII
+       bool "CyrixIII/VIA-C3"
+       help
+         Select this for a Cyrix III or C3 chip.  Presently Linux and GCC
+         treat this chip as a generic 586. Whilst the CPU is 686 class,
+         it lacks the cmov extension which gcc assumes is present when
+         generating 686 code.
+         Note that Nehemiah (Model 9) and above will not boot with this
+         kernel due to them lacking the 3DNow! instructions used in earlier
+         incarnations of the CPU.
+
+config MVIAC3_2
+       bool "VIA C3-2 (Nehemiah)"
+       help
+         Select this for a VIA C3 "Nehemiah". Selecting this enables usage
+         of SSE and tells gcc to treat the CPU as a 686.
+         Note, this kernel will not boot on older (pre model 9) C3s.
+
+endchoice
+
+config X86_GENERIC
+       bool "Generic x86 support"
+       help
+         Instead of just including optimizations for the selected
+         x86 variant (e.g. PII, Crusoe or Athlon), include some more
+         generic optimizations as well. This will make the kernel
+         perform better on x86 CPUs other than that selected.
+
+         This is really intended for distributors who need more
+         generic optimizations.
+
+endif
+
+#
+# Define implied options from the CPU selection here
+#
+config X86_CMPXCHG
+       bool
+       depends on !M386
+       default y
+
+config X86_XADD
+       bool
+       depends on !M386
+       default y
+
+config X86_L1_CACHE_SHIFT
+       int
+       default "7" if MPENTIUM4 || X86_GENERIC
+       default "4" if X86_ELAN || M486 || M386
+       default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+       default "6" if MK7 || MK8 || MPENTIUMM
+
+config RWSEM_GENERIC_SPINLOCK
+       bool
+       depends on M386
+       default y
+
+config RWSEM_XCHGADD_ALGORITHM
+       bool
+       depends on !M386
+       default y
+
+config GENERIC_CALIBRATE_DELAY
+       bool
+       default y
+
+config X86_PPRO_FENCE
+       bool
+       depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1
+       default y
+
+config X86_F00F_BUG
+       bool
+       depends on M586MMX || M586TSC || M586 || M486 || M386
+       default y
+
+config X86_WP_WORKS_OK
+       bool
+       depends on !M386
+       default y
+
+config X86_INVLPG
+       bool
+       depends on !M386
+       default y
+
+config X86_BSWAP
+       bool
+       depends on !M386
+       default y
+
+config X86_POPAD_OK
+       bool
+       depends on !M386
+       default y
+
+config X86_CMPXCHG64
+       bool
+       depends on !M386 && !M486
+       default y
+
+config X86_ALIGNMENT_16
+       bool
+       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+       default y
+
+config X86_GOOD_APIC
+       bool
+       depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON
+       default y
+
+config X86_INTEL_USERCOPY
+       bool
+       depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON
+       default y
+
+config X86_USE_PPRO_CHECKSUM
+       bool
+       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+       default y
+
+config X86_USE_3DNOW
+       bool
+       depends on MCYRIXIII || MK7
+       default y
+
+config X86_OOSTORE
+       bool
+       depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR
+       default y
+
+config X86_TSC
+       bool
+       depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ
+       default y
index 09951990a6226b0a422c5812c6af7dbe67ef18a1..d121ea18460fe89335c2019c818f55dedd4c14b0 100644 (file)
@@ -34,35 +34,8 @@ CFLAGS += -pipe -msoft-float
 # prevent gcc from keeping the stack 16 byte aligned
 CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
 
-align := $(cc-option-align)
-cflags-$(CONFIG_M386)          += -march=i386
-cflags-$(CONFIG_M486)          += -march=i486
-cflags-$(CONFIG_M586)          += -march=i586
-cflags-$(CONFIG_M586TSC)       += -march=i586
-cflags-$(CONFIG_M586MMX)       += $(call cc-option,-march=pentium-mmx,-march=i586)
-cflags-$(CONFIG_M686)          += -march=i686
-cflags-$(CONFIG_MPENTIUMII)    += -march=i686 $(call cc-option,-mtune=pentium2)
-cflags-$(CONFIG_MPENTIUMIII)   += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUMM)     += -march=i686 $(call cc-option,-mtune=pentium3)
-cflags-$(CONFIG_MPENTIUM4)     += -march=i686 $(call cc-option,-mtune=pentium4)
-cflags-$(CONFIG_MK6)           += -march=k6
-# Please note, that patches that add -march=athlon-xp and friends are pointless.
-# They make zero difference whatsosever to performance at this time.
-cflags-$(CONFIG_MK7)           += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
-cflags-$(CONFIG_MK8)           += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
-cflags-$(CONFIG_MCRUSOE)       += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MEFFICEON)     += -march=i686 $(call cc-option,-mtune=pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MWINCHIPC6)    += $(call cc-option,-march=winchip-c6,-march=i586)
-cflags-$(CONFIG_MWINCHIP2)     += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MWINCHIP3D)    += $(call cc-option,-march=winchip2,-march=i586)
-cflags-$(CONFIG_MCYRIXIII)     += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
-cflags-$(CONFIG_MVIAC3_2)      += $(call cc-option,-march=c3-2,-march=i686)
-
-# AMD Elan support
-cflags-$(CONFIG_X86_ELAN)      += -march=i486
-
-# Geode GX1 support
-cflags-$(CONFIG_MGEODEGX1)             += $(call cc-option,-march=pentium-mmx,-march=i486)
+# CPU-specific tuning. Anything which can be shared with UML should go here.
+include $(srctree)/arch/i386/Makefile.cpu
 
 # -mregparm=3 works ok on gcc-3.0 and later
 #
diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
new file mode 100644 (file)
index 0000000..8e51456
--- /dev/null
@@ -0,0 +1,41 @@
+# CPU tuning section - shared with UML.
+# Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
+
+#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
+HAS_MTUNE      := $(call cc-option-yn, -mtune=i386)
+ifeq ($(HAS_MTUNE),y)
+tune           = $(call cc-option,-mtune=$(1),)
+else
+tune           = $(call cc-option,-mcpu=$(1),)
+endif
+
+align := $(cc-option-align)
+cflags-$(CONFIG_M386)          += -march=i386
+cflags-$(CONFIG_M486)          += -march=i486
+cflags-$(CONFIG_M586)          += -march=i586
+cflags-$(CONFIG_M586TSC)       += -march=i586
+cflags-$(CONFIG_M586MMX)       += $(call cc-option,-march=pentium-mmx,-march=i586)
+cflags-$(CONFIG_M686)          += -march=i686
+cflags-$(CONFIG_MPENTIUMII)    += -march=i686 $(call tune,pentium2)
+cflags-$(CONFIG_MPENTIUMIII)   += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUMM)     += -march=i686 $(call tune,pentium3)
+cflags-$(CONFIG_MPENTIUM4)     += -march=i686 $(call tune,pentium4)
+cflags-$(CONFIG_MK6)           += -march=k6
+# Please note, that patches that add -march=athlon-xp and friends are pointless.
+# They make zero difference whatsosever to performance at this time.
+cflags-$(CONFIG_MK7)           += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
+cflags-$(CONFIG_MK8)           += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
+cflags-$(CONFIG_MCRUSOE)       += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MEFFICEON)     += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MWINCHIPC6)    += $(call cc-option,-march=winchip-c6,-march=i586)
+cflags-$(CONFIG_MWINCHIP2)     += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MWINCHIP3D)    += $(call cc-option,-march=winchip2,-march=i586)
+cflags-$(CONFIG_MCYRIXIII)     += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+cflags-$(CONFIG_MVIAC3_2)      += $(call cc-option,-march=c3-2,-march=i686)
+
+# AMD Elan support
+cflags-$(CONFIG_X86_ELAN)      += -march=i486
+
+# Geode GX1 support
+cflags-$(CONFIG_MGEODEGX1)             += $(call cc-option,-march=pentium-mmx,-march=i486)
+
index 5546ddebec33dc994c93b5f3f604867da4e94413..9204be6eedb3c5e4d25c1add893359de85fda1ab 100644 (file)
@@ -803,6 +803,7 @@ no_apic:
 
 void __init init_apic_mappings(void)
 {
+       unsigned int orig_apicid;
        unsigned long apic_phys;
 
        /*
@@ -824,8 +825,11 @@ void __init init_apic_mappings(void)
         * Fetch the APIC ID of the BSP in case we have a
         * default configuration (or the MP table is broken).
         */
-       if (boot_cpu_physical_apicid == -1U)
-               boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+       orig_apicid = boot_cpu_physical_apicid;
+       boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+       if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
+               printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
+                       orig_apicid, boot_cpu_physical_apicid);
 
 #ifdef CONFIG_X86_IO_APIC
        {
@@ -1046,10 +1050,11 @@ static unsigned int calibration_result;
 
 void __init setup_boot_APIC_clock(void)
 {
+       unsigned long flags;
        apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n");
        using_apic_timer = 1;
 
-       local_irq_disable();
+       local_irq_save(flags);
 
        calibration_result = calibrate_APIC_clock();
        /*
@@ -1057,7 +1062,7 @@ void __init setup_boot_APIC_clock(void)
         */
        setup_APIC_timer(calibration_result);
 
-       local_irq_enable();
+       local_irq_restore(flags);
 }
 
 void __devinit setup_secondary_APIC_clock(void)
@@ -1254,40 +1259,81 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
 }
 
 /*
- * This initializes the IO-APIC and APIC hardware if this is
- * a UP kernel.
+ * This initializes the IO-APIC and APIC hardware.
  */
-int __init APIC_init_uniprocessor (void)
+int __init APIC_init(void)
 {
-       if (enable_local_apic < 0)
-               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+       if (enable_local_apic < 0) {
+               printk(KERN_INFO "APIC disabled\n");
+               return -1;
+       }
 
-       if (!smp_found_config && !cpu_has_apic)
+       /* See if we have a SMP configuration or have forced enabled
+        * the local apic.
+        */
+       if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
+               enable_local_apic = -1;
                return -1;
+       }
 
        /*
-        * Complain if the BIOS pretends there is one.
+        * Complain if the BIOS pretends there is an apic.
+        * Then get out because we don't have an a local apic.
         */
        if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                        boot_cpu_physical_apicid);
+               printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
+               enable_local_apic = -1;
                return -1;
        }
 
        verify_local_APIC();
 
+       /*
+        * Should not be necessary because the MP table should list the boot
+        * CPU too, but we do it for the sake of robustness anyway.
+        * Makes no sense to do this check in clustered apic mode, so skip it
+        */
+       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
+               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+                               boot_cpu_physical_apicid);
+               physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
+       }
+
+       /*
+        * Switch from PIC to APIC mode.
+        */
        connect_bsp_APIC();
+       setup_local_APIC();
 
-       phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
+#ifdef CONFIG_X86_IO_APIC
+       /*
+        * Now start the IO-APICs
+        */
+       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+               setup_IO_APIC();
+#endif
+       return 0;
+}
 
-       setup_local_APIC();
+void __init APIC_late_time_init(void)
+{
+       /* Improve our loops per jiffy estimate */
+       loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
+       boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
+       cpu_data[0].loops_per_jiffy = loops_per_jiffy;
+
+       /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
+        * initialized.  So redo it here to ensure the boot cpu is setup
+        * properly.
+        */
+       if (nmi_watchdog == NMI_LOCAL_APIC)
+               setup_apic_nmi_watchdog();
 
 #ifdef CONFIG_X86_IO_APIC
-       if (smp_found_config)
-               if (!skip_ioapic_setup && nr_ioapics)
-                       setup_IO_APIC();
+       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+               IO_APIC_late_time_init();
 #endif
        setup_boot_APIC_clock();
-
-       return 0;
 }
index d7811c4e8b509b30fa5fd15f822d94ebddb0d82c..d2ef0c2aa93e462df516ec6e78c8473bed7c56b7 100644 (file)
@@ -597,12 +597,14 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
        cpumask_t               cpus;
        int                     cpu;
        struct desc_struct      save_desc_40;
+       struct desc_struct      *gdt;
 
        cpus = apm_save_cpus();
        
        cpu = get_cpu();
-       save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
-       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+       gdt = get_cpu_gdt_table(cpu);
+       save_desc_40 = gdt[0x40 / 8];
+       gdt[0x40 / 8] = bad_bios_desc;
 
        local_save_flags(flags);
        APM_DO_CLI;
@@ -610,7 +612,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
        apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
        APM_DO_RESTORE_SEGS;
        local_irq_restore(flags);
-       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = save_desc_40;
+       gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);
        
@@ -639,13 +641,14 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
        cpumask_t               cpus;
        int                     cpu;
        struct desc_struct      save_desc_40;
-
+       struct desc_struct      *gdt;
 
        cpus = apm_save_cpus();
        
        cpu = get_cpu();
-       save_desc_40 = per_cpu(cpu_gdt_table, cpu)[0x40 / 8];
-       per_cpu(cpu_gdt_table, cpu)[0x40 / 8] = bad_bios_desc;
+       gdt = get_cpu_gdt_table(cpu);
+       save_desc_40 = gdt[0x40 / 8];
+       gdt[0x40 / 8] = bad_bios_desc;
 
        local_save_flags(flags);
        APM_DO_CLI;
@@ -653,7 +656,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
        error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
        APM_DO_RESTORE_SEGS;
        local_irq_restore(flags);
-       __get_cpu_var(cpu_gdt_table)[0x40 / 8] = save_desc_40;
+       gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);
        return error;
@@ -2295,35 +2298,36 @@ static int __init apm_init(void)
        apm_bios_entry.segment = APM_CS;
 
        for (i = 0; i < NR_CPUS; i++) {
-               set_base(per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+               struct desc_struct *gdt = get_cpu_gdt_table(i);
+               set_base(gdt[APM_CS >> 3],
                         __va((unsigned long)apm_info.bios.cseg << 4));
-               set_base(per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+               set_base(gdt[APM_CS_16 >> 3],
                         __va((unsigned long)apm_info.bios.cseg_16 << 4));
-               set_base(per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+               set_base(gdt[APM_DS >> 3],
                         __va((unsigned long)apm_info.bios.dseg << 4));
 #ifndef APM_RELAX_SEGMENTS
                if (apm_info.bios.version == 0x100) {
 #endif
                        /* For ASUS motherboard, Award BIOS rev 110 (and others?) */
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 - 1);
+                       _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
                        /* For some unknown machine. */
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3], 64 * 1024 - 1);
+                       _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
                        /* For the DEC Hinote Ultra CT475 (and others?) */
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3], 64 * 1024 - 1);
+                       _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
 #ifndef APM_RELAX_SEGMENTS
                } else {
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3],
+                       _set_limit((char *)&gdt[APM_CS >> 3],
                                (apm_info.bios.cseg_len - 1) & 0xffff);
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS_16 >> 3],
+                       _set_limit((char *)&gdt[APM_CS_16 >> 3],
                                (apm_info.bios.cseg_16_len - 1) & 0xffff);
-                       _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_DS >> 3],
+                       _set_limit((char *)&gdt[APM_DS >> 3],
                                (apm_info.bios.dseg_len - 1) & 0xffff);
                      /* workaround for broken BIOSes */
                        if (apm_info.bios.cseg_len <= apm_info.bios.offset)
-                               _set_limit((char *)&per_cpu(cpu_gdt_table, i)[APM_CS >> 3], 64 * 1024 -1);
+                               _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
                        if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
                                /* for the BIOS that assumes granularity = 1 */
-                               per_cpu(cpu_gdt_table, i)[APM_DS >> 3].b |= 0x800000;
+                               gdt[APM_DS >> 3].b |= 0x800000;
                                printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
                        }
                }
index 9ad43be9a01f0ebc2102f7d1fef5a11aa0146c71..74145a33cb0fd9cc4b69d9e07717e65adac35f74 100644 (file)
@@ -573,6 +573,7 @@ void __devinit cpu_init(void)
        int cpu = smp_processor_id();
        struct tss_struct * t = &per_cpu(init_tss, cpu);
        struct thread_struct *thread = &current->thread;
+       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
        __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
 
        if (cpu_test_and_set(cpu, cpu_initialized)) {
@@ -594,24 +595,16 @@ void __devinit cpu_init(void)
         * Initialize the per-CPU GDT with the boot GDT,
         * and set up the GDT descriptor:
         */
-       memcpy(&per_cpu(cpu_gdt_table, cpu), cpu_gdt_table,
-              GDT_SIZE);
+       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
 
        /* Set up GDT entry for 16bit stack */
-       *(__u64 *)&(per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_ESPFIX_SS]) |=
+       *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
                ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) |
                ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
                (CPU_16BIT_STACK_SIZE - 1);
 
        cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
-       cpu_gdt_descr[cpu].address =
-           (unsigned long)&per_cpu(cpu_gdt_table, cpu);
-
-       /*
-        * Set up the per-thread TLS descriptor cache:
-        */
-       memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu),
-               GDT_ENTRY_TLS_ENTRIES * 8);
+       cpu_gdt_descr[cpu].address = (unsigned long)gdt;
 
        load_gdt(&cpu_gdt_descr[cpu]);
        load_idt(&idt_descr);
index 822c8ce9d1f19374618ffa9c633d560dc1833f21..caa9f77113439c3aa4fb0276c1c21961151baf64 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/compiler.h>
+#include <linux/sched.h>       /* current */
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
index aa622d52c6e538bf616c8d4eeaee8bbe4efce96a..270f2188d68b1857d3ef59c3a71adf7f106de2c4 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/cpumask.h>
+#include <linux/sched.h>       /* current / set_cpus_allowed() */
 
 #include <asm/processor.h> 
 #include <asm/msr.h>
index 58ca98fdc2cabbc3e73ad03f910c59af64e30d69..2d5c9adba0cdc9a183743993dd3f2a794ccc6e47 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/cpumask.h>
+#include <linux/sched.h>       /* for current / set_cpus_allowed() */
 
 #include <asm/msr.h>
 #include <asm/io.h>
index c397b622043019196ffb9fdef2834c120ff4536e..1465974256c9a57300427cc3ca851c890f79684f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/config.h>
+#include <linux/sched.h>       /* current */
 #include <linux/delay.h>
 #include <linux/compiler.h>
 
index 9e0d5f83cb9f63879b59b06683449d97923e4ce9..4dc42a189ae5ebefc3b3f0595211a51a2182f8be 100644 (file)
@@ -3,6 +3,7 @@
  *
  *      Changes:
  *      Venkatesh Pallipadi    : Adding cache identification through cpuid(4)
+ *             Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
  */
 
 #include <linux/init.h>
@@ -10,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/compiler.h>
 #include <linux/cpu.h>
+#include <linux/sched.h>
 
 #include <asm/processor.h>
 #include <asm/smp.h>
@@ -28,7 +30,7 @@ struct _cache_table
 };
 
 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __devinitdata =
+static struct _cache_table cache_table[] __cpuinitdata =
 {
        { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
        { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
@@ -117,10 +119,9 @@ struct _cpuid4_info {
        cpumask_t shared_cpu_map;
 };
 
-#define MAX_CACHE_LEAVES               4
 static unsigned short                  num_cache_leaves;
 
-static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 {
        unsigned int            eax, ebx, ecx, edx;
        union _cpuid4_leaf_eax  cache_eax;
@@ -144,23 +145,18 @@ static int __init find_num_cache_leaves(void)
 {
        unsigned int            eax, ebx, ecx, edx;
        union _cpuid4_leaf_eax  cache_eax;
-       int                     i;
-       int                     retval;
+       int                     i = -1;
 
-       retval = MAX_CACHE_LEAVES;
-       /* Do cpuid(4) loop to find out num_cache_leaves */
-       for (i = 0; i < MAX_CACHE_LEAVES; i++) {
+       do {
+               ++i;
+               /* Do cpuid(4) loop to find out num_cache_leaves */
                cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
                cache_eax.full = eax;
-               if (cache_eax.split.type == CACHE_TYPE_NULL) {
-                       retval = i;
-                       break;
-               }
-       }
-       return retval;
+       } while (cache_eax.split.type != CACHE_TYPE_NULL);
+       return i;
 }
 
-unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
        unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
@@ -284,13 +280,7 @@ unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
                if ( l3 )
                        printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
 
-               /*
-                * This assumes the L3 cache is shared; it typically lives in
-                * the northbridge.  The L1 caches are included by the L2
-                * cache, and so should not be included for the purpose of
-                * SMP switching weights.
-                */
-               c->x86_cache_size = l2 ? l2 : (l1i+l1d);
+               c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
        }
 
        return l2;
@@ -301,7 +291,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
 #define CPUID4_INFO_IDX(x,y)    (&((cpuid4_info[x])[y]))
 
 #ifdef CONFIG_SMP
-static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 {
        struct _cpuid4_info     *this_leaf;
        unsigned long num_threads_sharing;
@@ -334,7 +324,7 @@ static void free_cache_attributes(unsigned int cpu)
        cpuid4_info[cpu] = NULL;
 }
 
-static int __devinit detect_cache_attributes(unsigned int cpu)
+static int __cpuinit detect_cache_attributes(unsigned int cpu)
 {
        struct _cpuid4_info     *this_leaf;
        unsigned long           j;
@@ -511,7 +501,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
        free_cache_attributes(cpu);
 }
 
-static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
+static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
 {
 
        if (num_cache_leaves == 0)
@@ -542,7 +532,7 @@ err_out:
 }
 
 /* Add/Remove cache interface for CPU device */
-static int __devinit cache_add_dev(struct sys_device * sys_dev)
+static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 {
        unsigned int cpu = sys_dev->id;
        unsigned long i, j;
@@ -579,7 +569,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev)
        return retval;
 }
 
-static int __devexit cache_remove_dev(struct sys_device * sys_dev)
+static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
 {
        unsigned int cpu = sys_dev->id;
        unsigned long i;
@@ -588,24 +578,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev)
                kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
        kobject_unregister(cache_kobject[cpu]);
        cpuid4_cache_sysfs_exit(cpu);
-       return 0;
+       return;
+}
+
+static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long)hcpu;
+       struct sys_device *sys_dev;
+
+       sys_dev = get_cpu_sysdev(cpu);
+       switch (action) {
+       case CPU_ONLINE:
+               cache_add_dev(sys_dev);
+               break;
+       case CPU_DEAD:
+               cache_remove_dev(sys_dev);
+               break;
+       }
+       return NOTIFY_OK;
 }
 
-static struct sysdev_driver cache_sysdev_driver = {
-       .add = cache_add_dev,
-       .remove = __devexit_p(cache_remove_dev),
+static struct notifier_block cacheinfo_cpu_notifier =
+{
+    .notifier_call = cacheinfo_cpu_callback,
 };
 
-/* Register/Unregister the cpu_cache driver */
-static int __devinit cache_register_driver(void)
+static int __cpuinit cache_sysfs_init(void)
 {
+       int i;
+
        if (num_cache_leaves == 0)
                return 0;
 
-       return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver);
+       register_cpu_notifier(&cacheinfo_cpu_notifier);
+
+       for_each_online_cpu(i) {
+               cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
+                       (void *)(long)i);
+       }
+
+       return 0;
 }
 
-device_initcall(cache_register_driver);
+device_initcall(cache_sysfs_init);
 
 #endif
-
index 3c035b8fa3d9bb9f0fd121826ce2eac01f69413d..979b18bc95c192aa4fe2740245d4923319124927 100644 (file)
@@ -102,11 +102,16 @@ void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
                wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
        nr_mce_banks = l & 0xff;
 
-       /* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
-       for (i=1; i<nr_mce_banks; i++) {
+       /*
+        * Following the example in IA-32 SDM Vol 3:
+        * - MC0_CTL should not be written
+        * - Status registers on all banks should be cleared on reset
+        */
+       for (i=1; i<nr_mce_banks; i++)
                wrmsr (MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
+
+       for (i=0; i<nr_mce_banks; i++)
                wrmsr (MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-       }
 
        set_in_cr4 (X86_CR4_MCE);
        printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
index 1923e0aed26a896816bc19d4c65257c9d28ae838..cf39e205d33ca2a7192bf284a573d5d39b711ee9 100644 (file)
@@ -149,60 +149,89 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
        return -EINVAL;
 }
 
-static int
-mtrr_ioctl(struct inode *inode, struct file *file,
-          unsigned int cmd, unsigned long __arg)
+static long
+mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 {
-       int err;
+       int err = 0;
        mtrr_type type;
        struct mtrr_sentry sentry;
        struct mtrr_gentry gentry;
        void __user *arg = (void __user *) __arg;
 
+       switch (cmd) {
+       case MTRRIOC_ADD_ENTRY:
+       case MTRRIOC_SET_ENTRY:
+       case MTRRIOC_DEL_ENTRY:
+       case MTRRIOC_KILL_ENTRY:
+       case MTRRIOC_ADD_PAGE_ENTRY:
+       case MTRRIOC_SET_PAGE_ENTRY:
+       case MTRRIOC_DEL_PAGE_ENTRY:
+       case MTRRIOC_KILL_PAGE_ENTRY:
+               if (copy_from_user(&sentry, arg, sizeof sentry))
+                       return -EFAULT;
+               break;
+       case MTRRIOC_GET_ENTRY:
+       case MTRRIOC_GET_PAGE_ENTRY:
+               if (copy_from_user(&gentry, arg, sizeof gentry))
+                       return -EFAULT;
+               break;
+#ifdef CONFIG_COMPAT
+       case MTRRIOC32_ADD_ENTRY:
+       case MTRRIOC32_SET_ENTRY:
+       case MTRRIOC32_DEL_ENTRY:
+       case MTRRIOC32_KILL_ENTRY:
+       case MTRRIOC32_ADD_PAGE_ENTRY:
+       case MTRRIOC32_SET_PAGE_ENTRY:
+       case MTRRIOC32_DEL_PAGE_ENTRY:
+       case MTRRIOC32_KILL_PAGE_ENTRY: {
+               struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+               err = get_user(sentry.base, &s32->base);
+               err |= get_user(sentry.size, &s32->size);
+               err |= get_user(sentry.type, &s32->type);
+               if (err)
+                       return err;
+               break;
+       }
+       case MTRRIOC32_GET_ENTRY:
+       case MTRRIOC32_GET_PAGE_ENTRY: {
+               struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+               err = get_user(gentry.regnum, &g32->regnum);
+               err |= get_user(gentry.base, &g32->base);
+               err |= get_user(gentry.size, &g32->size);
+               err |= get_user(gentry.type, &g32->type);
+               if (err)
+                       return err;
+               break;
+       }
+#endif
+       }
+
        switch (cmd) {
        default:
                return -ENOTTY;
        case MTRRIOC_ADD_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err =
                    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
                                  file, 0);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_SET_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_add(sentry.base, sentry.size, sentry.type, 0);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_DEL_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_file_del(sentry.base, sentry.size, file, 0);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_KILL_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_del(-1, sentry.base, sentry.size);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_GET_ENTRY:
-               if (copy_from_user(&gentry, arg, sizeof gentry))
-                       return -EFAULT;
                if (gentry.regnum >= num_var_ranges)
                        return -EINVAL;
                mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
@@ -217,60 +246,59 @@ mtrr_ioctl(struct inode *inode, struct file *file,
                        gentry.type = type;
                }
 
-               if (copy_to_user(arg, &gentry, sizeof gentry))
-                       return -EFAULT;
                break;
        case MTRRIOC_ADD_PAGE_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err =
                    mtrr_file_add(sentry.base, sentry.size, sentry.type, 1,
                                  file, 1);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_SET_PAGE_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_add_page(sentry.base, sentry.size, sentry.type, 0);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_DEL_PAGE_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_file_del(sentry.base, sentry.size, file, 1);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_KILL_PAGE_ENTRY:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               if (copy_from_user(&sentry, arg, sizeof sentry))
-                       return -EFAULT;
                err = mtrr_del_page(-1, sentry.base, sentry.size);
-               if (err < 0)
-                       return err;
                break;
        case MTRRIOC_GET_PAGE_ENTRY:
-               if (copy_from_user(&gentry, arg, sizeof gentry))
-                       return -EFAULT;
                if (gentry.regnum >= num_var_ranges)
                        return -EINVAL;
                mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type);
                gentry.type = type;
+               break;
+       }
+
+       if (err)
+               return err;
 
+       switch(cmd) {
+       case MTRRIOC_GET_ENTRY:
+       case MTRRIOC_GET_PAGE_ENTRY:
                if (copy_to_user(arg, &gentry, sizeof gentry))
-                       return -EFAULT;
+                       err = -EFAULT;
+               break;
+#ifdef CONFIG_COMPAT
+       case MTRRIOC32_GET_ENTRY:
+       case MTRRIOC32_GET_PAGE_ENTRY: {
+               struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+               err = put_user(gentry.base, &g32->base);
+               err |= put_user(gentry.size, &g32->size);
+               err |= put_user(gentry.regnum, &g32->regnum);
+               err |= put_user(gentry.type, &g32->type);
                break;
        }
-       return 0;
+#endif
+       }
+       return err;
 }
 
 static int
@@ -310,7 +338,8 @@ static struct file_operations mtrr_fops = {
        .read    = seq_read,
        .llseek  = seq_lseek,
        .write   = mtrr_write,
-       .ioctl   = mtrr_ioctl,
+       .unlocked_ioctl = mtrr_ioctl,
+       .compat_ioctl = mtrr_ioctl,
        .release = mtrr_close,
 };
 
index 8bd77d948a8446b578472d4d1bfac7a757d38936..41b871ecf4b353ddd1e0dfa0f366e7668cdc220c 100644 (file)
@@ -44,7 +44,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Intel-defined (#2) */
-               "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+               "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
                "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
index 0248e084017ceddd74bcc7e92052cef801b897ff..af809ccf5fbe14d526dfca29be0a3a160c6eacd4 100644 (file)
@@ -21,7 +21,6 @@
 #include <asm/hardirq.h>
 #include <asm/nmi.h>
 #include <asm/hw_irq.h>
-#include <asm/apic.h>
 #include <mach_ipi.h>
 
 
@@ -148,7 +147,6 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
                regs = &fixed_regs;
        }
        crash_save_this_cpu(regs, cpu);
-       disable_local_APIC();
        atomic_dec(&waiting_for_crash_ipi);
        /* Assume hlt works */
        halt();
@@ -188,7 +186,6 @@ static void nmi_shootdown_cpus(void)
        }
 
        /* Leave the nmi callback set */
-       disable_local_APIC();
 }
 #else
 static void nmi_shootdown_cpus(void)
@@ -213,9 +210,5 @@ void machine_crash_shutdown(struct pt_regs *regs)
        /* Make a note of crashing cpu. Will be used in NMI callback.*/
        crashing_cpu = smp_processor_id();
        nmi_shootdown_cpus();
-       lapic_shutdown();
-#if defined(CONFIG_X86_IO_APIC)
-       disable_IO_APIC();
-#endif
        crash_save_self(regs);
 }
index 323ef8ab3244e880c1b32468a12122990ba0ceba..d86f2490928449ce15acfc8ffff5522e11139453 100644 (file)
@@ -435,4 +435,8 @@ void __init init_IRQ(void)
                setup_irq(FPU_IRQ, &fpu_irq);
 
        irq_ctx_init(smp_processor_id());
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       APIC_init();
+#endif
 }
index fb3991e8229e5e65cf696cc4d2d7eec55546cd28..5a77c52b20a934d2d9a168ee20a1a965201e1818 100644 (file)
@@ -46,6 +46,9 @@
 int (*ioapic_renumber_irq)(int ioapic, int irq);
 atomic_t irq_mis_count;
 
+/* Where if anywhere is the i8259 connect in external int mode */
+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+
 static DEFINE_SPINLOCK(ioapic_lock);
 
 /*
@@ -738,7 +741,7 @@ static int find_irq_entry(int apic, int pin, int type)
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
-static int find_isa_irq_pin(int irq, int type)
+static int __init find_isa_irq_pin(int irq, int type)
 {
        int i;
 
@@ -758,6 +761,33 @@ static int find_isa_irq_pin(int irq, int type)
        return -1;
 }
 
+static int __init find_isa_irq_apic(int irq, int type)
+{
+       int i;
+
+       for (i = 0; i < mp_irq_entries; i++) {
+               int lbus = mp_irqs[i].mpc_srcbus;
+
+               if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
+                    mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
+                    mp_bus_id_to_type[lbus] == MP_BUS_MCA ||
+                    mp_bus_id_to_type[lbus] == MP_BUS_NEC98
+                   ) &&
+                   (mp_irqs[i].mpc_irqtype == type) &&
+                   (mp_irqs[i].mpc_srcbusirq == irq))
+                       break;
+       }
+       if (i < mp_irq_entries) {
+               int apic;
+               for(apic = 0; apic < nr_ioapics; apic++) {
+                       if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+                               return apic;
+               }
+       }
+
+       return -1;
+}
+
 /*
  * Find a specific PCI IRQ entry.
  * Not an __init, possibly needed by modules
@@ -1253,7 +1283,7 @@ static void __init setup_IO_APIC_irqs(void)
 /*
  * Set up the 8259A-master output pin:
  */
-static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
 {
        struct IO_APIC_route_entry entry;
        unsigned long flags;
@@ -1287,8 +1317,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
         * Add it to the IO-APIC irq-routing table:
         */
        spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
-       io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+       io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
+       io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        enable_8259A_irq(0);
@@ -1595,7 +1625,8 @@ void /*__init*/ print_PIC(void)
 static void __init enable_IO_APIC(void)
 {
        union IO_APIC_reg_01 reg_01;
-       int i;
+       int i8259_apic, i8259_pin;
+       int i, apic;
        unsigned long flags;
 
        for (i = 0; i < PIN_MAP_SIZE; i++) {
@@ -1609,11 +1640,52 @@ static void __init enable_IO_APIC(void)
        /*
         * The number of IO-APIC IRQ registers (== #pins):
         */
-       for (i = 0; i < nr_ioapics; i++) {
+       for (apic = 0; apic < nr_ioapics; apic++) {
                spin_lock_irqsave(&ioapic_lock, flags);
-               reg_01.raw = io_apic_read(i, 1);
+               reg_01.raw = io_apic_read(apic, 1);
                spin_unlock_irqrestore(&ioapic_lock, flags);
-               nr_ioapic_registers[i] = reg_01.bits.entries+1;
+               nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+       }
+       for(apic = 0; apic < nr_ioapics; apic++) {
+               int pin;
+               /* See if any of the pins is in ExtINT mode */
+               for(pin = 0; pin < nr_ioapic_registers[i]; pin++) {
+                       struct IO_APIC_route_entry entry;
+                       spin_lock_irqsave(&ioapic_lock, flags);
+                       *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+                       *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+                       spin_unlock_irqrestore(&ioapic_lock, flags);
+
+
+                       /* If the interrupt line is enabled and in ExtInt mode
+                        * I have found the pin where the i8259 is connected.
+                        */
+                       if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
+                               ioapic_i8259.apic = apic;
+                               ioapic_i8259.pin  = pin;
+                               goto found_i8259;
+                       }
+               }
+       }
+ found_i8259:
+       /* Look to see what if the MP table has reported the ExtINT */
+       /* If we could not find the appropriate pin by looking at the ioapic
+        * the i8259 probably is not connected the ioapic but give the
+        * mptable a chance anyway.
+        */
+       i8259_pin  = find_isa_irq_pin(0, mp_ExtINT);
+       i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
+       /* Trust the MP table if nothing is setup in the hardware */
+       if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
+               printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
+               ioapic_i8259.pin  = i8259_pin;
+               ioapic_i8259.apic = i8259_apic;
+       }
+       /* Complain if the MP table and the hardware disagree */
+       if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
+               (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
+       {
+               printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
        }
 
        /*
@@ -1627,7 +1699,6 @@ static void __init enable_IO_APIC(void)
  */
 void disable_IO_APIC(void)
 {
-       int pin;
        /*
         * Clear the IO-APIC before rebooting:
         */
@@ -1638,8 +1709,7 @@ void disable_IO_APIC(void)
         * Put that IOAPIC in virtual wire mode
         * so legacy interrupts can be delivered.
         */
-       pin = find_isa_irq_pin(0, mp_ExtINT);
-       if (pin != -1) {
+       if (ioapic_i8259.pin != -1) {
                struct IO_APIC_route_entry entry;
                unsigned long flags;
 
@@ -1650,7 +1720,7 @@ void disable_IO_APIC(void)
                entry.polarity        = 0; /* High */
                entry.delivery_status = 0;
                entry.dest_mode       = 0; /* Physical */
-               entry.delivery_mode   = 7; /* ExtInt */
+               entry.delivery_mode   = dest_ExtINT; /* ExtInt */
                entry.vector          = 0;
                entry.dest.physical.physical_dest = 0;
 
@@ -1659,11 +1729,13 @@ void disable_IO_APIC(void)
                 * Add it to the IO-APIC irq-routing table:
                 */
                spin_lock_irqsave(&ioapic_lock, flags);
-               io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
-               io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+               io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
+                       *(((int *)&entry)+1));
+               io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
+                       *(((int *)&entry)+0));
                spin_unlock_irqrestore(&ioapic_lock, flags);
        }
-       disconnect_bsp_APIC(pin != -1);
+       disconnect_bsp_APIC(ioapic_i8259.pin != -1);
 }
 
 /*
@@ -2113,20 +2185,21 @@ static void setup_nmi (void)
  */
 static inline void unlock_ExtINT_logic(void)
 {
-       int pin, i;
+       int apic, pin, i;
        struct IO_APIC_route_entry entry0, entry1;
        unsigned char save_control, save_freq_select;
        unsigned long flags;
 
-       pin = find_isa_irq_pin(8, mp_INT);
+       pin  = find_isa_irq_pin(8, mp_INT);
+       apic = find_isa_irq_apic(8, mp_INT);
        if (pin == -1)
                return;
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
-       *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
+       *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+       *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
        spin_unlock_irqrestore(&ioapic_lock, flags);
-       clear_IO_APIC_pin(0, pin);
+       clear_IO_APIC_pin(apic, pin);
 
        memset(&entry1, 0, sizeof(entry1));
 
@@ -2139,8 +2212,8 @@ static inline void unlock_ExtINT_logic(void)
        entry1.vector = 0;
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
-       io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
+       io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
+       io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        save_control = CMOS_READ(RTC_CONTROL);
@@ -2158,11 +2231,11 @@ static inline void unlock_ExtINT_logic(void)
 
        CMOS_WRITE(save_control, RTC_CONTROL);
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-       clear_IO_APIC_pin(0, pin);
+       clear_IO_APIC_pin(apic, pin);
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
-       io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
+       io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
+       io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -2174,7 +2247,7 @@ static inline void unlock_ExtINT_logic(void)
  */
 static inline void check_timer(void)
 {
-       int pin1, pin2;
+       int apic1, pin1, apic2, pin2;
        int vector;
 
        /*
@@ -2196,10 +2269,13 @@ static inline void check_timer(void)
        timer_ack = 1;
        enable_8259A_irq(0);
 
-       pin1 = find_isa_irq_pin(0, mp_INT);
-       pin2 = find_isa_irq_pin(0, mp_ExtINT);
+       pin1  = find_isa_irq_pin(0, mp_INT);
+       apic1 = find_isa_irq_apic(0, mp_INT);
+       pin2  = ioapic_i8259.pin;
+       apic2 = ioapic_i8259.apic;
 
-       printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
+       printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n",
+               vector, apic1, pin1, apic2, pin2);
 
        if (pin1 != -1) {
                /*
@@ -2216,8 +2292,9 @@ static inline void check_timer(void)
                                clear_IO_APIC_pin(0, pin1);
                        return;
                }
-               clear_IO_APIC_pin(0, pin1);
-               printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
+               clear_IO_APIC_pin(apic1, pin1);
+               printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to "
+                               "IO-APIC\n");
        }
 
        printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
@@ -2226,13 +2303,13 @@ static inline void check_timer(void)
                /*
                 * legacy devices should be connected to IO APIC #0
                 */
-               setup_ExtINT_IRQ0_pin(pin2, vector);
+               setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
                if (timer_irq_works()) {
                        printk("works.\n");
                        if (pin1 != -1)
-                               replace_pin_at_irq(0, 0, pin1, 0, pin2);
+                               replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
                        else
-                               add_pin_to_irq(0, 0, pin2);
+                               add_pin_to_irq(0, apic2, pin2);
                        if (nmi_watchdog == NMI_IO_APIC) {
                                setup_nmi();
                        }
@@ -2241,7 +2318,7 @@ static inline void check_timer(void)
                /*
                 * Cleanup, just in case ...
                 */
-               clear_IO_APIC_pin(0, pin2);
+               clear_IO_APIC_pin(apic2, pin2);
        }
        printk(" failed.\n");
 
@@ -2310,11 +2387,15 @@ void __init setup_IO_APIC(void)
        sync_Arb_IDs();
        setup_IO_APIC_irqs();
        init_IO_APIC_traps();
-       check_timer();
        if (!acpi_ioapic)
                print_IO_APIC();
 }
 
+void __init IO_APIC_late_time_init(void)
+{
+       check_timer();
+}
+
 /*
  *     Called after all the initialization is done. If we didnt find any
  *     APIC bugs then we can allow the modify fast path
index ce66dcc26d9072cf14bea63c83ae1db8ddde1934..1a201a9328659930d41ade1ccc5aa7f1ef977455 100644 (file)
@@ -218,7 +218,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
        if (i == 0) {
                seq_printf(p, "           ");
-               for_each_cpu(j)
+               for_each_online_cpu(j)
                        seq_printf(p, "CPU%d       ",j);
                seq_putc(p, '\n');
        }
@@ -232,7 +232,7 @@ int show_interrupts(struct seq_file *p, void *v)
 #ifndef CONFIG_SMP
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-               for_each_cpu(j)
+               for_each_online_cpu(j)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
                seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -246,12 +246,12 @@ skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
        } else if (i == NR_IRQS) {
                seq_printf(p, "NMI: ");
-               for_each_cpu(j)
+               for_each_online_cpu(j)
                        seq_printf(p, "%10u ", nmi_count(j));
                seq_putc(p, '\n');
 #ifdef CONFIG_X86_LOCAL_APIC
                seq_printf(p, "LOC: ");
-               for_each_cpu(j)
+               for_each_online_cpu(j)
                        seq_printf(p, "%10u ",
                                per_cpu(irq_stat,j).apic_timer_irqs);
                seq_putc(p, '\n');
index 27aabfceb67ec3c90800c7fe9b06f7ee5bfc153d..8f767d9aa45d73286af9f8a8a92b2fe901b33608 100644 (file)
@@ -69,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
 /* Internal processor count */
-static unsigned int __initdata num_processors;
+static unsigned int __devinitdata num_processors;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
@@ -119,7 +119,7 @@ static int MP_valid_apicid(int apicid, int version)
 }
 #endif
 
-static void __init MP_processor_info (struct mpc_config_processor *m)
+static void __devinit MP_processor_info (struct mpc_config_processor *m)
 {
        int ver, apicid;
        physid_mask_t phys_cpu;
@@ -182,17 +182,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                boot_cpu_physical_apicid = m->mpc_apicid;
        }
 
-       if (num_processors >= NR_CPUS) {
-               printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
-                       "  Processor ignored.\n", NR_CPUS); 
-               return;
-       }
-
-       if (num_processors >= maxcpus) {
-               printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
-                       " Processor ignored.\n", maxcpus); 
-               return;
-       }
        ver = m->mpc_apicver;
 
        if (!MP_valid_apicid(apicid, ver)) {
@@ -201,11 +190,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                return;
        }
 
-       cpu_set(num_processors, cpu_possible_map);
-       num_processors++;
-       phys_cpu = apicid_to_cpu_present(apicid);
-       physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
-
        /*
         * Validate version
         */
@@ -216,6 +200,25 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                ver = 0x10;
        }
        apic_version[m->mpc_apicid] = ver;
+
+       phys_cpu = apicid_to_cpu_present(apicid);
+       physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu);
+
+       if (num_processors >= NR_CPUS) {
+               printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+                       "  Processor ignored.\n", NR_CPUS);
+               return;
+       }
+
+       if (num_processors >= maxcpus) {
+               printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+                       " Processor ignored.\n", maxcpus);
+               return;
+       }
+
+       cpu_set(num_processors, cpu_possible_map);
+       num_processors++;
+
        if ((num_processors > 8) &&
            APIC_XAPIC(ver) &&
            (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
@@ -834,7 +837,7 @@ void __init mp_register_lapic_address (
 }
 
 
-void __init mp_register_lapic (
+void __devinit mp_register_lapic (
        u8                      id, 
        u8                      enabled)
 {
index 72515b8a1b129bf6a6b69c01fb4441ad0fce2956..d661703ac1cb713db7327de628e4f7f5b09efcb1 100644 (file)
@@ -100,16 +100,44 @@ int nmi_active;
        (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|     \
         P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
 
+#ifdef CONFIG_SMP
+/* The performance counters used by NMI_LOCAL_APIC don't trigger when
+ * the CPU is idle. To make sure the NMI watchdog really ticks on all
+ * CPUs during the test make them busy.
+ */
+static __init void nmi_cpu_busy(void *data)
+{
+       volatile int *endflag = data;
+       local_irq_enable();
+       /* Intentionally don't use cpu_relax here. This is
+          to make sure that the performance counter really ticks,
+          even if there is a simulator or similar that catches the
+          pause instruction. On a real HT machine this is fine because
+          all other CPUs are busy with "useless" delay loops and don't
+          care if they get somewhat less cycles. */
+       while (*endflag == 0)
+               barrier();
+}
+#endif
+
 static int __init check_nmi_watchdog(void)
 {
-       unsigned int prev_nmi_count[NR_CPUS];
+       volatile int endflag = 0;
+       unsigned int *prev_nmi_count;
        int cpu;
 
        if (nmi_watchdog == NMI_NONE)
                return 0;
 
+       prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
+       if (!prev_nmi_count)
+               return -1;
+
        printk(KERN_INFO "Testing NMI watchdog ... ");
 
+       if (nmi_watchdog == NMI_LOCAL_APIC)
+               smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
+
        for (cpu = 0; cpu < NR_CPUS; cpu++)
                prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
        local_irq_enable();
@@ -123,12 +151,18 @@ static int __init check_nmi_watchdog(void)
                        continue;
 #endif
                if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
-                       printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+                       endflag = 1;
+                       printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
+                               cpu,
+                               prev_nmi_count[cpu],
+                               nmi_count(cpu));
                        nmi_active = 0;
                        lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG;
+                       kfree(prev_nmi_count);
                        return -1;
                }
        }
+       endflag = 1;
        printk("OK.\n");
 
        /* now that we know it works we can reduce NMI frequency to
@@ -136,6 +170,7 @@ static int __init check_nmi_watchdog(void)
        if (nmi_watchdog == NMI_LOCAL_APIC)
                nmi_hz = 1;
 
+       kfree(prev_nmi_count);
        return 0;
 }
 /* This needs to happen later in boot so counters are working */
index 7b6368bf89746eaffc913d0c73e8b50d34ef15c4..efd11f09c99663208a14e918d69fe2a607b666fe 100644 (file)
@@ -354,7 +354,7 @@ ptrace_set_thread_area(struct task_struct *child,
        return 0;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        struct user * dummy = NULL;
index 1b183b378c2c269ac06c05d2ba622fe0dad0884a..c9b87330aeeacfb49009faa725f51c1343d3a308 100644 (file)
@@ -44,7 +44,7 @@ void mach_reboot_fixups(void)
 
        for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
                cur = &(fixups_table[i]);
-               dev = pci_get_device(cur->vendor, cur->device, 0);
+               dev = pci_get_device(cur->vendor, cur->device, NULL);
                if (!dev)
                        continue;
 
index 9b8c8a19824de64c9a308177e11f55df3974099c..b48ac635f3c19cb79d11086835b538cc0b1dcf00 100644 (file)
@@ -389,14 +389,24 @@ static void __init limit_regions(unsigned long long size)
                }
        }
        for (i = 0; i < e820.nr_map; i++) {
-               if (e820.map[i].type == E820_RAM) {
-                       current_addr = e820.map[i].addr + e820.map[i].size;
-                       if (current_addr >= size) {
-                               e820.map[i].size -= current_addr-size;
-                               e820.nr_map = i + 1;
-                               return;
-                       }
+               current_addr = e820.map[i].addr + e820.map[i].size;
+               if (current_addr < size)
+                       continue;
+
+               if (e820.map[i].type != E820_RAM)
+                       continue;
+
+               if (e820.map[i].addr >= size) {
+                       /*
+                        * This region starts past the end of the
+                        * requested size, skip it completely.
+                        */
+                       e820.nr_map = i;
+               } else {
+                       e820.nr_map = i + 1;
+                       e820.map[i].size -= current_addr - size;
                }
+               return;
        }
 }
 
index 1fb26d0e30b6b79d243de220cab1859f3729e82e..5a2bbe0c4ffff7ffcc5344d3d7015bd6651061d8 100644 (file)
@@ -87,7 +87,11 @@ EXPORT_SYMBOL(cpu_online_map);
 cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
 EXPORT_SYMBOL(cpu_callout_map);
+#ifdef CONFIG_HOTPLUG_CPU
+cpumask_t cpu_possible_map = CPU_MASK_ALL;
+#else
 cpumask_t cpu_possible_map;
+#endif
 EXPORT_SYMBOL(cpu_possible_map);
 static cpumask_t smp_commenced_mask;
 
@@ -1074,6 +1078,16 @@ void *xquad_portio;
 EXPORT_SYMBOL(xquad_portio);
 #endif
 
+/*
+ * Fall back to non SMP mode after errors.
+ *
+ */
+static __init void disable_smp(void)
+{
+       cpu_set(0, cpu_sibling_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+}
+
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
        int apicid, cpu, bit, kicked;
@@ -1086,7 +1100,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        printk("CPU%d: ", 0);
        print_cpu_info(&cpu_data[0]);
 
-       boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
        boot_cpu_logical_apicid = logical_smp_processor_id();
        x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
 
@@ -1098,68 +1111,27 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        cpus_clear(cpu_core_map[0]);
        cpu_set(0, cpu_core_map[0]);
 
+       map_cpu_to_logical_apicid();
+
        /*
         * If we couldn't find an SMP configuration at boot time,
         * get out of here now!
         */
        if (!smp_found_config && !acpi_lapic) {
                printk(KERN_NOTICE "SMP motherboard not detected.\n");
-               smpboot_clear_io_apic_irqs();
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               if (APIC_init_uniprocessor())
-                       printk(KERN_NOTICE "Local APIC not detected."
-                                          " Using dummy APIC emulation.\n");
-               map_cpu_to_logical_apicid();
-               cpu_set(0, cpu_sibling_map[0]);
-               cpu_set(0, cpu_core_map[0]);
+               disable_smp();
                return;
        }
 
-       /*
-        * Should not be necessary because the MP table should list the boot
-        * CPU too, but we do it for the sake of robustness anyway.
-        * Makes no sense to do this check in clustered apic mode, so skip it
-        */
-       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
-               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
-                               boot_cpu_physical_apicid);
-               physid_set(hard_smp_processor_id(), phys_cpu_present_map);
-       }
-
-       /*
-        * If we couldn't find a local APIC, then get out of here now!
-        */
-       if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
-               printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
-                       boot_cpu_physical_apicid);
-               printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
-               smpboot_clear_io_apic_irqs();
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               cpu_set(0, cpu_sibling_map[0]);
-               cpu_set(0, cpu_core_map[0]);
-               return;
-       }
-
-       verify_local_APIC();
-
        /*
         * If SMP should be disabled, then really disable it!
         */
-       if (!max_cpus) {
-               smp_found_config = 0;
-               printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
-               smpboot_clear_io_apic_irqs();
-               phys_cpu_present_map = physid_mask_of_physid(0);
-               cpu_set(0, cpu_sibling_map[0]);
-               cpu_set(0, cpu_core_map[0]);
+       if (!max_cpus || (enable_local_apic < 0)) {
+               printk(KERN_INFO "SMP mode deactivated.\n");
+               disable_smp();
                return;
        }
 
-       connect_bsp_APIC();
-       setup_local_APIC();
-       map_cpu_to_logical_apicid();
-
-
        setup_portio_remap();
 
        /*
@@ -1240,10 +1212,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        cpu_set(0, cpu_sibling_map[0]);
        cpu_set(0, cpu_core_map[0]);
 
-       smpboot_setup_io_apic();
-
-       setup_boot_APIC_clock();
-
        /*
         * Synchronize the TSC with the AP
         */
index 516bf5653b0266ea1f4beb9258bd6577c0b3e6ab..8de658db814624b012cf31cd387d461cf1605686 100644 (file)
@@ -327,7 +327,12 @@ int __init get_memcfg_from_srat(void)
        int tables = 0;
        int i = 0;
 
-       acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING, rsdp_address);
+       if (ACPI_FAILURE(acpi_find_root_pointer(ACPI_PHYSICAL_ADDRESSING,
+                                               rsdp_address))) {
+               printk("%s: System description tables not found\n",
+                      __FUNCTION__);
+               goto out_err;
+       }
 
        if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
                printk("%s: assigning address to rsdp\n", __FUNCTION__);
index 2883a4d4f01f824bfdc48457b82f3c0212b2690c..07471bba2dc6a7d10b28a09ef0c2ae119444f797 100644 (file)
@@ -74,10 +74,6 @@ int pit_latch_buggy;              /* extern */
 
 #include "do_timer.h"
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 unsigned int cpu_khz;  /* Detected as we calibrate the TSC */
 EXPORT_SYMBOL(cpu_khz);
 
@@ -444,8 +440,8 @@ static int time_init_device(void)
 
 device_initcall(time_init_device);
 
-#ifdef CONFIG_HPET_TIMER
 extern void (*late_time_init)(void);
+#ifdef CONFIG_HPET_TIMER
 /* Duplicate of time_init() below, with hpet_enable part added */
 static void __init hpet_time_init(void)
 {
@@ -462,6 +458,11 @@ static void __init hpet_time_init(void)
        printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
        time_init_hook();
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       if (enable_local_apic >= 0)
+               APIC_late_time_init();
+#endif
 }
 #endif
 
@@ -486,4 +487,9 @@ void __init time_init(void)
        printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
        time_init_hook();
+
+#ifdef CONFIG_X86_LOCAL_APIC
+       if (enable_local_apic >= 0)
+               late_time_init = APIC_late_time_init;
+#endif
 }
index 658c0629ba6aa9e9d2062cd9111ba14a3b888e0c..9caeaa315cd7c00157ba7621a8c2082e116cfa68 100644 (file)
@@ -275,6 +275,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
 static unsigned long PIE_count;
 
 static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
 
 /*
  * Timer 1 for RTC, we do not use periodic interrupt feature,
@@ -306,10 +307,12 @@ int hpet_rtc_timer_init(void)
        cnt = hpet_readl(HPET_COUNTER);
        cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
        hpet_writel(cnt, HPET_T1_CMP);
+       hpet_t1_cmp = cnt;
        local_irq_restore(flags);
 
        cfg = hpet_readl(HPET_T1_CFG);
-       cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+       cfg &= ~HPET_TN_PERIODIC;
+       cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
        hpet_writel(cfg, HPET_T1_CFG);
 
        return 1;
@@ -319,8 +322,12 @@ static void hpet_rtc_timer_reinit(void)
 {
        unsigned int cfg, cnt;
 
-       if (!(PIE_on | AIE_on | UIE_on))
+       if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+               cfg = hpet_readl(HPET_T1_CFG);
+               cfg &= ~HPET_TN_ENABLE;
+               hpet_writel(cfg, HPET_T1_CFG);
                return;
+       }
 
        if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
                hpet_rtc_int_freq = PIE_freq;
@@ -328,15 +335,10 @@ static void hpet_rtc_timer_reinit(void)
                hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
 
        /* It is more accurate to use the comparator value than current count.*/
-       cnt = hpet_readl(HPET_T1_CMP);
+       cnt = hpet_t1_cmp;
        cnt += hpet_tick*HZ/hpet_rtc_int_freq;
        hpet_writel(cnt, HPET_T1_CMP);
-
-       cfg = hpet_readl(HPET_T1_CFG);
-       cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
-       hpet_writel(cfg, HPET_T1_CFG);
-
-       return;
+       hpet_t1_cmp = cnt;
 }
 
 /*
index d973a8b681fd5256d75212e77e43131141e07641..be242723c33988fc2cf8222ea20430554e775c89 100644 (file)
@@ -30,23 +30,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
  *  basic equation:
  *             ns = cycles / (freq / ns_per_sec)
  *             ns = cycles * (ns_per_sec / freq)
- *             ns = cycles * (10^9 / (cpu_mhz * 10^6))
- *             ns = cycles * (10^3 / cpu_mhz)
+ *             ns = cycles * (10^9 / (cpu_khz * 10^3))
+ *             ns = cycles * (10^6 / cpu_khz)
  *
  *     Then we use scaling math (suggested by george@mvista.com) to get:
- *             ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ *             ns = cycles * (10^6 * SC / cpu_khz) / SC
  *             ns = cycles * cyc2ns_scale / SC
  *
  *     And since SC is a constant power of two, we can convert the div
  *  into a shift.
+ *
+ *  We can use khz divisor instead of mhz to keep a better percision, since
+ *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ *  (mathieu.desnoyers@polymtl.ca)
+ *
  *                     -johnstul@us.ibm.com "math is hard, lets go shopping!"
  */
 static unsigned long cyc2ns_scale;
 #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
 
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
 {
-       cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+       cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
 }
 
 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -163,7 +168,7 @@ static int __init init_hpet(char* override)
                                printk("Detected %u.%03u MHz processor.\n",
                                        cpu_khz / 1000, cpu_khz % 1000);
                        }
-                       set_cyc2ns_scale(cpu_khz/1000);
+                       set_cyc2ns_scale(cpu_khz);
                }
                /* set this only when cpu_has_tsc */
                timer_hpet.read_timer = read_timer_tsc;
index 6dd470cc9f72a2e6e71264c988112bd1ef11e2a7..d395e3b42485f68fafa1d7f73ca9a44273a0827c 100644 (file)
@@ -49,23 +49,28 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
  *  basic equation:
  *             ns = cycles / (freq / ns_per_sec)
  *             ns = cycles * (ns_per_sec / freq)
- *             ns = cycles * (10^9 / (cpu_mhz * 10^6))
- *             ns = cycles * (10^3 / cpu_mhz)
+ *             ns = cycles * (10^9 / (cpu_khz * 10^3))
+ *             ns = cycles * (10^6 / cpu_khz)
  *
  *     Then we use scaling math (suggested by george@mvista.com) to get:
- *             ns = cycles * (10^3 * SC / cpu_mhz) / SC
+ *             ns = cycles * (10^6 * SC / cpu_khz) / SC
  *             ns = cycles * cyc2ns_scale / SC
  *
  *     And since SC is a constant power of two, we can convert the div
- *  into a shift.   
+ *  into a shift.
+ *
+ *  We can use khz divisor instead of mhz to keep a better percision, since
+ *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
+ *  (mathieu.desnoyers@polymtl.ca)
+ *
  *                     -johnstul@us.ibm.com "math is hard, lets go shopping!"
  */
 static unsigned long cyc2ns_scale; 
 #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
 
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
 {
-       cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+       cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
 }
 
 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -286,7 +291,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
                if (use_tsc) {
                        if (!(freq->flags & CPUFREQ_CONST_LOOPS)) {
                                fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
-                               set_cyc2ns_scale(cpu_khz/1000);
+                               set_cyc2ns_scale(cpu_khz);
                        }
                }
 #endif
@@ -536,7 +541,7 @@ static int __init init_tsc(char* override)
                                printk("Detected %u.%03u MHz processor.\n",
                                        cpu_khz / 1000, cpu_khz % 1000);
                        }
-                       set_cyc2ns_scale(cpu_khz/1000);
+                       set_cyc2ns_scale(cpu_khz);
                        return 0;
                }
        }
index 19e90bdd84eac1834efe26127429b0cec15f1670..c34d1bfc51619b0ee978740d34ffad9d6dd499bb 100644 (file)
@@ -488,6 +488,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
                                tss->io_bitmap_max - thread->io_bitmap_max);
                tss->io_bitmap_max = thread->io_bitmap_max;
                tss->io_bitmap_base = IO_BITMAP_OFFSET;
+               tss->io_bitmap_owner = thread;
                put_cpu();
                return;
        }
index 898ed905e1195638c9e39594d0cd5495bd1a3d59..f1e3204f5deca799b82060afdfd0666eb13d20df 100644 (file)
  * http://www.unisys.com
  */
 
+/*
+ * ES7000 chipsets
+ */
+
+#define NON_UNISYS             0
+#define ES7000_CLASSIC         1
+#define ES7000_ZORRO           2
+
+
 #define        MIP_REG                 1
 #define        MIP_PSAI_REG            4
 
@@ -106,6 +115,6 @@ struct mip_reg {
 
 extern int parse_unisys_oem (char *oemptr);
 extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys ();
+extern void setup_unisys(void);
 extern int es7000_start_cpu(int cpu, unsigned long eip);
 extern void es7000_sw_apic(void);
index dc6660511b075e2b10292c5343a0a2b65a3eddbc..a9ab0644f4035fd6b6e8e16b5054e09e663d117b 100644 (file)
@@ -62,6 +62,9 @@ static unsigned int base;
 static int
 es7000_rename_gsi(int ioapic, int gsi)
 {
+       if (es7000_plat == ES7000_ZORRO)
+               return gsi;
+
        if (!base) {
                int i;
                for (i = 0; i < nr_ioapics; i++)
@@ -76,7 +79,7 @@ es7000_rename_gsi(int ioapic, int gsi)
 #endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
 
 void __init
-setup_unisys ()
+setup_unisys(void)
 {
        /*
         * Determine the generation of the ES7000 currently running.
@@ -86,9 +89,9 @@ setup_unisys ()
         *
         */
        if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2))
-               es7000_plat = 2;
+               es7000_plat = ES7000_ZORRO;
        else
-               es7000_plat = 1;
+               es7000_plat = ES7000_CLASSIC;
        ioapic_renumber_irq = es7000_rename_gsi;
 }
 
@@ -151,7 +154,7 @@ parse_unisys_oem (char *oemptr)
        }
 
        if (success < 2) {
-               es7000_plat = 0;
+               es7000_plat = NON_UNISYS;
        } else
                setup_unisys();
        return es7000_plat;
index 9edd4485b91eafd6396affe5649c92d00b8666ae..cf572d9a3b6e253273e08594eab6b9cd4c4d64ad 100644 (file)
@@ -108,7 +108,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
                desc = (void *)desc + (seg & ~7);
        } else {
                /* Must disable preemption while reading the GDT. */
-               desc = (u32 *)&per_cpu(cpu_gdt_table, get_cpu());
+               desc = (u32 *)get_cpu_gdt_table(get_cpu());
                desc = (void *)desc + (seg & ~7);
        }
 
index cddafe33ff7c522ca007569e0d73faade5465fc7..19e6f4871d1e7d09bace430522315c5e25fafff9 100644 (file)
@@ -547,31 +547,48 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
        return 0;
 }
 
-static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+static __init int via_router_probe(struct irq_router *r,
+                               struct pci_dev *router, u16 device)
 {
        /* FIXME: We should move some of the quirk fixup stuff here */
 
-       if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
-                       device == PCI_DEVICE_ID_VIA_82C586_0) {
-               /* Asus k7m bios wrongly reports 82C686A as 586-compatible */
-               device = PCI_DEVICE_ID_VIA_82C686;
+       /*
+        * work arounds for some buggy BIOSes
+        */
+       if (device == PCI_DEVICE_ID_VIA_82C586_0) {
+               switch(router->device) {
+               case PCI_DEVICE_ID_VIA_82C686:
+                       /*
+                        * Asus k7m bios wrongly reports 82C686A
+                        * as 586-compatible
+                        */
+                       device = PCI_DEVICE_ID_VIA_82C686;
+                       break;
+               case PCI_DEVICE_ID_VIA_8235:
+                       /**
+                        * Asus a7v-x bios wrongly reports 8235
+                        * as 586-compatible
+                        */
+                       device = PCI_DEVICE_ID_VIA_8235;
+                       break;
+               }
        }
 
-       switch(device)
-       {
-               case PCI_DEVICE_ID_VIA_82C586_0:
-                       r->name = "VIA";
-                       r->get = pirq_via586_get;
-                       r->set = pirq_via586_set;
-                       return 1;
-               case PCI_DEVICE_ID_VIA_82C596:
-               case PCI_DEVICE_ID_VIA_82C686:
-               case PCI_DEVICE_ID_VIA_8231:
+       switch(device) {
+       case PCI_DEVICE_ID_VIA_82C586_0:
+               r->name = "VIA";
+               r->get = pirq_via586_get;
+               r->set = pirq_via586_set;
+               return 1;
+       case PCI_DEVICE_ID_VIA_82C596:
+       case PCI_DEVICE_ID_VIA_82C686:
+       case PCI_DEVICE_ID_VIA_8231:
+       case PCI_DEVICE_ID_VIA_8235:
                /* FIXME: add new ones for 8233/5 */
-                       r->name = "VIA";
-                       r->get = pirq_via_get;
-                       r->set = pirq_via_set;
-                       return 1;
+               r->name = "VIA";
+               r->get = pirq_via_get;
+               r->set = pirq_via_set;
+               return 1;
        }
        return 0;
 }
index b27c5acc79d01fbd5ef053add840609bb4215365..1f1572692e0b7eeaa9c318a5051c98f4d8de2402 100644 (file)
@@ -51,16 +51,14 @@ void save_processor_state(void)
        __save_processor_state(&saved_context);
 }
 
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
 {
-        /* restore FPU regs if necessary */
-       /* Do it out of line so that gcc does not move cr0 load to some stupid place */
-        kernel_fpu_end();
-       mxcsr_feature_mask_init();
+       /*
+        * Restore FPU regs if necessary.
+        */
+       kernel_fpu_end();
 }
 
-
 static void fix_processor_context(void)
 {
        int cpu = smp_processor_id();
index 3fa67ecebc838043c99fab4589e9d334dbd31604..dc282710421a18b71053a3ecb86f9ae8f778f129 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/uio.h>
 #include <linux/nfs_fs.h>
 #include <linux/quota.h>
+#include <linux/syscalls.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
index 768c7e46957c0ed4a8da581c1c8315041d06d13f..6ade3790ce07967ae09a3d65a1810c399ea5495c 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/smp.h>
 #include <linux/time.h>
 #include <linux/errno.h>
+#include <linux/timex.h>
 #include <asm/io.h>
 
 /* IBM Summit (EXA) Cyclone counter code*/
index 8b8a5a45b621cffed8fb384e5e272c0fdd1a8ecb..5b7e736f3b4924beb5e779a92b3c93a7f2a606f2 100644 (file)
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 #define TIME_KEEPER_ID 0       /* smp_processor_id() of time-keeper */
 
 #ifdef CONFIG_IA64_DEBUG_IRQ
index 85920fb8d08c1541642a66670da6ad7661274199..396c94218cc215441f9431e73ab27ee15b22b3e0 100644 (file)
@@ -653,8 +653,6 @@ ENTRY(rie_handler)
        SAVE_ALL
        mvfc    r0, bpc
        ld      r1, @r0
-       seth    r0, #0xa0f0
-       st      r1, @r0
        ldi     r1, #0x20                       ; error_code
        mv      r0, sp                          ; pt_regs
        bl      do_rie_handler
index e545b065f7e98e1f80f2a8f876b751aedd999ccb..eda9f963c1ebc38f5179be4a98cc8a9c922e3db5 100644 (file)
@@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsigned long port)
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART    0x300
-#define LAN_IOEND      0x320
+#define LAN_IOSTART    0xa0000300
+#define LAN_IOEND      0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+       return (void *)(port + 0x10000000);
 }
 static inline void *_port2addr_usb(unsigned long port)
 {
index 78033165fb5c7ecb489bb35a442654f8ce415ccc..3c3da042fbd1437a26cb11dcfaf081696c2cdfb5 100644 (file)
@@ -31,7 +31,7 @@ extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
 
 static inline void *_port2addr(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET);
+       return (void *)(port | (NONCACHE_OFFSET));
 }
 
 static inline void *_port2addr_ne(unsigned long port)
index 5c03504bf65375646880da8f8eadd973fabbbf24..df3c729cb3e0afc7d53cc84cc51b1545dc261495 100644 (file)
@@ -33,12 +33,9 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 static inline void *_port2addr(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET);
+       return (void *)(port | (NONCACHE_OFFSET));
 }
 
-#define LAN_IOSTART    0x300
-#define LAN_IOEND      0x320
-
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 static inline void *__port2addr_ata(unsigned long port)
 {
@@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsigned long port)
 }
 #endif
 
+#define LAN_IOSTART    0xa0000300
+#define LAN_IOEND      0xa0000320
 #ifdef CONFIG_CHIP_OPSP
 static inline void *_port2addr_ne(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+       return (void *)(port + 0x10000000);
 }
 #else
 static inline void *_port2addr_ne(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET + 0x04000000);
+       return (void *)(port + 0x04000000);
 }
 #endif
 static inline void *_port2addr_usb(unsigned long port)
index c80bde657854cbf62a7d5bc9adae8101e6857b6c..6716ffea769a17b9d4423acfd79ccbea81c060ca 100644 (file)
@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned long port)
        return (void *)(port + NONCACHE_OFFSET);
 }
 
-#define LAN_IOSTART    0x300
-#define LAN_IOEND      0x320
-
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 static inline void *__port2addr_ata(unsigned long port)
 {
@@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsigned long port)
 }
 #endif
 
+#define LAN_IOSTART    0xa0000300
+#define LAN_IOEND      0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+       return (void *)(port + 0x10000000);
 }
 
 static inline void *_port2addr_usb(unsigned long port)
index 9997dddd24d7ea8584bc5e66ae579b5249aca3e8..8be323931e4ab66d37397ebf8674fdbc5ad69fd9 100644 (file)
@@ -16,7 +16,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET);
+       return (void *)(port | (NONCACHE_OFFSET));
 }
 
 static inline  void *_port2addr_ne(unsigned long port)
index e34951e8156fe227e431fcad50289edf638653df..4793bd18e11599a187e1f1068cb6b80bc7c13c39 100644 (file)
@@ -36,7 +36,7 @@ extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
 
 static inline void *_port2addr(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET);
+       return (void *)(port | (NONCACHE_OFFSET));
 }
 
 /*
@@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned long port)
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART    0x300
-#define LAN_IOEND      0x320
+#define LAN_IOSTART    0xa0000300
+#define LAN_IOEND      0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-       return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+       return (void *)(port + 0x10000000);
 }
 static inline void *_port2addr_usb(unsigned long port)
 {
index 9eb161dcc1042ea86a0154a7ec2bc324773578cc..39a379af40bca621472910c097ba76310800b80d 100644 (file)
@@ -47,7 +47,7 @@ static inline void *_port2addr(unsigned long port)
        else if (port >= UART1_IOSTART && port <= UART1_IOEND)
                port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART;
 #endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */
-       return (void *)(port + NONCACHE_OFFSET);
+       return (void *)(port | (NONCACHE_OFFSET));
 }
 
 static inline void delay(void)
index 124f7c1b775e4c95dccdef47dd3ef458800a26b2..078d2a0e71c2669f3ce47673bc49e5857a03b3fc 100644 (file)
@@ -756,7 +756,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
        return ret;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index ec5674727e7f148c0b42fc4224143223a726d9a6..f722ec8eb021c6e48f19bc49829d026fdeda374a 100644 (file)
@@ -305,19 +305,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        seq_printf(m, "processor\t: %ld\n", cpu);
 
-#ifdef CONFIG_CHIP_VDEC2
+#if defined(CONFIG_CHIP_VDEC2)
        seq_printf(m, "cpu family\t: VDEC2\n"
                "cache size\t: Unknown\n");
-#elif  CONFIG_CHIP_M32700
+#elif defined(CONFIG_CHIP_M32700)
        seq_printf(m,"cpu family\t: M32700\n"
                "cache size\t: I-8KB/D-8KB\n");
-#elif  CONFIG_CHIP_M32102
+#elif defined(CONFIG_CHIP_M32102)
        seq_printf(m,"cpu family\t: M32102\n"
                "cache size\t: I-8KB\n");
-#elif  CONFIG_CHIP_OPSP
+#elif defined(CONFIG_CHIP_OPSP)
        seq_printf(m,"cpu family\t: OPSP\n"
                "cache size\t: I-8KB/D-8KB\n");
-#elif  CONFIG_CHIP_MP
+#elif defined(CONFIG_CHIP_MP)
        seq_printf(m, "cpu family\t: M32R-MP\n"
                "cache size\t: I-xxKB/D-xxKB\n");
 #else
@@ -326,19 +326,19 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        seq_printf(m, "bogomips\t: %lu.%02lu\n",
                c->loops_per_jiffy/(500000/HZ),
                (c->loops_per_jiffy/(5000/HZ)) % 100);
-#ifdef CONFIG_PLAT_MAPPI
+#if defined(CONFIG_PLAT_MAPPI)
        seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI2
+#elif defined(CONFIG_PLAT_MAPPI2)
        seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
-#elif CONFIG_PLAT_MAPPI3
+#elif defined(CONFIG_PLAT_MAPPI3)
        seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n");
-#elif  CONFIG_PLAT_M32700UT
+#elif defined(CONFIG_PLAT_M32700UT)
        seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
-#elif  CONFIG_PLAT_OPSPUT
+#elif defined(CONFIG_PLAT_OPSPUT)
        seq_printf(m, "Machine\t\t: OPSPUT Evaluation board\n");
-#elif  CONFIG_PLAT_USRV
+#elif defined(CONFIG_PLAT_USRV)
        seq_printf(m, "Machine\t\t: uServer\n");
-#elif  CONFIG_PLAT_OAKS32R
+#elif defined(CONFIG_PLAT_OAKS32R)
        seq_printf(m, "Machine\t\t: OAKS32R\n");
 #else
        seq_printf(m, "Machine\t\t: Unknown\n");
index 539c562cd54de57b04eb45f59ea5bea9fc3f0012..2ebce2063fea3038d4875db603b5ebd72d8758ae 100644 (file)
@@ -39,10 +39,6 @@ extern void send_IPI_allbutself(int, int);
 extern void smp_local_timer_interrupt(struct pt_regs *);
 #endif
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 extern unsigned long wall_jiffies;
 #define TICK_SIZE      (tick_nsec / 1000)
 
index ddb16a83a8ce4621af77840971e24e9868e8bb99..3d5f06145854e3f7fda80b440c593daac9d294b8 100644 (file)
 
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/string.h>
 
 #include <net/checksum.h>
 #include <asm/byteorder.h>
-#include <asm/string.h>
 #include <asm/uaccess.h>
 
 /*
index 8ed1b01a6a8742a7d44dad74f96bf11d7e395558..f7f1d2e5b90bcec403526c14c1f183fc74d3fe4e 100644 (file)
@@ -121,7 +121,7 @@ void ptrace_disable(struct task_struct *child)
        child->thread.work.syscall_trace = 0;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        unsigned long tmp;
index 4ec95e3cb8748721ec6b37880d0a87aaf1b55f83..98e4b1adfa29f3836cf69ddd339f02017669bff5 100644 (file)
 #include <linux/timex.h>
 #include <linux/profile.h>
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 static inline int set_rtc_mmss(unsigned long nowtime)
 {
   if (mach_set_clock_mmss)
index 9724e1cd82e5325dba472f78cb18554d165b70ba..621d7b91ccfe5147833dc47f1de8e8c6de79c1b7 100644 (file)
@@ -101,7 +101,7 @@ void ptrace_disable(struct task_struct *child)
        put_reg(child, PT_SR, tmp);
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index b17c1ecba966e103d36ad2f7108b4c28a16d2b1a..b9d8abb454301cb0a5b4081e67f49dfb4fb96ad2 100644 (file)
 
 #define        TICK_SIZE (tick_nsec / 1000)
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 extern unsigned long wall_jiffies;
 
 
index 7ce34d4aa220f0af0900b5e384892c673fe5dd75..10d3644e360863b1133a07fbb85b06880cc124c3 100644 (file)
@@ -1077,8 +1077,8 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
        struct elfhdr elf;
        off_t offset = 0, dataoff;
        int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
-       int numnote = 4;
-       struct memelfnote notes[4];
+       int numnote = 3;
+       struct memelfnote notes[3];
        struct elf_prstatus prstatus;   /* NT_PRSTATUS */
        elf_fpregset_t fpu;             /* NT_PRFPREG */
        struct elf_prpsinfo psinfo;     /* NT_PRPSINFO */
@@ -1211,20 +1211,15 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
        }
        strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));
 
-       notes[2].name = "CORE";
-       notes[2].type = NT_TASKSTRUCT;
-       notes[2].datasz = sizeof(*current);
-       notes[2].data = current;
-
        /* Try to dump the FPU. */
        prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
        if (!prstatus.pr_fpvalid) {
                numnote--;
        } else {
-               notes[3].name = "CORE";
-               notes[3].type = NT_PRFPREG;
-               notes[3].datasz = sizeof(fpu);
-               notes[3].data = &fpu;
+               notes[2].name = "CORE";
+               notes[2].type = NT_PRFPREG;
+               notes[2].datasz = sizeof(fpu);
+               notes[2].data = &fpu;
        }
 
        /* Write notes phdr entry. */
index fcceab8f2e009e1899e752c0b8289f0f1f64bee0..f1b0f3e1f95b4c1ebd0dcfd23cafaffb9824dc97 100644 (file)
@@ -174,7 +174,7 @@ int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
        return 0;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret;
index a24651dfaaba773b9c63a7476c5986292b73daa2..787ed541d442b2449947825dbdd480d55b6d80bf 100644 (file)
 
 #define TICK_SIZE      (tick_nsec / 1000)
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /*
  * forward reference
  */
index e1829a5d3b192fd38bcaa05302c0a6f716265273..07631a97670bd85897c9e9208b708a6200b87bd1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/signal.h>      /* for SIGBUS */
 
 #include <asm/module.h>
 #include <asm/sn/addrs.h>
index 8cad8f004f009fdecadb85ffb42bc8c1b3253e18..0a331104ad5675a0c8f9440e44d8bb63977996ad 100644 (file)
@@ -561,11 +561,6 @@ IOCTL_TABLE_START
 #define DECLARES
 #include "compat_ioctl.c"
 
-/* Might be moved to compat_ioctl.h with some ifdefs... */
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
-
 /* PA-specific ioctls */
 COMPATIBLE_IOCTL(PA_PERF_ON)
 COMPATIBLE_IOCTL(PA_PERF_OFF)
index f3428e5e86fb9fd25c2148d5c37c5fb390ea2a39..18130c3748f3e4a46c6632c93e6c5b449abd19aa 100644 (file)
@@ -78,7 +78,7 @@ void ptrace_disable(struct task_struct *child)
        pa_psw(child)->l = 0;
 }
 
-long sys_ptrace(long request, pid_t pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        long ret;
index bc979e1abdec4dbc936a715354b1f5b93f1aa43e..cded2568078741c3177f56b23ef64a3e4a9d2488 100644 (file)
 
 #include <linux/timex.h>
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /* xtime and wall_jiffies keep wall-clock time */
 extern unsigned long wall_jiffies;
 
index e7aee4108dea69985ba02507a78a46f227ba47da..e2744b6879da4a2158615558ccf5813ecdfc30b3 100644 (file)
@@ -240,7 +240,7 @@ void ptrace_disable(struct task_struct *child)
        clear_single_step(child);
 }
 
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret = -EPERM;
index 22d7fd1e0aea7e4e86851db796699ffa3c8f9bee..67797184f4eb3f99e9ae35147f8d6e438233997d 100644 (file)
 
 #include <asm/time.h>
 
-/* XXX false sharing with below? */
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 unsigned long disarm_decr[NR_CPUS];
 
 extern struct timezone sys_tz;
index ff3796860123ae46ec899ea5da0a9afcaeeb7bdd..eed4ff6903f1e4c3a2da0a8374b27755973aa76c 100644 (file)
@@ -609,11 +609,6 @@ static void parse_bootinfo(unsigned long r3,
 }
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-       return check_region(from, extent);
-}
-
 static void
 hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
 {
index 93c7231ea709295313de744788bdfa3d085134e9..85b8212516358652452a633087159cf04737afad 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
 #include <asm/errno.h>
 #include <asm/of_device.h>
 
index bde8f42da8543af7354d2ee3462651427a554720..4d584172055a6e923dc6d69e7a0b83c01b0b2019 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/slab.h>
+
 #include <asm/hvcall.h>
 #include <asm/hvcserver.h>
 #include <asm/io.h>
index a8005db23ec58d62f062e87b3267c460437792b3..ba4a899045c2b7738b193370144633110bb3dcd2 100644 (file)
@@ -39,9 +39,7 @@ IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
 #define DECLARES
 #include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
+
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
 COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
 COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
index 9f200f0f2ad54ae4eaac0fa7a7bc173d20200b87..3aabfd0d3dda845aff862ec079a56318a686c0d6 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+
 #include <asm/errno.h>
 #include <asm/of_device.h>
 
index b1c044ca57568d3aee5b4cc60286c8e22d6dbbb3..b33073c317244b6b4d17321d3963adca0d88eb1e 100644 (file)
@@ -53,7 +53,7 @@ void ptrace_disable(struct task_struct *child)
        clear_single_step(child);
 }
 
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret = -EPERM;
index b56c6a324e17f9c2b612ea1bebe0bbb62e2a5c69..ab565468578a4c6bd1db3c4d473036803963ffb4 100644 (file)
 #include <asm/systemcfg.h>
 #include <asm/firmware.h>
 
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
 extern int piranha_simulator;
index 033643ab69e0bfac4903c4544fbfc52f70ba8972..d622c1d58e4ee380963badde1047d2a2e05d59a5 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/spinlock.h>
 #include <linux/module.h>
 #include <linux/stringify.h>
+#include <linux/smp.h>
+
 #include <asm/hvcall.h>
 #include <asm/iSeries/HvCall.h>
 
index 24a1e9f069a7f0adb9ac9aab34fa6613243c0cd3..6504c4e69986783da98e0f27f26217587949dfe3 100644 (file)
@@ -18,6 +18,8 @@
 #include <asm/dasd.h>
 #include <asm/cmb.h>
 #include <asm/tape390.h>
+#include <asm/ccwdev.h>
+#include "../../../drivers/s390/char/raw3270.h"
 
 static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
                                unsigned long arg, struct file *f)
@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
 COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
 COMPATIBLE_IOCTL(BIODASDREADALLCMB)
 
+COMPATIBLE_IOCTL(TUBICMD)
+COMPATIBLE_IOCTL(TUBOCMD)
+COMPATIBLE_IOCTL(TUBGETI)
+COMPATIBLE_IOCTL(TUBGETO)
+COMPATIBLE_IOCTL(TUBSETMOD)
+COMPATIBLE_IOCTL(TUBGETMOD)
+
 COMPATIBLE_IOCTL(TAPE390_DISPLAY)
 
 /* s390 doesn't need handlers here */
index 55654b6e16dce24c38e6642b6ddd48724124f5b0..039354d72348eae678124fe62a9dc30dff2ac53f 100644 (file)
@@ -485,7 +485,9 @@ start:
 #
         .org  0x10000
 startup:basr  %r13,0                     # get base
-.LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+.LPG1: l     %r1, .Lget_ipl_device_addr-.LPG1(%r13)
+       basr  %r14, %r1
+       lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
        la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
                                         # move IPL device to lowcore
         mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
@@ -560,6 +562,9 @@ startup:basr  %r13,0                     # get base
        mr    %r2,%r1                   # mem size in bytes in %r3
        b     .Lfchunk-.LPG1(%r13)
 
+       .align 4
+.Lget_ipl_device_addr:
+       .long .Lget_ipl_device
 .Lpmask:
        .byte 0
 .align 8
@@ -755,6 +760,63 @@ _pstart:
        .global _pend
 _pend: 
 
+.Lget_ipl_device:
+       basr  %r12,0
+.LPG2: l     %r1,0xb8                  # get sid
+       sll   %r1,15                    # test if subchannel is enabled
+       srl   %r1,31
+       ltr   %r1,%r1
+       bz    0(%r14)                   # subchannel disabled
+       l     %r1,0xb8
+       la    %r5,.Lipl_schib-.LPG2(%r12)
+       stsch 0(%r5)                    # get schib of subchannel
+       bnz   0(%r14)                   # schib not available
+       tm    5(%r5),0x01               # devno valid?
+       bno   0(%r14)
+       la    %r6,ipl_parameter_flags-.LPG2(%r12)
+       oi    3(%r6),0x01               # set flag
+       la    %r2,ipl_devno-.LPG2(%r12)
+       mvc   0(2,%r2),6(%r5)           # store devno
+       tm    4(%r5),0x80               # qdio capable device?
+       bno   0(%r14)
+       oi    3(%r6),0x02               # set flag
+
+       # copy ipl parameters
+
+       lhi   %r0,4096
+       l     %r2,20(%r0)               # get address of parameter list
+       lhi   %r3,IPL_PARMBLOCK_ORIGIN
+       st    %r3,20(%r0)
+       lhi   %r4,1
+       cr    %r2,%r3                   # start parameters < destination ?
+       jl    0f
+       lhi   %r1,1                     # copy direction is upwards
+       j     1f
+0:     lhi   %r1,-1                    # copy direction is downwards
+       ar    %r2,%r0
+       ar    %r3,%r0
+       ar    %r2,%r1
+       ar    %r3,%r1
+1:     mvc   0(1,%r3),0(%r2)           # finally copy ipl parameters
+       ar    %r3,%r1
+       ar    %r2,%r1
+       sr    %r0,%r4
+       jne   1b
+       b     0(%r14)
+
+       .align 4
+.Lipl_schib:
+       .rept 13
+       .long 0
+       .endr
+
+       .globl ipl_parameter_flags
+ipl_parameter_flags:
+       .long 0
+       .globl ipl_devno
+ipl_devno:
+       .word 0
+
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
 #endif
@@ -764,11 +826,11 @@ _pend:
 #
         .globl _stext
 _stext:        basr  %r13,0                    # get base
-.LPG2:
+.LPG3:
 #
 # Setup stack
 #
-        l     %r15,.Linittu-.LPG2(%r13)
+        l     %r15,.Linittu-.LPG3(%r13)
        mvc   __LC_CURRENT(4),__TI_task(%r15)
         ahi   %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
         st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
@@ -782,8 +844,8 @@ _stext:     basr  %r13,0                    # get base
         lctl   %c0,%c15,0(%r15)
 
 #
-        lam    0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
-        l      %r14,.Lstart-.LPG2(%r13)
+        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+        l      %r14,.Lstart-.LPG3(%r13)
         basr   %r14,%r14                # call start_kernel
 #
 # We returned from start_kernel ?!? PANIK
index c9ff0404c875e15895ce794833c25adaf45bcb34..193aafa72f54a200158d6320728b0ca0b3037654 100644 (file)
@@ -484,6 +484,8 @@ start:
 startup:basr  %r13,0                     # get base
 .LPG1:  sll   %r13,1                     # remove high order bit
         srl   %r13,1
+       l     %r1,.Lget_ipl_device_addr-.LPG1(%r13)
+       basr  %r14,%r1
         lhi   %r1,1                      # mode 1 = esame
         slr   %r0,%r0                    # set cpuid to zero
         sigp  %r1,%r0,0x12               # switch to esame mode
@@ -556,6 +558,9 @@ startup:basr  %r13,0                     # get base
        mlgr  %r2,%r1                   # mem size in bytes in %r3
        b     .Lfchunk-.LPG1(%r13)
 
+       .align 4
+.Lget_ipl_device_addr:
+       .long .Lget_ipl_device
 .Lpmask:
        .byte 0
        .align 8
@@ -746,6 +751,63 @@ _pstart:
        .global _pend
 _pend: 
 
+.Lget_ipl_device:
+       basr  %r12,0
+.LPG2: l     %r1,0xb8                  # get sid
+       sll   %r1,15                    # test if subchannel is enabled
+       srl   %r1,31
+       ltr   %r1,%r1
+       bz    0(%r14)                   # subchannel disabled
+       l     %r1,0xb8
+       la    %r5,.Lipl_schib-.LPG2(%r12)
+       stsch 0(%r5)                    # get schib of subchannel
+       bnz   0(%r14)                   # schib not available
+       tm    5(%r5),0x01               # devno valid?
+       bno   0(%r14)
+       la    %r6,ipl_parameter_flags-.LPG2(%r12)
+       oi    3(%r6),0x01               # set flag
+       la    %r2,ipl_devno-.LPG2(%r12)
+       mvc   0(2,%r2),6(%r5)           # store devno
+       tm    4(%r5),0x80               # qdio capable device?
+       bno   0(%r14)
+       oi    3(%r6),0x02               # set flag
+
+       # copy ipl parameters
+
+       lhi   %r0,4096
+       l     %r2,20(%r0)               # get address of parameter list
+       lhi   %r3,IPL_PARMBLOCK_ORIGIN
+       st    %r3,20(%r0)
+       lhi   %r4,1
+       cr    %r2,%r3                   # start parameters < destination ?
+       jl    0f
+       lhi   %r1,1                     # copy direction is upwards
+       j     1f
+0:     lhi   %r1,-1                    # copy direction is downwards
+       ar    %r2,%r0
+       ar    %r3,%r0
+       ar    %r2,%r1
+       ar    %r3,%r1
+1:     mvc   0(1,%r3),0(%r2)           # finally copy ipl parameters
+       ar    %r3,%r1
+       ar    %r2,%r1
+       sr    %r0,%r4
+       jne   1b
+       b     0(%r14)
+
+       .align 4
+.Lipl_schib:
+       .rept 13
+       .long 0
+       .endr
+
+       .globl ipl_parameter_flags
+ipl_parameter_flags:
+       .long 0
+       .globl ipl_devno
+ipl_devno:
+       .word 0
+
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
 #endif
@@ -755,7 +817,7 @@ _pend:
 #
         .globl _stext
 _stext:        basr  %r13,0                    # get base
-.LPG2:
+.LPG3:
 #
 # Setup stack
 #
@@ -774,7 +836,7 @@ _stext:     basr  %r13,0                    # get base
         lctlg  %c0,%c15,0(%r15)
 
 #
-        lam    0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess
+        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
         brasl  %r14,start_kernel        # go to C code
 #
 # We returned from start_kernel ?!? PANIK
index 5204778b8e5e7b8921949c8cfb8689316943ee6d..31e7b19348b75947e1d97c780c912b1bea0427a6 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/console.h>
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
+#include <linux/device.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -685,3 +686,188 @@ struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 
+#define DEFINE_IPL_ATTR(_name, _format, _value)                        \
+static ssize_t ipl_##_name##_show(struct subsystem *subsys,    \
+               char *page)                                     \
+{                                                              \
+       return sprintf(page, _format, _value);                  \
+}                                                              \
+static struct subsys_attribute ipl_##_name##_attr =            \
+       __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
+
+DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
+               IPL_PARMBLOCK_START->fcp.wwpn);
+DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
+               IPL_PARMBLOCK_START->fcp.lun);
+DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
+               IPL_PARMBLOCK_START->fcp.bootprog);
+DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
+               IPL_PARMBLOCK_START->fcp.br_lba);
+
+enum ipl_type_type {
+       ipl_type_unknown,
+       ipl_type_ccw,
+       ipl_type_fcp,
+};
+
+static enum ipl_type_type
+get_ipl_type(void)
+{
+       struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+       if (!IPL_DEVNO_VALID)
+               return ipl_type_unknown;
+       if (!IPL_PARMBLOCK_VALID)
+               return ipl_type_ccw;
+       if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
+               return ipl_type_unknown;
+       if (ipl->fcp.pbt != IPL_TYPE_FCP)
+               return ipl_type_unknown;
+       return ipl_type_fcp;
+}
+
+static ssize_t
+ipl_type_show(struct subsystem *subsys, char *page)
+{
+       switch (get_ipl_type()) {
+       case ipl_type_ccw:
+               return sprintf(page, "ccw\n");
+       case ipl_type_fcp:
+               return sprintf(page, "fcp\n");
+       default:
+               return sprintf(page, "unknown\n");
+       }
+}
+
+static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
+
+static ssize_t
+ipl_device_show(struct subsystem *subsys, char *page)
+{
+       struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+
+       switch (get_ipl_type()) {
+       case ipl_type_ccw:
+               return sprintf(page, "0.0.%04x\n", ipl_devno);
+       case ipl_type_fcp:
+               return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
+       default:
+               return 0;
+       }
+}
+
+static struct subsys_attribute ipl_device_attr =
+       __ATTR(device, S_IRUGO, ipl_device_show, NULL);
+
+static struct attribute *ipl_fcp_attrs[] = {
+       &ipl_type_attr.attr,
+       &ipl_device_attr.attr,
+       &ipl_wwpn_attr.attr,
+       &ipl_lun_attr.attr,
+       &ipl_bootprog_attr.attr,
+       &ipl_br_lba_attr.attr,
+       NULL,
+};
+
+static struct attribute_group ipl_fcp_attr_group = {
+       .attrs = ipl_fcp_attrs,
+};
+
+static struct attribute *ipl_ccw_attrs[] = {
+       &ipl_type_attr.attr,
+       &ipl_device_attr.attr,
+       NULL,
+};
+
+static struct attribute_group ipl_ccw_attr_group = {
+       .attrs = ipl_ccw_attrs,
+};
+
+static struct attribute *ipl_unknown_attrs[] = {
+       &ipl_type_attr.attr,
+       NULL,
+};
+
+static struct attribute_group ipl_unknown_attr_group = {
+       .attrs = ipl_unknown_attrs,
+};
+
+static ssize_t
+ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       unsigned int size = IPL_PARMBLOCK_SIZE;
+
+       if (off > size)
+               return 0;
+       if (off + count > size)
+               count = size - off;
+
+       memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
+       return count;
+}
+
+static struct bin_attribute ipl_parameter_attr = {
+       .attr = {
+               .name = "binary_parameter",
+               .mode = S_IRUGO,
+               .owner = THIS_MODULE,
+       },
+       .size = PAGE_SIZE,
+       .read = &ipl_parameter_read,
+};
+
+static ssize_t
+ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       unsigned int size =  IPL_PARMBLOCK_START->fcp.scp_data_len;
+       void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
+
+       if (off > size)
+               return 0;
+       if (off + count > size)
+               count = size - off;
+
+       memcpy(buf, scp_data + off, count);
+       return count;
+}
+
+static struct bin_attribute ipl_scp_data_attr = {
+       .attr = {
+               .name = "scp_data",
+               .mode = S_IRUGO,
+               .owner = THIS_MODULE,
+       },
+       .size = PAGE_SIZE,
+       .read = &ipl_scp_data_read,
+};
+
+static decl_subsys(ipl, NULL, NULL);
+
+static int __init
+ipl_device_sysfs_register(void) {
+       int rc;
+
+       rc = firmware_register(&ipl_subsys);
+       if (rc)
+               return rc;
+
+       switch (get_ipl_type()) {
+       case ipl_type_ccw:
+               sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
+               break;
+       case ipl_type_fcp:
+               sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
+               sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+                                     &ipl_parameter_attr);
+               sysfs_create_bin_file(&ipl_subsys.kset.kobj,
+                                     &ipl_scp_data_attr);
+               break;
+       default:
+               sysfs_create_group(&ipl_subsys.kset.kobj,
+                                  &ipl_unknown_attr_group);
+               break;
+       }
+       return 0;
+}
+
+__initcall(ipl_device_sysfs_register);
index 2fd75da1549522b13816e9a9c50e1be8c4db2b42..9a1d95894f3df95e8201f210894ab88dcf651e07 100644 (file)
 
 #define TICK_SIZE tick
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 static ext_int_info_t ext_int_info_cc;
 static u64 init_timer_cc;
 static u64 jiffies_timer_cc;
index fa0726507b3d57152e5af6b11448757050ece7cc..22a895ecb7a4f2b5bbcde59377d4061f947e76b5 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/s390_ext.h>
 #include <asm/timer.h>
 
-#define VTIMER_MAGIC (TIMER_MAGIC + 1)
 static ext_int_info_t ext_int_info_timer;
 DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
 
@@ -277,20 +276,12 @@ static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
 
 void init_virt_timer(struct vtimer_list *timer)
 {
-       timer->magic = VTIMER_MAGIC;
        timer->function = NULL;
        INIT_LIST_HEAD(&timer->entry);
        spin_lock_init(&timer->lock);
 }
 EXPORT_SYMBOL(init_virt_timer);
 
-static inline int check_vtimer(struct vtimer_list *timer)
-{
-       if (timer->magic != VTIMER_MAGIC)
-               return -EINVAL;
-       return 0;
-}
-
 static inline int vtimer_pending(struct vtimer_list *timer)
 {
        return (!list_empty(&timer->entry));
@@ -346,7 +337,7 @@ static void internal_add_vtimer(struct vtimer_list *timer)
 
 static inline int prepare_vtimer(struct vtimer_list *timer)
 {
-       if (check_vtimer(timer) || !timer->function) {
+       if (!timer->function) {
                printk("add_virt_timer: uninitialized timer\n");
                return -EINVAL;
        }
@@ -414,7 +405,7 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
        unsigned long flags;
        int cpu;
 
-       if (check_vtimer(timer) || !timer->function) {
+       if (!timer->function) {
                printk("mod_virt_timer: uninitialized timer\n");
                return  -EINVAL;
        }
@@ -481,11 +472,6 @@ int del_virt_timer(struct vtimer_list *timer)
        unsigned long flags;
        struct vtimer_queue *vt_list;
 
-       if (check_vtimer(timer)) {
-               printk("del_virt_timer: timer not initialized\n");
-               return -EINVAL;
-       }
-
        /* check if timer is pending */
        if (!vtimer_pending(timer))
                return 0;
index 71a6d4e7809fbe91699fc04a85cf4c8a380b1fa8..6e3b58bd8795f4790223fa74b2c914377a862c08 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/module.h>
+#include <linux/string.h>
 #include <asm/dma.h>
 
 static struct sysdev_class dma_sysclass = {
index e0b384bef55f244c6f48e9ec719d5671120af916..47abf6e49dfb116ce712c94c6ccbd4e3efb17d6e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/cpumask.h>
 #include <linux/smp.h>
+#include <linux/sched.h>       /* set_cpus_allowed() */
 
 #include <asm/processor.h>
 #include <asm/watchdog.h>
index b28919b65682ab475d6463c20763084de8946da3..1fbe5a428e31fe54c017a58bff0d5b82efaea24e 100644 (file)
@@ -80,7 +80,7 @@ void ptrace_disable(struct task_struct *child)
        /* nothing to do.. */
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        struct user * dummy = NULL;
index 02ca69918d7c0992a943f7d7d856149f0145a9a3..671b876416bf184a1b66554547802bfc219aa52f 100644 (file)
@@ -56,10 +56,6 @@ extern unsigned long wall_jiffies;
 #define TICK_SIZE (tick_nsec / 1000)
 DEFINE_SPINLOCK(tmu0_lock);
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /* XXX: Can we initialize this in a routine somewhere?  Dreamcast doesn't want
  * these routines anywhere... */
 #ifdef CONFIG_SH_RTC
index fd2000956daeed262b571bc0d4b4406926c6f34a..71f2eec00b99d3f6004457a2be1fec1347ee651d 100644 (file)
@@ -121,7 +121,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
        return 0;
 }
 
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
index 43e395a14f490b8f3d6252d930747f55020c2bcc..870fe5327e09490b43c4d63c706b24de15402798 100644 (file)
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
 static unsigned long tmu_base, rtc_base;
 unsigned long cprc_base;
 
index 36a40697b8d61e66a9c129a61cb009712199f663..25e31d5ec99b57defc60e5714439bb9e0d0e6ead 100644 (file)
@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
                                 * CheerIO makes a similar conversion.
                                 * See ebus.c for details.
                                 *
-                                * Note that check_region()/request_region()
-                                * work for these devices.
+                                * Note that request_region()
+                                * works for these devices.
                                 *
                                 * XXX Neat trick, but it's a *bad* idea
                                 * to shit into regions like that.
index 279a62627c109906d7286f14d96659c7ffa0683a..24814d58f9e10363569ac0a8e3a254c3de111288 100644 (file)
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 DEFINE_SPINLOCK(rtc_lock);
 enum sparc_clock_type sp_clock_typ;
 DEFINE_SPINLOCK(mostek_lock);
index 43fc3173d48062f4eab0c01c7c633ec5a851b862..e6a00325075ac2d44df6b59a3087711a18d1fe04 100644 (file)
@@ -475,9 +475,6 @@ IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
 #define DECLARES
 #include "compat_ioctl.c"
-COMPATIBLE_IOCTL(TIOCSTART)
-COMPATIBLE_IOCTL(TIOCSTOP)
-COMPATIBLE_IOCTL(TIOCSLTC)
 COMPATIBLE_IOCTL(FBIOGTYPE)
 COMPATIBLE_IOCTL(FBIOSATTR)
 COMPATIBLE_IOCTL(FBIOGATTR)
index 3f08a32f51a16d2a91231ddcf15701dbdbe3d51b..38c5525087a2149c0c921a51c1fe64a5b2c4f7fa 100644 (file)
@@ -55,10 +55,6 @@ unsigned long ds1287_regs = 0UL;
 
 extern unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 static void __iomem *mstk48t08_regs;
 static void __iomem *mstk48t59_regs;
 
index 684e1f8b2755da5c5b2da0ad5e973505aa71a1a7..cd06ed7d842d93d54f18886efcf512d5471c009d 100644 (file)
@@ -27,10 +27,6 @@ config UID16
        bool
        default y
 
-config RWSEM_GENERIC_SPINLOCK
-       bool
-       default y
-
 config GENERIC_CALIBRATE_DELAY
        bool
        default y
@@ -40,6 +36,12 @@ config IRQ_RELEASE_METHOD
        bool
        default y
 
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
 menu "UML-specific options"
 
 config MODE_TT
index bd35e59419c8b8ff88aeeb2277a74b875eacc6df..aae19bc4b06a7055e4f3742af315f2064f0575db 100644 (file)
@@ -6,6 +6,11 @@ config 64BIT
        bool
        default y
 
+#XXX: this is so in the underlying arch, but it's wrong!!!
+config RWSEM_GENERIC_SPINLOCK
+       bool
+       default y
+
 config SEMAPHORE_SLEEPERS
        bool
        default y
index 2ee8a2858117357f3ae2fdc1412ff42fe633cedc..aef7c50f8e1365a6478de2d84471bab6213e1547 100644 (file)
@@ -29,6 +29,12 @@ endif
 
 CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
 
-ifneq ($(CONFIG_GPROF),y)
-ARCH_CFLAGS += -DUM_FASTCALL
-endif
+# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
+include $(srctree)/arch/i386/Makefile.cpu
+
+# prevent gcc from keeping the stack 16 byte aligned. Taken from i386.
+cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
+
+CFLAGS += $(cflags-y)
+USER_CFLAGS += $(cflags-y)
+
index a0d5b74d3731f41f0b7b03138c882557dc022bb1..57bd79efbee305887c0ac59cfa2504e3d6a1a2ba 100644 (file)
@@ -11,7 +11,6 @@ typedef long syscall_handler_t(struct pt_regs);
 /* Not declared on x86, incompatible declarations on x86_64, so these have
  * to go here rather than in sys_call_table.c
  */
-extern syscall_handler_t sys_ptrace;
 extern syscall_handler_t sys_rt_sigaction;
 
 extern syscall_handler_t old_mmap_i386;
index 4e08f7545d63d6df96558ff6506a764db1b7e4ca..020ca79b8d33200b3c6f4c29c582e4528cf5a00b 100644 (file)
 #include "mode.h"
 #include "os.h"
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 int hz(void)
 {
        return(HZ);
index 4726b87f5e5acb567f3b8d0d4fbbc5d8e513488b..d6077ff47d229282b3fcd7a1f0a8341bd932f392 100644 (file)
@@ -113,7 +113,7 @@ static int set_single_step (struct task_struct *t, int val)
        return 1;
 }
 
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int rval;
index ea3fd8844ff06b1bc4df01188db13407def7b833..c1e85c2aef65093f0ae70c90d8f1efc893e1e1b3 100644 (file)
 
 #include "mach.h"
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 #define TICK_SIZE      (tick_nsec / 1000)
 
 /*
index 419758f19ca4f4ec4da887da494b89f397f149c7..4ba0e293d5e5faccdcf8362521c4c15649ac096f 100644 (file)
 #define INCLUDES
 #include <linux/syscalls.h>
 #include "compat_ioctl.c"
-#include <asm/mtrr.h>
 #include <asm/ia32.h>
 
 #define CODE
 #include "compat_ioctl.c"
   
-#ifndef TIOCGDEV
-#define TIOCGDEV       _IOR('T',0x32, unsigned int)
-#endif
-static int tiocgdev(unsigned fd, unsigned cmd,  unsigned int __user *ptr) 
-{ 
-
-       struct file *file;
-       struct tty_struct *real_tty;
-       int fput_needed, ret;
-
-       file = fget_light(fd, &fput_needed);
-       if (!file)
-               return -EBADF;
-
-       ret = -EINVAL;
-       if (file->f_op->ioctl != tty_ioctl)
-               goto out;
-       real_tty = (struct tty_struct *)file->private_data;
-       if (!real_tty)  
-               goto out;
-
-       ret = put_user(new_encode_dev(tty_devnum(real_tty)), ptr); 
-
-out:
-       fput_light(file, fput_needed);
-       return ret;
-} 
-
 #define RTC_IRQP_READ32        _IOR('p', 0x0b, unsigned int)    /* Read IRQ rate   */
 #define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int)    /* Set IRQ rate    */
 #define RTC_EPOCH_READ32       _IOR('p', 0x0d, unsigned)        /* Read epoch      */
@@ -85,90 +56,6 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
        return sys_ioctl(fd,cmd,arg); 
 } 
 
-/* /proc/mtrr ioctls */
-
-
-struct mtrr_sentry32
-{
-    compat_ulong_t base;    /*  Base address     */
-    compat_uint_t size;    /*  Size of region   */
-    compat_uint_t type;     /*  Type of region   */
-};
-
-struct mtrr_gentry32
-{
-    compat_ulong_t regnum;   /*  Register number  */
-    compat_uint_t base;    /*  Base address     */
-    compat_uint_t size;    /*  Size of region   */
-    compat_uint_t type;     /*  Type of region   */
-};
-
-#define        MTRR_IOCTL_BASE 'M'
-
-#define MTRRIOC32_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
-#define MTRRIOC32_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
-#define MTRRIOC32_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
-#define MTRRIOC32_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
-#define MTRRIOC32_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
-#define MTRRIOC32_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
-#define MTRRIOC32_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
-#define MTRRIOC32_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
-
-
-static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
-{ 
-       struct mtrr_gentry g;
-       struct mtrr_sentry s;
-       int get = 0, err = 0; 
-       struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg; 
-       mm_segment_t oldfs = get_fs(); 
-
-       switch (cmd) { 
-#define SET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; break 
-#define GET(x) case MTRRIOC32_ ## x ## _ENTRY: cmd = MTRRIOC_ ## x ## _ENTRY; get=1; break
-               SET(ADD);
-               SET(SET); 
-               SET(DEL);
-               GET(GET); 
-               SET(KILL);
-               SET(ADD_PAGE); 
-               SET(SET_PAGE); 
-               SET(DEL_PAGE); 
-               GET(GET_PAGE); 
-               SET(KILL_PAGE); 
-       } 
-       
-       if (get) { 
-               err = get_user(g.regnum, &g32->regnum);
-               err |= get_user(g.base, &g32->base);
-               err |= get_user(g.size, &g32->size);
-               err |= get_user(g.type, &g32->type); 
-
-               arg = (unsigned long)&g; 
-       } else { 
-               struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg;
-               err = get_user(s.base, &s32->base);
-               err |= get_user(s.size, &s32->size);
-               err |= get_user(s.type, &s32->type);
-
-               arg = (unsigned long)&s; 
-       } 
-       if (err) return err;
-       
-       set_fs(KERNEL_DS); 
-       err = sys_ioctl(fd, cmd, arg); 
-       set_fs(oldfs); 
-               
-       if (!err && get) { 
-               err = put_user(g.base, &g32->base);
-               err |= put_user(g.size, &g32->size);
-               err |= put_user(g.regnum, &g32->regnum);
-               err |= put_user(g.type, &g32->type); 
-       } 
-       return err;
-} 
 
 #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
@@ -185,7 +72,6 @@ COMPATIBLE_IOCTL(0x4B51)   /* KDSHWCLK - not in the kernel, but don't complain *
 COMPATIBLE_IOCTL(FIOQSIZE)
 
 /* And these ioctls need translation */
-HANDLE_IOCTL(TIOCGDEV, tiocgdev)
 /* realtime device */
 HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
 HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
@@ -193,17 +79,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
 HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
 HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
 /* take care of sizeof(sizeof()) breakage */
-/* mtrr */
-HANDLE_IOCTL(MTRRIOC32_ADD_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_ADD_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_SET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_DEL_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
-HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
 }; 
 
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index b2a238b5a17ed36cc7a071be01f62231d80cc5c0..c6c9791d77c18aa2ed7025f7b9c7a0b07e18f132 100644 (file)
@@ -494,7 +494,7 @@ void invalidate_interrupt7(void);
 void thermal_interrupt(void);
 void i8254_timer_resume(void);
 
-static void setup_timer(void)
+static void setup_timer_hardware(void)
 {
        outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
        udelay(10);
@@ -505,13 +505,13 @@ static void setup_timer(void)
 
 static int timer_resume(struct sys_device *dev)
 {
-       setup_timer();
+       setup_timer_hardware();
        return 0;
 }
 
 void i8254_timer_resume(void)
 {
-       setup_timer();
+       setup_timer_hardware();
 }
 
 static struct sysdev_class timer_sysclass = {
@@ -594,7 +594,7 @@ void __init init_IRQ(void)
         * Set the clock to HZ Hz, we already have a valid
         * vector now:
         */
-       setup_timer();
+       setup_timer_hardware();
 
        if (!acpi_ioapic)
                setup_irq(2, &irq2);
index cb28df14ff6fea87991daba07241b86835db30ee..da0bc3e7bdf5cfbd7394c612f25836110fdd2816 100644 (file)
@@ -1213,7 +1213,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
                /* Intel-defined (#2) */
-               "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
+               "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", NULL, "est",
                "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
index f066c6ab3618f24a5d7d7323de14d4a9cd0c1144..fd2bef7808825fe670b3a6864cd9b7208f6746a4 100644 (file)
@@ -63,13 +63,12 @@ void save_processor_state(void)
        __save_processor_state(&saved_context);
 }
 
-static void
-do_fpu_end(void)
+static void do_fpu_end(void)
 {
-        /* restore FPU regs if necessary */
-       /* Do it out of line so that gcc does not move cr0 load to some stupid place */
-        kernel_fpu_end();
-       mxcsr_feature_mask_init();
+       /*
+        * Restore FPU regs if necessary
+        */
+       kernel_fpu_end();
 }
 
 void __restore_processor_state(struct saved_context *ctxt)
@@ -148,57 +147,7 @@ extern int restore_image(void);
 
 pgd_t *temp_level4_pgt;
 
-static void **pages;
-
-static inline void *__add_page(void)
-{
-       void **c;
-
-       c = (void **)get_usable_page(GFP_ATOMIC);
-       if (c) {
-               *c = pages;
-               pages = c;
-       }
-       return c;
-}
-
-static inline void *__next_page(void)
-{
-       void **c;
-
-       c = pages;
-       if (c) {
-               pages = *c;
-               *c = NULL;
-       }
-       return c;
-}
-
-/*
- * Try to allocate as many usable pages as needed and daisy chain them.
- * If one allocation fails, free the pages allocated so far
- */
-static int alloc_usable_pages(unsigned long n)
-{
-       void *p;
-
-       pages = NULL;
-       do
-               if (!__add_page())
-                       break;
-       while (--n);
-       if (n) {
-               p = __next_page();
-               while (p) {
-                       free_page((unsigned long)p);
-                       p = __next_page();
-               }
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
+static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
 {
        long i, j;
 
@@ -212,7 +161,9 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
                if (paddr >= end)
                        break;
 
-               pmd = (pmd_t *)__next_page();
+               pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+               if (!pmd)
+                       return -ENOMEM;
                set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
                for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
                        unsigned long pe;
@@ -224,13 +175,17 @@ static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long e
                        set_pmd(pmd, __pmd(pe));
                }
        }
+       return 0;
 }
 
-static void set_up_temporary_mappings(void)
+static int set_up_temporary_mappings(void)
 {
        unsigned long start, end, next;
+       int error;
 
-       temp_level4_pgt = (pgd_t *)__next_page();
+       temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
+       if (!temp_level4_pgt)
+               return -ENOMEM;
 
        /* It is safe to reuse the original kernel mapping */
        set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
@@ -241,29 +196,27 @@ static void set_up_temporary_mappings(void)
        end = (unsigned long)pfn_to_kaddr(end_pfn);
 
        for (; start < end; start = next) {
-               pud_t *pud = (pud_t *)__next_page();
+               pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+               if (!pud)
+                       return -ENOMEM;
                next = start + PGDIR_SIZE;
                if (next > end)
                        next = end;
-               res_phys_pud_init(pud, __pa(start), __pa(next));
+               if ((error = res_phys_pud_init(pud, __pa(start), __pa(next))))
+                       return error;
                set_pgd(temp_level4_pgt + pgd_index(start),
                        mk_kernel_pgd(__pa(pud)));
        }
+       return 0;
 }
 
 int swsusp_arch_resume(void)
 {
-       unsigned long n;
+       int error;
 
-       n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
-       n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
-       pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
-       if (alloc_usable_pages(n)) {
-               free_eaten_memory();
-               return -ENOMEM;
-       }
        /* We have got enough memory and from now on we cannot recover */
-       set_up_temporary_mappings();
+       if ((error = set_up_temporary_mappings()))
+               return error;
        restore_image();
        return 0;
 }
index 703acde2a1a58647978e48cc3b4a5cf216eabc0c..fdaddc4e52847a1f0fea0c50ff960aadcc9caf60 100644 (file)
 #include <asm/apic.h>
 #endif
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 #ifdef CONFIG_CPU_FREQ
 static void cpufreq_delayed_get(void);
 #endif
@@ -481,9 +477,9 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static unsigned int cyc2ns_scale;
 #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
 
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
 {
-       cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+       cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
 }
 
 static inline unsigned long long cycles_2_ns(unsigned long long cyc)
@@ -655,7 +651,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
                        vxtime.tsc_quot = (1000L << 32) / cpu_khz;
        }
        
-       set_cyc2ns_scale(cpu_khz_ref / 1000);
+       set_cyc2ns_scale(cpu_khz_ref);
 
        return 0;
 }
@@ -939,7 +935,7 @@ void __init time_init(void)
        rdtscll_sync(&vxtime.last_tsc);
        setup_irq(0, &irq0);
 
-       set_cyc2ns_scale(cpu_khz / 1000);
+       set_cyc2ns_scale(cpu_khz);
 
 #ifndef CONFIG_SMP
        time_init_gtod();
@@ -1093,6 +1089,7 @@ static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
 static unsigned long PIE_count;
 
 static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+static unsigned int hpet_t1_cmp; /* cached comparator register */
 
 int is_hpet_enabled(void)
 {
@@ -1129,10 +1126,12 @@ int hpet_rtc_timer_init(void)
        cnt = hpet_readl(HPET_COUNTER);
        cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
        hpet_writel(cnt, HPET_T1_CMP);
+       hpet_t1_cmp = cnt;
        local_irq_restore(flags);
 
        cfg = hpet_readl(HPET_T1_CFG);
-       cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+       cfg &= ~HPET_TN_PERIODIC;
+       cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
        hpet_writel(cfg, HPET_T1_CFG);
 
        return 1;
@@ -1142,8 +1141,12 @@ static void hpet_rtc_timer_reinit(void)
 {
        unsigned int cfg, cnt;
 
-       if (!(PIE_on | AIE_on | UIE_on))
+       if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
+               cfg = hpet_readl(HPET_T1_CFG);
+               cfg &= ~HPET_TN_ENABLE;
+               hpet_writel(cfg, HPET_T1_CFG);
                return;
+       }
 
        if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
                hpet_rtc_int_freq = PIE_freq;
@@ -1151,15 +1154,10 @@ static void hpet_rtc_timer_reinit(void)
                hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
 
        /* It is more accurate to use the comparator value than current count.*/
-       cnt = hpet_readl(HPET_T1_CMP);
+       cnt = hpet_t1_cmp;
        cnt += hpet_tick*HZ/hpet_rtc_int_freq;
        hpet_writel(cnt, HPET_T1_CMP);
-
-       cfg = hpet_readl(HPET_T1_CFG);
-       cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
-       hpet_writel(cfg, HPET_T1_CFG);
-
-       return;
+       hpet_t1_cmp = cnt;
 }
 
 /*
index 03674daabc66b25ea73ccbd204fc928cbef1d797..a17930747f204046e7d0456d6382b485fa2c2dc6 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/time.h>
 #include <asm/platform.h>
 #include <asm/timex.h>
+#include <asm/param.h>         /* HZ */
 
 #define _F(r,f,a,b)                                                    \
        r __platform_##f a b;                                           \
index 2659efdd4e9906f3fdc3a7e1d6a1d6727e5e5574..14460743de079dd32263a003b6d58d640f335027 100644 (file)
@@ -45,7 +45,7 @@ void ptrace_disable(struct task_struct *child)
        /* Nothing to do.. */
 }
 
-int sys_ptrace(long request, long pid, long addr, long data)
+long sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
        int ret = -EPERM;
index 8e423d1335cee107ad8918710f5bbe3386fc440b..cb6e38ed2b1dfc26ed03963cea0be6f37fc71480 100644 (file)
@@ -29,9 +29,6 @@
 
 extern volatile unsigned long wall_jiffies;
 
-u64 jiffies_64 = INITIAL_JIFFIES;
-EXPORT_SYMBOL(jiffies_64);
-
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 EXPORT_SYMBOL(rtc_lock);
 
index 26a3a4016115364467b5feff71415c7e88f4d016..161db4acfb91de2d26ddbde096688de93322f93c 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/moduleparam.h>
+#include <linux/sched.h>       /* need_resched() */
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index aee50b453265905d22442992afc6f4701177a98e..930427fc0c4b33ff923a5623038adcdf7073ea1c 100644 (file)
@@ -158,7 +158,15 @@ int acpi_suspend(u32 acpi_state)
        return -EINVAL;
 }
 
+static int acpi_pm_state_valid(suspend_state_t pm_state)
+{
+       u32 acpi_state = acpi_suspend_states[pm_state];
+
+       return sleep_states[acpi_state];
+}
+
 static struct pm_ops acpi_pm_ops = {
+       .valid = acpi_pm_state_valid,
        .prepare = acpi_pm_prepare,
        .enter = acpi_pm_enter,
        .finish = acpi_pm_finish,
index c3e569730afe709e46973fbc456b9038cc76d8aa..db65fd0babe937f4ba88682293db9a2bae5907d2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/kdev_t.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
index 081c927b1ed8b6839e8674e2cc8c07e9f7791fa9..a95844790f7bb50acfff48eb299c56fa28718035 100644 (file)
@@ -16,6 +16,8 @@ struct sysdev_class cpu_sysdev_class = {
 };
 EXPORT_SYMBOL(cpu_sysdev_class);
 
+static struct sys_device *cpu_sys_devices[NR_CPUS];
+
 #ifdef CONFIG_HOTPLUG_CPU
 int __attribute__((weak)) smp_prepare_cpu (int cpu)
 {
@@ -64,6 +66,7 @@ static void __devinit register_cpu_control(struct cpu *cpu)
 }
 void unregister_cpu(struct cpu *cpu, struct node *root)
 {
+       int logical_cpu = cpu->sysdev.id;
 
        if (root)
                sysfs_remove_link(&root->sysdev.kobj,
@@ -71,7 +74,7 @@ void unregister_cpu(struct cpu *cpu, struct node *root)
        sysdev_remove_file(&cpu->sysdev, &attr_online);
 
        sysdev_unregister(&cpu->sysdev);
-
+       cpu_sys_devices[logical_cpu] = NULL;
        return;
 }
 #else /* ... !CONFIG_HOTPLUG_CPU */
@@ -103,10 +106,19 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
                                          kobject_name(&cpu->sysdev.kobj));
        if (!error && !cpu->no_control)
                register_cpu_control(cpu);
+       if (!error)
+               cpu_sys_devices[num] = &cpu->sysdev;
        return error;
 }
 
-
+struct sys_device *get_cpu_sysdev(int cpu)
+{
+       if (cpu < NR_CPUS)
+               return cpu_sys_devices[cpu];
+       else
+               return NULL;
+}
+EXPORT_SYMBOL_GPL(get_cpu_sysdev);
 
 int __init cpu_dev_init(void)
 {
index 4acb2c5733c3b46710d6321b886d16b8704f1d1c..98f6c02d6790a9d78220ccffa33b616cae91a30d 100644 (file)
@@ -62,14 +62,16 @@ firmware_timeout_show(struct class *class, char *buf)
 }
 
 /**
- * firmware_timeout_store:
- * Description:
+ * firmware_timeout_store - set number of seconds to wait for firmware
+ * @class: device class pointer
+ * @buf: buffer to scan for timeout value
+ * @count: number of bytes in @buf
+ *
  *     Sets the number of seconds to wait for the firmware.  Once
- *     this expires an error will be return to the driver and no
+ *     this expires an error will be returned to the driver and no
  *     firmware will be provided.
  *
- *     Note: zero means 'wait for ever'
- *
+ *     Note: zero means 'wait forever'.
  **/
 static ssize_t
 firmware_timeout_store(struct class *class, const char *buf, size_t count)
@@ -123,12 +125,15 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
 }
 
 /**
- * firmware_loading_store: - loading control file
- * Description:
+ * firmware_loading_store - set value in the 'loading' control file
+ * @class_dev: class_device pointer
+ * @buf: buffer to scan for loading control value
+ * @count: number of bytes in @buf
+ *
  *     The relevant values are:
  *
  *      1: Start a load, discarding any previous partial load.
- *      0: Conclude the load and handle the data to the driver code.
+ *      0: Conclude the load and hand the data to the driver code.
  *     -1: Conclude the load with an error and discard any written data.
  **/
 static ssize_t
@@ -201,6 +206,7 @@ out:
        up(&fw_lock);
        return ret_count;
 }
+
 static int
 fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
 {
@@ -227,11 +233,13 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
 }
 
 /**
- * firmware_data_write:
+ * firmware_data_write - write method for firmware
+ * @kobj: kobject for the class_device
+ * @buffer: buffer being written
+ * @offset: buffer offset for write in total data store area
+ * @count: buffer size
  *
- * Description:
- *
- *     Data written to the 'data' attribute will be later handled to
+ *     Data written to the 'data' attribute will be later handed to
  *     the driver as a firmware image.
  **/
 static ssize_t
@@ -264,6 +272,7 @@ out:
        up(&fw_lock);
        return retval;
 }
+
 static struct bin_attribute firmware_attr_data_tmpl = {
        .attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
        .size = 0,
@@ -448,13 +457,16 @@ out:
 
 /**
  * request_firmware: - request firmware to hotplug and wait for it
- * Description:
- *      @firmware will be used to return a firmware image by the name
+ * @firmware_p: pointer to firmware image
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ *
+ *      @firmware_p will be used to return a firmware image by the name
  *      of @name for device @device.
  *
  *      Should be called from user context where sleeping is allowed.
  *
- *      @name will be use as $FIRMWARE in the hotplug environment and
+ *      @name will be used as $FIRMWARE in the hotplug environment and
  *      should be distinctive enough not to be confused with any other
  *      firmware image for this or any other device.
  **/
@@ -468,6 +480,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
 
 /**
  * release_firmware: - release the resource associated with a firmware image
+ * @fw: firmware resource to release
  **/
 void
 release_firmware(const struct firmware *fw)
@@ -480,8 +493,10 @@ release_firmware(const struct firmware *fw)
 
 /**
  * register_firmware: - provide a firmware image for later usage
+ * @name: name of firmware image file
+ * @data: buffer pointer for the firmware image
+ * @size: size of the data buffer area
  *
- * Description:
  *     Make sure that @data will be available by requesting firmware @name.
  *
  *     Note: This will not be possible until some kind of persistence
@@ -526,21 +541,19 @@ request_firmware_work_func(void *arg)
 }
 
 /**
- * request_firmware_nowait:
+ * request_firmware_nowait: asynchronous version of request_firmware
+ * @module: module requesting the firmware
+ * @hotplug: invokes hotplug event to copy the firmware image if this flag
+ *     is non-zero else the firmware copy must be done manually.
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded
+ * @context: will be passed over to @cont, and
+ *     @fw may be %NULL if firmware request fails.
+ * @cont: function will be called asynchronously when the firmware
+ *     request is over.
  *
- * Description:
  *     Asynchronous variant of request_firmware() for contexts where
  *     it is not possible to sleep.
- *
- *      @hotplug invokes hotplug event to copy the firmware image if this flag
- *      is non-zero else the firmware copy must be done manually.
- *
- *     @cont will be called asynchronously when the firmware request is over.
- *
- *     @context will be passed over to @cont.
- *
- *     @fw may be %NULL if firmware request fails.
- *
  **/
 int
 request_firmware_nowait(
index 75ce8711bca5d7a6df22f06167a932145ed33b6a..08d9cc99c7de134613a92565c9be883ccb194861 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/bootmem.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include "base.h"
 
index 3431eb6004c3287f6c0be52ddcb75d13d6037f0e..66ed8f2fece5009082d4e994622fcb5acc49f82e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <asm/semaphore.h>
 
 extern struct subsystem devices_subsys;
 
index 6070a480600b6ba2e24902e70a48a71290faaf7c..5b90d2fa63b8382d80de600d0410e4a1cf0518e2 100644 (file)
@@ -38,4 +38,32 @@ config IOSCHED_CFQ
          among all processes in the system. It should provide a fair
          working environment, suitable for desktop systems.
 
+choice
+       prompt "Default I/O scheduler"
+       default DEFAULT_AS
+       help
+         Select the I/O scheduler which will be used by default for all
+         block devices.
+
+       config DEFAULT_AS
+               bool "Anticipatory" if IOSCHED_AS
+
+       config DEFAULT_DEADLINE
+               bool "Deadline" if IOSCHED_DEADLINE
+
+       config DEFAULT_CFQ
+               bool "CFQ" if IOSCHED_CFQ
+
+       config DEFAULT_NOOP
+               bool "No-op"
+
+endchoice
+
+config DEFAULT_IOSCHED
+       string
+       default "anticipatory" if DEFAULT_AS
+       default "deadline" if DEFAULT_DEADLINE
+       default "cfq" if DEFAULT_CFQ
+       default "noop" if DEFAULT_NOOP
+
 endmenu
index 56417223481946ca499c8305da27ef065485068f..c6744ff382944a590767cef1827e627c1915c7ad 100644 (file)
@@ -1973,8 +1973,8 @@ static int __init as_init(void)
 
 static void __exit as_exit(void)
 {
-       kmem_cache_destroy(arq_pool);
        elv_unregister(&iosched_as);
+       kmem_cache_destroy(arq_pool);
 }
 
 module_init(as_init);
index e183a3ef7839fdabd5dfc8a2ec9d1f1fa11d94db..ec27976a57da1285c5b2e0f3be357cc91c63038f 100644 (file)
    through the array controller.  Note in particular, neither 
    physical nor logical disks are presented through the scsi layer. */
 
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/atomic.h>
+
 #include <scsi/scsi.h> 
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h> 
-#include <asm/atomic.h>
-#include <linux/timer.h>
-#include <linux/completion.h>
 
 #include "cciss_scsi.h"
 
index 94690e4d41e096b4a988eb5a27f76d8d1925fc72..5281f8e70510cda1717f2bd385e0c19353476fdd 100644 (file)
@@ -2418,28 +2418,8 @@ static int __init cfq_init(void)
 
 static void __exit cfq_exit(void)
 {
-       struct task_struct *g, *p;
-       unsigned long flags;
-
-       read_lock_irqsave(&tasklist_lock, flags);
-
-       /*
-        * iterate each process in the system, removing our io_context
-        */
-       do_each_thread(g, p) {
-               struct io_context *ioc = p->io_context;
-
-               if (ioc && ioc->cic) {
-                       ioc->cic->exit(ioc->cic);
-                       cfq_free_io_context(ioc->cic);
-                       ioc->cic = NULL;
-               }
-       } while_each_thread(g, p);
-
-       read_unlock_irqrestore(&tasklist_lock, flags);
-
-       cfq_slab_kill();
        elv_unregister(&iosched_cfq);
+       cfq_slab_kill();
 }
 
 module_init(cfq_init);
index 55621d5c577403e3024a6dac9b580185c6c6b9cf..36f1057084b024bdc978db18d3b1fab43ecd3273 100644 (file)
@@ -147,24 +147,17 @@ static void elevator_setup_default(void)
        struct elevator_type *e;
 
        /*
-        * check if default is set and exists
+        * If default has not been set, use the compiled-in selection.
         */
-       if (chosen_elevator[0] && (e = elevator_get(chosen_elevator))) {
-               elevator_put(e);
-               return;
-       }
+       if (!chosen_elevator[0])
+               strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
 
-#if defined(CONFIG_IOSCHED_AS)
-       strcpy(chosen_elevator, "anticipatory");
-#elif defined(CONFIG_IOSCHED_DEADLINE)
-       strcpy(chosen_elevator, "deadline");
-#elif defined(CONFIG_IOSCHED_CFQ)
-       strcpy(chosen_elevator, "cfq");
-#elif defined(CONFIG_IOSCHED_NOOP)
-       strcpy(chosen_elevator, "noop");
-#else
-#error "You must build at least 1 IO scheduler into the kernel"
-#endif
+       /*
+        * If the given scheduler is not available, fall back to no-op.
+        */
+       if (!(e = elevator_find(chosen_elevator)))
+               strcpy(chosen_elevator, "noop");
+       elevator_put(e);
 }
 
 static int __init elevator_setup(char *str)
@@ -642,6 +635,27 @@ EXPORT_SYMBOL_GPL(elv_register);
 
 void elv_unregister(struct elevator_type *e)
 {
+       struct task_struct *g, *p;
+
+       /*
+        * Iterate every thread in the process to remove the io contexts.
+        */
+       read_lock(&tasklist_lock);
+       do_each_thread(g, p) {
+               struct io_context *ioc = p->io_context;
+               if (ioc && ioc->cic) {
+                       ioc->cic->exit(ioc->cic);
+                       ioc->cic->dtor(ioc->cic);
+                       ioc->cic = NULL;
+               }
+               if (ioc && ioc->aic) {
+                       ioc->aic->exit(ioc->aic);
+                       ioc->aic->dtor(ioc->aic);
+                       ioc->aic = NULL;
+               }
+       } while_each_thread(g, p);
+       read_unlock(&tasklist_lock);
+
        spin_lock_irq(&elv_list_lock);
        list_del_init(&e->list);
        spin_unlock_irq(&elv_list_lock);
@@ -739,8 +753,10 @@ ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
                return -EINVAL;
        }
 
-       if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name))
+       if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
+               elevator_put(e);
                return count;
+       }
 
        elevator_switch(q, e);
        return count;
index 1fef136c0e412a53538d6e0833eece3df2822b84..ce94aa11f6a7020d900a5e07def3959479366ea6 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/sched.h>       /* TASK_* */
 
 #ifdef CONFIG_PARPORT_MODULE
 #define CONFIG_PARPORT
index 94af920465b588392c262fe6fe88fc35730601f1..e9746af29b9f0299f03261667e43fb86f8f7063d 100644 (file)
@@ -807,10 +807,6 @@ static int pf_next_buf(void)
                return 1;
        spin_lock_irqsave(&pf_spin_lock, saved_flags);
        pf_end_request(1);
-       if (pf_req) {
-               pf_count = pf_req->current_nr_sectors;
-               pf_buf = pf_req->buffer;
-       }
        spin_unlock_irqrestore(&pf_spin_lock, saved_flags);
        return 1;
 }
index 82f2d6d2eeefef8e6e53e9400f7bce6a3cd9f272..6f5df0fad70384b1eab9537740f3a8a2bb73cdfe 100644 (file)
@@ -162,6 +162,8 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
 #include <linux/mtio.h>
 #include <linux/pg.h>
 #include <linux/device.h>
+#include <linux/sched.h>       /* current, TASK_* */
+#include <linux/jiffies.h>
 
 #include <asm/uaccess.h>
 
index 686c955734523f37d8e18bb1294bcd8a0d45031b..715ae5dc88fba4f8a2e1dd191d2bd8d591997d4c 100644 (file)
@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
 #include <linux/slab.h>
 #include <linux/mtio.h>
 #include <linux/device.h>
+#include <linux/sched.h>       /* current, TASK_*, schedule_timeout() */
 
 #include <asm/uaccess.h>
 
index c29365d5b524a5c4d5abd072c1dd7ee458f6cec7..fdf4370db994ca6f17be96070a0b2153a087764a 100644 (file)
@@ -661,7 +661,7 @@ config HW_RANDOM
 
 config NVRAM
        tristate "/dev/nvram support"
-       depends on ATARI || X86 || X86_64 || ARM || GENERIC_NVRAM
+       depends on ATARI || X86 || ARM || GENERIC_NVRAM
        ---help---
          If you say Y here and create a character special file /dev/nvram
          with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -985,7 +985,7 @@ config MAX_RAW_DEVS
 
 config HANGCHECK_TIMER
        tristate "Hangcheck timer"
-       depends on X86_64 || X86 || IA64 || PPC64 || ARCH_S390
+       depends on X86 || IA64 || PPC64 || ARCH_S390
        help
          The hangcheck-timer module detects when the system has gone
          out to lunch past a certain margin.  It can reboot the system
@@ -1001,5 +1001,17 @@ config MMTIMER
 
 source "drivers/char/tpm/Kconfig"
 
+config TELCLOCK
+       tristate "Telecom clock driver for MPBL0010 ATCA SBC"
+       depends on EXPERIMENTAL
+       default n
+       help
+         The telecom clock device is specific to the MPBL0010 ATCA computer and
+         allows direct userspace access to the configuration of the telecom clock
+         configuration settings.  This device is used for hardware synchronization
+         across the ATCA backplane fabric.  Upon loading, the driver exports a
+         sysfs directory, /sys/devices/platform/telco_clock, with a number of
+         files for controlling the behavior of this hardware.
+
 endmenu
 
index 08f69287ea36157c31477f23c8a4fc856637bebb..4aeae687e88a20e8911781ad5747a6ebb69d1948 100644 (file)
@@ -82,6 +82,7 @@ obj-$(CONFIG_NWFLASH) += nwflash.o
 obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
 obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
 obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
+obj-$(CONFIG_TELCLOCK) += tlclk.o
 
 obj-$(CONFIG_WATCHDOG) += watchdog/
 obj-$(CONFIG_MWAVE) += mwave/
index 7f8c1b53b754e095e0f6f401addf3ccb4e4bf4e5..486ed8a11b5921899ef2252759477343723b42f3 100644 (file)
@@ -27,7 +27,7 @@ config AGP
 
 config AGP_ALI
        tristate "ALI chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        ---help---
          This option gives you AGP support for the GLX component of
          XFree86 4.x on the following ALi chipsets.  The supported chipsets
@@ -45,7 +45,7 @@ config AGP_ALI
 
 config AGP_ATI
        tristate "ATI chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        ---help---
       This option gives you AGP support for the GLX component of
       XFree86 4.x on the ATI RadeonIGP family of chipsets.
@@ -55,7 +55,7 @@ config AGP_ATI
 
 config AGP_AMD
        tristate "AMD Irongate, 761, and 762 chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          This option gives you AGP support for the GLX component of
          XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
@@ -91,7 +91,7 @@ config AGP_INTEL
 
 config AGP_NVIDIA
        tristate "NVIDIA nForce/nForce2 chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          This option gives you AGP support for the GLX component of
          XFree86 4.x on the following NVIDIA chipsets.  The supported chipsets
@@ -99,7 +99,7 @@ config AGP_NVIDIA
 
 config AGP_SIS
        tristate "SiS chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          This option gives you AGP support for the GLX component of
          XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
@@ -111,14 +111,14 @@ config AGP_SIS
 
 config AGP_SWORKS
        tristate "Serverworks LE/HE chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          Say Y here to support the Serverworks AGP card.  See 
          <http://www.serverworks.com/> for product descriptions and images.
 
 config AGP_VIA
        tristate "VIA chipset support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          This option gives you AGP support for the GLX component of
          XFree86 4.x on VIA MVP3/Apollo Pro chipsets.
@@ -154,7 +154,7 @@ config AGP_UNINORTH
 
 config AGP_EFFICEON
        tristate "Transmeta Efficeon support"
-       depends on AGP && X86 && !X86_64
+       depends on AGP && X86_32
        help
          This option gives you AGP support for the Transmeta Efficeon
          series processors with integrated northbridges.
index 9c9c9c2247cecfe8c48d0607e8a5d5a0b5f0921f..b02fc2267159675c32e8e6a58c27ab8173a9161f 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
+#include <asm/page.h>          /* PAGE_SIZE */
 #include "agp.h"
 
 #define ALI_AGPCTRL    0xb8
index 0a7624a9b1c1c6e3a3a5feffb3364f9e14c1eba9..0e6c3a31d3448a820f4f8a95d8f43d6d6d2a9915 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
+#include <asm/page.h>          /* PAGE_SIZE */
 #include "agp.h"
 
 /* Will need to be increased if AMD64 ever goes >8-way. */
index e572ced9100aeb8d78fc9bdf5379952ae3ff3905..0b6e72642d6e5a0126038d5cd553f39fd87d4d0c 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/agp_backend.h>
 #include <asm/agp.h>
 #include "agp.h"
index 94943298c03eb42056d00ba73875147bd40b7e24..a2d9e5e48bbeeff576bb7f0ac953b837017695b3 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/agp_backend.h>
 
 #include "agp.h"
index c9ac731504f229a11f18f588f23e1f8dc1d0df27..40083241804eee1b48f09902e7c67a82d0cf7276 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/pci.h>
 #include <linux/agp_backend.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 #include "agp.h"
 
index a9fb12c20eb72e92aa343413094270022a159e47..71ea59a1dbebf982fecbd86cc06fa516d2bcd152 100644 (file)
@@ -5,6 +5,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/agp_backend.h>
 #include "agp.h"
 
index cf4c3648463dbf8d0cd28c9079be19e110dbefa4..c7f818cd7b0214b321d9c6d5d7e3b5bf4c34ef03 100644 (file)
@@ -281,7 +281,7 @@ static char rcsid[] =
  * make sure "cyc" appears in all kernel messages; all soft interrupts
  * handled by same routine; recognize out-of-band reception; comment
  * out some diagnostic messages; leave RTS/CTS flow control to hardware;
- * fix race condition in -Z buffer management; only -Y needs to explictly
+ * fix race condition in -Z buffer management; only -Y needs to explicitly
  * flush chars; tidy up some startup messages;
  *
  * Revision 1.36.4.18  1996/07/25 18:57:31  bentson
index 475cc5e555e1c43626ed18be91df2e90babcf5a4..6d3449761914cc3099298d3456c86906ec8cddb3 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/device.h>
 #include <linux/kdev_t.h>
 #include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include "drm_core.h"
 #include "drmP.h"
index 407708a001e421ea0322ee908074a09381e2125a..b7a0e4d6b9344168441ef60e6c942f8575d06770 100644 (file)
@@ -3113,6 +3113,7 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
 int __init init_PCI (void)
 {      /* Begin init_PCI */
        memset (&epca_driver, 0, sizeof (epca_driver));
+       epca_driver.owner = THIS_MODULE;
        epca_driver.name = "epca";
        epca_driver.id_table = epca_pci_tbl;
        epca_driver.probe = epca_init_one;
index a54bc93353af1d62d37ddf96af94d344e1bd60e4..66e53dd450ff251ecb1642dbb0817af2c1131f5d 100644 (file)
@@ -117,7 +117,7 @@ __setup("hcheck_reboot", hangcheck_parse_reboot);
 __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks);
 #endif /* not MODULE */
 
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
 # define HAVE_MONOTONIC
 # define TIMER_FREQ 1000000000ULL
 #elif defined(CONFIG_ARCH_S390)
index c055bb630ffcda9e882923c2256cb6137dfb491d..3808d95726195d3bb5c18ab8946d77cc341d765b 100644 (file)
@@ -49,7 +49,9 @@
 #define        HPET_USER_FREQ  (64)
 #define        HPET_DRIFT      (500)
 
-static u32 hpet_ntimer, hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
+#define HPET_RANGE_SIZE                1024    /* from HPET spec */
+
+static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
 
 /* A lock for concurrent access by app and isr hpet activity. */
 static DEFINE_SPINLOCK(hpet_lock);
@@ -78,7 +80,7 @@ struct hpets {
        struct hpet __iomem *hp_hpet;
        unsigned long hp_hpet_phys;
        struct time_interpolator *hp_interpolator;
-       unsigned long hp_period;
+       unsigned long long hp_tick_freq;
        unsigned long hp_delta;
        unsigned int hp_ntimer;
        unsigned int hp_which;
@@ -90,6 +92,7 @@ static struct hpets *hpets;
 #define        HPET_OPEN               0x0001
 #define        HPET_IE                 0x0002  /* interrupt enabled */
 #define        HPET_PERIODIC           0x0004
+#define        HPET_SHARED_IRQ         0x0008
 
 #if BITS_PER_LONG == 64
 #define        write_counter(V, MC)    writeq(V, MC)
@@ -120,6 +123,11 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
        unsigned long isr;
 
        devp = data;
+       isr = 1 << (devp - devp->hd_hpets->hp_dev);
+
+       if ((devp->hd_flags & HPET_SHARED_IRQ) &&
+           !(isr & readl(&devp->hd_hpet->hpet_isr)))
+               return IRQ_NONE;
 
        spin_lock(&hpet_lock);
        devp->hd_irqdata++;
@@ -137,8 +145,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
                              &devp->hd_timer->hpet_compare);
        }
 
-       isr = (1 << (devp - devp->hd_hpets->hp_dev));
-       writeq(isr, &devp->hd_hpet->hpet_isr);
+       if (devp->hd_flags & HPET_SHARED_IRQ)
+               writel(isr, &devp->hd_hpet->hpet_isr);
        spin_unlock(&hpet_lock);
 
        spin_lock(&hpet_task_lock);
@@ -276,7 +284,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
 
        if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
                                        PAGE_SIZE, vma->vm_page_prot)) {
-               printk(KERN_ERR "remap_pfn_range failed in hpet.c\n");
+               printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
+                       __FUNCTION__);
                return -EAGAIN;
        }
 
@@ -364,7 +373,9 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
        hpet = devp->hd_hpet;
        hpetp = devp->hd_hpets;
 
-       v = readq(&timer->hpet_config);
+       if (!devp->hd_ireqfreq)
+               return -EIO;
+
        spin_lock_irq(&hpet_lock);
 
        if (devp->hd_flags & HPET_IE) {
@@ -373,16 +384,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
        }
 
        devp->hd_flags |= HPET_IE;
+
+       if (readl(&timer->hpet_config) & Tn_INT_TYPE_CNF_MASK)
+               devp->hd_flags |= HPET_SHARED_IRQ;
        spin_unlock_irq(&hpet_lock);
 
-       t = readq(&timer->hpet_config);
        irq = devp->hd_hdwirq;
 
        if (irq) {
-               sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+               unsigned long irq_flags;
 
-               if (request_irq
-                   (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) {
+               sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
+               irq_flags = devp->hd_flags & HPET_SHARED_IRQ
+                                               ? SA_SHIRQ : SA_INTERRUPT;
+               if (request_irq(irq, hpet_interrupt, irq_flags,
+                               devp->hd_name, (void *)devp)) {
                        printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
                        irq = 0;
                }
@@ -416,20 +432,24 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
                write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare);
        }
 
-       isr = (1 << (devp - hpets->hp_dev));
-       writeq(isr, &hpet->hpet_isr);
+       if (devp->hd_flags & HPET_SHARED_IRQ) {
+               isr = 1 << (devp - devp->hd_hpets->hp_dev);
+               writel(isr, &hpet->hpet_isr);
+       }
        writeq(g, &timer->hpet_config);
        local_irq_restore(flags);
 
        return 0;
 }
 
-static inline unsigned long hpet_time_div(unsigned long dis)
+/* converts Hz to number of timer ticks */
+static inline unsigned long hpet_time_div(struct hpets *hpets,
+                                         unsigned long dis)
 {
-       unsigned long long m = 1000000000000000ULL;
+       unsigned long long m;
 
+       m = hpets->hp_tick_freq + (dis >> 1);
        do_div(m, dis);
-
        return (unsigned long)m;
 }
 
@@ -477,14 +497,21 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
                {
                        struct hpet_info info;
 
-                       info.hi_ireqfreq = hpet_time_div(hpetp->hp_period *
-                                                        devp->hd_ireqfreq);
+                       if (devp->hd_ireqfreq)
+                               info.hi_ireqfreq =
+                                       hpet_time_div(hpetp, devp->hd_ireqfreq);
+                       else
+                               info.hi_ireqfreq = 0;
                        info.hi_flags =
                            readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK;
-                       info.hi_hpet = devp->hd_hpets->hp_which;
-                       info.hi_timer = devp - devp->hd_hpets->hp_dev;
-                       if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                               err = -EFAULT;
+                       info.hi_hpet = hpetp->hp_which;
+                       info.hi_timer = devp - hpetp->hp_dev;
+                       if (kernel)
+                               memcpy((void *)arg, &info, sizeof(info));
+                       else
+                               if (copy_to_user((void __user *)arg, &info,
+                                                sizeof(info)))
+                                       err = -EFAULT;
                        break;
                }
        case HPET_EPI:
@@ -516,12 +543,12 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
                        break;
                }
 
-               if (arg & (arg - 1)) {
+               if (!arg) {
                        err = -EINVAL;
                        break;
                }
 
-               devp->hd_ireqfreq = hpet_time_div(hpetp->hp_period * arg);
+               devp->hd_ireqfreq = hpet_time_div(hpetp, arg);
        }
 
        return err;
@@ -539,6 +566,17 @@ static struct file_operations hpet_fops = {
        .mmap = hpet_mmap,
 };
 
+static int hpet_is_known(struct hpet_data *hdp)
+{
+       struct hpets *hpetp;
+
+       for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
+               if (hpetp->hp_hpet_phys == hdp->hd_phys_address)
+                       return 1;
+
+       return 0;
+}
+
 EXPORT_SYMBOL(hpet_alloc);
 EXPORT_SYMBOL(hpet_register);
 EXPORT_SYMBOL(hpet_unregister);
@@ -563,6 +601,8 @@ int hpet_register(struct hpet_task *tp, int periodic)
                return -EINVAL;
        }
 
+       tp->ht_opaque = NULL;
+
        spin_lock_irq(&hpet_task_lock);
        spin_lock(&hpet_lock);
 
@@ -702,15 +742,14 @@ static void hpet_register_interpolator(struct hpets *hpetp)
 #ifdef CONFIG_TIME_INTERPOLATION
        struct time_interpolator *ti;
 
-       ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+       ti = kzalloc(sizeof(*ti), GFP_KERNEL);
        if (!ti)
                return;
 
-       memset(ti, 0, sizeof(*ti));
        ti->source = TIME_SOURCE_MMIO64;
        ti->shift = 10;
        ti->addr = &hpetp->hp_hpet->hpet_mc;
-       ti->frequency = hpet_time_div(hpets->hp_period);
+       ti->frequency = hpetp->hp_tick_freq;
        ti->drift = HPET_DRIFT;
        ti->mask = -1;
 
@@ -743,11 +782,11 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
        if (!timer)
                return 0;
 
-       hpet = hpets->hp_hpet;
+       hpet = hpetp->hp_hpet;
        t = read_counter(&timer->hpet_compare);
 
        i = 0;
-       count = hpet_time_div(hpetp->hp_period * TICK_CALIBRATE);
+       count = hpet_time_div(hpetp, TICK_CALIBRATE);
 
        local_irq_save(flags);
 
@@ -771,28 +810,29 @@ int hpet_alloc(struct hpet_data *hdp)
        struct hpets *hpetp;
        size_t siz;
        struct hpet __iomem *hpet;
-       static struct hpets *last = (struct hpets *)0;
-       unsigned long ns;
+       static struct hpets *last = NULL;
+       unsigned long period;
+       unsigned long long temp;
 
        /*
         * hpet_alloc can be called by platform dependent code.
-        * if platform dependent code has allocated the hpet
-        * ACPI also reports hpet, then we catch it here.
+        * If platform dependent code has allocated the hpet that
+        * ACPI has also reported, then we catch it here.
         */
-       for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
-               if (hpetp->hp_hpet == hdp->hd_address)
-                       return 0;
+       if (hpet_is_known(hdp)) {
+               printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
+                       __FUNCTION__);
+               return 0;
+       }
 
        siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
                                      sizeof(struct hpet_dev));
 
-       hpetp = kmalloc(siz, GFP_KERNEL);
+       hpetp = kzalloc(siz, GFP_KERNEL);
 
        if (!hpetp)
                return -ENOMEM;
 
-       memset(hpetp, 0, siz);
-
        hpetp->hp_which = hpet_nhpet++;
        hpetp->hp_hpet = hdp->hd_address;
        hpetp->hp_hpet_phys = hdp->hd_phys_address;
@@ -822,21 +862,23 @@ int hpet_alloc(struct hpet_data *hdp)
 
        last = hpetp;
 
-       hpetp->hp_period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
-           HPET_COUNTER_CLK_PERIOD_SHIFT;
+       period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
+               HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
+       temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
+       temp += period >> 1; /* round */
+       do_div(temp, period);
+       hpetp->hp_tick_freq = temp; /* ticks per second */
 
-       printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
-               hpetp->hp_which, hdp->hd_phys_address,
+       printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s",
+               hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address,
                hpetp->hp_ntimer > 1 ? "s" : "");
        for (i = 0; i < hpetp->hp_ntimer; i++)
                printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
        printk("\n");
 
-       ns = hpetp->hp_period;  /* femptoseconds, 10^-15 */
-       ns /= 1000000;          /* convert to nanoseconds, 10^-9 */
-       printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
-               hpetp->hp_which, ns, hpetp->hp_ntimer,
-               cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
+       printk(KERN_INFO "hpet%u: %u %d-bit timers, %Lu Hz\n",
+              hpetp->hp_which, hpetp->hp_ntimer,
+              cap & HPET_COUNTER_SIZE_MASK ? 64 : 32, hpetp->hp_tick_freq);
 
        mcfg = readq(&hpet->hpet_config);
        if ((mcfg & HPET_ENABLE_CNF_MASK) == 0) {
@@ -845,13 +887,10 @@ int hpet_alloc(struct hpet_data *hdp)
                writeq(mcfg, &hpet->hpet_config);
        }
 
-       for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer;
-            i++, hpet_ntimer++, devp++) {
-               unsigned long v;
+       for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
                struct hpet_timer __iomem *timer;
 
                timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
-               v = readq(&timer->hpet_config);
 
                devp->hd_hpets = hpetp;
                devp->hd_hpet = hpet;
@@ -880,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
        struct hpet_data *hdp;
        acpi_status status;
        struct acpi_resource_address64 addr;
-       struct hpets *hpetp;
 
        hdp = data;
 
@@ -893,9 +931,29 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
                hdp->hd_phys_address = addr.min_address_range;
                hdp->hd_address = ioremap(addr.min_address_range, size);
 
-               for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
-                       if (hpetp->hp_hpet == hdp->hd_address)
-                               return -EBUSY;
+               if (hpet_is_known(hdp)) {
+                       printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+                               __FUNCTION__, hdp->hd_phys_address);
+                       iounmap(hdp->hd_address);
+                       return -EBUSY;
+               }
+       } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
+               struct acpi_resource_fixed_mem32 *fixmem32;
+
+               fixmem32 = &res->data.fixed_memory32;
+               if (!fixmem32)
+                       return -EINVAL;
+
+               hdp->hd_phys_address = fixmem32->range_base_address;
+               hdp->hd_address = ioremap(fixmem32->range_base_address,
+                                               HPET_RANGE_SIZE);
+
+               if (hpet_is_known(hdp)) {
+                       printk(KERN_DEBUG "%s: 0x%lx is busy\n",
+                               __FUNCTION__, hdp->hd_phys_address);
+                       iounmap(hdp->hd_address);
+                       return -EBUSY;
+               }
        } else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
                struct acpi_resource_ext_irq *irqp;
                int i;
index 613aed9e1840a15e4843e396591dc205a5ceecf1..d1fe05e83882b57176b93f9be0f89d23478242da 100644 (file)
@@ -53,6 +53,8 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/sched.h>       /* cond_resched() */
+
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index 5b1d3680c8ab1e808e8a9c535bf23cbee1322bc8..928b850cc679839707c47e44d3e13ab4a06ac09e 100644 (file)
@@ -256,7 +256,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
 static int sReadAiopID(ByteIO_t io);
 static int sReadAiopNumChan(WordIO_t io);
 
-#ifdef MODULE
 MODULE_AUTHOR("Theodore Ts'o");
 MODULE_DESCRIPTION("Comtrol RocketPort driver");
 module_param(board1, ulong, 0);
@@ -288,17 +287,14 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1
 module_param_array(pc104_4, ulong, NULL, 0);
 MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
 
-int rp_init(void);
+static int rp_init(void);
 static void rp_cleanup_module(void);
 
 module_init(rp_init);
 module_exit(rp_cleanup_module);
 
-#endif
 
-#ifdef MODULE_LICENSE
 MODULE_LICENSE("Dual BSD/GPL");
-#endif
 
 /*************************************************************************/
 /*                     Module code starts here                           */
@@ -2378,7 +2374,7 @@ static struct tty_operations rocket_ops = {
 /*
  * The module "startup" routine; it's run when the module is loaded.
  */
-int __init rp_init(void)
+static int __init rp_init(void)
 {
        int retval, pci_boards_found, isa_boards_found, i;
 
@@ -2502,7 +2498,6 @@ int __init rp_init(void)
        return 0;
 }
 
-#ifdef MODULE
 
 static void rp_cleanup_module(void)
 {
@@ -2530,7 +2525,6 @@ static void rp_cleanup_module(void)
        if (controller)
                release_region(controller, 4);
 }
-#endif
 
 /***************************************************************************
 Function: sInitController
index 6b4e9d155f5053bdd154f8b5434810d69d0da2d1..dda30e42ec79806b8e2de0d79e365c407befb4eb 100644 (file)
@@ -790,7 +790,7 @@ static int __init a2232board_init(void)
 
        }       
 
-       printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */
+       printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
 
        a2232_init_portstructs();
 
index 50e0b612a8a2980242b648c06a908d1f6a687a00..352547eabf7b171bb4a676d7d772f65a1e575a15 100644 (file)
  *
  * Revision 1.0:  April 1st 1997.
  *                Initial release for alpha testing.
- * Revision 1.1:  April 14th 1997. 
- *                Incorporated Richard Hudsons suggestions, 
+ * Revision 1.1:  April 14th 1997.
+ *                Incorporated Richard Hudsons suggestions,
  *                removed some debugging printk's.
  * Revision 1.2:  April 15th 1997.
  *                Ported to 2.1.x kernels.
- * Revision 1.3:  April 17th 1997 
- *                Backported to 2.0. (Compatibility macros). 
+ * Revision 1.3:  April 17th 1997
+ *                Backported to 2.0. (Compatibility macros).
  * Revision 1.4:  April 18th 1997
- *                Fixed DTR/RTS bug that caused the card to indicate 
- *                "don't send data" to a modem after the password prompt.  
+ *                Fixed DTR/RTS bug that caused the card to indicate
+ *                "don't send data" to a modem after the password prompt.
  *                Fixed bug for premature (fake) interrupts.
  * Revision 1.5:  April 19th 1997
- *                fixed a minor typo in the header file, cleanup a little. 
+ *                fixed a minor typo in the header file, cleanup a little.
  *                performance warnings are now MAXed at once per minute.
  * Revision 1.6:  May 23 1997
  *                Changed the specialix=... format to include interrupt.
  *                port to linux-2.1.43 kernel.
  * Revision 1.9:  Oct 9  1998
  *                Added stuff for the IO8+/PCI version.
- * Revision 1.10: Oct 22  1999 / Jan 21 2000. 
- *                Added stuff for setserial. 
+ * Revision 1.10: Oct 22  1999 / Jan 21 2000.
+ *                Added stuff for setserial.
  *                Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
- * 
+ *
  */
 
 #define VERSION "1.11"
@@ -154,7 +154,7 @@ static int sx_poll = HZ;
 
 
 
-/* 
+/*
  * The following defines are mostly for testing purposes. But if you need
  * some nice reporting in your syslog, you can define them also.
  */
@@ -188,7 +188,7 @@ static DECLARE_MUTEX(tmp_buf_sem);
 
 static unsigned long baud_table[] =  {
        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 57600, 115200, 0, 
+       9600, 19200, 38400, 57600, 115200, 0,
 };
 
 static struct specialix_board sx_board[SX_NBOARD] =  {
@@ -216,7 +216,7 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
                KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
        static const char *badinfo =
                KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
+
        if (!port) {
                printk(badinfo, name, routine);
                return 1;
@@ -231,9 +231,9 @@ static inline int sx_paranoia_check(struct specialix_port const * port,
 
 
 /*
- * 
+ *
  *  Service functions for specialix IO8+ driver.
- * 
+ *
  */
 
 /* Get board number from pointer */
@@ -246,7 +246,7 @@ static inline int board_No (struct specialix_board * bp)
 /* Get port number from pointer */
 static inline int port_No (struct specialix_port const * port)
 {
-       return SX_PORT(port - sx_port); 
+       return SX_PORT(port - sx_port);
 }
 
 
@@ -309,7 +309,7 @@ static inline void sx_wait_CCR(struct specialix_board  * bp)
                        return;
                udelay (1);
        }
-       
+
        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 }
 
@@ -329,7 +329,7 @@ static inline void sx_wait_CCR_off(struct specialix_board  * bp)
                        return;
                udelay (1);
        }
-       
+
        printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 }
 
@@ -338,34 +338,28 @@ static inline void sx_wait_CCR_off(struct specialix_board  * bp)
  *  specialix IO8+ IO range functions.
  */
 
-static inline int sx_check_io_range(struct specialix_board * bp)
+static inline int sx_request_io_range(struct specialix_board * bp)
 {
-       return check_region (bp->base, SX_IO_SPACE);
-}
-
-
-static inline void sx_request_io_range(struct specialix_board * bp)
-{
-       request_region(bp->base, 
-                      bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
-                      "specialix IO8+" );
+       return request_region(bp->base,
+               bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
+               "specialix IO8+") == NULL;
 }
 
 
 static inline void sx_release_io_range(struct specialix_board * bp)
 {
-       release_region(bp->base, 
+       release_region(bp->base,
                       bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
 }
 
-       
+
 /* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization 
+/* Ugly. Very ugly. Don't use this for anything else than initialization
    code */
 static inline void sx_long_delay(unsigned long delay)
 {
        unsigned long i;
-       
+
        for (i = jiffies + delay; time_after(i, jiffies); ) ;
 }
 
@@ -378,7 +372,7 @@ static int sx_set_irq ( struct specialix_board *bp)
        int i;
        unsigned long flags;
 
-       if (bp->flags & SX_BOARD_IS_PCI) 
+       if (bp->flags & SX_BOARD_IS_PCI)
                return 1;
        switch (bp->irq) {
        /* In the same order as in the docs... */
@@ -420,7 +414,7 @@ static int sx_init_CD186x(struct specialix_board  * bp)
        sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
        /* Set RegAckEn */
        sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
-       
+
        /* Setting up prescaler. We need 4 ticks per 1 ms */
        scaler =  SX_OSCFREQ/SPECIALIX_TPS;
 
@@ -448,7 +442,7 @@ static int read_cross_byte (struct specialix_board *bp, int reg, int bit)
        spin_lock_irqsave(&bp->lock, flags);
        for (i=0, t=0;i<8;i++) {
                sx_out_off (bp, CD186x_CAR, i);
-               if (sx_in_off (bp, reg) & bit) 
+               if (sx_in_off (bp, reg) & bit)
                        t |= 1 << i;
        }
        spin_unlock_irqrestore(&bp->lock, flags);
@@ -472,7 +466,7 @@ void missed_irq (unsigned long data)
        spin_unlock_irqrestore(&bp->lock, flags);
        if (irq) {
                printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
-               sx_interrupt (((struct specialix_board *)data)->irq, 
+               sx_interrupt (((struct specialix_board *)data)->irq,
                              (void*)data, NULL);
        }
        missed_irq_timer.expires = jiffies + sx_poll;
@@ -495,7 +489,7 @@ static int sx_probe(struct specialix_board *bp)
 
        func_enter();
 
-       if (sx_check_io_range(bp)) {
+       if (sx_request_io_range(bp)) {
                func_exit();
                return 1;
        }
@@ -509,15 +503,16 @@ static int sx_probe(struct specialix_board *bp)
        short_pause ();
        val2 = sx_in_off(bp, CD186x_PPRL);
 
-       
+
        if ((val1 != 0x5a) || (val2 != 0xa5)) {
                printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
                       board_No(bp), bp->base);
+               sx_release_io_range(bp);
                func_exit();
                return 1;
        }
 
-       /* Check the DSR lines that Specialix uses as board 
+       /* Check the DSR lines that Specialix uses as board
           identification */
        val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
        val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
@@ -532,6 +527,7 @@ static int sx_probe(struct specialix_board *bp)
        if (val1 != val2) {
                printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
                       board_No(bp), val2, bp->base, val1);
+               sx_release_io_range(bp);
                func_exit();
                return 1;
        }
@@ -546,7 +542,7 @@ static int sx_probe(struct specialix_board *bp)
                sx_wait_CCR(bp);
                sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
                sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
-               sx_long_delay(HZ/20);                   
+               sx_long_delay(HZ/20);
                irqs = probe_irq_off(irqs);
 
                dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
@@ -561,14 +557,15 @@ static int sx_probe(struct specialix_board *bp)
                }
 
                dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
-                       val1, val2, val3); 
-       
+                       val1, val2, val3);
+
        }
-       
+
 #if 0
        if (irqs <= 0) {
                printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
                       board_No(bp), bp->base);
+               sx_release_io_range(bp);
                func_exit();
                return 1;
        }
@@ -579,19 +576,20 @@ static int sx_probe(struct specialix_board *bp)
 #endif
        /* Reset CD186x again  */
        if (!sx_init_CD186x(bp)) {
+               sx_release_io_range(bp);
                func_exit();
-               return -EIO;
+               return 1;
        }
 
        sx_request_io_range(bp);
        bp->flags |= SX_BOARD_PRESENT;
-       
+
        /* Chip           revcode   pkgtype
                          GFRCR     SRCR bit 7
           CD180 rev B    0x81      0
           CD180 rev C    0x82      0
           CD1864 rev A   0x82      1
-          CD1865 rev A   0x83      1  -- Do not use!!! Does not work. 
+          CD1865 rev A   0x83      1  -- Do not use!!! Does not work.
           CD1865 rev B   0x84      1
         -- Thanks to Gwen Wang, Cirrus Logic.
         */
@@ -623,8 +621,8 @@ static int sx_probe(struct specialix_board *bp)
        return 0;
 }
 
-/* 
- * 
+/*
+ *
  *  Interrupt processing routines.
  * */
 
@@ -657,7 +655,7 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
                        return port;
                }
        }
-       printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", 
+       printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
               board_No(bp), what, channel);
        return NULL;
 }
@@ -681,7 +679,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
        tty = port->tty;
        dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
                 port,  tty->flip.count, TTY_FLIPBUF_SIZE);
-       
+
        status = sx_in(bp, CD186x_RCSR);
 
        dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
@@ -707,30 +705,30 @@ static inline void sx_receive_exc(struct specialix_board * bp)
                return;
        }
        if (status & RCSR_TOUT) {
-               printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", 
+               printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
                       board_No(bp), port_No(port));
                func_exit();
                return;
-               
+
        } else if (status & RCSR_BREAK) {
                dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
                       board_No(bp), port_No(port));
                *tty->flip.flag_buf_ptr++ = TTY_BREAK;
                if (port->flags & ASYNC_SAK)
                        do_SAK(tty);
-               
-       } else if (status & RCSR_PE) 
+
+       } else if (status & RCSR_PE)
                *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-       
-       else if (status & RCSR_FE) 
+
+       else if (status & RCSR_FE)
                *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-       
+
        else if (status & RCSR_OE)
                *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-       
+
        else
                *tty->flip.flag_buf_ptr++ = 0;
-       
+
        *tty->flip.char_buf_ptr++ = ch;
        tty->flip.count++;
        schedule_delayed_work(&tty->flip.work, 1);
@@ -746,18 +744,18 @@ static inline void sx_receive(struct specialix_board * bp)
        unsigned char count;
 
        func_enter();
-       
+
        if (!(port = sx_get_port(bp, "Receive"))) {
                dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
                func_exit();
                return;
        }
        tty = port->tty;
-       
+
        count = sx_in(bp, CD186x_RDCR);
        dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
        port->hits[count > 8 ? 9 : count]++;
-       
+
        while (count--) {
                if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
                        printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
@@ -787,7 +785,7 @@ static inline void sx_transmit(struct specialix_board * bp)
        }
        dprintk (SX_DEBUG_TX, "port: %p\n", port);
        tty = port->tty;
-       
+
        if (port->IER & IER_TXEMPTY) {
                /* FIFO drained */
                sx_out(bp, CD186x_CAR, port_No(port));
@@ -796,7 +794,7 @@ static inline void sx_transmit(struct specialix_board * bp)
                func_exit();
                return;
        }
-       
+
        if ((port->xmit_cnt <= 0 && !port->break_length)
            || tty->stopped || tty->hw_stopped) {
                sx_out(bp, CD186x_CAR, port_No(port));
@@ -805,7 +803,7 @@ static inline void sx_transmit(struct specialix_board * bp)
                func_exit();
                return;
        }
-       
+
        if (port->break_length) {
                if (port->break_length > 0) {
                        if (port->COR2 & COR2_ETC) {
@@ -831,7 +829,7 @@ static inline void sx_transmit(struct specialix_board * bp)
                func_exit();
                return;
        }
-       
+
        count = CD186x_NFIFO;
        do {
                sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
@@ -839,7 +837,7 @@ static inline void sx_transmit(struct specialix_board * bp)
                if (--port->xmit_cnt <= 0)
                        break;
        } while (--count > 0);
-       
+
        if (port->xmit_cnt <= 0) {
                sx_out(bp, CD186x_CAR, port_No(port));
                port->IER &= ~IER_TXRDY;
@@ -862,9 +860,9 @@ static inline void sx_check_modem(struct specialix_board * bp)
        dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
        if (!(port = sx_get_port(bp, "Modem")))
                return;
-       
+
        tty = port->tty;
-       
+
        mcr = sx_in(bp, CD186x_MCR);
        printk ("mcr = %02x.\n", mcr);
 
@@ -879,7 +877,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
                        schedule_work(&port->tqueue_hangup);
                }
        }
-       
+
 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
        if (mcr & MCR_CTSCHG) {
                if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
@@ -906,7 +904,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
                sx_out(bp, CD186x_IER, port->IER);
        }
 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
-       
+
        /* Clear change bits */
        sx_out(bp, CD186x_MCR, 0);
 }
@@ -940,7 +938,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
                                           (SRSR_RREQint |
                                            SRSR_TREQint |
-                                           SRSR_MREQint)))) {  
+                                           SRSR_MREQint)))) {
                if (status & SRSR_RREQint) {
                        ack = sx_in(bp, CD186x_RRAR);
 
@@ -951,7 +949,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        else
                                printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
                                       board_No(bp), status, ack);
-               
+
                } else if (status & SRSR_TREQint) {
                        ack = sx_in(bp, CD186x_TRAR);
 
@@ -963,13 +961,13 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                } else if (status & SRSR_MREQint) {
                        ack = sx_in(bp, CD186x_MRAR);
 
-                       if (ack == (SX_ID | GIVR_IT_MODEM)) 
+                       if (ack == (SX_ID | GIVR_IT_MODEM))
                                sx_check_modem(bp);
                        else
                                printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
                                       board_No(bp), status, ack);
-               
-               } 
+
+               }
 
                sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
        }
@@ -1026,7 +1024,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
 {
        int error;
 
-       if (bp->flags & SX_BOARD_ACTIVE) 
+       if (bp->flags & SX_BOARD_ACTIVE)
                return 0;
 
        if (bp->flags & SX_BOARD_IS_PCI)
@@ -1034,7 +1032,7 @@ static inline int sx_setup_board(struct specialix_board * bp)
        else
                error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
 
-       if (error) 
+       if (error)
                return error;
 
        turn_ints_on (bp);
@@ -1055,7 +1053,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
        }
 
        bp->flags &= ~SX_BOARD_ACTIVE;
-       
+
        dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
                 bp->irq, board_No (bp));
        free_irq(bp->irq, bp);
@@ -1068,7 +1066,7 @@ static inline void sx_shutdown_board(struct specialix_board *bp)
 
 
 /*
- * Setting up port characteristics. 
+ * Setting up port characteristics.
  * Must be called with disabled interrupts
  */
 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
@@ -1103,10 +1101,10 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
        spin_unlock_irqrestore(&bp->lock, flags);
        dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
        baud = C_BAUD(tty);
-       
+
        if (baud & CBAUDEX) {
                baud &= ~CBAUDEX;
-               if (baud < 1 || baud > 2) 
+               if (baud < 1 || baud > 2)
                        port->tty->termios->c_cflag &= ~CBAUDEX;
                else
                        baud += 15;
@@ -1117,8 +1115,8 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
                        baud += 2;
        }
-       
-       
+
+
        if (!baud_table[baud]) {
                /* Drop DTR & exit */
                dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
@@ -1127,7 +1125,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                        spin_lock_irqsave(&bp->lock, flags);
                        sx_out(bp, CD186x_MSVR, port->MSVR );
                        spin_unlock_irqrestore(&bp->lock, flags);
-               } 
+               }
                else
                        dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
                return;
@@ -1137,9 +1135,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                        port ->MSVR |= MSVR_DTR;
                }
        }
-       
+
        /*
-        * Now we must calculate some speed depended things 
+        * Now we must calculate some speed depended things
         */
 
        /* Set baud rate for port */
@@ -1152,7 +1150,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
                         CD186x_TPC/2) / CD186x_TPC);
 
-       if ((tmp < 0x10) && time_before(again, jiffies)) { 
+       if ((tmp < 0x10) && time_before(again, jiffies)) {
                again = jiffies + HZ * 60;
                /* Page 48 of version 2.0 of the CL-CD1865 databook */
                if (tmp >= 12) {
@@ -1164,27 +1162,27 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                        printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
                                "Warning: overstressing Cirrus chip. "
                                "This might not work.\n"
-                               "Read specialix.txt for more info.\n", 
+                               "Read specialix.txt for more info.\n",
                                port_No (port), tmp);
                }
        }
        spin_lock_irqsave(&bp->lock, flags);
-       sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); 
-       sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); 
-       sx_out(bp, CD186x_RBPRL, tmp & 0xff); 
+       sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
+       sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
+       sx_out(bp, CD186x_RBPRL, tmp & 0xff);
        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
        spin_unlock_irqrestore(&bp->lock, flags);
        if (port->custom_divisor) {
                baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
                baud = ( baud + 5 ) / 10;
-       } else 
+       } else
                baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
 
        /* Two timer ticks seems enough to wakeup something like SLIP driver */
-       tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;          
+       tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
        port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
                                              SERIAL_XMIT_SIZE - 1 : tmp);
-       
+
        /* Receiver timeout will be transmission time for 1.5 chars */
        tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
        tmp = (tmp > 0xff) ? 0xff : tmp;
@@ -1205,29 +1203,29 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                cor1 |= COR1_8BITS;
                break;
        }
-       
-       if (C_CSTOPB(tty)) 
+
+       if (C_CSTOPB(tty))
                cor1 |= COR1_2SB;
-       
+
        cor1 |= COR1_IGNORE;
        if (C_PARENB(tty)) {
                cor1 |= COR1_NORMPAR;
-               if (C_PARODD(tty)) 
+               if (C_PARODD(tty))
                        cor1 |= COR1_ODDP;
-               if (I_INPCK(tty)) 
+               if (I_INPCK(tty))
                        cor1 &= ~COR1_IGNORE;
        }
        /* Set marking of some errors */
        port->mark_mask = RCSR_OE | RCSR_TOUT;
-       if (I_INPCK(tty)) 
+       if (I_INPCK(tty))
                port->mark_mask |= RCSR_FE | RCSR_PE;
-       if (I_BRKINT(tty) || I_PARMRK(tty)) 
+       if (I_BRKINT(tty) || I_PARMRK(tty))
                port->mark_mask |= RCSR_BREAK;
-       if (I_IGNPAR(tty)) 
+       if (I_IGNPAR(tty))
                port->mark_mask &= ~(RCSR_FE | RCSR_PE);
        if (I_IGNBRK(tty)) {
                port->mark_mask &= ~RCSR_BREAK;
-               if (I_IGNPAR(tty)) 
+               if (I_IGNPAR(tty))
                        /* Real raw mode. Ignore all */
                        port->mark_mask &= ~RCSR_OE;
        }
@@ -1241,7 +1239,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
                spin_unlock_irqrestore(&bp->lock, flags);
 #else
-               port->COR2 |= COR2_CTSAE; 
+               port->COR2 |= COR2_CTSAE;
 #endif
        }
        /* Enable Software Flow Control. FIXME: I'm not sure about this */
@@ -1264,11 +1262,11 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
                mcor1 |= MCOR1_CDZD;
                mcor2 |= MCOR2_CDOD;
        }
-       
-       if (C_CREAD(tty)) 
+
+       if (C_CREAD(tty))
                /* Enable receiver */
                port->IER |= IER_RXD;
-       
+
        /* Set input FIFO size (1-8 bytes) */
        cor3 |= sx_rxfifo;
        /* Setting up CD186x channel registers */
@@ -1311,11 +1309,11 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
                func_exit();
                return 0;
        }
-       
+
        if (!port->xmit_buf) {
                /* We may sleep in get_zeroed_page() */
                unsigned long tmp;
-               
+
                if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
                        func_exit();
                        return -ENOMEM;
@@ -1328,10 +1326,10 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
                }
                port->xmit_buf = (unsigned char *) tmp;
        }
-               
+
        spin_lock_irqsave(&port->lock, flags);
 
-       if (port->tty) 
+       if (port->tty)
                clear_bit(TTY_IO_ERROR, &port->tty->flags);
 
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -1340,7 +1338,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
 
        spin_unlock_irqrestore(&port->lock, flags);
 
-               
+
        func_exit();
        return 0;
 }
@@ -1352,14 +1350,14 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
        struct tty_struct *tty;
        int i;
        unsigned long flags;
-       
+
        func_enter();
 
        if (!(port->flags & ASYNC_INITIALIZED)) {
                func_exit();
                return;
        }
-       
+
        if (sx_debug & SX_DEBUG_FIFO) {
                dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
                        board_No(bp), port_No(port), port->overrun);
@@ -1394,13 +1392,13 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
        if (tty)
                set_bit(TTY_IO_ERROR, &tty->flags);
        port->flags &= ~ASYNC_INITIALIZED;
-       
-       if (!bp->count) 
+
+       if (!bp->count)
                sx_shutdown_board(bp);
        func_exit();
 }
 
-       
+
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
                            struct specialix_port *port)
 {
@@ -1427,7 +1425,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                        return -ERESTARTSYS;
                }
        }
-       
+
        /*
         * If non-blocking mode is set, or the port is not enabled,
         * then make the check up front and then exit.
@@ -1477,7 +1475,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                        if (port->flags & ASYNC_HUP_NOTIFY)
                                retval = -EAGAIN;
                        else
-                               retval = -ERESTARTSYS;  
+                               retval = -ERESTARTSYS;
                        break;
                }
                if (!(port->flags & ASYNC_CLOSING) &&
@@ -1506,7 +1504,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
        port->flags |= ASYNC_NORMAL_ACTIVE;
        func_exit();
        return 0;
-}      
+}
 
 
 static int sx_open(struct tty_struct * tty, struct file * filp)
@@ -1526,7 +1524,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
                func_exit();
                return -ENODEV;
        }
-       
+
        bp = &sx_board[board];
        port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
        port->overrun = 0;
@@ -1557,7 +1555,7 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
                func_enter();
                return error;
        }
-       
+
        if ((error = block_til_ready(tty, filp, port))) {
                func_enter();
                return error;
@@ -1574,7 +1572,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
        struct specialix_board *bp;
        unsigned long flags;
        unsigned long timeout;
-       
+
        func_enter();
        if (!port || sx_paranoia_check(port, tty->name, "close")) {
                func_exit();
@@ -1587,7 +1585,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
                func_exit();
                return;
        }
-       
+
        bp = port_Board(port);
        if ((tty->count == 1) && (port->count != 1)) {
                printk(KERN_ERR "sx%d: sx_close: bad port count;"
@@ -1607,7 +1605,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
        }
        port->flags |= ASYNC_CLOSING;
        /*
-        * Now we wait for the transmit buffer to clear; and we notify 
+        * Now we wait for the transmit buffer to clear; and we notify
         * the line discipline to only process XON/XOFF characters.
         */
        tty->closing = 1;
@@ -1681,7 +1679,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
 }
 
 
-static int sx_write(struct tty_struct * tty, 
+static int sx_write(struct tty_struct * tty,
                     const unsigned char *buf, int count)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -1694,7 +1692,7 @@ static int sx_write(struct tty_struct * tty,
                func_exit();
                return 0;
        }
-       
+
        bp = port_Board(port);
 
        if (!tty || !port->xmit_buf || !tmp_buf) {
@@ -1824,7 +1822,7 @@ static int sx_chars_in_buffer(struct tty_struct *tty)
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
 
        func_enter();
-       
+
        if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
                func_exit();
                return 0;
@@ -1881,13 +1879,13 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
                port_No(port), status, sx_in (bp, CD186x_CAR));
        dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
        if (SX_CRTSCTS(port->tty)) {
-               result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ 
+               result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
                          |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
                          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
                          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
        } else {
-               result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ 
+               result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
                          |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
                          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
                          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
@@ -1955,7 +1953,7 @@ static inline void sx_send_break(struct specialix_port * port, unsigned long len
 {
        struct specialix_board *bp = port_Board(port);
        unsigned long flags;
-       
+
        func_enter();
 
        spin_lock_irqsave (&port->lock, flags);
@@ -1996,8 +1994,8 @@ static inline int sx_set_serial_info(struct specialix_port * port,
                func_enter();
                return -EFAULT;
        }
-       
-#if 0  
+
+#if 0
        if ((tmp.irq != bp->irq) ||
            (tmp.port != bp->base) ||
            (tmp.type != PORT_CIRRUS) ||
@@ -2008,12 +2006,12 @@ static inline int sx_set_serial_info(struct specialix_port * port,
                func_exit();
                return -EINVAL;
        }
-#endif 
+#endif
 
        change_speed = ((port->flags & ASYNC_SPD_MASK) !=
                        (tmp.flags & ASYNC_SPD_MASK));
        change_speed |= (tmp.custom_divisor != port->custom_divisor);
-       
+
        if (!capable(CAP_SYS_ADMIN)) {
                if ((tmp.close_delay != port->close_delay) ||
                    (tmp.closing_wait != port->closing_wait) ||
@@ -2045,7 +2043,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
 {
        struct serial_struct tmp;
        struct specialix_board *bp = port_Board(port);
-       
+
        func_enter();
 
        /*
@@ -2074,7 +2072,7 @@ static inline int sx_get_serial_info(struct specialix_port * port,
 }
 
 
-static int sx_ioctl(struct tty_struct * tty, struct file * filp, 
+static int sx_ioctl(struct tty_struct * tty, struct file * filp,
                     unsigned int cmd, unsigned long arg)
 {
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -2087,7 +2085,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
                func_exit();
                return -ENODEV;
        }
-       
+
        switch (cmd) {
         case TCSBRK:   /* SVID version: non-zero arg --> no break */
                retval = tty_check_change(tty);
@@ -2129,7 +2127,7 @@ static int sx_ioctl(struct tty_struct * tty, struct file * filp,
         case TIOCGSERIAL:
                 func_exit();
                return sx_get_serial_info(port, argp);
-        case TIOCSSERIAL:      
+        case TIOCSSERIAL:
                 func_exit();
                return sx_set_serial_info(port, argp);
         default:
@@ -2153,16 +2151,16 @@ static void sx_throttle(struct tty_struct * tty)
                func_exit();
                return;
        }
-       
+
        bp = port_Board(port);
-       
+
        /* Use DTR instead of RTS ! */
-       if (SX_CRTSCTS (tty)) 
+       if (SX_CRTSCTS (tty))
                port->MSVR &= ~MSVR_DTR;
        else {
                /* Auch!!! I think the system shouldn't call this then. */
                /* Or maybe we're supposed (allowed?) to do our side of hw
-                  handshake anyway, even when hardware handshake is off. 
+                  handshake anyway, even when hardware handshake is off.
                   When you see this in your logs, please report.... */
                printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
                         port_No (port));
@@ -2193,14 +2191,14 @@ static void sx_unthrottle(struct tty_struct * tty)
        unsigned long flags;
 
        func_enter();
-                               
+
        if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
                func_exit();
                return;
        }
-       
+
        bp = port_Board(port);
-       
+
        spin_lock_irqsave(&port->lock, flags);
        /* XXXX Use DTR INSTEAD???? */
        if (SX_CRTSCTS(tty)) {
@@ -2234,14 +2232,14 @@ static void sx_stop(struct tty_struct * tty)
        unsigned long flags;
 
        func_enter();
-       
+
        if (sx_paranoia_check(port, tty->name, "sx_stop")) {
                func_exit();
                return;
        }
 
        bp = port_Board(port);
-       
+
        spin_lock_irqsave(&port->lock, flags);
        port->IER &= ~IER_TXRDY;
        spin_lock_irqsave(&bp->lock, flags);
@@ -2261,14 +2259,14 @@ static void sx_start(struct tty_struct * tty)
        unsigned long flags;
 
        func_enter();
-                               
+
        if (sx_paranoia_check(port, tty->name, "sx_start")) {
                func_exit();
                return;
        }
-       
+
        bp = port_Board(port);
-       
+
        spin_lock_irqsave(&port->lock, flags);
        if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
                port->IER |= IER_TXRDY;
@@ -2290,13 +2288,13 @@ static void sx_start(struct tty_struct * tty)
  *
  *     serial interrupt routine -> (workqueue) ->
  *     do_sx_hangup() -> tty->hangup() -> sx_hangup()
- * 
+ *
  */
 static void do_sx_hangup(void *private_)
 {
        struct specialix_port   *port = (struct specialix_port *) private_;
        struct tty_struct       *tty;
-       
+
        func_enter();
 
        tty = port->tty;
@@ -2319,9 +2317,9 @@ static void sx_hangup(struct tty_struct * tty)
                func_exit();
                return;
        }
-       
+
        bp = port_Board(port);
-       
+
        sx_shutdown_port(bp, port);
        spin_lock_irqsave(&port->lock, flags);
        port->event = 0;
@@ -2346,10 +2344,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios
        struct specialix_port *port = (struct specialix_port *)tty->driver_data;
        unsigned long flags;
        struct specialix_board  * bp;
-                               
+
        if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
                return;
-       
+
        if (tty->termios->c_cflag == old_termios->c_cflag &&
            tty->termios->c_iflag == old_termios->c_iflag)
                return;
@@ -2420,7 +2418,7 @@ static int sx_init_drivers(void)
                func_exit();
                return 1;
        }
-       
+
        if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
                printk(KERN_ERR "sx: Couldn't get free page.\n");
                put_tty_driver(specialix_driver);
@@ -2457,7 +2455,7 @@ static int sx_init_drivers(void)
                init_waitqueue_head(&sx_port[i].close_wait);
                spin_lock_init(&sx_port[i].lock);
        }
-       
+
        func_exit();
        return 0;
 }
@@ -2472,8 +2470,8 @@ static void sx_release_drivers(void)
        func_exit();
 }
 
-/* 
- * This routine must be called by kernel at boot time 
+/*
+ * This routine must be called by kernel at boot time
  */
 static int __init specialix_init(void)
 {
@@ -2489,7 +2487,7 @@ static int __init specialix_init(void)
 #else
        printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
 #endif
-       
+
        for (i = 0; i < SX_NBOARD; i++)
                sx_board[i].lock = SPIN_LOCK_UNLOCKED;
 
@@ -2498,7 +2496,7 @@ static int __init specialix_init(void)
                return -EIO;
        }
 
-       for (i = 0; i < SX_NBOARD; i++) 
+       for (i = 0; i < SX_NBOARD; i++)
                if (sx_board[i].base && !sx_probe(&sx_board[i]))
                        found++;
 
@@ -2512,8 +2510,8 @@ static int __init specialix_init(void)
                                i++;
                                continue;
                        }
-                       pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
-                                               PCI_DEVICE_ID_SPECIALIX_IO8, 
+                       pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+                                               PCI_DEVICE_ID_SPECIALIX_IO8,
                                                pdev);
                        if (!pdev) break;
 
@@ -2557,10 +2555,10 @@ module_param(sx_poll, int, 0);
 /*
  * You can setup up to 4 boards.
  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
- * You should specify the IRQs too in that case "irq=....,...". 
- * 
+ * You should specify the IRQs too in that case "irq=....,...".
+ *
  * More than 4 boards in one computer is not possible, as the card can
- * only use 4 different interrupts. 
+ * only use 4 different interrupts.
  *
  */
 static int __init specialix_init_module(void)
@@ -2583,16 +2581,16 @@ static int __init specialix_init_module(void)
 
        return specialix_init();
 }
-       
+
 static void __exit specialix_exit_module(void)
 {
        int i;
-       
+
        func_enter();
 
        sx_release_drivers();
        for (i = 0; i < SX_NBOARD; i++)
-               if (sx_board[i].flags & SX_BOARD_PRESENT) 
+               if (sx_board[i].flags & SX_BOARD_PRESENT)
                        sx_release_io_range(&sx_board[i]);
 #ifdef SPECIALIX_TIMER
        del_timer (&missed_irq_timer);
index ea2d54be4843e07c17efc83ebf14a6677e599a5d..0133dc0e25d087cfd4cabedb261d28f0572fdd98 100644 (file)
@@ -912,6 +912,7 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver synclink_pci_driver = {
+       .owner          = THIS_MODULE,
        .name           = "synclink",
        .id_table       = synclink_pci_tbl,
        .probe          = synclink_init_one,
index 6fb165cf8a61ca0ca4be7532e00909f342bb4f03..f185724448b142e6da58b3761e10ac74f85f9a05 100644 (file)
@@ -500,6 +500,7 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver synclinkmp_pci_driver = {
+       .owner          = THIS_MODULE,
        .name           = "synclinkmp",
        .id_table       = synclinkmp_pci_tbl,
        .probe          = synclinkmp_init_one,
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
new file mode 100644 (file)
index 0000000..18cdd43
--- /dev/null
@@ -0,0 +1,896 @@
+/*
+ * Telecom Clock driver for Intel NetStructure(tm) MPCBL0010
+ *
+ * Copyright (C) 2005 Kontron Canada
+ *
+ * All rights reserved.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <sebastien.bouchard@ca.kontron.com> and the current
+ * Maintainer  <mark.gross@intel.com>
+ *
+ * Description : This is the TELECOM CLOCK module driver for the ATCA
+ * MPCBL0010 ATCA computer.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>      /* printk() */
+#include <linux/fs.h>          /* everything... */
+#include <linux/errno.h>       /* error codes */
+#include <linux/delay.h>       /* udelay */
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <asm/io.h>            /* inb/outb */
+#include <asm/uaccess.h>
+
+MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>");
+MODULE_LICENSE("GPL");
+
+/*Hardware Reset of the PLL */
+#define RESET_ON       0x00
+#define RESET_OFF      0x01
+
+/* MODE SELECT */
+#define NORMAL_MODE    0x00
+#define HOLDOVER_MODE  0x10
+#define FREERUN_MODE   0x20
+
+/* FILTER SELECT */
+#define FILTER_6HZ     0x04
+#define FILTER_12HZ    0x00
+
+/* SELECT REFERENCE FREQUENCY */
+#define REF_CLK1_8kHz          0x00
+#define REF_CLK2_19_44MHz      0x02
+
+/* Select primary or secondary redundant clock */
+#define PRIMARY_CLOCK  0x00
+#define SECONDARY_CLOCK        0x01
+
+/* CLOCK TRANSMISSION DEFINE */
+#define CLK_8kHz       0xff
+#define CLK_16_384MHz  0xfb
+
+#define CLK_1_544MHz   0x00
+#define CLK_2_048MHz   0x01
+#define CLK_4_096MHz   0x02
+#define CLK_6_312MHz   0x03
+#define CLK_8_192MHz   0x04
+#define CLK_19_440MHz  0x06
+
+#define CLK_8_592MHz   0x08
+#define CLK_11_184MHz  0x09
+#define CLK_34_368MHz  0x0b
+#define CLK_44_736MHz  0x0a
+
+/* RECEIVED REFERENCE */
+#define AMC_B1 0
+#define AMC_B2 1
+
+/* HARDWARE SWITCHING DEFINE */
+#define HW_ENABLE      0x80
+#define HW_DISABLE     0x00
+
+/* HARDWARE SWITCHING MODE DEFINE */
+#define PLL_HOLDOVER   0x40
+#define LOST_CLOCK     0x00
+
+/* ALARMS DEFINE */
+#define UNLOCK_MASK    0x10
+#define HOLDOVER_MASK  0x20
+#define SEC_LOST_MASK  0x40
+#define PRI_LOST_MASK  0x80
+
+/* INTERRUPT CAUSE DEFINE */
+
+#define PRI_LOS_01_MASK                0x01
+#define PRI_LOS_10_MASK                0x02
+
+#define SEC_LOS_01_MASK                0x04
+#define SEC_LOS_10_MASK                0x08
+
+#define HOLDOVER_01_MASK       0x10
+#define HOLDOVER_10_MASK       0x20
+
+#define UNLOCK_01_MASK         0x40
+#define UNLOCK_10_MASK         0x80
+
+struct tlclk_alarms {
+       __u32 lost_clocks;
+       __u32 lost_primary_clock;
+       __u32 lost_secondary_clock;
+       __u32 primary_clock_back;
+       __u32 secondary_clock_back;
+       __u32 switchover_primary;
+       __u32 switchover_secondary;
+       __u32 pll_holdover;
+       __u32 pll_end_holdover;
+       __u32 pll_lost_sync;
+       __u32 pll_sync;
+};
+/* Telecom clock I/O register definition */
+#define TLCLK_BASE 0xa08
+#define TLCLK_REG0 TLCLK_BASE
+#define TLCLK_REG1 (TLCLK_BASE+1)
+#define TLCLK_REG2 (TLCLK_BASE+2)
+#define TLCLK_REG3 (TLCLK_BASE+3)
+#define TLCLK_REG4 (TLCLK_BASE+4)
+#define TLCLK_REG5 (TLCLK_BASE+5)
+#define TLCLK_REG6 (TLCLK_BASE+6)
+#define TLCLK_REG7 (TLCLK_BASE+7)
+
+#define SET_PORT_BITS(port, mask, val) outb(((inb(port) & mask) | val), port)
+
+/* 0 = Dynamic allocation of the major device number */
+#define TLCLK_MAJOR 0
+
+/* sysfs interface definition:
+Upon loading the driver will create a sysfs directory under
+/sys/devices/platform/telco_clock.
+
+This directory exports the following interfaces.  There operation is
+documented in the MCPBL0010 TPS under the Telecom Clock API section, 11.4.
+alarms                         :
+current_ref                    :
+enable_clk3a_output            :
+enable_clk3b_output            :
+enable_clka0_output            :
+enable_clka1_output            :
+enable_clkb0_output            :
+enable_clkb1_output            :
+filter_select                  :
+hardware_switching             :
+hardware_switching_mode                :
+interrupt_switch               :
+mode_select                    :
+refalign                       :
+reset                          :
+select_amcb1_transmit_clock    :
+select_amcb2_transmit_clock    :
+select_redundant_clock         :
+select_ref_frequency           :
+test_mode                      :
+
+All sysfs interfaces are integers in hex format, i.e echo 99 > refalign
+has the same effect as echo 0x99 > refalign.
+*/
+
+static unsigned int telclk_interrupt;
+
+static int int_events;         /* Event that generate a interrupt */
+static int got_event;          /* if events processing have been done */
+
+static void switchover_timeout(unsigned long data);
+static struct timer_list switchover_timer =
+       TIMER_INITIALIZER(switchover_timeout , 0, 0);
+
+static struct tlclk_alarms *alarm_events;
+
+static DEFINE_SPINLOCK(event_lock);
+
+static int tlclk_major = TLCLK_MAJOR;
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static DECLARE_WAIT_QUEUE_HEAD(wq);
+
+static int tlclk_open(struct inode *inode, struct file *filp)
+{
+       int result;
+
+       /* Make sure there is no interrupt pending while
+        * initialising interrupt handler */
+       inb(TLCLK_REG6);
+
+       /* This device is wired through the FPGA IO space of the ATCA blade
+        * we can't share this IRQ */
+       result = request_irq(telclk_interrupt, &tlclk_interrupt,
+                            SA_INTERRUPT, "telco_clock", tlclk_interrupt);
+       if (result == -EBUSY) {
+               printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n");
+               return -EBUSY;
+       }
+       inb(TLCLK_REG6);        /* Clear interrupt events */
+
+       return 0;
+}
+
+static int tlclk_release(struct inode *inode, struct file *filp)
+{
+       free_irq(telclk_interrupt, tlclk_interrupt);
+
+       return 0;
+}
+
+ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count,
+               loff_t *f_pos)
+{
+       if (count < sizeof(struct tlclk_alarms))
+               return -EIO;
+
+       wait_event_interruptible(wq, got_event);
+       if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms)))
+               return -EFAULT;
+
+       memset(alarm_events, 0, sizeof(struct tlclk_alarms));
+       got_event = 0;
+
+       return  sizeof(struct tlclk_alarms);
+}
+
+ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count,
+           loff_t *f_pos)
+{
+       return 0;
+}
+
+static struct file_operations tlclk_fops = {
+       .read = tlclk_read,
+       .write = tlclk_write,
+       .open = tlclk_open,
+       .release = tlclk_release,
+
+};
+
+static struct miscdevice tlclk_miscdev = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "telco_clock",
+       .fops = &tlclk_fops,
+};
+
+static ssize_t show_current_ref(struct device *d,
+               struct device_attribute *attr, char *buf)
+{
+       unsigned long ret_val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&event_lock, flags);
+       ret_val = ((inb(TLCLK_REG1) & 0x08) >> 3);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL);
+
+
+static ssize_t show_interrupt_switch(struct device *d,
+               struct device_attribute *attr, char *buf)
+{
+       unsigned long ret_val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&event_lock, flags);
+       ret_val = inb(TLCLK_REG6);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(interrupt_switch, S_IRUGO,
+               show_interrupt_switch, NULL);
+
+static ssize_t show_alarms(struct device *d,
+               struct device_attribute *attr,  char *buf)
+{
+       unsigned long ret_val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&event_lock, flags);
+       ret_val = (inb(TLCLK_REG2) & 0xf0);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return sprintf(buf, "0x%lX\n", ret_val);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t store_enable_clk3b_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, ": tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG3, 0x7f, val << 7);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL,
+               store_enable_clk3b_output);
+
+static ssize_t store_enable_clk3a_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG3, 0xbf, val << 6);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL,
+               store_enable_clk3a_output);
+
+static ssize_t store_enable_clkb1_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG2, 0xf7, val << 3);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL,
+               store_enable_clkb1_output);
+
+
+static ssize_t store_enable_clka1_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG2, 0xfb, val << 2);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL,
+               store_enable_clka1_output);
+
+static ssize_t store_enable_clkb0_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG2, 0xfd, val << 1);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL,
+               store_enable_clkb0_output);
+
+static ssize_t store_enable_clka0_output(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG2, 0xfe, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL,
+               store_enable_clka0_output);
+
+static ssize_t store_test_mode(struct device *d,
+               struct device_attribute *attr,  const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG4, 0xfd, 2);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode);
+
+static ssize_t store_select_amcb2_transmit_clock(struct device *d,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long flags;
+       unsigned long tmp;
+       unsigned char val;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+               if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+                       SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28);
+                       SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+               } else if (val >= CLK_8_592MHz) {
+                       SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38);
+                       switch (val) {
+                       case CLK_8_592MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+                               break;
+                       case CLK_11_184MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+                               break;
+                       case CLK_34_368MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+                               break;
+                       case CLK_44_736MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+                               break;
+                       }
+               } else
+                       SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3);
+
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL,
+       store_select_amcb2_transmit_clock);
+
+static ssize_t store_select_amcb1_transmit_clock(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+               if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) {
+                       SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5);
+                       SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val);
+               } else if (val >= CLK_8_592MHz) {
+                       SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7);
+                       switch (val) {
+                       case CLK_8_592MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 1);
+                               break;
+                       case CLK_11_184MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 0);
+                               break;
+                       case CLK_34_368MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 3);
+                               break;
+                       case CLK_44_736MHz:
+                               SET_PORT_BITS(TLCLK_REG0, 0xfc, 2);
+                               break;
+                       }
+               } else
+                       SET_PORT_BITS(TLCLK_REG3, 0xf8, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL,
+               store_select_amcb1_transmit_clock);
+
+static ssize_t store_select_redundant_clock(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG1, 0xfe, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL,
+               store_select_redundant_clock);
+
+static ssize_t store_select_ref_frequency(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG1, 0xfd, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL,
+               store_select_ref_frequency);
+
+static ssize_t store_filter_select(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG0, 0xfb, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select);
+
+static ssize_t store_hardware_switching_mode(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG0, 0xbf, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL,
+               store_hardware_switching_mode);
+
+static ssize_t store_hardware_switching(struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG0, 0x7f, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL,
+               store_hardware_switching);
+
+static ssize_t store_refalign (struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+       udelay(2);
+       SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08);
+       udelay(2);
+       SET_PORT_BITS(TLCLK_REG0, 0xf7, 0);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign);
+
+static ssize_t store_mode_select (struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG0, 0xcf, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select);
+
+static ssize_t store_reset (struct device *d,
+                struct device_attribute *attr, const char *buf, size_t count)
+{
+       unsigned long tmp;
+       unsigned char val;
+       unsigned long flags;
+
+       sscanf(buf, "%lX", &tmp);
+       dev_dbg(d, "tmp = 0x%lX\n", tmp);
+
+       val = (unsigned char)tmp;
+       spin_lock_irqsave(&event_lock, flags);
+       SET_PORT_BITS(TLCLK_REG4, 0xfd, val);
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset);
+
+static struct attribute *tlclk_sysfs_entries[] = {
+       &dev_attr_current_ref.attr,
+       &dev_attr_interrupt_switch.attr,
+       &dev_attr_alarms.attr,
+       &dev_attr_enable_clk3a_output.attr,
+       &dev_attr_enable_clk3b_output.attr,
+       &dev_attr_enable_clkb1_output.attr,
+       &dev_attr_enable_clka1_output.attr,
+       &dev_attr_enable_clkb0_output.attr,
+       &dev_attr_enable_clka0_output.attr,
+       &dev_attr_test_mode.attr,
+       &dev_attr_select_amcb1_transmit_clock.attr,
+       &dev_attr_select_amcb2_transmit_clock.attr,
+       &dev_attr_select_redundant_clock.attr,
+       &dev_attr_select_ref_frequency.attr,
+       &dev_attr_filter_select.attr,
+       &dev_attr_hardware_switching_mode.attr,
+       &dev_attr_hardware_switching.attr,
+       &dev_attr_refalign.attr,
+       &dev_attr_mode_select.attr,
+       &dev_attr_reset.attr,
+       NULL
+};
+
+static struct attribute_group tlclk_attribute_group = {
+       .name = NULL,           /* put in device directory */
+       .attrs = tlclk_sysfs_entries,
+};
+
+static struct platform_device *tlclk_device;
+
+static int __init tlclk_init(void)
+{
+       int ret;
+
+       ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops);
+       if (ret < 0) {
+               printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major);
+               return ret;
+       }
+       alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
+       if (!alarm_events)
+               goto out1;
+
+       /* Read telecom clock IRQ number (Set by BIOS) */
+       if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
+               printk(KERN_ERR "tlclk: request_region failed! 0x%X\n",
+                       TLCLK_BASE);
+               ret = -EBUSY;
+               goto out2;
+       }
+       telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
+
+       if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
+               printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n",
+                       telclk_interrupt);
+               ret = -ENXIO;
+               goto out3;
+       }
+
+       init_timer(&switchover_timer);
+
+       ret = misc_register(&tlclk_miscdev);
+       if (ret < 0) {
+               printk(KERN_ERR " misc_register retruns %d\n", ret);
+               ret = -EBUSY;
+               goto out3;
+       }
+
+       tlclk_device = platform_device_register_simple("telco_clock",
+                               -1, NULL, 0);
+       if (!tlclk_device) {
+               printk(KERN_ERR " platform_device_register retruns 0x%X\n",
+                       (unsigned int) tlclk_device);
+               ret = -EBUSY;
+               goto out4;
+       }
+
+       ret = sysfs_create_group(&tlclk_device->dev.kobj,
+                       &tlclk_attribute_group);
+       if (ret) {
+               printk(KERN_ERR "failed to create sysfs device attributes\n");
+               sysfs_remove_group(&tlclk_device->dev.kobj,
+                       &tlclk_attribute_group);
+               goto out5;
+       }
+
+       return 0;
+out5:
+       platform_device_unregister(tlclk_device);
+out4:
+       misc_deregister(&tlclk_miscdev);
+out3:
+       release_region(TLCLK_BASE, 8);
+out2:
+       kfree(alarm_events);
+out1:
+       unregister_chrdev(tlclk_major, "telco_clock");
+       return ret;
+}
+
+static void __exit tlclk_cleanup(void)
+{
+       sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group);
+       platform_device_unregister(tlclk_device);
+       misc_deregister(&tlclk_miscdev);
+       unregister_chrdev(tlclk_major, "telco_clock");
+
+       release_region(TLCLK_BASE, 8);
+       del_timer_sync(&switchover_timer);
+       kfree(alarm_events);
+
+}
+
+static void switchover_timeout(unsigned long data)
+{
+       if ((data & 1)) {
+               if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+                       alarm_events->switchover_primary++;
+       } else {
+               if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08))
+                       alarm_events->switchover_secondary++;
+       }
+
+       /* Alarm processing is done, wake up read task */
+       del_timer(&switchover_timer);
+       got_event = 1;
+       wake_up(&wq);
+}
+
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&event_lock, flags);
+       /* Read and clear interrupt events */
+       int_events = inb(TLCLK_REG6);
+
+       /* Primary_Los changed from 0 to 1 ? */
+       if (int_events & PRI_LOS_01_MASK) {
+               if (inb(TLCLK_REG2) & SEC_LOST_MASK)
+                       alarm_events->lost_clocks++;
+               else
+                       alarm_events->lost_primary_clock++;
+       }
+
+       /* Primary_Los changed from 1 to 0 ? */
+       if (int_events & PRI_LOS_10_MASK) {
+               alarm_events->primary_clock_back++;
+               SET_PORT_BITS(TLCLK_REG1, 0xFE, 1);
+       }
+       /* Secondary_Los changed from 0 to 1 ? */
+       if (int_events & SEC_LOS_01_MASK) {
+               if (inb(TLCLK_REG2) & PRI_LOST_MASK)
+                       alarm_events->lost_clocks++;
+               else
+                       alarm_events->lost_secondary_clock++;
+       }
+       /* Secondary_Los changed from 1 to 0 ? */
+       if (int_events & SEC_LOS_10_MASK) {
+               alarm_events->secondary_clock_back++;
+               SET_PORT_BITS(TLCLK_REG1, 0xFE, 0);
+       }
+       if (int_events & HOLDOVER_10_MASK)
+               alarm_events->pll_end_holdover++;
+
+       if (int_events & UNLOCK_01_MASK)
+               alarm_events->pll_lost_sync++;
+
+       if (int_events & UNLOCK_10_MASK)
+               alarm_events->pll_sync++;
+
+       /* Holdover changed from 0 to 1 ? */
+       if (int_events & HOLDOVER_01_MASK) {
+               alarm_events->pll_holdover++;
+
+               /* TIMEOUT in ~10ms */
+               switchover_timer.expires = jiffies + msecs_to_jiffies(10);
+               switchover_timer.data = inb(TLCLK_REG1);
+               add_timer(&switchover_timer);
+       } else {
+               got_event = 1;
+               wake_up(&wq);
+       }
+       spin_unlock_irqrestore(&event_lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+module_init(tlclk_init);
+module_exit(tlclk_cleanup);
index 049d128ae7f07de2605cd5cd2e3d4c4efdba26ac..303f15880466293f967a94ea5267262039006e2e 100644 (file)
@@ -64,7 +64,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
        if (count == 0)
                return -ENODATA;
        if (count > bufsiz) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "invalid count value %x %zx \n", count, bufsiz);
                return -E2BIG;
        }
@@ -72,21 +72,21 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
        down(&chip->tpm_mutex);
 
        if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
        stop = jiffies + 2 * 60 * HZ;
        do {
-               u8 status = inb(chip->vendor->base + 1);
+               u8 status = chip->vendor->status(chip);
                if ((status & chip->vendor->req_complete_mask) ==
                    chip->vendor->req_complete_val) {
                        goto out_recv;
                }
 
                if ((status == chip->vendor->req_canceled)) {
-                       dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+                       dev_err(chip->dev, "Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
                }
@@ -97,14 +97,14 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 
 
        chip->vendor->cancel(chip);
-       dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+       dev_err(chip->dev, "Operation Timed out\n");
        rc = -ETIME;
        goto out;
 
 out_recv:
        rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
        if (rc < 0)
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
        up(&chip->tpm_mutex);
@@ -139,15 +139,14 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
        __be32 index;
        char *str = buf;
 
-       struct tpm_chip *chip =
-           pci_get_drvdata(to_pci_dev(dev));
+       struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
        memcpy(data, cap_pcr, sizeof(cap_pcr));
        if ((len = tpm_transmit(chip, data, sizeof(data)))
            < CAP_PCR_RESULT_SIZE) {
-               dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
                                "attempting to determine the number of PCRS\n",
                        be32_to_cpu(*((__be32 *) (data + 6))));
                return 0;
@@ -161,9 +160,10 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                memcpy(data + 10, &index, 4);
                if ((len = tpm_transmit(chip, data, sizeof(data)))
                    < READ_PCR_RESULT_SIZE){
-                       dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
+                       dev_dbg(chip->dev, "A TPM error (%d) occurred"
                                " attempting to read PCR %d of %d\n",
-                               be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
+                               be32_to_cpu(*((__be32 *) (data + 6))),
+                               i, num_pcrs);
                        goto out;
                }
                str += sprintf(str, "PCR-%02d: ", i);
@@ -191,21 +191,19 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
        int i, rc;
        char *str = buf;
 
-       struct tpm_chip *chip =
-           pci_get_drvdata(to_pci_dev(dev));
+       struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
-       data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+       data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
        memcpy(data, readpubek, sizeof(readpubek));
-       memset(data + sizeof(readpubek), 0, 20);        /* zero nonce */
 
        if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
            READ_PUBEK_RESULT_SIZE) {
-               dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
                                "attempting to read the PUBEK\n",
                            be32_to_cpu(*((__be32 *) (data + 6))));
                rc = 0;
@@ -245,7 +243,6 @@ out:
        kfree(data);
        return rc;
 }
-
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
 #define CAP_VER_RESULT_SIZE 18
@@ -274,8 +271,7 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
        ssize_t len;
        char *str = buf;
 
-       struct tpm_chip *chip =
-           pci_get_drvdata(to_pci_dev(dev));
+       struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
@@ -315,7 +311,6 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
 }
 EXPORT_SYMBOL_GPL(tpm_store_cancel);
 
-
 /*
  * Device file system interface to the TPM
  */
@@ -339,21 +334,20 @@ int tpm_open(struct inode *inode, struct file *file)
        }
 
        if (chip->num_opens) {
-               dev_dbg(&chip->pci_dev->dev,
-                       "Another process owns this TPM\n");
+               dev_dbg(chip->dev, "Another process owns this TPM\n");
                rc = -EBUSY;
                goto err_out;
        }
 
        chip->num_opens++;
-       pci_dev_get(chip->pci_dev);
+       get_device(chip->dev);
 
        spin_unlock(&driver_lock);
 
        chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
        if (chip->data_buffer == NULL) {
                chip->num_opens--;
-               pci_dev_put(chip->pci_dev);
+               put_device(chip->dev);
                return -ENOMEM;
        }
 
@@ -366,7 +360,6 @@ err_out:
        spin_unlock(&driver_lock);
        return rc;
 }
-
 EXPORT_SYMBOL_GPL(tpm_open);
 
 int tpm_release(struct inode *inode, struct file *file)
@@ -378,15 +371,14 @@ int tpm_release(struct inode *inode, struct file *file)
        chip->num_opens--;
        del_singleshot_timer_sync(&chip->user_read_timer);
        atomic_set(&chip->data_pending, 0);
-       pci_dev_put(chip->pci_dev);
+       put_device(chip->dev);
        kfree(chip->data_buffer);
        spin_unlock(&driver_lock);
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(tpm_release);
 
-ssize_t tpm_write(struct file * file, const char __user * buf,
+ssize_t tpm_write(struct file *file, const char __user *buf,
                  size_t size, loff_t * off)
 {
        struct tpm_chip *chip = file->private_data;
@@ -422,7 +414,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
 
 EXPORT_SYMBOL_GPL(tpm_write);
 
-ssize_t tpm_read(struct file * file, char __user * buf,
+ssize_t tpm_read(struct file * file, char __user *buf,
                 size_t size, loff_t * off)
 {
        struct tpm_chip *chip = file->private_data;
@@ -444,15 +436,14 @@ ssize_t tpm_read(struct file * file, char __user * buf,
 
        return ret_size;
 }
-
 EXPORT_SYMBOL_GPL(tpm_read);
 
-void __devexit tpm_remove(struct pci_dev *pci_dev)
+void tpm_remove_hardware(struct device *dev)
 {
-       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       struct tpm_chip *chip = dev_get_drvdata(dev);
 
        if (chip == NULL) {
-               dev_err(&pci_dev->dev, "No device data found\n");
+               dev_err(dev, "No device data found\n");
                return;
        }
 
@@ -462,22 +453,20 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
 
        spin_unlock(&driver_lock);
 
-       pci_set_drvdata(pci_dev, NULL);
+       dev_set_drvdata(dev, NULL);
        misc_deregister(&chip->vendor->miscdev);
        kfree(chip->vendor->miscdev.name);
 
-       sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+       sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
 
-       pci_disable_device(pci_dev);
-
-       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
+               !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 
        kfree(chip);
 
-       pci_dev_put(pci_dev);
+       put_device(dev);
 }
-
-EXPORT_SYMBOL_GPL(tpm_remove);
+EXPORT_SYMBOL_GPL(tpm_remove_hardware);
 
 static u8 savestate[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
@@ -489,32 +478,30 @@ static u8 savestate[] = {
  * We are about to suspend. Save the TPM state
  * so that it can be restored.
  */
-int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
+int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
 {
-       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
        tpm_transmit(chip, savestate, sizeof(savestate));
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(tpm_pm_suspend);
 
 /*
  * Resume from a power safe. The BIOS already restored
  * the TPM state.
  */
-int tpm_pm_resume(struct pci_dev *pci_dev)
+int tpm_pm_resume(struct device *dev)
 {
-       struct tpm_chip *chip = pci_get_drvdata(pci_dev);
+       struct tpm_chip *chip = dev_get_drvdata(dev);
 
        if (chip == NULL)
                return -ENODEV;
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(tpm_pm_resume);
 
 /*
@@ -524,8 +511,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  * upon errant exit from this function specific probe function should call
  * pci_disable_device
  */
-int tpm_register_hardware(struct pci_dev *pci_dev,
-                         struct tpm_vendor_specific *entry)
+int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
 {
 #define DEVNAME_SIZE 7
 
@@ -534,12 +520,10 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
        int i, j;
 
        /* Driver specific per-device data */
-       chip = kmalloc(sizeof(*chip), GFP_KERNEL);
+       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (chip == NULL)
                return -ENOMEM;
 
-       memset(chip, 0, sizeof(struct tpm_chip));
-
        init_MUTEX(&chip->buffer_mutex);
        init_MUTEX(&chip->tpm_mutex);
        INIT_LIST_HEAD(&chip->list);
@@ -563,8 +547,7 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
 
 dev_num_search_complete:
        if (chip->dev_num < 0) {
-               dev_err(&pci_dev->dev,
-                       "No available tpm device numbers\n");
+               dev_err(dev, "No available tpm device numbers\n");
                kfree(chip);
                return -ENODEV;
        } else if (chip->dev_num == 0)
@@ -576,15 +559,15 @@ dev_num_search_complete:
        scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
        chip->vendor->miscdev.name = devname;
 
-       chip->vendor->miscdev.dev = &(pci_dev->dev);
-       chip->pci_dev = pci_dev_get(pci_dev);
+       chip->vendor->miscdev.dev = dev;
+       chip->dev = get_device(dev);
 
        if (misc_register(&chip->vendor->miscdev)) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "unable to misc_register %s, minor %d\n",
                        chip->vendor->miscdev.name,
                        chip->vendor->miscdev.minor);
-               pci_dev_put(pci_dev);
+               put_device(dev);
                kfree(chip);
                dev_mask[i] &= !(1 << j);
                return -ENODEV;
@@ -592,17 +575,16 @@ dev_num_search_complete:
 
        spin_lock(&driver_lock);
 
-       pci_set_drvdata(pci_dev, chip);
+       dev_set_drvdata(dev, chip);
 
        list_add(&chip->list, &tpm_chip_list);
 
        spin_unlock(&driver_lock);
 
-       sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
+       sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
 
        return 0;
 }
-
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
index 373b41f6b4604168fc24b0e73c2eff2a8ec6aaca..024814b50c3caf158b4d3ddc837abd0cbd7be627 100644 (file)
@@ -55,12 +55,13 @@ struct tpm_vendor_specific {
        int (*recv) (struct tpm_chip *, u8 *, size_t);
        int (*send) (struct tpm_chip *, u8 *, size_t);
        void (*cancel) (struct tpm_chip *);
+       u8 (*status) (struct tpm_chip *);
        struct miscdevice miscdev;
        struct attribute_group *attr_group;
 };
 
 struct tpm_chip {
-       struct pci_dev *pci_dev;        /* PCI device stuff */
+       struct device *dev;     /* Device stuff */
 
        int dev_num;            /* /dev/tpm# */
        int num_opens;          /* only one allowed */
@@ -91,13 +92,13 @@ static inline void tpm_write_index(int base, int index, int value)
        outb(value & 0xFF, base+1);
 }
 
-extern int tpm_register_hardware(struct pci_dev *,
+extern int tpm_register_hardware(struct device *,
                                 struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
 extern int tpm_release(struct inode *, struct file *);
 extern ssize_t tpm_write(struct file *, const char __user *, size_t,
                         loff_t *);
 extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
-extern void __devexit tpm_remove(struct pci_dev *);
-extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
-extern int tpm_pm_resume(struct pci_dev *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_pm_suspend(struct device *, pm_message_t);
+extern int tpm_pm_resume(struct device *);
index c0d64914595fe182fb31bce1d8cc207fb19d66e4..8cb42e84723c4381db5798ee817d866aa150d437 100644 (file)
@@ -40,7 +40,7 @@ enum tpm_atmel_read_status {
        ATML_STATUS_READY = 0x08
 };
 
-static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        u8 status, *hdr = buf;
        u32 size;
@@ -54,7 +54,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
        for (i = 0; i < 6; i++) {
                status = inb(chip->vendor->base + 1);
                if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(&chip->pci_dev->dev,
+                       dev_err(chip->dev,
                                "error reading header\n");
                        return -EIO;
                }
@@ -66,12 +66,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
        size = be32_to_cpu(*native_size);
 
        if (count < size) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "Recv size(%d) less than available space\n", size);
                for (; i < size; i++) { /* clear the waiting data anyway */
                        status = inb(chip->vendor->base + 1);
                        if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                               dev_err(&chip->pci_dev->dev,
+                               dev_err(chip->dev,
                                        "error reading data\n");
                                return -EIO;
                        }
@@ -83,7 +83,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
        for (; i < size; i++) {
                status = inb(chip->vendor->base + 1);
                if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
-                       dev_err(&chip->pci_dev->dev,
+                       dev_err(chip->dev,
                                "error reading data\n");
                        return -EIO;
                }
@@ -93,20 +93,20 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
        /* make sure data available is gone */
        status = inb(chip->vendor->base + 1);
        if (status & ATML_STATUS_DATA_AVAIL) {
-               dev_err(&chip->pci_dev->dev, "data available is stuck\n");
+               dev_err(chip->dev, "data available is stuck\n");
                return -EIO;
        }
 
        return size;
 }
 
-static int tpm_atml_send(struct tpm_chip *chip, u8 * buf, size_t count)
+static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        int i;
 
-       dev_dbg(&chip->pci_dev->dev, "tpm_atml_send: ");
+       dev_dbg(chip->dev, "tpm_atml_send:\n");
        for (i = 0; i < count; i++) {
-               dev_dbg(&chip->pci_dev->dev, "0x%x(%d) ", buf[i], buf[i]);
+               dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
                outb(buf[i], chip->vendor->base);
        }
 
@@ -118,6 +118,11 @@ static void tpm_atml_cancel(struct tpm_chip *chip)
        outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
 }
 
+static u8 tpm_atml_status(struct tpm_chip *chip)
+{
+       return inb(chip->vendor->base + 1);
+}
+
 static struct file_operations atmel_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
@@ -137,7 +142,7 @@ static struct attribute* atmel_attrs[] = {
        &dev_attr_pcrs.attr,
        &dev_attr_caps.attr,
        &dev_attr_cancel.attr,
-       0,
+       NULL,
 };
 
 static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
@@ -146,6 +151,7 @@ static struct tpm_vendor_specific tpm_atmel = {
        .recv = tpm_atml_recv,
        .send = tpm_atml_send,
        .cancel = tpm_atml_cancel,
+       .status = tpm_atml_status,
        .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
        .req_complete_val = ATML_STATUS_DATA_AVAIL,
        .req_canceled = ATML_STATUS_READY,
@@ -153,86 +159,94 @@ static struct tpm_vendor_specific tpm_atmel = {
        .miscdev = { .fops = &atmel_ops, },
 };
 
-static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
-                                  const struct pci_device_id *pci_id)
+static struct platform_device *pdev;
+
+static void __devexit tpm_atml_remove(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip) {
+               release_region(chip->vendor->base, 2);
+               tpm_remove_hardware(chip->dev);
+       }
+}
+
+static struct device_driver atml_drv = {
+       .name = "tpm_atmel",
+       .bus = &platform_bus_type,
+       .owner = THIS_MODULE,
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_atmel(void)
 {
-       u8 version[4];
        int rc = 0;
        int lo, hi;
 
-       if (pci_enable_device(pci_dev))
-               return -EIO;
+       driver_register(&atml_drv);
 
        lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
        hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
 
        tpm_atmel.base = (hi<<8)|lo;
-       dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
 
        /* verify that it is an Atmel part */
        if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
            || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
-               rc = -ENODEV;
-               goto out_err;
+               return -ENODEV;
        }
 
-       /* query chip for its version number */
-       if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
-               version[1] = tpm_read_index(TPM_ADDR, 0x01);
-               version[2] = tpm_read_index(TPM_ADDR, 0x02);
-               version[3] = tpm_read_index(TPM_ADDR, 0x03);
-       } else {
-               dev_info(&pci_dev->dev, "version query failed\n");
-               rc = -ENODEV;
-               goto out_err;
+       /* verify chip version number is 1.1 */
+       if (    (tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
+               (tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
+               return -ENODEV;
+
+       pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+       if ( !pdev )
+               return -ENOMEM;
+
+       pdev->name = "tpm_atmel0";
+       pdev->id = -1;
+       pdev->num_resources = 0;
+       pdev->dev.release = tpm_atml_remove;
+       pdev->dev.driver = &atml_drv;
+
+       if ((rc = platform_device_register(pdev)) < 0) {
+               kfree(pdev);
+               pdev = NULL;
+               return rc;
        }
 
-       if ((rc = tpm_register_hardware(pci_dev, &tpm_atmel)) < 0)
-               goto out_err;
+       if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+               return -EBUSY;
+       }
 
-       dev_info(&pci_dev->dev,
-                "Atmel TPM version %d.%d.%d.%d\n", version[0], version[1],
-                version[2], version[3]);
+       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
+               release_region(tpm_atmel.base, 2);
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+               return rc;
+       }
 
+       dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
+                       tpm_atmel.base);
        return 0;
-out_err:
-       pci_disable_device(pci_dev);
-       return rc;
-}
-
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
-       {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
-       {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver atmel_pci_driver = {
-       .name = "tpm_atmel",
-       .id_table = tpm_pci_tbl,
-       .probe = tpm_atml_init,
-       .remove = __devexit_p(tpm_remove),
-       .suspend = tpm_pm_suspend,
-       .resume = tpm_pm_resume,
-};
-
-static int __init init_atmel(void)
-{
-       return pci_register_driver(&atmel_pci_driver);
 }
 
 static void __exit cleanup_atmel(void)
 {
-       pci_unregister_driver(&atmel_pci_driver);
+       if (pdev) {
+               tpm_atml_remove(&pdev->dev);
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+       }
+
+       driver_unregister(&atml_drv);
 }
 
 module_init(init_atmel);
index 939e51e119e62bb63665afbf4591887861e5ea33..8198dbb7370f1596a3b55eed4c7ac7cbaa429408 100644 (file)
@@ -5,6 +5,7 @@
  * Specifications at www.trustedcomputinggroup.org
  *
  * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Sirrix AG - security technologies, http://www.sirrix.com and
  * Applied Data Security Group, Ruhr-University Bochum, Germany
  * Project-Homepage: http://www.prosec.rub.de/tpm
  *
 #define        TPM_INFINEON_DEV_VEN_VALUE      0x15D1
 
 /* These values will be filled after PnP-call */
-static int TPM_INF_DATA = 0;
-static int TPM_INF_ADDR = 0;
-static int pnp_registered = 0;
+static int TPM_INF_DATA;
+static int TPM_INF_ADDR;
+static int TPM_INF_BASE;
+static int TPM_INF_PORT_LEN;
 
 /* TPM header definitions */
 enum infineon_tpm_header {
@@ -143,11 +145,9 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
        }
        if (i == TPM_MAX_TRIES) {       /* timeout occurs */
                if (wait_for_bit == STAT_XFE)
-                       dev_err(&chip->pci_dev->dev,
-                               "Timeout in wait(STAT_XFE)\n");
+                       dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
                if (wait_for_bit == STAT_RDA)
-                       dev_err(&chip->pci_dev->dev,
-                               "Timeout in wait(STAT_RDA)\n");
+                       dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
                return -EIO;
        }
        return 0;
@@ -170,7 +170,7 @@ static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
 static void tpm_wtx(struct tpm_chip *chip)
 {
        number_of_wtx++;
-       dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n",
+       dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
                 number_of_wtx, TPM_MAX_WTX_PACKAGES);
        wait_and_send(chip, TPM_VL_VER);
        wait_and_send(chip, TPM_CTRL_WTX);
@@ -181,7 +181,7 @@ static void tpm_wtx(struct tpm_chip *chip)
 
 static void tpm_wtx_abort(struct tpm_chip *chip)
 {
-       dev_info(&chip->pci_dev->dev, "Aborting WTX\n");
+       dev_info(chip->dev, "Aborting WTX\n");
        wait_and_send(chip, TPM_VL_VER);
        wait_and_send(chip, TPM_CTRL_WTX_ABORT);
        wait_and_send(chip, 0x00);
@@ -206,7 +206,7 @@ recv_begin:
        }
 
        if (buf[0] != TPM_VL_VER) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "Wrong transport protocol implementation!\n");
                return -EIO;
        }
@@ -221,8 +221,7 @@ recv_begin:
                }
 
                if ((size == 0x6D00) && (buf[1] == 0x80)) {
-                       dev_err(&chip->pci_dev->dev,
-                               "Error handling on vendor layer!\n");
+                       dev_err(chip->dev, "Error handling on vendor layer!\n");
                        return -EIO;
                }
 
@@ -234,7 +233,7 @@ recv_begin:
        }
 
        if (buf[1] == TPM_CTRL_WTX) {
-               dev_info(&chip->pci_dev->dev, "WTX-package received\n");
+               dev_info(chip->dev, "WTX-package received\n");
                if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
                        tpm_wtx(chip);
                        goto recv_begin;
@@ -245,14 +244,14 @@ recv_begin:
        }
 
        if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
-               dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n");
+               dev_info(chip->dev, "WTX-abort acknowledged\n");
                return size;
        }
 
        if (buf[1] == TPM_CTRL_ERROR) {
-               dev_err(&chip->pci_dev->dev, "ERROR-package received:\n");
+               dev_err(chip->dev, "ERROR-package received:\n");
                if (buf[4] == TPM_INF_NAK)
-                       dev_err(&chip->pci_dev->dev,
+                       dev_err(chip->dev,
                                "-> Negative acknowledgement"
                                " - retransmit command!\n");
                return -EIO;
@@ -271,7 +270,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
 
        ret = empty_fifo(chip, 1);
        if (ret) {
-               dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n");
+               dev_err(chip->dev, "Timeout while clearing FIFO\n");
                return -EIO;
        }
 
@@ -316,6 +315,11 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
         */
 }
 
+static u8 tpm_inf_status(struct tpm_chip *chip)
+{
+       return inb(chip->vendor->base + STAT);
+}
+
 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
@@ -344,6 +348,7 @@ static struct tpm_vendor_specific tpm_inf = {
        .recv = tpm_inf_recv,
        .send = tpm_inf_send,
        .cancel = tpm_inf_cancel,
+       .status = tpm_inf_status,
        .req_complete_mask = 0,
        .req_complete_val = 0,
        .attr_group = &inf_attr_grp,
@@ -356,30 +361,11 @@ static const struct pnp_device_id tpm_pnp_tbl[] = {
        {"IFX0102", 0},
        {"", 0}
 };
+
 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
 
 static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
-                                       const struct pnp_device_id *dev_id)
-{
-       if (pnp_port_valid(dev, 0)) {
-               TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
-               TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
-               tpm_inf.base = pnp_port_start(dev, 1);
-               dev_info(&dev->dev, "Found %s with ID %s\n",
-               dev->name, dev_id->id);
-               return 0;
-       }
-       return -ENODEV;
-}
-
-static struct pnp_driver tpm_inf_pnp = {
-       .name = "tpm_inf_pnp",
-       .id_table = tpm_pnp_tbl,
-       .probe = tpm_inf_pnp_probe,
-};
-
-static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
-                                  const struct pci_device_id *pci_id)
+                                      const struct pnp_device_id *dev_id)
 {
        int rc = 0;
        u8 iol, ioh;
@@ -388,30 +374,28 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
        int productid[2];
        char chipname[20];
 
-       rc = pci_enable_device(pci_dev);
-       if (rc)
-               return rc;
-
-       dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
-
-       /* read IO-ports from PnP */
-       rc = pnp_register_driver(&tpm_inf_pnp);
-       if (rc < 0) {
-               dev_err(&pci_dev->dev,
-                       "Error %x from pnp_register_driver!\n",rc);
-               goto error2;
-       }
-       if (!rc) {
-               dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
-               goto error;
+       /* read IO-ports through PnP */
+       if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+           !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
+               TPM_INF_ADDR = pnp_port_start(dev, 0);
+               TPM_INF_DATA = (TPM_INF_ADDR + 1);
+               TPM_INF_BASE = pnp_port_start(dev, 1);
+               TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
+               if (!TPM_INF_PORT_LEN)
+                       return -EINVAL;
+               dev_info(&dev->dev, "Found %s with ID %s\n",
+                        dev->name, dev_id->id);
+               if (!((TPM_INF_BASE >> 8) & 0xff))
+                       return -EINVAL;
+               /* publish my base address and request region */
+               tpm_inf.base = TPM_INF_BASE;
+               if (request_region
+                   (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+                       release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+                       return -EINVAL;
+               }
        } else {
-               pnp_registered = 1;
-       }
-
-       /* Make sure, we have received valid config ports */
-       if (!TPM_INF_ADDR) {
-               dev_err(&pci_dev->dev, "No valid IO-ports received!\n");
-               goto error;
+               return -EINVAL;
        }
 
        /* query chip for its vendor, its version number a.s.o. */
@@ -443,10 +427,6 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
 
        if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
 
-               if (tpm_inf.base == 0) {
-                       dev_err(&pci_dev->dev, "No IO-ports found!\n");
-                       goto error;
-               }
                /* configure TPM with IO-ports */
                outb(IOLIMH, TPM_INF_ADDR);
                outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
@@ -460,10 +440,11 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
                iol = inb(TPM_INF_DATA);
 
                if ((ioh << 8 | iol) != tpm_inf.base) {
-                       dev_err(&pci_dev->dev,
+                       dev_err(&dev->dev,
                                "Could not set IO-ports to %04x\n",
                                tpm_inf.base);
-                       goto error;
+                       release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+                       return -EIO;
                }
 
                /* activate register */
@@ -475,7 +456,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
                outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
 
                /* Finally, we're done, print some infos */
-               dev_info(&pci_dev->dev, "TPM found: "
+               dev_info(&dev->dev, "TPM found: "
                         "config base 0x%x, "
                         "io base 0x%x, "
                         "chip version %02x%02x, "
@@ -483,59 +464,53 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
                         "product id %02x%02x"
                         "%s\n",
                         TPM_INF_ADDR,
-                        tpm_inf.base,
+                        TPM_INF_BASE,
                         version[0], version[1],
                         vendorid[0], vendorid[1],
                         productid[0], productid[1], chipname);
 
-               rc = tpm_register_hardware(pci_dev, &tpm_inf);
-               if (rc < 0)
-                       goto error;
+               rc = tpm_register_hardware(&dev->dev, &tpm_inf);
+               if (rc < 0) {
+                       release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+                       return -ENODEV;
+               }
                return 0;
        } else {
-               dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
-error:
-               pnp_unregister_driver(&tpm_inf_pnp);
-error2:
-               pci_disable_device(pci_dev);
-               pnp_registered = 0;
+               dev_info(&dev->dev, "No Infineon TPM found!\n");
                return -ENODEV;
        }
 }
 
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
-       {0,}
-};
+static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
+{
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
 
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+       if (chip) {
+               release_region(chip->vendor->base, TPM_INF_PORT_LEN);
+               tpm_remove_hardware(chip->dev);
+       }
+}
 
-static struct pci_driver inf_pci_driver = {
-       .name = "tpm_inf",
-       .id_table = tpm_pci_tbl,
-       .probe = tpm_inf_probe,
-       .remove = __devexit_p(tpm_remove),
-       .suspend = tpm_pm_suspend,
-       .resume = tpm_pm_resume,
+static struct pnp_driver tpm_inf_pnp = {
+       .name = "tpm_inf_pnp",
+       .driver = {
+               .owner = THIS_MODULE,
+               .suspend = tpm_pm_suspend,
+               .resume = tpm_pm_resume,
+       },
+       .id_table = tpm_pnp_tbl,
+       .probe = tpm_inf_pnp_probe,
+       .remove = tpm_inf_pnp_remove,
 };
 
 static int __init init_inf(void)
 {
-       return pci_register_driver(&inf_pci_driver);
+       return pnp_register_driver(&tpm_inf_pnp);
 }
 
 static void __exit cleanup_inf(void)
 {
-       if (pnp_registered)
-               pnp_unregister_driver(&tpm_inf_pnp);
-       pci_unregister_driver(&inf_pci_driver);
+       pnp_unregister_driver(&tpm_inf_pnp);
 }
 
 module_init(init_inf);
@@ -543,5 +518,5 @@ module_exit(cleanup_inf);
 
 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.5");
+MODULE_VERSION("1.6");
 MODULE_LICENSE("GPL");
index b4127348c063279ada48d3af60056e036318ae45..253871b5b1e223ac2035faf83d16bad594ffc5e9 100644 (file)
@@ -111,7 +111,7 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
        }
        while (time_before(jiffies, stop));
 
-       dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
+       dev_info(chip->dev, "wait for ready failed\n");
        return -EBUSY;
 }
 
@@ -127,12 +127,12 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
                return -EIO;
 
        if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
-               dev_err(&chip->pci_dev->dev, "F0 timeout\n");
+               dev_err(chip->dev, "F0 timeout\n");
                return -EIO;
        }
        if ((data =
             inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
-               dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
+               dev_err(chip->dev, "not in normal mode (0x%x)\n",
                        data);
                return -EIO;
        }
@@ -141,7 +141,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
        for (p = buffer; p < &buffer[count]; p++) {
                if (wait_for_stat
                    (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
-                       dev_err(&chip->pci_dev->dev,
+                       dev_err(chip->dev,
                                "OBF timeout (while reading data)\n");
                        return -EIO;
                }
@@ -152,11 +152,11 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 
        if ((data & NSC_STATUS_F0) == 0 &&
        (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
-               dev_err(&chip->pci_dev->dev, "F0 not set\n");
+               dev_err(chip->dev, "F0 not set\n");
                return -EIO;
        }
        if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
-               dev_err(&chip->pci_dev->dev,
+               dev_err(chip->dev,
                        "expected end of command(0x%x)\n", data);
                return -EIO;
        }
@@ -187,19 +187,19 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
                return -EIO;
 
        if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-               dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+               dev_err(chip->dev, "IBF timeout\n");
                return -EIO;
        }
 
        outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
        if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
-               dev_err(&chip->pci_dev->dev, "IBR timeout\n");
+               dev_err(chip->dev, "IBR timeout\n");
                return -EIO;
        }
 
        for (i = 0; i < count; i++) {
                if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-                       dev_err(&chip->pci_dev->dev,
+                       dev_err(chip->dev,
                                "IBF timeout (while writing data)\n");
                        return -EIO;
                }
@@ -207,7 +207,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
        }
 
        if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
-               dev_err(&chip->pci_dev->dev, "IBF timeout\n");
+               dev_err(chip->dev, "IBF timeout\n");
                return -EIO;
        }
        outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
@@ -220,6 +220,11 @@ static void tpm_nsc_cancel(struct tpm_chip *chip)
        outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
 }
 
+static u8 tpm_nsc_status(struct tpm_chip *chip)
+{
+       return inb(chip->vendor->base + NSC_STATUS);
+}
+
 static struct file_operations nsc_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
@@ -239,7 +244,7 @@ static struct attribute * nsc_attrs[] = {
        &dev_attr_pcrs.attr,
        &dev_attr_caps.attr,
        &dev_attr_cancel.attr,
-       0,
+       NULL,
 };
 
 static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
@@ -248,6 +253,7 @@ static struct tpm_vendor_specific tpm_nsc = {
        .recv = tpm_nsc_recv,
        .send = tpm_nsc_send,
        .cancel = tpm_nsc_cancel,
+       .status = tpm_nsc_status,
        .req_complete_mask = NSC_STATUS_OBF,
        .req_complete_val = NSC_STATUS_OBF,
        .req_canceled = NSC_STATUS_RDY,
@@ -255,16 +261,32 @@ static struct tpm_vendor_specific tpm_nsc = {
        .miscdev = { .fops = &nsc_ops, },
 };
 
-static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
-                                 const struct pci_device_id *pci_id)
+static struct platform_device *pdev = NULL;
+
+static void __devexit tpm_nsc_remove(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if ( chip ) {
+               release_region(chip->vendor->base, 2);
+               tpm_remove_hardware(chip->dev);
+       }
+}
+
+static struct device_driver nsc_drv = {
+       .name = "tpm_nsc",
+       .bus = &platform_bus_type,
+       .owner = THIS_MODULE,
+       .suspend = tpm_pm_suspend,
+       .resume = tpm_pm_resume,
+};
+
+static int __init init_nsc(void)
 {
        int rc = 0;
        int lo, hi;
        int nscAddrBase = TPM_ADDR;
 
-
-       if (pci_enable_device(pci_dev))
-               return -EIO;
+       driver_register(&nsc_drv);
 
        /* select PM channel 1 */
        tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
@@ -273,37 +295,71 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
        if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
                nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
                        (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
-               if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
-                       rc = -ENODEV;
-                       goto out_err;
-               }
+               if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6)
+                       return -ENODEV;
        }
 
        hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
        lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
        tpm_nsc.base = (hi<<8) | lo;
 
-       dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
-       dev_dbg(&pci_dev->dev,
+       /* enable the DPM module */
+       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
+
+       pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL);
+       if ( !pdev )
+               return -ENOMEM;
+
+       memset(pdev, 0, sizeof(struct platform_device));
+
+       pdev->name = "tpm_nscl0";
+       pdev->id = -1;
+       pdev->num_resources = 0;
+       pdev->dev.release = tpm_nsc_remove;
+       pdev->dev.driver = &nsc_drv;
+
+       if ((rc=platform_device_register(pdev)) < 0) {
+               kfree(pdev);
+               pdev = NULL;
+               return rc;
+       }
+
+       if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+               return -EBUSY;
+       }
+
+       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) {
+               release_region(tpm_nsc.base, 2);
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+               return rc;
+       }
+
+       dev_dbg(&pdev->dev, "NSC TPM detected\n");
+       dev_dbg(&pdev->dev,
                "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
                tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
                tpm_read_index(nscAddrBase,0x27));
-       dev_dbg(&pci_dev->dev,
+       dev_dbg(&pdev->dev,
                "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
                tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
                tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
-       dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
+       dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n",
                (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
-       dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
+       dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n",
                (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
-       dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
+       dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n",
                tpm_read_index(nscAddrBase,0x70));
-       dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
+       dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n",
                tpm_read_index(nscAddrBase,0x71));
-       dev_dbg(&pci_dev->dev,
+       dev_dbg(&pdev->dev,
                "NSC DMA channel select0 0x%x, select1 0x%x\n",
                tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
-       dev_dbg(&pci_dev->dev,
+       dev_dbg(&pdev->dev,
                "NSC Config "
                "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
                tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
@@ -312,55 +368,23 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
                tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
                tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
 
-       dev_info(&pci_dev->dev,
+       dev_info(&pdev->dev,
                 "NSC TPM revision %d\n",
                 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
-       /* enable the DPM module */
-       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
-
-       if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
-               goto out_err;
-
        return 0;
-
-out_err:
-       pci_disable_device(pci_dev);
-       return rc;
-}
-
-static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
-       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
-       {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
-       {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
-
-static struct pci_driver nsc_pci_driver = {
-       .name = "tpm_nsc",
-       .id_table = tpm_pci_tbl,
-       .probe = tpm_nsc_init,
-       .remove = __devexit_p(tpm_remove),
-       .suspend = tpm_pm_suspend,
-       .resume = tpm_pm_resume,
-};
-
-static int __init init_nsc(void)
-{
-       return pci_register_driver(&nsc_pci_driver);
 }
 
 static void __exit cleanup_nsc(void)
 {
-       pci_unregister_driver(&nsc_pci_driver);
+       if (pdev) {
+               tpm_nsc_remove(&pdev->dev);
+               platform_device_unregister(pdev);
+               kfree(pdev);
+               pdev = NULL;
+       }
+
+       driver_unregister(&nsc_drv);
 }
 
 module_init(init_nsc);
index f5649a3377431faba359c87af568193cc9735cd4..c586bfa852eec510c2e486a331e4564655791fab 100644 (file)
@@ -809,7 +809,7 @@ static void do_tty_hangup(void *data)
        check_tty_count(tty, "do_tty_hangup");
        file_list_lock();
        /* This breaks for file handles being sent over AF_UNIX sockets ? */
-       list_for_each_entry(filp, &tty->tty_files, f_list) {
+       list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
                if (filp->f_op->write == redirected_tty_write)
                        cons_filp = filp;
                if (filp->f_op->write != tty_write)
index 1d44f69e1fda12bfb0abd092435d53ab04d9c610..003dda147cd093a226d52a485d7b98d64186874d 100644 (file)
@@ -192,6 +192,9 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
        int i, j, k;
        int ret;
 
+       if (!capable(CAP_SYS_TTY_CONFIG))
+               return -EPERM;
+
        kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
        if (!kbs) {
                ret = -ENOMEM;
index 2865dac0a81396a059f83aa3d0435da697c041d7..e75045fe2641405dc0d772486c2fb2e0e930d815 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/timer.h>
+#include <linux/jiffies.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
index 7fc2188386d96b56ac062cf4830736a6f6222a79..d8dede575402e14ab31952fec1d249cb0156b008 100644 (file)
@@ -45,6 +45,8 @@
 #include <linux/fs.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
index 427ad51b7a3519f23844d4c012402c50bec150e7..37c9e13ad3acfc1c20c9592b4c89c6ead8bfff51 100644 (file)
@@ -66,7 +66,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/reboot.h>
-
+#include <linux/sched.h>       /* TASK_INTERRUPTIBLE, set_current_state() and friends */
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
index 0b8e493be04570577d017f2aa69398e84064f7d3..5308e5c8f29af139867d36436ccb32314d05cde6 100644 (file)
@@ -753,6 +753,7 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
 
 static struct pci_driver pcipcwd_driver = {
+       .owner          = THIS_MODULE,
        .name           = WATCHDOG_NAME,
        .id_table       = pcipcwd_pci_tbl,
        .probe          = pcipcwd_card_init,
index 72501be79b0c6a93b4affbf27a1dcd74c346b20e..4ee9974ad8cbaec08ada8758d120c8bb32fdbc48 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 20e5eb8667f2a738d9bbb16031cf0e6a4dc22733..a91edaf3a350a1d7230740fe7832f537e85986f3 100644 (file)
@@ -47,6 +47,8 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+
 #include <asm/uaccess.h>
 
 #define PFX "SoftDog: "
index 4b3311993d4876bf91f07ef9e9c2147bc75e3278..dc9370f6c3480e55b13f6e1d8803a0461eb66d25 100644 (file)
@@ -711,6 +711,7 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
 
 
 static struct pci_driver wdtpci_driver = {
+       .owner          = THIS_MODULE,
        .name           = "wdt_pci",
        .id_table       = wdtpci_pci_tbl,
        .probe          = wdtpci_init_one,
index 109d62ccf6514fe5475154ed821c7cb6bbefcbdf..6c6121b85a54ba36168a73a737a0163e179f79a7 100644 (file)
@@ -4,6 +4,9 @@
  *  Copyright (C) 2001 Russell King
  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
  *
+ *  Oct 2005 - Ashok Raj <ashok.raj@intel.com>
+ *                     Added handling for CPU hotplug
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -36,13 +39,6 @@ static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
 static DEFINE_SPINLOCK(cpufreq_driver_lock);
 
 
-/* we keep a copy of all ->add'ed CPU's struct sys_device here;
- * as it is only accessed in ->add and ->remove, no lock or reference
- * count is necessary.
- */
-static struct sys_device       *cpu_sys_devices[NR_CPUS];
-
-
 /* internal prototypes */
 static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
 static void handle_update(void *data);
@@ -574,6 +570,9 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
        unsigned long flags;
        unsigned int j;
 
+       if (cpu_is_offline(cpu))
+               return 0;
+
        cpufreq_debug_disable_ratelimit();
        dprintk("adding CPU %u\n", cpu);
 
@@ -582,7 +581,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
         * CPU because it is in the same boat. */
        policy = cpufreq_cpu_get(cpu);
        if (unlikely(policy)) {
-               cpu_sys_devices[cpu] = sys_dev;
                dprintk("CPU already managed, adding link\n");
                sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
                cpufreq_debug_enable_ratelimit();
@@ -657,7 +655,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
        }
 
        module_put(cpufreq_driver->owner);
-       cpu_sys_devices[cpu] = sys_dev;
        dprintk("initialization complete\n");
        cpufreq_debug_enable_ratelimit();
        
@@ -682,7 +679,7 @@ err_out:
 
 nomem_out:
        module_put(cpufreq_driver->owner);
- module_out:
+module_out:
        cpufreq_debug_enable_ratelimit();
        return ret;
 }
@@ -698,6 +695,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
        unsigned int cpu = sys_dev->id;
        unsigned long flags;
        struct cpufreq_policy *data;
+       struct sys_device *cpu_sys_dev;
 #ifdef CONFIG_SMP
        unsigned int j;
 #endif
@@ -710,7 +708,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
 
        if (!data) {
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-               cpu_sys_devices[cpu] = NULL;
                cpufreq_debug_enable_ratelimit();
                return -EINVAL;
        }
@@ -725,14 +722,12 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
                dprintk("removing link\n");
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
                sysfs_remove_link(&sys_dev->kobj, "cpufreq");
-               cpu_sys_devices[cpu] = NULL;
                cpufreq_cpu_put(data);
                cpufreq_debug_enable_ratelimit();
                return 0;
        }
 #endif
 
-       cpu_sys_devices[cpu] = NULL;
 
        if (!kobject_get(&data->kobj)) {
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -761,7 +756,8 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
                        if (j == cpu)
                                continue;
                        dprintk("removing link for cpu %u\n", j);
-                       sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
+                       cpu_sys_dev = get_cpu_sysdev(j);
+                       sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
                        cpufreq_cpu_put(data);
                }
        }
@@ -772,7 +768,6 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
        down(&data->lock);
        if (cpufreq_driver->target)
                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
-       cpufreq_driver->target = NULL;
        up(&data->lock);
 
        kobject_unregister(&data->kobj);
@@ -1119,17 +1114,30 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
                            unsigned int relation)
 {
        int retval = -EINVAL;
-       lock_cpu_hotplug();
+
+       /*
+        * Converted the lock_cpu_hotplug to preempt_disable()
+        * and preempt_enable(). This is a bit kludgy and relies on how cpu
+        * hotplug works. All we need is a guarantee that cpu hotplug won't make
+        * progress on any cpu. Once we do preempt_disable(), this would ensure
+        * that hotplug threads don't get onto this cpu, thereby delaying
+        * the cpu remove process.
+        *
+        * We removed the lock_cpu_hotplug since we need to call this function
+        * via cpu hotplug callbacks, which result in locking the cpu hotplug
+        * thread itself. Agree this is not very clean, cpufreq community
+        * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
+        */
+       preempt_disable();
        dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
                target_freq, relation);
        if (cpu_online(policy->cpu) && cpufreq_driver->target)
                retval = cpufreq_driver->target(policy, target_freq, relation);
-       unlock_cpu_hotplug();
+       preempt_enable();
        return retval;
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
 
-
 int cpufreq_driver_target(struct cpufreq_policy *policy,
                          unsigned int target_freq,
                          unsigned int relation)
@@ -1416,6 +1424,45 @@ int cpufreq_update_policy(unsigned int cpu)
 }
 EXPORT_SYMBOL(cpufreq_update_policy);
 
+static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long)hcpu;
+       struct cpufreq_policy *policy;
+       struct sys_device *sys_dev;
+
+       sys_dev = get_cpu_sysdev(cpu);
+
+       if (sys_dev) {
+               switch (action) {
+               case CPU_ONLINE:
+                       cpufreq_add_dev(sys_dev);
+                       break;
+               case CPU_DOWN_PREPARE:
+                       /*
+                        * We attempt to put this cpu in lowest frequency
+                        * possible before going down. This will permit
+                        * hardware-managed P-State to switch other related
+                        * threads to min or higher speeds if possible.
+                        */
+                       policy = cpufreq_cpu_data[cpu];
+                       if (policy) {
+                               cpufreq_driver_target(policy, policy->min,
+                                               CPUFREQ_RELATION_H);
+                       }
+                       break;
+               case CPU_DEAD:
+                       cpufreq_remove_dev(sys_dev);
+                       break;
+               }
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_cpu_notifier =
+{
+    .notifier_call = cpufreq_cpu_callback,
+};
 
 /*********************************************************************
  *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
@@ -1476,6 +1523,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
        }
 
        if (!ret) {
+               register_cpu_notifier(&cpufreq_cpu_notifier);
                dprintk("driver %s up and running\n", driver_data->name);
                cpufreq_debug_enable_ratelimit();
        }
@@ -1507,6 +1555,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
        dprintk("unregistering driver %s\n", driver->name);
 
        sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
+       unregister_cpu_notifier(&cpufreq_cpu_notifier);
 
        spin_lock_irqsave(&cpufreq_driver_lock, flags);
        cpufreq_driver = NULL;
index 741b6b191e6a2ca667b5ab6f36888279cb9823ce..3597f25d5efa8957a0ee1ed8389131a71675f91d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/percpu.h>
 #include <linux/kobject.h>
 #include <linux/spinlock.h>
+#include <linux/notifier.h>
 #include <asm/cputime.h>
 
 static spinlock_t cpufreq_stats_lock;
@@ -298,6 +299,27 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
        return 0;
 }
 
+static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned long)hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+               cpufreq_update_policy(cpu);
+               break;
+       case CPU_DEAD:
+               cpufreq_stats_free_table(cpu);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block cpufreq_stat_cpu_notifier =
+{
+       .notifier_call = cpufreq_stat_cpu_callback,
+};
+
 static struct notifier_block notifier_policy_block = {
        .notifier_call = cpufreq_stat_notifier_policy
 };
@@ -311,6 +333,7 @@ __init cpufreq_stats_init(void)
 {
        int ret;
        unsigned int cpu;
+
        spin_lock_init(&cpufreq_stats_lock);
        if ((ret = cpufreq_register_notifier(&notifier_policy_block,
                                CPUFREQ_POLICY_NOTIFIER)))
@@ -323,20 +346,31 @@ __init cpufreq_stats_init(void)
                return ret;
        }
 
-       for_each_cpu(cpu)
-               cpufreq_update_policy(cpu);
+       register_cpu_notifier(&cpufreq_stat_cpu_notifier);
+       lock_cpu_hotplug();
+       for_each_online_cpu(cpu) {
+               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
+                       (void *)(long)cpu);
+       }
+       unlock_cpu_hotplug();
        return 0;
 }
 static void
 __exit cpufreq_stats_exit(void)
 {
        unsigned int cpu;
+
        cpufreq_unregister_notifier(&notifier_policy_block,
                        CPUFREQ_POLICY_NOTIFIER);
        cpufreq_unregister_notifier(&notifier_trans_block,
                        CPUFREQ_TRANSITION_NOTIFIER);
-       for_each_cpu(cpu)
-               cpufreq_stats_free_table(cpu);
+       unregister_cpu_notifier(&cpufreq_stat_cpu_notifier);
+       lock_cpu_hotplug();
+       for_each_online_cpu(cpu) {
+               cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
+                       (void *)(long)cpu);
+       }
+       unlock_cpu_hotplug();
 }
 
 MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
index 094835cce321061458f1e6013160ce0f0428ff0d..4263935443cc6801807d991e4cc2a304fa566eba 100644 (file)
@@ -2,7 +2,7 @@ menu "Hardware crypto devices"
 
 config CRYPTO_DEV_PADLOCK
        tristate "Support for VIA PadLock ACE"
-       depends on CRYPTO && X86 && !X86_64
+       depends on CRYPTO && X86_32
        help
          Some VIA processors come with an integrated crypto engine
          (so called VIA PadLock ACE, Advanced Cryptography Engine)
index 327b58e648753013e28026f4fb9f66f4af89edfe..b6815c6c29a2ca6bf579c1f7c814a694a0389bad 100644 (file)
@@ -70,8 +70,7 @@ config DELL_RBU
 
 config DCDBAS
        tristate "Dell Systems Management Base Driver"
-       depends on X86 || X86_64
-       default m
+       depends on X86
        help
          The Dell Systems Management Base Driver provides a sysfs interface
          for systems management software to perform System Management
index 74af7e07486880d8c0c20f637a90d92442805dea..8b9d85526596a38380dbf65ce0a3f6dcc82527d7 100644 (file)
@@ -2211,13 +2211,12 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
 
        if (toc == NULL) {
                /* Try to allocate space. */
-               toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
-                                                   GFP_KERNEL);
-               info->toc = toc;
+               toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
                if (toc == NULL) {
                        printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
                        return -ENOMEM;
                }
+               info->toc = toc;
        }
 
        /* Check to see if the existing data is still valid.
@@ -2240,7 +2239,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
        /* First read just the header, so we know how long the TOC is. */
        stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
                                    sizeof(struct atapi_toc_header), sense);
-       if (stat) return stat;
+       if (stat)
+               return stat;
 
 #if ! STANDARD_ATAPI
        if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
@@ -2324,7 +2324,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
                /* Read the multisession information. */
                stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
                                           sizeof(ms_tmp), sense);
-               if (stat) return stat;
+               if (stat)
+                       return stat;
 
                toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
        } else {
@@ -2460,7 +2461,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
                            struct packet_command *cgc)
 {
        struct request req;
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
 
        if (cgc->timeout <= 0)
                cgc->timeout = ATAPI_WAIT_PC;
@@ -2537,7 +2538,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
                           unsigned int cmd, void *arg)
                           
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct cdrom_info *info = drive->driver_data;
        int stat;
 
@@ -2548,7 +2549,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
         */
        case CDROMPLAYTRKIND: {
                unsigned long lba_start, lba_end;
-               struct cdrom_ti *ti = (struct cdrom_ti *)arg;
+               struct cdrom_ti *ti = arg;
                struct atapi_toc_entry *first_toc, *last_toc;
 
                stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
@@ -2571,12 +2572,13 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
        }
 
        case CDROMREADTOCHDR: {
-               struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;
+               struct cdrom_tochdr *tochdr = arg;
                struct atapi_toc *toc;
 
                /* Make sure our saved TOC is valid. */
                stat = cdrom_read_toc(drive, NULL);
-               if (stat) return stat;
+               if (stat)
+                       return stat;
 
                toc = info->toc;
                tochdr->cdth_trk0 = toc->hdr.first_track;
@@ -2586,11 +2588,12 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
        }
 
        case CDROMREADTOCENTRY: {
-               struct cdrom_tocentry *tocentry = (struct cdrom_tocentry*) arg;
+               struct cdrom_tocentry *tocentry = arg;
                struct atapi_toc_entry *toce;
 
                stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
-               if (stat) return stat;
+               if (stat)
+                       return stat;
 
                tocentry->cdte_ctrl = toce->control;
                tocentry->cdte_adr  = toce->adr;
@@ -2613,7 +2616,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
 static
 int ide_cdrom_reset (struct cdrom_device_info *cdi)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct request_sense sense;
        struct request req;
        int ret;
@@ -2636,12 +2639,13 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi)
 static
 int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct request_sense sense;
 
        if (position) {
                int stat = cdrom_lockdoor(drive, 0, &sense);
-               if (stat) return stat;
+               if (stat)
+                       return stat;
        }
 
        return cdrom_eject(drive, !position, &sense);
@@ -2650,7 +2654,7 @@ int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
 static
 int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        return cdrom_lockdoor(drive, lock, NULL);
 }
 
@@ -2700,7 +2704,7 @@ void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page
 static
 int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct request_sense sense;
        struct atapi_capabilities_page cap;
        int stat;
@@ -2723,7 +2727,7 @@ int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
 static
 int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct media_event_desc med;
        struct request_sense sense;
        int stat;
@@ -2769,7 +2773,7 @@ int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
                                struct cdrom_multisession *ms_info)
 {
        struct atapi_toc *toc;
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        struct cdrom_info *info = drive->driver_data;
        struct request_sense sense;
        int ret;
@@ -2791,7 +2795,7 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
 {
        int stat;
        char mcnbuf[24];
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
 
 /* get MCN */
        if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
@@ -2815,7 +2819,7 @@ static
 int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
                                       int slot_nr)
 {
-       ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+       ide_drive_t *drive = cdi->handle;
        int retval;
        
        if (slot_nr == CDSL_CURRENT) {
@@ -2886,7 +2890,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
        devinfo->mask = 0;
        devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
        devinfo->capacity = nslots;
-       devinfo->handle = (void *) drive;
+       devinfo->handle = drive;
        strcpy(devinfo->name, drive->name);
        
        /* set capability mask to match the probe. */
@@ -2942,7 +2946,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
         * registered with the Uniform layer yet, it can't do this.
         * Same goes for cdi->ops.
         */
-       cdi->handle = (ide_drive_t *) drive;
+       cdi->handle = drive;
        cdi->ops = &ide_cdrom_dops;
 
        if (ide_cdrom_get_capabilities(drive, &cap))
@@ -3254,6 +3258,7 @@ int ide_cdrom_setup (ide_drive_t *drive)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 static
 sector_t ide_cdrom_capacity (ide_drive_t *drive)
 {
@@ -3264,6 +3269,7 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive)
 
        return capacity * sectors_per_frame;
 }
+#endif
 
 static int ide_cd_remove(struct device *dev)
 {
@@ -3309,7 +3315,7 @@ static int ide_cd_probe(struct device *);
 static int proc_idecd_read_capacity
        (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-       ide_drive_t*drive = (ide_drive_t *)data;
+       ide_drive_t *drive = data;
        int len;
 
        len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
@@ -3449,7 +3455,7 @@ static int ide_cd_probe(struct device *dev)
                printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
                goto failed;
        }
-       info = (struct cdrom_info *) kmalloc (sizeof (struct cdrom_info), GFP_KERNEL);
+       info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL);
        if (info == NULL) {
                printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
                goto failed;
index f014e639088ca13d923df980234b998244062983..c57a3871184ca0d419698ffb3b2cf10d8c155185 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/sched.h>       /* INIT_WORK, schedule_work(), flush_scheduled_work() */
 
 #include <rdma/ib_cache.h>
 
index 89ce9dc210d40b0e271996e8bd8736205bc95db7..acda7d63d6feb9bf24d481f81243e6d991931133 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/kref.h>
 #include <linux/idr.h>
+#include <linux/workqueue.h>
 
 #include <rdma/ib_pack.h>
 #include <rdma/ib_sa.h>
index 889e85096736c198ef2cbc6a6525cfafcd06c7ea..22fdc446f25cdcd0d3100cd20dd800d7b7d42830 100644 (file)
@@ -34,6 +34,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
index 8561b297a19b4162f8a1b90565327e8585f2c34f..1229c604c6e0258e49c73d5d4a4d26f695587c14 100644 (file)
@@ -34,6 +34,9 @@
  * $Id: mthca_mad.c 1349 2004-12-16 21:09:43Z roland $
  */
 
+#include <linux/string.h>
+#include <linux/slab.h>
+
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_mad.h>
 #include <rdma/ib_smi.h>
index b47ea7daf0886cdf2eeb41e0d3c9824ef3b5e1b6..2fc449da418d280e534472cebe9ea8797ed7504c 100644 (file)
@@ -33,6 +33,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
index 0576056b34f463742b7979ac9791b5bde002d8d0..bd1338682074bff3f01e3c7fd66945b57429e5a8 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "mthca_profile.h"
 
index 62ff091505da73e43dc074319f5e58c14d89dfe4..7c9afde5ace56ba73258a7d0505df408a45c7139 100644 (file)
@@ -36,6 +36,8 @@
  */
 
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
index 4f995391dd1d8176e7ff0cc25f4ac5b049288ae3..df5e494a9d3887ca9b71c9cd8721c7ffdaea0d54 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
index 1c8791ded6ffc442d200b91a4cc58a69c454cbb4..8e9219842be42a687e08f20cfdd7a04a72e2ca65 100644 (file)
@@ -32,6 +32,8 @@
  * $Id$
  */
 
+#include <asm/page.h>          /* PAGE_SHIFT */
+
 #include "mthca_dev.h"
 #include "mthca_memfree.h"
 
index ab09cf4093e32595cbd84824db790e73f91d2881..0506934244f001861f309f40fa33e0eee4e0fc3b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/sched.h>       /* HZ */
 
 /*#include <asm/io.h>*/
 
index bf65430181faf0f2ee5db443f950bd35c90963f8..4571ea3a4b92f77004cebe725bf14c1d979b5b56 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "FP-Gaming Assasin 3D joystick driver"
 
index 9d95459f4bcbf4839b0aa3489c3b3b908b1e436e..704bf70f1db739b7860b0a3b4c67b10e867c06ab 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/input.h>
 #include <linux/gameport.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Logitech ADI joystick family driver"
 
index c75ac6eb1ffbcd526443b92435cc12b2696733de..3121961e3e7c8876153fc70a41448f88d8468913 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/gameport.h>
+#include <linux/jiffies.h>
 #include <asm/timex.h>
 
 #define DRIVER_DESC    "Analog joystick and gamepad driver"
index 9a3dfc724a41aee1ee680c638c96255757e5faf5..1909f7ef340c7b939259e8b398f6dfec3b80fc2d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Creative Labs Blaster GamePad Cobra driver"
 
index e151f8c5bcb9faceb2958a32e04f74733c5ad0fe..8a3ad455eb385c2dc79285fe5db31f48c7126bdf 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/gameport.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Genius Flight 2000 joystick driver"
 
index e206bb56e53ce383502a60cd9a5f0cb8020b24e8..a936e7aedb103552e617010d7260a74664c6ff29 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Gravis GrIP protocol joystick driver"
 
index a0ba93ccac7255433e6dd3e46fd30c6d71a6aa88..51a912222e85e6b93e4a6f8e4fc35b245db14341 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Gravis Grip Multiport driver"
 
index c528473c09d8945448791dad332c8a52b28793d0..6e2c721c26bae3229b9a0a1a87a15f547a416dec 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Guillemot Digital joystick driver"
 
index 8511ee7bb2637b8482182e7e7966702be2ac1ee0..c4ed01758226ae34b07f4210461245c6a1e69c1f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "InterAct digital joystick driver"
 
index 4234ccaf9146d6b07fe06c673031496365507155..88ec5a918f2e80ea980f7098075553f5a782f94f 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #define DRIVER_DESC    "Gameport data dumper module"
 
index eaaad45cc7501d252453e5da298df139cdffd25a..78dd163cd7021cb6d7f079a443c07d0dc5ce6562 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/gameport.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Microsoft SideWinder joystick family driver"
 
index 3a7d1bb46472b7c616c22ace3706029ea2c70edd..60e2aac7d06ec955e873f40dc8c3cd5f97a3c947 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "ThrustMaster DirectConnect joystick driver"
 
index bb934e6d9636cf87ce6a2cc133c0d886f155a23b..b3eaac1b35b64109b27c475a8b4b818ce35be780 100644 (file)
@@ -14,7 +14,7 @@ if INPUT_MISC
 
 config INPUT_PCSPKR
        tristate "PC Speaker support"
-       depends on ALPHA || X86 || X86_64 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
+       depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES
        help
          Say Y here if you want the standard PC Speaker to be used for
          bells and whistles.
index e3c44ffae67420d75200ac6a807e0e1e3fe6aecb..1c9426fd5205665ff0ac45ba9ef35321489d2680 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <asm/semaphore.h>
 
 #define PREFIX "HP SDC MLC: "
 
index 3abd7fc6e5ef3e0331cc080a61a214b2be27066f..7b564c0dd996cb305232922ef06d76c4996e1f08 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
+#include <linux/sched.h>       /* current */
 
 MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
 MODULE_AUTHOR("Carsten Paeth");
index 7333377ab31de0cc9e7d866626c9c9dd8cd9de88..e3866b0a97fd25b244520ed30f247f0b9e67cf3e 100644 (file)
@@ -1063,7 +1063,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
                                Write_hfc8(l1->hw, A_INC_RES_FIFO, 1);
                        }
                        ack_len += skb->truesize;
-                       bch->tx_skb = 0;
+                       bch->tx_skb = NULL;
                        bch->tx_cnt = 0;
                        dev_kfree_skb(skb);
                } else
@@ -1659,10 +1659,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
 }
 
 static struct pci_driver hfc4s8s_driver = {
-      name:"hfc4s8s_l1",
-      probe:hfc4s8s_probe,
-      remove:__devexit_p(hfc4s8s_remove),
-      id_table:hfc4s8s_ids,
+      .name    = "hfc4s8s_l1",
+      .probe   = hfc4s8s_probe,
+      .remove  = __devexit_p(hfc4s8s_remove),
+      .id_table        = hfc4s8s_ids,
 };
 
 /**********************/
index 1ee003346923d7ca6a74a1fd0e6ba4ab7c773083..c34c96d189071a063f60ff055a2225b4d10fd306 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/pci_ids.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/slab.h>
+
 #include <asm/machdep.h>
 #include <asm/macio.h>
 #include <asm/pmac_feature.h>
index 76d430aa243faaebfa820572c8794122c885c09d..e7adf89fae412d49c74a56b2df0028ed20264165 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/mca.h>
+#include <linux/string.h>
 
 /**
  *     mca_device_read_stored_pos - read POS register from stored data
index 06f4d4686a6c7176f441061cf89ed27a4ef1e4a0..31fccb4f05d6ad8ade936d8b4aec9edaf82bf019 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <media/ir-common.h>
 
 /* -------------------------------------------------------------------------- */
index 88757e2634e5c85244dfb5dc79ec604b9e7c2a55..2aa767f9bd7dd88f797c8b9d48d485289661cb8a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/rwsem.h>
+#include <linux/sched.h>
 
 #include "dvb_ca_en50221.h"
 #include "dvb_ringbuffer.h"
index 5aa12ebab34f1cbfffee444ace0a89a4d547734e..b595476332cd9dba9006c6bcb94761122cc7ba97 100644 (file)
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
                  .cold_ids = { &dtt200u_usb_table[0], NULL },
                  .warm_ids = { &dtt200u_usb_table[1], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
                  .cold_ids = { &dtt200u_usb_table[2], NULL },
                  .warm_ids = { &dtt200u_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index 0f57abeb6d6bc8d982f6ea16d7b91be64440de62..75765e3a569c811f2f93f5fd25983caf5437b055 100644 (file)
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
                  .cold_ids = { &vp7045_usb_table[2], NULL },
                  .warm_ids = { &vp7045_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index f5fdc5c3e605cd9c03cafad821fa252e20e34e1f..f6d4ee78bdd43d84b63402dba4a42b13e0713c13 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "bcm3510.h"
index 21433e1831e744f22e55cef34afdbe555eb75a92..6b05536086109fd40a1b3c1a9a9c3a9e89b58365 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dib3000-common.h"
 #include "dib3000mb_priv.h"
index 441de665fec32aa28850d6b680fdc6a6ea638080..c024fad173370f62f8222cbcb947de31b530bf0a 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dib3000-common.h"
 #include "dib3000mc_priv.h"
index cff93b9d8ab2653e141fdd2ab466ac7b4f5c8bc2..794be520d5902fdad363d1a44486a76d9f5ecafc 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "dvb_dummy_fe.h"
index 7142b9c51dd2460e3b2c65ec91bddf08d877f8b0..8dde72bd10461fb5997cf13e6748e73bfee43535 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include "dvb_frontend.h"
index e455aecd76b2f9c6732ff03e07c65fffbbf6dffe..e38454901dd12e31d281a9e2ec9d1210534ae43d 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mt312_priv.h"
index cc1bc0edd65e7d14424744985cc83c89a0b054ae..f0c610f2c2dfe437e696417cf5aafbe8c3d71848 100644 (file)
@@ -35,6 +35,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mt352_priv.h"
index 35a1d60f19273023ee5cfab5ce276a7aff74d0ce..30786b1911bdab48dbec0808f01a44bacb9230e1 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "nxt2002.h"
index b6d0eecc59eb0ed75c445e3872c8b6a0c8b6138e..817b044c7fd1dd992898b6d680d62426d572729f 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include "dvb_frontend.h"
index ad56a99584043a2ad340b434f3f5b42dae2d1bbd..8a9db23dd1b705578bffa9467e47990e06ee5a9d 100644 (file)
@@ -34,6 +34,8 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <asm/byteorder.h>
 
 #include "dvb_frontend.h"
index c7fe27fd530c8037e05c4ef289ab17923d293b92..f265418e326102ba5c56855a8fc4443aeb3289be 100644 (file)
@@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/div64.h>
 
 #include "dvb_frontend.h"
 #include "s5h1420.h"
index 764a95a2e212b2972434c743184d1f06002fb1f9..1c6b2e9264bc15c7b78cd8bac150ef8957abba41 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "sp8870.h"
index d868a6927a16d022d7643f7a4e2b2fc52ec680b2..73384e75625ee8ea1d0c83eb222142aba7866fa1 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "sp887x.h"
index 8d09afd7545d8a054ef8efe0c1675173206f2dc6..6122ba754bc57167939c1342d21708025c09623c 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "stv0297.h"
index 2d62931f20b547b4588190148d879b71cda3d708..889d9257215d733893d2deb16caed9ae66b4384d 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/jiffies.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
index 74cea9f8d72106d2561aa9c4695f99853cdf9bb3..3529c618f8287f3de6101ecf3e48dfa965c1f8c0 100644 (file)
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
 #include "dvb_frontend.h"
 #include "tda1004x.h"
 
index 168e013d23bd5478f06b048e3185c06e73b72c31..c05cf1861051b3271effd7136625e5cc6b3cd543 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/jiffies.h>
 #include "dvb_frontend.h"
 #include "tda8083.h"
 
index df79d5e0aaedfe62f8ce700b2b9a9f2b952ad1be..e09214082e011ef974bdd09297786e3839eef424 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/sched.h>       /* current, TASK_*, schedule_timeout() */
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include "miropcm20-rds-core.h"
index 018ca887ca8561e9f5f81b5e113587206fb3eb5b..40d4ea898dbc58eba732fa4a4cc7bbc8c54df61a 100644 (file)
@@ -90,7 +90,7 @@ static void i2o_report_fail_status(u8 req_status, u32 * msg)
        };
 
        if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
-               printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.",
+               printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
                       req_status);
        else
                printk(KERN_DEBUG "TRANSPORT_%s.\n",
index d9879965eb5096862282352b5bcc549def0f0ab9..8eb50cdb8ae1bb5c7a81d593a16a07aa75066fc5 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include "core.h"
 
 /**
index 0079a4be0af28a6eb6e8479100265e8d5a14d2aa..0fb9c4e2ad4c325e62e56ee37df4f8e98daed72e 100644 (file)
@@ -17,6 +17,9 @@
 #include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/i2o.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include "core.h"
 
 #define OSM_NAME       "i2o"
index bda2c62648bac566529ccdbdd32f82bc33f1d7ca..b675b4ebbebdff558521b181d81b4eb2ab59b7c7 100644 (file)
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/param.h>         /* HZ */
 #include "core.h"
 
 #define OSM_NAME "exec-osm"
index 361da8d1d5e766e2cb7b5b98de5f5a309dce042b..61b837de4b6a134756e5af4eb0892b9a8c318685 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include "core.h"
 
 #define OSM_NAME       "i2o"
index fa83f15fdf161d8eafda24958a8e9ccb6ebc2573..9b629856c7358bc8061d8413b13e4ab331071426 100644 (file)
@@ -85,6 +85,12 @@ static void mmc_blk_put(struct mmc_blk_data *md)
        up(&open_lock);
 }
 
+static inline int mmc_blk_readonly(struct mmc_card *card)
+{
+       return mmc_card_readonly(card) ||
+              !(card->csd.cmdclass & CCC_BLOCK_WRITE);
+}
+
 static int mmc_blk_open(struct inode *inode, struct file *filp)
 {
        struct mmc_blk_data *md;
@@ -97,7 +103,7 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
                ret = 0;
 
                if ((filp->f_mode & FMODE_WRITE) &&
-                       mmc_card_readonly(md->queue.card))
+                       mmc_blk_readonly(md->queue.card))
                        ret = -EROFS;
        }
 
@@ -410,7 +416,7 @@ static int mmc_blk_probe(struct mmc_card *card)
        printk(KERN_INFO "%s: %s %s %dKiB %s\n",
                md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
                (card->csd.capacity << card->csd.read_blkbits) / 1024,
-               mmc_card_readonly(card)?"(ro)":"");
+               mmc_blk_readonly(card)?"(ro)":"");
 
        mmc_set_drvdata(card, md);
        add_disk(md->disk);
index 8eba373d42d70ff91f0e1b37b37da8d9bda2d217..d575e3a018bc109365d37153b4ecd305b6966789 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/scatterlist.h>
 #include <asm/sizes.h>
 
index 62d235a9a4e21930baa3ca972e5ee82509ca52ef..4f6778f3ee3e2a9d9714389805a56b6311111e3c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/mtd/jedec.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
index dfd335e4a2a80ca6e3da1bddbd920e7e4af606ce..df987a53ed9cf918c5c8d318e0dc8b1267f2a96e 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 #include <linux/mtd/mtd.h>
 #ifdef HAVE_PARTITIONS
 #include <linux/mtd/partitions.h>
index a423a382095a7231f23391979df5f9a6145af580..765c0179c8df9097e476982c57131edea2399647 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 
 #define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
index 0ba0ff7d43b9593489659f6ffb933e73d9d33c4f..63104c73ca3c8bb7caadb6e3b038318fcffd06ec 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index da8584a662f4f4ad01ca7a7ced252f01cf609251..c68b31dc7e6d4979c363a8ac1e32bb0abba09f5b 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 938c41f2f05699f01c6f199c98e06ce6fbae5093..e5b74169fde621167b96aa47cb127f7b098296a8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 0bc79c93a58491c9cea700c786b5ff64fa0d5a85..f99519692cb7815d369577c0c54ede59e7332f1f 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/concat.h>
 
+#include <asm/io.h>
+
 /*
 ** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
 ** Destroying any of these blocks transforms the DNPC into
index ab6dbe2b8cce3a896e022c8e45e45103aebf1ced..1df6188926b3aa81e99b402bdaa265d4fa666d16 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
+#include <asm/io.h>
 #include <asm/hardware.h>
+
 #ifdef CONFIG_EPXA10DB
 #define BOARD_NAME "EPXA10DB"
 #else
index 068bb6a545201f3b5b259f5df5205167b5c45143..00f7bbe5479e47d74aa5570e6d85d103d26f750d 100644 (file)
@@ -7,11 +7,14 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/string.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
+#include <asm/io.h>
+
 #define MAX_NUM_REGIONS                4
 #define MAX_NUM_PARTITIONS     8
 
index a9f86c7fbd52e7319c8825196070e54da6e20a0e..1e5d6e1d05f318c1f0e45c866ed465a825fe6b6c 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
 
 #include <asm/io.h>
 #include <asm/hardware.h>
index 3fcc3288407437792479c456574ac09c50ee716e..da316e543237676e8fdf61a6a98923f06d27adca 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
+
 #include <asm/io.h>
 #include <asm/mach/flash.h>
 
index 1298de475c9a7d047c860759683dd01e6c858cb9..2337e0c4675061419bb9ddc6f64c4f7ff9f40378 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+
 #include <linux/dma-mapping.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
index 87e93fa60588aa29384705ba8e904fc2df1c3b88..da0f8a692628a253f7a95831d8d44cb9664683d6 100644 (file)
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
index 496109071cb10dc86bb828a0654ff295660f1ac0..da36e8dddd17e9833d222d108bb20fdabb53a4e3 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index b17bca657daf53599d8e8328ee1110b08cb50e95..fa84566245a7093588a53df13f30774a4d323591 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
index 18dbd3af1eaa652a34d4677a97f1742d4851d74c..d9c64e99ee32a7ae466499f0b053df0908dcefd6 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 118b04544cad36b11307b1d560f418e1b885b533..a0577ea00c3c974bb1121d5a11d9cac0765c82b4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index 995e9991cb8dfa0ed3858b41a075ad3212c20af3..4e28b977f224120db3c5dc5d278c3593081accfb 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
 
+#include <asm/io.h>
+
 #define FLASH_ADDR 0x40000000
 #define FLASH_SIZE 0x00800000
 #define FLASH_BANK_MAX 4
index b7c32c242bc712ce6e0bd87e358dc33eb40a8a56..400dd9c89883bb1462c85ae48646738abb8fb72b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/sched.h>       /* TASK_* */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
 
index c534fd5d95cb979430101e8ed1cfcb8f39231994..16df1e4fb0e94d2efec9542e6114f0593c3ad3bf 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fs.h>
+#include <linux/sched.h>       /* TASK_* */
 #include <asm/uaccess.h>
 
 #include <linux/device.h>
index 8f66d093c80d5b15084dc233b8cb05e718e4ac76..f3e65af33a9c86d6338847ddb2b4c16ed5229774 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-
+#include <linux/sched.h>       /* TASK_* */
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/concat.h>
 
index b47ebcb31e0fdf5a1116c0e2a99d387dbc2941f9..b58ba236a9eb8a5ffd479da0b56d88a041acc860 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
index 1ce2c675b8a74d3a39da9f18a9ae6a6118458225..a806dfe54d23c1a7ff58f0900e0c7b98076d09bc 100644 (file)
@@ -552,8 +552,7 @@ static int __init do_eepro_probe(struct net_device *dev)
        {
                unsigned short int WS[32]=WakeupSeq;
 
-               if (check_region(WakeupPort, 2)==0) {
-
+               if (request_region(WakeupPort, 2, "eepro wakeup")) {
                        if (net_debug>5)
                                printk(KERN_DEBUG "Waking UP\n");
 
@@ -563,7 +562,10 @@ static int __init do_eepro_probe(struct net_device *dev)
                                outb_p(WS[i],WakeupPort);
                                if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
                        }
-               } else printk(KERN_WARNING "Checkregion Failed!\n");
+
+                       release_region(WakeupPort, 2);
+               } else
+                       printk(KERN_WARNING "PnP wakeup region busy!\n");
        }
 #endif
 
@@ -705,7 +707,7 @@ static void __init eepro_print_info (struct net_device *dev)
                                        dev->name, (unsigned)dev->base_addr);
                        break;
                case LAN595FX:
-                       printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
+                       printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
                                        dev->name, (unsigned)dev->base_addr);
                        break;
                case LAN595TX:
@@ -713,7 +715,7 @@ static void __init eepro_print_info (struct net_device *dev)
                                        dev->name, (unsigned)dev->base_addr);
                        break;
                case LAN595:
-                       printk("%s: Intel 82595-based lan card at %#x,", 
+                       printk("%s: Intel 82595-based lan card at %#x,",
                                        dev->name, (unsigned)dev->base_addr);
        }
 
@@ -726,7 +728,7 @@ static void __init eepro_print_info (struct net_device *dev)
 
        if (dev->irq > 2)
                printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
-       else 
+       else
                printk(", %s.\n", ifmap[dev->if_port]);
 
        if (net_debug > 3) {
@@ -756,7 +758,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
        int err;
 
        /* Grab the region so we can find another board if autoIRQ fails. */
-       if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { 
+       if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
                if (!autoprobe)
                        printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
                                ioaddr);
@@ -838,15 +840,15 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
                /* Mask off INT number */
                int count = lp->word[1] & 7;
                unsigned irqMask = lp->word[7];
+
                while (count--)
                        irqMask &= irqMask - 1;
+
                count = ffs(irqMask);
+
                if (count)
                        dev->irq = count - 1;
+
                if (dev->irq < 2) {
                        printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
                        goto exit;
@@ -854,7 +856,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
                        dev->irq = 9;
                }
        }
+
        dev->open               = eepro_open;
        dev->stop               = eepro_close;
        dev->hard_start_xmit    = eepro_send_packet;
@@ -863,7 +865,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
        dev->tx_timeout         = eepro_tx_timeout;
        dev->watchdog_timeo     = TX_TIMEOUT;
        dev->ethtool_ops        = &eepro_ethtool_ops;
+
        /* print boot time info */
        eepro_print_info(dev);
 
@@ -1047,8 +1049,8 @@ static int eepro_open(struct net_device *dev)
 
 
        /* Initialize the RCV and XMT upper and lower limits */
-       outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG); 
-       outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG); 
+       outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
+       outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
        outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
        outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
 
@@ -1065,12 +1067,12 @@ static int eepro_open(struct net_device *dev)
        eepro_clear_int(ioaddr);
 
        /* Initialize RCV */
-       outw(lp->rcv_lower_limit, ioaddr + RCV_BAR); 
+       outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
        lp->rx_start = lp->rcv_lower_limit;
-       outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP); 
+       outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
 
        /* Initialize XMT */
-       outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar); 
+       outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
        lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
        lp->tx_last = 0;
 
@@ -1411,7 +1413,7 @@ set_multicast_list(struct net_device *dev)
                                outb(0x08, ioaddr + STATUS_REG);
 
                                if (i & 0x20) { /* command ABORTed */
-                                       printk(KERN_NOTICE "%s: multicast setup failed.\n", 
+                                       printk(KERN_NOTICE "%s: multicast setup failed.\n",
                                                dev->name);
                                        break;
                                } else if ((i & 0x0f) == 0x03)  { /* MC-Done */
@@ -1512,7 +1514,7 @@ hardware_send_packet(struct net_device *dev, void *buf, short length)
                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
        if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
-               if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {   
+               if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
                                /* Arrrr!!!, must keep the xmt header together,
                                several days were lost to chase this one down. */
                        last = lp->xmt_lower_limit;
@@ -1643,7 +1645,7 @@ eepro_rx(struct net_device *dev)
                        else if (rcv_status & 0x0800)
                                lp->stats.rx_crc_errors++;
 
-                       printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
+                       printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
                                dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
                }
 
@@ -1674,10 +1676,10 @@ eepro_transmit_interrupt(struct net_device *dev)
 {
        struct eepro_local *lp = netdev_priv(dev);
        short ioaddr = dev->base_addr;
-       short boguscount = 25; 
+       short boguscount = 25;
        short xmt_status;
 
-       while ((lp->tx_start != lp->tx_end) && boguscount--) { 
+       while ((lp->tx_start != lp->tx_end) && boguscount--) {
 
                outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
                xmt_status = inw(ioaddr+IO_PORT);
@@ -1723,7 +1725,7 @@ static int eepro_ethtool_get_settings(struct net_device *dev,
 {
        struct eepro_local      *lp = (struct eepro_local *)dev->priv;
 
-       cmd->supported =        SUPPORTED_10baseT_Half | 
+       cmd->supported =        SUPPORTED_10baseT_Half |
                                SUPPORTED_10baseT_Full |
                                SUPPORTED_Autoneg;
        cmd->advertising =      ADVERTISED_10baseT_Half |
index bbac720cca63d9cfc02231e07bdc4d0a0413e706..140b7cdb1f7e8186f43e896a75a0ecf09af9278a 100644 (file)
@@ -638,21 +638,14 @@ static void smsc_ircc_setup_qos(struct smsc_ircc_cb *self)
  */
 static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
 {
-       int iobase, ir_mode, ctrl, fast;
-
-       IRDA_ASSERT(self != NULL, return;);
-
-       iobase = self->io.fir_base;
-       ir_mode = IRCC_CFGA_IRDA_SIR_A;
-       ctrl = 0;
-       fast = 0;
+       int iobase = self->io.fir_base;
 
        register_bank(iobase, 0);
        outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
        outb(0x00, iobase + IRCC_MASTER);
 
        register_bank(iobase, 1);
-       outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | ir_mode),
+       outb(((inb(iobase + IRCC_SCE_CFGA) & 0x87) | IRCC_CFGA_IRDA_SIR_A),
             iobase + IRCC_SCE_CFGA);
 
 #ifdef smsc_669 /* Uses pin 88/89 for Rx/Tx */
@@ -666,10 +659,10 @@ static void smsc_ircc_init_chip(struct smsc_ircc_cb *self)
        outb(SMSC_IRCC2_FIFO_THRESHOLD, iobase + IRCC_FIFO_THRESHOLD);
 
        register_bank(iobase, 4);
-       outb((inb(iobase + IRCC_CONTROL) & 0x30) | ctrl, iobase + IRCC_CONTROL);
+       outb((inb(iobase + IRCC_CONTROL) & 0x30), iobase + IRCC_CONTROL);
 
        register_bank(iobase, 0);
-       outb(fast, iobase + IRCC_LCR_A);
+       outb(0, iobase + IRCC_LCR_A);
 
        smsc_ircc_set_sir_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
 
@@ -1556,6 +1549,46 @@ static int ircc_is_receiving(struct smsc_ircc_cb *self)
 }
 #endif /* unused */
 
+static int smsc_ircc_request_irq(struct smsc_ircc_cb *self)
+{
+       int error;
+
+       error = request_irq(self->io.irq, smsc_ircc_interrupt, 0,
+                           self->netdev->name, self->netdev);
+       if (error)
+               IRDA_DEBUG(0, "%s(), unable to allocate irq=%d, err=%d\n",
+                          __FUNCTION__, self->io.irq, error);
+
+       return error;
+}
+
+static void smsc_ircc_start_interrupts(struct smsc_ircc_cb *self)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&self->lock, flags);
+
+       self->io.speed = 0;
+       smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
+
+       spin_unlock_irqrestore(&self->lock, flags);
+}
+
+static void smsc_ircc_stop_interrupts(struct smsc_ircc_cb *self)
+{
+       int iobase = self->io.fir_base;
+       unsigned long flags;
+
+       spin_lock_irqsave(&self->lock, flags);
+
+       register_bank(iobase, 0);
+       outb(0, iobase + IRCC_IER);
+       outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
+       outb(0x00, iobase + IRCC_MASTER);
+
+       spin_unlock_irqrestore(&self->lock, flags);
+}
+
 
 /*
  * Function smsc_ircc_net_open (dev)
@@ -1567,7 +1600,6 @@ static int smsc_ircc_net_open(struct net_device *dev)
 {
        struct smsc_ircc_cb *self;
        char hwname[16];
-       unsigned long flags;
 
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
@@ -1575,6 +1607,11 @@ static int smsc_ircc_net_open(struct net_device *dev)
        self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
+       if (self->io.suspended) {
+               IRDA_DEBUG(0, "%s(), device is suspended\n", __FUNCTION__);
+               return -EAGAIN;
+       }
+
        if (request_irq(self->io.irq, smsc_ircc_interrupt, 0, dev->name,
                        (void *) dev)) {
                IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
@@ -1582,11 +1619,7 @@ static int smsc_ircc_net_open(struct net_device *dev)
                return -EAGAIN;
        }
 
-       spin_lock_irqsave(&self->lock, flags);
-       /*smsc_ircc_sir_start(self);*/
-       self->io.speed = 0;
-       smsc_ircc_change_speed(self, SMSC_IRCC2_C_IRDA_FALLBACK_SPEED);
-       spin_unlock_irqrestore(&self->lock, flags);
+       smsc_ircc_start_interrupts(self);
 
        /* Give self a hardware name */
        /* It would be cool to offer the chip revision here - Jean II */
@@ -1639,7 +1672,12 @@ static int smsc_ircc_net_close(struct net_device *dev)
                irlap_close(self->irlap);
        self->irlap = NULL;
 
-       free_irq(self->io.irq, dev);
+       smsc_ircc_stop_interrupts(self);
+
+       /* if we are called from smsc_ircc_resume we don't have IRQ reserved */
+       if (!self->io.suspended)
+               free_irq(self->io.irq, dev);
+
        disable_dma(self->io.dma);
        free_dma(self->io.dma);
 
@@ -1650,11 +1688,18 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
 {
        struct smsc_ircc_cb *self = dev_get_drvdata(dev);
 
-       IRDA_MESSAGE("%s, Suspending\n", driver_name);
-
        if (!self->io.suspended) {
-               smsc_ircc_net_close(self->netdev);
+               IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
+
+               rtnl_lock();
+               if (netif_running(self->netdev)) {
+                       netif_device_detach(self->netdev);
+                       smsc_ircc_stop_interrupts(self);
+                       free_irq(self->io.irq, self->netdev);
+                       disable_dma(self->io.dma);
+               }
                self->io.suspended = 1;
+               rtnl_unlock();
        }
 
        return 0;
@@ -1665,11 +1710,25 @@ static int smsc_ircc_resume(struct device *dev)
        struct smsc_ircc_cb *self = dev_get_drvdata(dev);
 
        if (self->io.suspended) {
-
-               smsc_ircc_net_open(self->netdev);
+               IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+
+               rtnl_lock();
+               smsc_ircc_init_chip(self);
+               if (netif_running(self->netdev)) {
+                       if (smsc_ircc_request_irq(self)) {
+                               /*
+                                * Don't fail resume process, just kill this
+                                * network interface
+                                */
+                               unregister_netdevice(self->netdev);
+                       } else {
+                               enable_dma(self->io.dma);
+                               smsc_ircc_start_interrupts(self);
+                               netif_device_attach(self->netdev);
+                       }
+               }
                self->io.suspended = 0;
-
-               IRDA_MESSAGE("%s, Waking up\n", driver_name);
+               rtnl_unlock();
        }
        return 0;
 }
@@ -1682,9 +1741,6 @@ static int smsc_ircc_resume(struct device *dev)
  */
 static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
 {
-       int iobase;
-       unsigned long flags;
-
        IRDA_DEBUG(1, "%s\n", __FUNCTION__);
 
        IRDA_ASSERT(self != NULL, return -1;);
@@ -1694,22 +1750,7 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self)
        /* Remove netdevice */
        unregister_netdev(self->netdev);
 
-       /* Make sure the irq handler is not exectuting */
-       spin_lock_irqsave(&self->lock, flags);
-
-       /* Stop interrupts */
-       iobase = self->io.fir_base;
-       register_bank(iobase, 0);
-       outb(0, iobase + IRCC_IER);
-       outb(IRCC_MASTER_RESET, iobase + IRCC_MASTER);
-       outb(0x00, iobase + IRCC_MASTER);
-#if 0
-       /* Reset to SIR mode */
-       register_bank(iobase, 1);
-        outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase + IRCC_SCE_CFGA);
-        outb(IRCC_CFGB_IR, iobase + IRCC_SCE_CFGB);
-#endif
-       spin_unlock_irqrestore(&self->lock, flags);
+       smsc_ircc_stop_interrupts(self);
 
        /* Release the PORTS that this driver is using */
        IRDA_DEBUG(0, "%s(), releasing 0x%03x\n",  __FUNCTION__,
index f17c05cbe44bf84a79eab3b4d3900369f9f8a706..99a776a51fb5764872d2d5a4ee7f44e373556b3f 100644 (file)
@@ -1896,7 +1896,7 @@ void smt_swap_para(struct smt_header *sm, int len, int direction)
 
 static void smt_string_swap(char *data, const char *format, int len)
 {
-       const char      *open_paren = 0 ;
+       const char      *open_paren = NULL ;
        int     x ;
 
        while (len > 0  && *format) {
index ac9ce6509eee78af13c014d184b27bb0f5922e64..817f200742c37132b4982bb0a333ebe76096fcb8 100644 (file)
@@ -230,12 +230,12 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define SMC_CAN_USE_16BIT      1
 #define SMC_CAN_USE_32BIT      0
 
-#define SMC_inb(a, r)          inb((a) + (r) - 0xa0000000)
-#define SMC_inw(a, r)          inw((a) + (r) - 0xa0000000)
-#define SMC_outb(v, a, r)      outb(v, (a) + (r) - 0xa0000000)
-#define SMC_outw(v, a, r)      outw(v, (a) + (r) - 0xa0000000)
-#define SMC_insw(a, r, p, l)   insw((a) + (r) - 0xa0000000, p, l)
-#define SMC_outsw(a, r, p, l)  outsw((a) + (r) - 0xa0000000, p, l)
+#define SMC_inb(a, r)          inb((u32)a) + (r))
+#define SMC_inw(a, r)          inw(((u32)a) + (r))
+#define SMC_outb(v, a, r)      outb(v, ((u32)a) + (r))
+#define SMC_outw(v, a, r)      outw(v, ((u32)a) + (r))
+#define SMC_insw(a, r, p, l)   insw(((u32)a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  outsw(((u32)a) + (r), p, l)
 
 #define set_irq_type(irq, type)        do {} while(0)
 
index 4937a5ad4b2cee319d63eabf5ee423b2e8aa955c..6a60c5970cb519b237f4c9b7b95f09a4d2adb649 100644 (file)
@@ -137,7 +137,7 @@ islpci_mgmt_rx_fill(struct net_device *ndev)
                                                       PCI_DMA_FROMDEVICE);
                        if (!buf->pci_addr) {
                                printk(KERN_WARNING
-                                      "Failed to make memory DMA'able\n.");
+                                      "Failed to make memory DMA'able.\n");
                                return -ENOMEM;
                        }
                }
index a62a4345b46631d2f89f5cf6bca4d23f3e503bba..2d4639d6841f4a6c93e29d6d3a2c9d5713ca3309 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/string.h>
 #include "cpci_hotplug.h"
 
 #define DRIVER_VERSION "0.1"
index 790abadd816c31c84439ed65270b6a8df7867939..f7cb00da38dfabbfd32e6c6ec366bf261f9ed7e4 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/signal.h>      /* SA_SHIRQ */
 #include "cpci_hotplug.h"
 #include "cpcihp_zt5550.h"
 
index 8e47fa66e25ecaa2e8a9a024d6f6473aa2df0421..060d74775d7be77d5a636cf892322d353d4cc5a0 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include "pci_hotplug.h"
 #include "../pci.h"
 
index 0392e004258f66a77c256cab41681cea3878b43e..aabf1e70b5280f70210c7f9efe840d3964ab1a31 100644 (file)
@@ -1077,7 +1077,7 @@ static int enable_slot(struct hotplug_slot *hs)
        if (rc) {
                err("Adding this card exceeds the limitations of this bus.\n");
                err("(i.e., >1 133MHz cards running on same bus, or "
-                    ">2 66 PCI cards running on same bus\n.");
+                    ">2 66 PCI cards running on same bus.\n");
                err("Try hot-adding into another bus\n");
                rc = -EINVAL;
                goto error_nopower;
index 33b539b34f7efd8e6f19f72bbd85018d25b247d9..ff17d8e07e94d09df1d197a8d64b18d7ac679c54 100644 (file)
@@ -113,7 +113,7 @@ int pciehp_unconfigure_device(struct pci_func* func)
  */
 int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
 {
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
        int rc;
        u16 temp_word;
        struct pci_dev fakedev;
index 3622965f89611cda42aef572a22dc30c091140e7..33b2c69a08295b786553b5697f5481b99e4c509f 100644 (file)
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+
 #include <asm/uaccess.h>
 #ifdef CONFIG_IA64
 #include <asm/iosapic.h>
 #endif
+
 #include "pciehp.h"
 #include "pciehprm.h"
 #include "pciehprm_nonacpi.h"
index ad1017da8656c350c5b6390aa25e74d1ac7e4b0d..fcb66b9a0e289c1a16ad262beff5984dc42e6e08 100644 (file)
  */
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/string.h>
+
 #include <asm/pci-bridge.h>
 #include <asm/semaphore.h>
 #include <asm/rtas.h>
 #include <asm/vio.h>
+
 #include "../pci.h"
 #include "rpaphp.h"
 #include "rpadlpar.h"
index 46c157d26a2f9b90d6cfbe3d08fa1229c30a0d46..f7c12d7dfcfc35bc164163672b60ef817bc23ff5 100644 (file)
  *
  */
 #include <linux/pci.h>
+#include <linux/string.h>
+
 #include <asm/pci-bridge.h>
 #include <asm/rtas.h>
 #include <asm/machdep.h>
-#include "../pci.h"            /* for pci_add_new_bus */
 
+#include "../pci.h"            /* for pci_add_new_bus */
 #include "rpaphp.h"
 
 static struct pci_bus *find_bus_among_children(struct pci_bus *bus,
index 0e88154950838fa770e5cd21d172102b7272993f..daa89ae57123b52b97c0c4678c41867118ed39f9 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 #include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
 #include <asm/rtas.h>
 #include "rpaphp.h"
 
index abe2cf411e6865927d6470cd84c13c24b68655f3..08ad26a0cae70c2d209e6a30af0408758a4c9eed 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/sched.h>       /* signal_pending(), struct timer_list */
+
 #include "pci_hotplug.h"
 
 #if !defined(MODULE)
index d70fe5408417a169a66505e49cb136d0846b29e3..c6b40998eeb31cd3a9cc461e0df0b9f4460f3bc8 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
+
 #include "shpchp.h"
 
 int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
index 8972e6a3aac0cce3850b5969d193b1f09106340b..ae986e590b48213544dd6f322147909bf52efcec 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/mempolicy.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include "pci.h"
 
 /*
index 61b855c99e3927db5d5a621957f9abac1ffe5542..e74d75843047c24cf299cf53daad16635355d640 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/string.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
index 14f05d22bb70bc62adc63a5263eec5a278d32f32..467a4ceccf1066d02ea1cf0942cafc9e99fc20bc 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/pcieport_if.h>
 
 #include "portdrv.h"
index 3c565ce7f77b5aada24f3e4f44b89533c86bc14e..02260141dc8107be19d943f4e35475b65559cf30 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/errno.h>
 #include <linux/pm.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/pcieport_if.h>
 
 #include "portdrv.h"
index bbd9c2323d8c0062ec6178c27659ae26d7c832f5..5627ce1d2b320460a058db828230cd649910bc11 100644 (file)
@@ -356,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
 /*
  * PIIX4 ACPI: Two IO regions pointed to by longwords at
  *     0x40 (64 bytes of ACPI registers)
- *     0x90 (32 bytes of SMB registers)
+ *     0x90 (16 bytes of SMB registers)
  * and a few strange programmable PIIX4 device resources.
  */
 static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
@@ -366,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
        pci_read_config_dword(dev, 0x40, &region);
        quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
        pci_read_config_dword(dev, 0x90, &region);
-       quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+       quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
 
        /* Device resource A has enables for some of the other ones */
        pci_read_config_dword(dev, 0x5c, &res_a);
index 49bd21702314ccda11e716c1b99aa2e2d1229ade..598a115cd00e762abb868b76e16447fa11faa0a3 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/slab.h>
 
 #include "pci.h"
 
index fc87e7e2b6b800e90ab43b9e203836b13afd0ba2..00960a379b9c177b6071d8bf0d76a9b386ae8938 100644 (file)
@@ -779,7 +779,7 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
        if (!s->cb_dev || !s->cb_dev->bus)
                return -ENODEV;
 
-#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+#if defined(CONFIG_X86)
        /* If this is the root bus, the risk of hitting
         * some strange system devices which aren't protected
         * by either ACPI resource tables or properly requested
index 94442ffd4aeddcd100ba9d573c6a8866fdb21b1b..cbb2749db178e1332be1c0693ce627ad29c502fa 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/pnp.h>
+#include <linux/slab.h>
+#include <linux/bitmap.h>
 #include "base.h"
 
 DECLARE_MUTEX(pnp_res_mutex);
index b0ca65b68645624e1ddd78ac1f4de6d71c4156e4..5e38cd7335f72d29a7c82540bab43d9298c9dc55 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/ctype.h>
 #include <linux/pnp.h>
 #include <linux/pnpbios.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
index fc7a213e591f5962f78084bbb7416db5a402aee9..c570a9f6ce9cfcd499ca50cdb64cbae6be462ecb 100644 (file)
@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp)
        struct string *s, *n;
        int rc;
 
+       if (cp->view.dev)
+               raw3270_activate_view(&cp->view);
+
        wrq = xchg(&cp->write, 0);
        if (!wrq) {
                con3270_set_timer(cp, 1);
@@ -489,8 +492,6 @@ con3270_write(struct console *co, const char *str, unsigned int count)
        unsigned char c;
 
        cp = condev;
-       if (cp->view.dev)
-               raw3270_activate_view(&cp->view);
        spin_lock_irqsave(&cp->view.lock, flags);
        while (count-- > 0) {
                c = *str++;
@@ -620,7 +621,7 @@ con3270_init(void)
                     (void (*)(unsigned long)) con3270_read_tasklet,
                     (unsigned long) condev->read);
 
-       raw3270_add_view(&condev->view, &con3270_fn, 0);
+       raw3270_add_view(&condev->view, &con3270_fn, 1);
 
        INIT_LIST_HEAD(&condev->freemem);
        for (i = 0; i < CON3270_STRING_PAGES; i++) {
index 60afcdcf91c255a9e8e39399e6a88bb613c2d59a..735a7fcdeff51dd1616a0481a0ebaa68b57217bc 100644 (file)
@@ -33,8 +33,11 @@ struct fs3270 {
        int read_command;               /* ccw command to use for reads. */
        int write_command;              /* ccw command to use for writes. */
        int attention;                  /* Got attention. */
-       struct raw3270_request *clear;  /* single clear request. */
-       wait_queue_head_t attn_wait;    /* Attention wait queue. */
+       int active;                     /* Fullscreen view is active. */
+       struct raw3270_request *init;   /* single init request. */
+       wait_queue_head_t wait;         /* Init & attention wait queue. */
+       struct idal_buffer *rdbuf;      /* full-screen-deactivate buffer */
+       size_t rdbuf_size;              /* size of data returned by RDBUF */
 };
 
 static void
@@ -43,58 +46,172 @@ fs3270_wake_up(struct raw3270_request *rq, void *data)
        wake_up((wait_queue_head_t *) data);
 }
 
+static inline int
+fs3270_working(struct fs3270 *fp)
+{
+       /*
+        * The fullscreen view is in working order if the view
+        * has been activated AND the initial request is finished.
+        */
+       return fp->active && raw3270_request_final(fp->init);
+}
+
 static int
 fs3270_do_io(struct raw3270_view *view, struct raw3270_request *rq)
 {
-       wait_queue_head_t wq;
+       struct fs3270 *fp;
        int rc;
 
-       init_waitqueue_head(&wq);
+       fp = (struct fs3270 *) view;
        rq->callback = fs3270_wake_up;
-       rq->callback_data = &wq;
-       rc = raw3270_start(view, rq);
-       if (rc)
-               return rc;
-       /* Started sucessfully. Now wait for completion. */
-       wait_event(wq, raw3270_request_final(rq));
-       return rq->rc;
+       rq->callback_data = &fp->wait;
+
+       do {
+               if (!fs3270_working(fp)) {
+                       /* Fullscreen view isn't ready yet. */
+                       rc = wait_event_interruptible(fp->wait,
+                                                     fs3270_working(fp));
+                       if (rc != 0)
+                               break;
+               }
+               rc = raw3270_start(view, rq);
+               if (rc == 0) {
+                       /* Started sucessfully. Now wait for completion. */
+                       wait_event(fp->wait, raw3270_request_final(rq));
+               }
+       } while (rc == -EACCES);
+       return rc;
 }
 
+/*
+ * Switch to the fullscreen view.
+ */
 static void
 fs3270_reset_callback(struct raw3270_request *rq, void *data)
 {
+       struct fs3270 *fp;
+
+       fp = (struct fs3270 *) rq->view;
        raw3270_request_reset(rq);
+       wake_up(&fp->wait);
+}
+
+static void
+fs3270_restore_callback(struct raw3270_request *rq, void *data)
+{
+       struct fs3270 *fp;
+
+       fp = (struct fs3270 *) rq->view;
+       if (rq->rc != 0 || rq->rescnt != 0) {
+               if (fp->fs_pid)
+                       kill_proc(fp->fs_pid, SIGHUP, 1);
+       }
+       fp->rdbuf_size = 0;
+       raw3270_request_reset(rq);
+       wake_up(&fp->wait);
 }
 
-/*
- * Switch to the fullscreen view.
- */
 static int
 fs3270_activate(struct raw3270_view *view)
 {
        struct fs3270 *fp;
+       char *cp;
+       int rc;
 
        fp = (struct fs3270 *) view;
-       raw3270_request_set_cmd(fp->clear, TC_EWRITEA);
-       fp->clear->callback = fs3270_reset_callback;
-       return raw3270_start(view, fp->clear);
+
+       /* If an old init command is still running just return. */
+       if (!raw3270_request_final(fp->init))
+               return 0;
+
+       if (fp->rdbuf_size == 0) {
+               /* No saved buffer. Just clear the screen. */
+               raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+               fp->init->callback = fs3270_reset_callback;
+       } else {
+               /* Restore fullscreen buffer saved by fs3270_deactivate. */
+               raw3270_request_set_cmd(fp->init, TC_EWRITEA);
+               raw3270_request_set_idal(fp->init, fp->rdbuf);
+               fp->init->ccw.count = fp->rdbuf_size;
+               cp = fp->rdbuf->data[0];
+               cp[0] = TW_KR;
+               cp[1] = TO_SBA;
+               cp[2] = cp[6];
+               cp[3] = cp[7];
+               cp[4] = TO_IC;
+               cp[5] = TO_SBA;
+               cp[6] = 0x40;
+               cp[7] = 0x40;
+               fp->init->rescnt = 0;
+               fp->init->callback = fs3270_restore_callback;
+       }
+       rc = fp->init->rc = raw3270_start_locked(view, fp->init);
+       if (rc)
+               fp->init->callback(fp->init, NULL);
+       else
+               fp->active = 1;
+       return rc;
 }
 
 /*
  * Shutdown fullscreen view.
  */
+static void
+fs3270_save_callback(struct raw3270_request *rq, void *data)
+{
+       struct fs3270 *fp;
+
+       fp = (struct fs3270 *) rq->view;
+
+       /* Correct idal buffer element 0 address. */
+       fp->rdbuf->data[0] -= 5;
+       fp->rdbuf->size += 5;
+
+       /*
+        * If the rdbuf command failed or the idal buffer is
+        * to small for the amount of data returned by the
+        * rdbuf command, then we have no choice but to send
+        * a SIGHUP to the application.
+        */
+       if (rq->rc != 0 || rq->rescnt == 0) {
+               if (fp->fs_pid)
+                       kill_proc(fp->fs_pid, SIGHUP, 1);
+               fp->rdbuf_size = 0;
+       } else
+               fp->rdbuf_size = fp->rdbuf->size - rq->rescnt;
+       raw3270_request_reset(rq);
+       wake_up(&fp->wait);
+}
+
 static void
 fs3270_deactivate(struct raw3270_view *view)
 {
-       // FIXME: is this a good idea? The user program using fullscreen 3270
-       // will die just because a console message appeared. On the other
-       // hand the fullscreen device is unoperational now.
        struct fs3270 *fp;
 
        fp = (struct fs3270 *) view;
-       if (fp->fs_pid != 0)
-               kill_proc(fp->fs_pid, SIGHUP, 1);
-       fp->fs_pid = 0;
+       fp->active = 0;
+
+       /* If an old init command is still running just return. */
+       if (!raw3270_request_final(fp->init))
+               return;
+
+       /* Prepare read-buffer request. */
+       raw3270_request_set_cmd(fp->init, TC_RDBUF);
+       /*
+        * Hackish: skip first 5 bytes of the idal buffer to make
+        * room for the TW_KR/TO_SBA/<address>/<address>/TO_IC sequence
+        * in the activation command.
+        */
+       fp->rdbuf->data[0] += 5;
+       fp->rdbuf->size -= 5;
+       raw3270_request_set_idal(fp->init, fp->rdbuf);
+       fp->init->rescnt = 0;
+       fp->init->callback = fs3270_save_callback;
+
+       /* Start I/O to read in the 3270 buffer. */
+       fp->init->rc = raw3270_start_locked(view, fp->init);
+       if (fp->init->rc)
+               fp->init->callback(fp->init, NULL);
 }
 
 static int
@@ -103,7 +220,7 @@ fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
        /* Handle ATTN. Set indication and wake waiters for attention. */
        if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
                fp->attention = 1;
-               wake_up(&fp->attn_wait);
+               wake_up(&fp->wait);
        }
 
        if (rq) {
@@ -125,7 +242,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
        struct fs3270 *fp;
        struct raw3270_request *rq;
        struct idal_buffer *ib;
-       int rc;
+       ssize_t rc;
        
        if (count == 0 || count > 65535)
                return -EINVAL;
@@ -133,7 +250,7 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
        if (!fp)
                return -ENODEV;
        ib = idal_buffer_alloc(count, 0);
-       if (!ib)
+       if (IS_ERR(ib))
                return -ENOMEM;
        rq = raw3270_request_alloc(0);
        if (!IS_ERR(rq)) {
@@ -141,10 +258,19 @@ fs3270_read(struct file *filp, char *data, size_t count, loff_t *off)
                        fp->read_command = 6;
                raw3270_request_set_cmd(rq, fp->read_command ? : 2);
                raw3270_request_set_idal(rq, ib);
-               wait_event(fp->attn_wait, fp->attention);
-               rc = fs3270_do_io(&fp->view, rq);
-               if (rc == 0 && idal_buffer_to_user(ib, data, count))
-                       rc = -EFAULT;
+               rc = wait_event_interruptible(fp->wait, fp->attention);
+               fp->attention = 0;
+               if (rc == 0) {
+                       rc = fs3270_do_io(&fp->view, rq);
+                       if (rc == 0) {
+                               count -= rq->rescnt;
+                               if (idal_buffer_to_user(ib, data, count) != 0)
+                                       rc = -EFAULT;
+                               else
+                                       rc = count;
+
+                       }
+               }
                raw3270_request_free(rq);
        } else
                rc = PTR_ERR(rq);
@@ -162,13 +288,13 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
        struct raw3270_request *rq;
        struct idal_buffer *ib;
        int write_command;
-       int rc;
+       ssize_t rc;
 
        fp = filp->private_data;
        if (!fp)
                return -ENODEV;
        ib = idal_buffer_alloc(count, 0);
-       if (!ib)
+       if (IS_ERR(ib))
                return -ENOMEM;
        rq = raw3270_request_alloc(0);
        if (!IS_ERR(rq)) {
@@ -179,6 +305,8 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
                        raw3270_request_set_cmd(rq, write_command);
                        raw3270_request_set_idal(rq, ib);
                        rc = fs3270_do_io(&fp->view, rq);
+                       if (rc == 0)
+                               rc = count - rq->rescnt;
                } else
                        rc = -EFAULT;
                raw3270_request_free(rq);
@@ -232,7 +360,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp,
 }
 
 /*
- * Allocate tty3270 structure.
+ * Allocate fs3270 structure.
  */
 static struct fs3270 *
 fs3270_alloc_view(void)
@@ -243,8 +371,8 @@ fs3270_alloc_view(void)
        if (!fp)
                return ERR_PTR(-ENOMEM);
        memset(fp, 0, sizeof(struct fs3270));
-       fp->clear = raw3270_request_alloc(0);
-       if (!IS_ERR(fp->clear)) {
+       fp->init = raw3270_request_alloc(0);
+       if (IS_ERR(fp->init)) {
                kfree(fp);
                return ERR_PTR(-ENOMEM);
        }
@@ -252,12 +380,17 @@ fs3270_alloc_view(void)
 }
 
 /*
- * Free tty3270 structure.
+ * Free fs3270 structure.
  */
 static void
 fs3270_free_view(struct raw3270_view *view)
 {
-       raw3270_request_free(((struct fs3270 *) view)->clear);
+       struct fs3270 *fp;
+
+       fp = (struct fs3270 *) view;
+       if (fp->rdbuf)
+               idal_buffer_free(fp->rdbuf);
+       raw3270_request_free(((struct fs3270 *) view)->init);
        kfree(view);
 }
 
@@ -285,11 +418,20 @@ static int
 fs3270_open(struct inode *inode, struct file *filp)
 {
        struct fs3270 *fp;
+       struct idal_buffer *ib;
        int minor, rc;
 
        if (imajor(filp->f_dentry->d_inode) != IBM_FS3270_MAJOR)
                return -ENODEV;
        minor = iminor(filp->f_dentry->d_inode);
+       /* Check for minor 0 multiplexer. */
+       if (minor == 0) {
+               if (!current->signal->tty)
+                       return -ENODEV;
+               if (current->signal->tty->driver->major != IBM_TTY3270_MAJOR)
+                       return -ENODEV;
+               minor = current->signal->tty->index + RAW3270_FIRSTMINOR;
+       }
        /* Check if some other program is already using fullscreen mode. */
        fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
        if (!IS_ERR(fp)) {
@@ -301,7 +443,7 @@ fs3270_open(struct inode *inode, struct file *filp)
        if (IS_ERR(fp))
                return PTR_ERR(fp);
 
-       init_waitqueue_head(&fp->attn_wait);
+       init_waitqueue_head(&fp->wait);
        fp->fs_pid = current->pid;
        rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
        if (rc) {
@@ -309,8 +451,18 @@ fs3270_open(struct inode *inode, struct file *filp)
                return rc;
        }
 
+       /* Allocate idal-buffer. */
+       ib = idal_buffer_alloc(2*fp->view.rows*fp->view.cols + 5, 0);
+       if (IS_ERR(ib)) {
+               raw3270_put_view(&fp->view);
+               raw3270_del_view(&fp->view);
+               return PTR_ERR(fp);
+       }
+       fp->rdbuf = ib;
+
        rc = raw3270_activate_view(&fp->view);
        if (rc) {
+               raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
                return rc;
        }
@@ -329,8 +481,12 @@ fs3270_close(struct inode *inode, struct file *filp)
 
        fp = filp->private_data;
        filp->private_data = 0;
-       if (fp)
+       if (fp) {
+               fp->fs_pid = 0;
+               raw3270_reset(&fp->view);
+               raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
+       }
        return 0;
 }
 
index 328d9cbc56a37f0b064c94ceb61b7f37a81921bb..d66946443dfc19f3df8186bfa9fdd77fb48d9233 100644 (file)
 
 #include "raw3270.h"
 
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/device.h>
+
+struct class *class3270;
+
 /* The main 3270 data structure. */
 struct raw3270 {
        struct list_head list;
@@ -41,6 +47,8 @@ struct raw3270 {
        struct timer_list timer;        /* Device timer. */
 
        unsigned char *ascebc;          /* ascii -> ebcdic table */
+       struct class_device *clttydev;  /* 3270-class tty device ptr */
+       struct class_device *cltubdev;  /* 3270-class tub device ptr */
 };
 
 /* raw3270->flags */
@@ -316,6 +324,22 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
        return rc;
 }
 
+int
+raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
+{
+       struct raw3270 *rp;
+       int rc;
+
+       rp = view->dev;
+       if (!rp || rp->view != view)
+               rc = -EACCES;
+       else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+               rc = -ENODEV;
+       else
+               rc =  __raw3270_start(rp, view, rq);
+       return rc;
+}
+
 int
 raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
 {
@@ -744,6 +768,22 @@ raw3270_reset_device(struct raw3270 *rp)
        return rc;
 }
 
+int
+raw3270_reset(struct raw3270_view *view)
+{
+       struct raw3270 *rp;
+       int rc;
+
+       rp = view->dev;
+       if (!rp || rp->view != view)
+               rc = -EACCES;
+       else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
+               rc = -ENODEV;
+       else
+               rc = raw3270_reset_device(view->dev);
+       return rc;
+}
+
 /*
  * Setup new 3270 device.
  */
@@ -774,11 +814,12 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
 
        /*
         * Add device to list and find the smallest unused minor
-        * number for it.
+        * number for it. Note: there is no device with minor 0,
+        * see special case for fs3270.c:fs3270_open().
         */
        down(&raw3270_sem);
        /* Keep the list sorted. */
-       minor = 0;
+       minor = RAW3270_FIRSTMINOR;
        rp->minor = -1;
        list_for_each(l, &raw3270_devices) {
                tmp = list_entry(l, struct raw3270, list);
@@ -789,7 +830,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
                }
                minor++;
        }
-       if (rp->minor == -1 && minor < RAW3270_MAXDEVS) {
+       if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
                rp->minor = minor;
                list_add_tail(&rp->list, &raw3270_devices);
        }
@@ -941,11 +982,12 @@ raw3270_deactivate_view(struct raw3270_view *view)
                list_add_tail(&view->list, &rp->view_list);
                /* Try to activate another view. */
                if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
-                       list_for_each_entry(view, &rp->view_list, list)
-                               if (view->fn->activate(view) == 0) {
-                                       rp->view = view;
+                       list_for_each_entry(view, &rp->view_list, list) {
+                               rp->view = view;
+                               if (view->fn->activate(view) == 0)
                                        break;
-                               }
+                               rp->view = 0;
+                       }
                }
        }
        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -961,6 +1003,8 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
        struct raw3270 *rp;
        int rc;
 
+       if (minor <= 0)
+               return -ENODEV;
        down(&raw3270_sem);
        rc = -ENODEV;
        list_for_each_entry(rp, &raw3270_devices, list) {
@@ -976,7 +1020,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
                        view->cols = rp->cols;
                        view->ascebc = rp->ascebc;
                        spin_lock_init(&view->lock);
-                       list_add_tail(&view->list, &rp->view_list);
+                       list_add(&view->list, &rp->view_list);
                        rc = 0;
                }
                spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
@@ -1039,7 +1083,7 @@ raw3270_del_view(struct raw3270_view *view)
        if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
                /* Try to activate another view. */
                list_for_each_entry(nv, &rp->view_list, list) {
-                       if (nv->fn->activate(view) == 0) {
+                       if (nv->fn->activate(nv) == 0) {
                                rp->view = nv;
                                break;
                        }
@@ -1063,6 +1107,12 @@ raw3270_delete_device(struct raw3270 *rp)
 
        /* Remove from device chain. */
        down(&raw3270_sem);
+       if (rp->clttydev)
+               class_device_destroy(class3270,
+                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+       if (rp->cltubdev)
+               class_device_destroy(class3270,
+                                    MKDEV(IBM_FS3270_MAJOR, rp->minor));
        list_del_init(&rp->list);
        up(&raw3270_sem);
 
@@ -1129,6 +1179,16 @@ raw3270_create_attributes(struct raw3270 *rp)
 {
        //FIXME: check return code
        sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
+       rp->clttydev =
+               class_device_create(class3270,
+                                   MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+                                   &rp->cdev->dev, "tty%s",
+                                   rp->cdev->dev.bus_id);
+       rp->cltubdev =
+               class_device_create(class3270,
+                                   MKDEV(IBM_FS3270_MAJOR, rp->minor),
+                                   &rp->cdev->dev, "tub%s",
+                                   rp->cdev->dev.bus_id);
 }
 
 /*
@@ -1189,13 +1249,13 @@ raw3270_set_online (struct ccw_device *cdev)
                return PTR_ERR(rp);
        rc = raw3270_reset_device(rp);
        if (rc)
-               return rc;
+               goto failure;
        rc = raw3270_size_device(rp);
        if (rc)
-               return rc;
+               goto failure;
        rc = raw3270_reset_device(rp);
        if (rc)
-               return rc;
+               goto failure;
        raw3270_create_attributes(rp);
        set_bit(RAW3270_FLAGS_READY, &rp->flags);
        down(&raw3270_sem);
@@ -1203,6 +1263,10 @@ raw3270_set_online (struct ccw_device *cdev)
                np->notifier(rp->minor, 1);
        up(&raw3270_sem);
        return 0;
+
+failure:
+       raw3270_delete_device(rp);
+       return rc;
 }
 
 /*
@@ -1217,6 +1281,14 @@ raw3270_remove (struct ccw_device *cdev)
        struct raw3270_notifier *np;
 
        rp = cdev->dev.driver_data;
+       /*
+        * _remove is the opposite of _probe; it's probe that
+        * should set up rp.  raw3270_remove gets entered for
+        * devices even if they haven't been varied online.
+        * Thus, rp may validly be NULL here.
+        */
+       if (rp == NULL)
+               return;
        clear_bit(RAW3270_FLAGS_READY, &rp->flags);
 
        sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
@@ -1301,6 +1373,7 @@ raw3270_init(void)
        if (rc == 0) {
                /* Create attributes for early (= console) device. */
                down(&raw3270_sem);
+               class3270 = class_create(THIS_MODULE, "3270");
                list_for_each_entry(rp, &raw3270_devices, list) {
                        get_device(&rp->cdev->dev);
                        raw3270_create_attributes(rp);
@@ -1314,6 +1387,7 @@ static void
 raw3270_exit(void)
 {
        ccw_driver_unregister(&raw3270_ccw_driver);
+       class_destroy(class3270);
 }
 
 MODULE_LICENSE("GPL");
@@ -1335,7 +1409,9 @@ EXPORT_SYMBOL(raw3270_find_view);
 EXPORT_SYMBOL(raw3270_activate_view);
 EXPORT_SYMBOL(raw3270_deactivate_view);
 EXPORT_SYMBOL(raw3270_start);
+EXPORT_SYMBOL(raw3270_start_locked);
 EXPORT_SYMBOL(raw3270_start_irq);
+EXPORT_SYMBOL(raw3270_reset);
 EXPORT_SYMBOL(raw3270_register_notifier);
 EXPORT_SYMBOL(raw3270_unregister_notifier);
 EXPORT_SYMBOL(raw3270_wait_queue);
index ed5d4eb9f623114508e7a2587508e41c84af766c..b635bf8e777524525c38df6032cb41d2b2e1a627 100644 (file)
@@ -21,6 +21,7 @@
 
 /* Local Channel Commands */
 #define TC_WRITE       0x01            /* Write */
+#define TC_RDBUF       0x02            /* Read Buffer */
 #define TC_EWRITE      0x05            /* Erase write */
 #define TC_READMOD     0x06            /* Read modified */
 #define TC_EWRITEA     0x0d            /* Erase write alternate */
@@ -76,7 +77,8 @@
 #define TW_KR          0xc2            /* Keyboard restore */
 #define TW_PLUSALARM   0x04            /* Add this bit for alarm */
 
-#define RAW3270_MAXDEVS        256
+#define RAW3270_FIRSTMINOR     1       /* First minor number */
+#define RAW3270_MAXDEVS                255     /* Max number of 3270 devices */
 
 /* For TUBGETMOD and TUBSETMOD. Should include. */
 struct raw3270_iocb {
@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_view *);
 void raw3270_deactivate_view(struct raw3270_view *);
 struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
 int raw3270_start(struct raw3270_view *, struct raw3270_request *);
+int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
 int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
+int raw3270_reset(struct raw3270_view *);
+struct raw3270_view *raw3270_view(struct raw3270_view *);
 
 /* Reference count inliner for view structures. */
 static inline void
index 7db5ebce7f0fe2d7cb5fe5d22814c6af23fe76f9..4b90693703881fc61c517fdb36ce5c724774e222 100644 (file)
@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *view)
        tp->update_flags = TTY_UPDATE_ALL;
        tty3270_set_timer(tp, 1);
        spin_unlock_irqrestore(&tp->view.lock, flags);
-       start_tty(tp->tty);
        return 0;
 }
 
 static void
 tty3270_deactivate(struct raw3270_view *view)
 {
-       struct tty3270 *tp;
-
-       tp = (struct tty3270 *) view;
-       if (tp && tp->tty)
-               stop_tty(tp->tty);
 }
 
 static int
@@ -716,13 +710,13 @@ tty3270_alloc_view(void)
                                  tp->freemem_pages[pages], PAGE_SIZE);
        }
        tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
-       if (!tp->write)
+       if (IS_ERR(tp->write))
                goto out_pages;
        tp->read = raw3270_request_alloc(0);
-       if (!tp->read)
+       if (IS_ERR(tp->read))
                goto out_write;
        tp->kreset = raw3270_request_alloc(1);
-       if (!tp->kreset)
+       if (IS_ERR(tp->kreset))
                goto out_read;
        tp->kbd = kbd_alloc();
        if (!tp->kbd)
@@ -845,7 +839,8 @@ tty3270_del_views(void)
        int i;
 
        for (i = 0; i < tty3270_max_index; i++) {
-               tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, i);
+               tp = (struct tty3270 *)
+                       raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
                if (!IS_ERR(tp))
                        raw3270_del_view(&tp->view);
        }
@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
        if (tty->count > 1)
                return 0;
        /* Check if the tty3270 is already there. */
-       tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index);
+       tp = (struct tty3270 *)
+               raw3270_find_view(&tty3270_fn,
+                                 tty->index + RAW3270_FIRSTMINOR);
        if (!IS_ERR(tp)) {
                tty->driver_data = tp;
                tty->winsize.ws_row = tp->view.rows - 2;
@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
                     (void (*)(unsigned long)) tty3270_read_tasklet,
                     (unsigned long) tp->read);
 
-       rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index);
+       rc = raw3270_add_view(&tp->view, &tty3270_fn,
+                             tty->index + RAW3270_FIRSTMINOR);
        if (rc) {
                tty3270_free_view(tp);
                return rc;
@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
 
        rc = tty3270_alloc_screen(tp);
        if (rc) {
-               raw3270_del_view(&tp->view);
                raw3270_put_view(&tp->view);
+               raw3270_del_view(&tp->view);
                return rc;
        }
 
@@ -1780,7 +1778,7 @@ tty3270_init(void)
        struct tty_driver *driver;
        int ret;
 
-       driver = alloc_tty_driver(256);
+       driver = alloc_tty_driver(RAW3270_MAXDEVS);
        if (!driver)
                return -ENOMEM;
 
@@ -1794,6 +1792,7 @@ tty3270_init(void)
        driver->driver_name = "ttyTUB";
        driver->name = "ttyTUB";
        driver->major = IBM_TTY3270_MAJOR;
+       driver->minor_start = RAW3270_FIRSTMINOR;
        driver->type = TTY_DRIVER_TYPE_SYSTEM;
        driver->subtype = SYSTEM_TYPE_TTY;
        driver->init_termios = tty_std_termios;
index 8cc4f1a940dcde952f6aafb124762185fb77fdeb..c05b069c29965e9894c5b87a5c6ce10627470eb9 100644 (file)
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/timex.h>       /* get_clock() */
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
 #include <asm/cmb.h>
+#include <asm/div64.h>
 
 #include "cio.h"
 #include "css.h"
index 9adc11e8b8bcea7f30cd5075ca8a802d6ccb5e78..811c9d15063765214223bd77033726cf3dc7634a 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
+#include <asm/param.h>         /* HZ */
 
 #include "cio.h"
 #include "css.h"
@@ -251,6 +252,23 @@ cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
                       id->cu_type, id->cu_model);
 }
 
+static ssize_t
+modalias_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct ccw_device *cdev = to_ccwdev(dev);
+       struct ccw_device_id *id = &(cdev->id);
+       int ret;
+
+       ret = sprintf(buf, "ccw:t%04Xm%02x",
+                       id->cu_type, id->cu_model);
+       if (id->dev_type != 0)
+               ret += sprintf(buf + ret, "dt%04Xdm%02X\n",
+                               id->dev_type, id->dev_model);
+       else
+               ret += sprintf(buf + ret, "dtdm\n");
+       return ret;
+}
+
 static ssize_t
 online_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -448,6 +466,7 @@ static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
 static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
 static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
 static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
+static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
 static DEVICE_ATTR(online, 0644, online_show, online_store);
 extern struct device_attribute dev_attr_cmb_enable;
 static DEVICE_ATTR(availability, 0444, available_show, NULL);
@@ -471,6 +490,7 @@ subchannel_add_files (struct device *dev)
 static struct attribute * ccwdev_attrs[] = {
        &dev_attr_devtype.attr,
        &dev_attr_cutype.attr,
+       &dev_attr_modalias.attr,
        &dev_attr_online.attr,
        &dev_attr_cmb_enable.attr,
        &dev_attr_availability.attr,
index fbe4202a3f6f462e2104e7acf84368f5cd15198f..c1c89f4fd4e3c3815c8fe7c9ddfaab2d4b3e4084 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
 
 #include <asm/ccwdev.h>
 #include <asm/cio.h>
index fe8187d6f58be248bdcf2f5ab053ff997ecb2dac..e2a5657d5fdb4887ae969158ac89ff95fcedb01a 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -192,7 +193,6 @@ static void ahci_port_stop(struct ata_port *ap);
 static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 static void ahci_qc_prep(struct ata_queued_cmd *qc);
 static u8 ahci_check_status(struct ata_port *ap);
-static u8 ahci_check_err(struct ata_port *ap);
 static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
 static void ahci_remove_one (struct pci_dev *pdev);
 
@@ -221,7 +221,6 @@ static const struct ata_port_operations ahci_ops = {
 
        .check_status           = ahci_check_status,
        .check_altstatus        = ahci_check_status,
-       .check_err              = ahci_check_err,
        .dev_select             = ata_noop_dev_select,
 
        .tf_read                = ahci_tf_read,
@@ -458,13 +457,6 @@ static u8 ahci_check_status(struct ata_port *ap)
        return readl(mmio + PORT_TFDATA) & 0xFF;
 }
 
-static u8 ahci_check_err(struct ata_port *ap)
-{
-       void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
-
-       return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
-}
-
 static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
 {
        struct ahci_port_priv *pp = ap->private_data;
@@ -609,7 +601,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
                 * not being called from the SCSI EH.
                 */
                qc->scsidone = scsi_finish_command;
-               ata_qc_complete(qc, ATA_ERR);
+               ata_qc_complete(qc, AC_ERR_OTHER);
        }
 
        spin_unlock_irqrestore(&host_set->lock, flags);
@@ -638,7 +630,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
        if (status & PORT_IRQ_FATAL) {
                ahci_intr_error(ap, status);
                if (qc)
-                       ata_qc_complete(qc, ATA_ERR);
+                       ata_qc_complete(qc, AC_ERR_OTHER);
        }
 
        return 1;
@@ -683,10 +675,10 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
                        if (!ahci_host_intr(ap, qc))
                                if (ata_ratelimit()) {
                                        struct pci_dev *pdev =
-                                         to_pci_dev(ap->host_set->dev);
-                                       printk(KERN_WARNING
-                                         "ahci(%s): unhandled interrupt on port %u\n",
-                                         pci_name(pdev), i);
+                                               to_pci_dev(ap->host_set->dev);
+                                       dev_printk(KERN_WARNING, &pdev->dev,
+                                         "unhandled interrupt on port %u\n",
+                                         i);
                                }
 
                        VPRINTK("port %u\n", i);
@@ -694,10 +686,9 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *
                        VPRINTK("port %u (no irq)\n", i);
                        if (ata_ratelimit()) {
                                struct pci_dev *pdev =
-                                 to_pci_dev(ap->host_set->dev);
-                               printk(KERN_WARNING
-                                 "ahci(%s): interrupt on disabled port %u\n",
-                                 pci_name(pdev), i);
+                                       to_pci_dev(ap->host_set->dev);
+                               dev_printk(KERN_WARNING, &pdev->dev,
+                                       "interrupt on disabled port %u\n", i);
                        }
                }
 
@@ -769,8 +760,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
 
        tmp = readl(mmio + HOST_CTL);
        if (tmp & HOST_RESET) {
-               printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
-                       pci_name(pdev), tmp);
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "controller reset failed (0x%x)\n", tmp);
                return -EIO;
        }
 
@@ -798,22 +789,22 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
                if (rc) {
                        rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                        if (rc) {
-                               printk(KERN_ERR DRV_NAME "(%s): 64-bit DMA enable failed\n",
-                                       pci_name(pdev));
+                               dev_printk(KERN_ERR, &pdev->dev,
+                                          "64-bit DMA enable failed\n");
                                return rc;
                        }
                }
        } else {
                rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                if (rc) {
-                       printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
-                               pci_name(pdev));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit DMA enable failed\n");
                        return rc;
                }
                rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                if (rc) {
-                       printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
-                               pci_name(pdev));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit consistent DMA enable failed\n");
                        return rc;
                }
        }
@@ -916,10 +907,10 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
        else
                scc_s = "unknown";
 
-       printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
+       dev_printk(KERN_INFO, &pdev->dev,
+               "AHCI %02x%02x.%02x%02x "
                "%u slots %u ports %s Gbps 0x%x impl %s mode\n"
                ,
-               pci_name(pdev),
 
                (vers >> 24) & 0xff,
                (vers >> 16) & 0xff,
@@ -932,11 +923,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
                impl,
                scc_s);
 
-       printk(KERN_INFO DRV_NAME "(%s) flags: "
+       dev_printk(KERN_INFO, &pdev->dev,
+               "flags: "
                "%s%s%s%s%s%s"
                "%s%s%s%s%s%s%s\n"
                ,
-               pci_name(pdev),
 
                cap & (1 << 31) ? "64bit " : "",
                cap & (1 << 30) ? "ncq " : "",
@@ -969,7 +960,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        VPRINTK("ENTER\n");
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
index be021478f41628ddc53f95adf0150534ce937454..7f8aa1b552ce1f6d89d23c38c74356bf54363a96 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -621,18 +622,19 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        struct ata_port_info *port_info[2];
-       unsigned int combined = 0, n_ports = 1;
+       unsigned int combined = 0;
        unsigned int pata_chan = 0, sata_chan = 0;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev,
+                          "version " DRV_VERSION "\n");
 
        /* no hotplugging support (FIXME) */
        if (!in_module_init)
                return -ENODEV;
 
        port_info[0] = &piix_port_info[ent->driver_data];
-       port_info[1] = NULL;
+       port_info[1] = &piix_port_info[ent->driver_data];
 
        if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
                u8 tmp;
@@ -670,12 +672,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                port_info[sata_chan] = &piix_port_info[ent->driver_data];
                port_info[sata_chan]->host_flags |= ATA_FLAG_SLAVE_POSS;
                port_info[pata_chan] = &piix_port_info[ich5_pata];
-               n_ports++;
 
-               printk(KERN_WARNING DRV_NAME ": combined mode detected\n");
+               dev_printk(KERN_WARNING, &pdev->dev,
+                          "combined mode detected (p=%u, s=%u)\n",
+                          pata_chan, sata_chan);
        }
 
-       return ata_pci_init_one(pdev, port_info, n_ports);
+       return ata_pci_init_one(pdev, port_info, 2);
 }
 
 static int __init piix_init(void)
index 3d62c9bcbff76931584364de2743060f9d398d68..00d6a6657ebc3ec78f19d28e25edb2e3354513d4 100644 (file)
@@ -180,19 +180,12 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               if (PageHighMem(pc->sg->page)) {
-                       unsigned long flags;
-
-                       local_irq_save(flags);
-                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
-                       drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
-                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
-                       local_irq_restore(flags);
-               } else {
-                       buf = page_address(pc->sg->page) + pc->sg->offset;
-                       drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count);
-               }
-               bcount -= count; pc->b_count += count;
+               buf = kmap_atomic(pc->sg->page, KM_IRQ0);
+               drive->hwif->atapi_input_bytes(drive,
+                               buf + pc->b_count + pc->sg->offset, count);
+               kunmap_atomic(buf, KM_IRQ0);
+               bcount -= count;
+               pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
                        pc->b_count = 0;
@@ -212,19 +205,12 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               if (PageHighMem(pc->sg->page)) {
-                       unsigned long flags;
-
-                       local_irq_save(flags);
-                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset;
-                       drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
-                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
-                       local_irq_restore(flags);
-               } else {
-                       buf = page_address(pc->sg->page) + pc->sg->offset;
-                       drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count);
-               }
-               bcount -= count; pc->b_count += count;
+               buf = kmap_atomic(pc->sg->page, KM_IRQ0);
+               drive->hwif->atapi_output_bytes(drive,
+                               buf + pc->b_count + pc->sg->offset, count);
+               kunmap_atomic(buf, KM_IRQ0);
+               bcount -= count;
+               pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
                        pc->b_count = 0;
index 5ca97605ff3565ac914cd92c3ed934f739d56297..8be7dc0b47b849858c8d5b37872e7112fb8e3b31 100644 (file)
@@ -372,7 +372,7 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
        tf->command = ata_check_status(ap);
-       tf->feature = ata_chk_err(ap);
+       tf->feature = inb(ioaddr->error_addr);
        tf->nsect = inb(ioaddr->nsect_addr);
        tf->lbal = inb(ioaddr->lbal_addr);
        tf->lbam = inb(ioaddr->lbam_addr);
@@ -406,7 +406,7 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
        struct ata_ioports *ioaddr = &ap->ioaddr;
 
        tf->command = ata_check_status(ap);
-       tf->feature = ata_chk_err(ap);
+       tf->feature = readb((void __iomem *)ioaddr->error_addr);
        tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
        tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
        tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
@@ -526,30 +526,6 @@ u8 ata_altstatus(struct ata_port *ap)
 }
 
 
-/**
- *     ata_chk_err - Read device error reg
- *     @ap: port where the device is
- *
- *     Reads ATA taskfile error register for
- *     currently-selected device and return its value.
- *
- *     Note: may NOT be used as the check_err() entry in
- *     ata_port_operations.
- *
- *     LOCKING:
- *     Inherited from caller.
- */
-u8 ata_chk_err(struct ata_port *ap)
-{
-       if (ap->ops->check_err)
-               return ap->ops->check_err(ap);
-
-       if (ap->flags & ATA_FLAG_MMIO) {
-               return readb((void __iomem *) ap->ioaddr.error_addr);
-       }
-       return inb(ap->ioaddr.error_addr);
-}
-
 /**
  *     ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
  *     @tf: Taskfile to convert
@@ -902,8 +878,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device)
 
        memset(&tf, 0, sizeof(tf));
 
-       err = ata_chk_err(ap);
        ap->ops->tf_read(ap, &tf);
+       err = tf.feature;
 
        dev->class = ATA_DEV_NONE;
 
@@ -1140,7 +1116,6 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
        unsigned int major_version;
        u16 tmp;
        unsigned long xfer_modes;
-       u8 status;
        unsigned int using_edd;
        DECLARE_COMPLETION(wait);
        struct ata_queued_cmd *qc;
@@ -1194,8 +1169,11 @@ retry:
        else
                wait_for_completion(&wait);
 
-       status = ata_chk_status(ap);
-       if (status & ATA_ERR) {
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       ap->ops->tf_read(ap, &qc->tf);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+       if (qc->tf.command & ATA_ERR) {
                /*
                 * arg!  EDD works for all test cases, but seems to return
                 * the ATA signature for some ATAPI devices.  Until the
@@ -1208,7 +1186,7 @@ retry:
                 * to have this problem.
                 */
                if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) {
-                       u8 err = ata_chk_err(ap);
+                       u8 err = qc->tf.feature;
                        if (err & ATA_ABORTED) {
                                dev->class = ATA_DEV_ATAPI;
                                qc->cursg = 0;
@@ -2685,7 +2663,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
  *     None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        struct ata_port *ap = qc->ap;
        unsigned long flags;
@@ -2693,7 +2671,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
        spin_lock_irqsave(&ap->host_set->lock, flags);
        ap->flags &= ~ATA_FLAG_NOINTR;
        ata_irq_on(ap);
-       ata_qc_complete(qc, drv_stat);
+       ata_qc_complete(qc, err_mask);
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2790,7 +2768,7 @@ static int ata_pio_complete (struct ata_port *ap)
 
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, drv_stat);
+       ata_poll_qc_complete(qc, 0);
 
        /* another command may start at this point */
 
@@ -3158,18 +3136,15 @@ static void ata_pio_block(struct ata_port *ap)
 static void ata_pio_error(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc;
-       u8 drv_stat;
+
+       printk(KERN_WARNING "ata%u: PIO error\n", ap->id);
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
        assert(qc != NULL);
 
-       drv_stat = ata_chk_status(ap);
-       printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n",
-              ap->id, drv_stat);
-
        ap->hsm_task_state = HSM_ST_IDLE;
 
-       ata_poll_qc_complete(qc, drv_stat | ATA_ERR);
+       ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
 }
 
 static void ata_pio_task(void *_data)
@@ -3292,7 +3267,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
                       ap->id, qc->tf.command, drv_stat, host_stat);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, drv_stat);
+               ata_qc_complete(qc, ac_err_mask(drv_stat));
                break;
        }
 
@@ -3397,7 +3372,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
        return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat)
+int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        return 0;
 }
@@ -3456,7 +3431,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        int rc;
 
@@ -3473,7 +3448,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
        qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
        /* call completion callback */
-       rc = qc->complete_fn(qc, drv_stat);
+       rc = qc->complete_fn(qc, err_mask);
 
        /* if callback indicates not to complete command (non-zero),
         * return immediately
@@ -3911,7 +3886,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
                ap->ops->irq_clear(ap);
 
                /* complete taskfile transaction */
-               ata_qc_complete(qc, status);
+               ata_qc_complete(qc, ac_err_mask(status));
                break;
 
        default:
@@ -4006,7 +3981,7 @@ static void atapi_packet_task(void *_data)
        /* sleep-wait for BSY to clear */
        DPRINTK("busy wait\n");
        if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-               goto err_out;
+               goto err_out_status;
 
        /* make sure DRQ is set */
        status = ata_chk_status(ap);
@@ -4043,8 +4018,10 @@ static void atapi_packet_task(void *_data)
 
        return;
 
+err_out_status:
+       status = ata_chk_status(ap);
 err_out:
-       ata_poll_qc_complete(qc, ATA_ERR);
+       ata_poll_qc_complete(qc, __ac_err_mask(status));
 }
 
 
@@ -4550,11 +4527,11 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
        return probe_ent;
 }
 
-static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info **port, int port_num)
+static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num)
 {
        struct ata_probe_ent *probe_ent;
 
-       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
+       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
        if (!probe_ent)
                return NULL;
 
@@ -4701,9 +4678,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 
        if (legacy_mode) {
                if (legacy_mode & (1 << 0))
-                       probe_ent = ata_pci_init_legacy_port(pdev, port, 0);
+                       probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
                if (legacy_mode & (1 << 1))
-                       probe_ent2 = ata_pci_init_legacy_port(pdev, port, 1);
+                       probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
        } else {
                if (n_ports == 2)
                        probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
@@ -4867,7 +4844,6 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
 EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_altstatus);
-EXPORT_SYMBOL_GPL(ata_chk_err);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_port_stop);
index 89a04b1a5a0ef052f6566c6b15f3aed8f3da4b30..1e3792f86fcf4359171d46b6ac326b099844e905 100644 (file)
@@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
         * Use ata_to_sense_error() to map status register bits
         * onto sense key, asc & ascq.
         */
-       if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+       if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
                                   &sb[1], &sb[2], &sb[3]);
                sb[1] &= 0x0f;
@@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
         * Use ata_to_sense_error() to map status register bits
         * onto sense key, asc & ascq.
         */
-       if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) {
+       if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
                                   &sb[2], &sb[12], &sb[13]);
                sb[2] &= 0x0f;
@@ -644,7 +644,11 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
        sb[0] = 0x70;
        sb[7] = 0x0a;
 
-       if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) {
+       if (tf->flags & ATA_TFLAG_LBA48) {
+               /* TODO: find solution for LBA48 descriptors */
+       }
+
+       else if (tf->flags & ATA_TFLAG_LBA) {
                /* A small (28b) LBA will fit in the 32b info field */
                sb[0] |= 0x80;          /* set valid bit */
                sb[3] = tf->device & 0x0f;
@@ -652,6 +656,10 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc)
                sb[5] = tf->lbam;
                sb[6] = tf->lbal;
        }
+
+       else {
+               /* TODO: C/H/S */
+       }
 }
 
 /**
@@ -1199,10 +1207,12 @@ nothing_to_do:
        return 1;
 }
 
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
+                               unsigned int err_mask)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
-       int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ);
+       u8 *cdb = cmd->cmnd;
+       int need_sense = (err_mask != 0);
 
        /* For ATA pass thru (SAT) commands, generate a sense block if
         * user mandated it or if there's an error.  Note that if we
@@ -1211,8 +1221,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
         * whether the command completed successfully or not. If there
         * was no error, SK, ASC and ASCQ will all be zero.
         */
-       if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) &&
-           ((cmd->cmnd[2] & 0x20) || need_sense)) {
+       if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
+           ((cdb[2] & 0x20) || need_sense)) {
                ata_gen_ata_desc_sense(qc);
        } else {
                if (!need_sense) {
@@ -1995,21 +2005,13 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
        DPRINTK("EXIT\n");
 }
 
-static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
+static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
 {
        struct scsi_cmnd *cmd = qc->scsicmd;
 
-       VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat);
-
-       if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ)))
-               /* FIXME: not quite right; we don't want the
-                * translation of taskfile registers into
-                * a sense descriptors, since that's only
-                * correct for ATA, not ATAPI
-                */
-               ata_gen_ata_desc_sense(qc);
+       VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
 
-       else if (unlikely(drv_stat & ATA_ERR)) {
+       if (unlikely(err_mask & AC_ERR_DEV)) {
                DPRINTK("request check condition\n");
 
                /* FIXME: command completion with check condition
@@ -2026,6 +2028,14 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
                return 1;
        }
 
+       else if (unlikely(err_mask))
+               /* FIXME: not quite right; we don't want the
+                * translation of taskfile registers into
+                * a sense descriptors, since that's only
+                * correct for ATA, not ATAPI
+                */
+               ata_gen_ata_desc_sense(qc);
+
        else {
                u8 *scsicmd = cmd->cmnd;
 
index 65c264b911369dfb10864025d2bf004e071f1bb1..10ecd9e15e4fb9296b8a0aa1eeacf99b5aaf2e29 100644 (file)
@@ -39,7 +39,7 @@ struct ata_scsi_args {
 
 /* libata-core.c */
 extern int atapi_enabled;
-extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
+extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
                                      struct ata_device *dev);
 extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
index b235556b7b65459775236f9940147ed1c118a772..bdccf73cf9fe246d880c9b4e2efbd48b5ec5820f 100644 (file)
@@ -730,7 +730,7 @@ static void start_phase(struct mesh_state *ms)
                 * issue a SEQ_MSGOUT to get the mesh to drop ACK.
                 */
                if ((in_8(&mr->bus_status0) & BS0_ATN) == 0) {
-                       dlog(ms, "bus0 was %.2x explictly asserting ATN", mr->bus_status0);
+                       dlog(ms, "bus0 was %.2x explicitly asserting ATN", mr->bus_status0);
                        out_8(&mr->bus_status0, BS0_ATN); /* explicit ATN */
                        mesh_flush_io(mr);
                        udelay(1);
index af99feb9d2375cd2e14cad88b0e2836843b1e144..665017eda8a6596754b7f69bb6d6565597e3172f 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <asm/io.h>
@@ -451,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
                struct adma_port_priv *pp;
                struct ata_queued_cmd *qc;
                void __iomem *chan = ADMA_REGS(mmio_base, port_no);
-               u8 drv_stat = 0, status = readb(chan + ADMA_STATUS);
+               u8 status = readb(chan + ADMA_STATUS);
 
                if (status == 0)
                        continue;
@@ -464,11 +465,14 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set)
                        continue;
                qc = ata_qc_from_tag(ap, ap->active_tag);
                if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
+                       unsigned int err_mask = 0;
+
                        if ((status & (aPERR | aPSD | aUIRQ)))
-                               drv_stat = ATA_ERR;
+                               err_mask = AC_ERR_OTHER;
                        else if (pp->pkt[0] != cDONE)
-                               drv_stat = ATA_ERR;
-                       ata_qc_complete(qc, drv_stat);
+                               err_mask = AC_ERR_OTHER;
+
+                       ata_qc_complete(qc, err_mask);
                }
        }
        return handled;
@@ -498,7 +502,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set)
                
                                /* complete taskfile transaction */
                                pp->state = adma_state_idle;
-                               ata_qc_complete(qc, status);
+                               ata_qc_complete(qc, ac_err_mask(status));
                                handled = 1;
                        }
                }
@@ -623,16 +627,14 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
 
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc) {
-               printk(KERN_ERR DRV_NAME
-                       "(%s): 32-bit DMA enable failed\n",
-                       pci_name(pdev));
+               dev_printk(KERN_ERR, &pdev->dev,
+                       "32-bit DMA enable failed\n");
                return rc;
        }
        rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc) {
-               printk(KERN_ERR DRV_NAME
-                       "(%s): 32-bit consistent DMA enable failed\n",
-                       pci_name(pdev));
+               dev_printk(KERN_ERR, &pdev->dev,
+                       "32-bit consistent DMA enable failed\n");
                return rc;
        }
        return 0;
@@ -648,7 +650,7 @@ static int adma_ata_init_one(struct pci_dev *pdev,
        int rc, port_no;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
index 422e0b6f603ac5b8960073def04a2757f8ed79e8..46dbdee79f77af8d51ecbe334323bea22c2f641c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -258,7 +259,6 @@ struct mv_host_priv {
 static void mv_irq_clear(struct ata_port *ap);
 static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
 static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
-static u8 mv_check_err(struct ata_port *ap);
 static void mv_phy_reset(struct ata_port *ap);
 static void mv_host_stop(struct ata_host_set *host_set);
 static int mv_port_start(struct ata_port *ap);
@@ -296,7 +296,6 @@ static const struct ata_port_operations mv_ops = {
        .tf_load                = ata_tf_load,
        .tf_read                = ata_tf_read,
        .check_status           = ata_check_status,
-       .check_err              = mv_check_err,
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
 
@@ -1067,6 +1066,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
        struct ata_queued_cmd *qc;
        u32 hc_irq_cause;
        int shift, port, port0, hard_port, handled;
+       unsigned int err_mask;
        u8 ata_status = 0;
 
        if (hc == 0) {
@@ -1102,15 +1102,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                        handled++;
                }
 
+               err_mask = ac_err_mask(ata_status);
+
                shift = port << 1;              /* (port * 2) */
                if (port >= MV_PORTS_PER_HC) {
                        shift++;        /* skip bit 8 in the HC Main IRQ reg */
                }
                if ((PORT0_ERR << shift) & relevant) {
                        mv_err_intr(ap);
-                       /* OR in ATA_ERR to ensure libata knows we took one */
-                       ata_status = readb((void __iomem *)
-                                          ap->ioaddr.status_addr) | ATA_ERR;
+                       err_mask |= AC_ERR_OTHER;
                        handled++;
                }
                
@@ -1120,7 +1120,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                                VPRINTK("port %u IRQ found for qc, "
                                        "ata_status 0x%x\n", port,ata_status);
                                /* mark qc status appropriately */
-                               ata_qc_complete(qc, ata_status);
+                               ata_qc_complete(qc, err_mask);
                        }
                }
        }
@@ -1184,22 +1184,6 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
        return IRQ_RETVAL(handled);
 }
 
-/**
- *      mv_check_err - Return the error shadow register to caller.
- *      @ap: ATA channel to manipulate
- *
- *      Marvell requires DMA to be stopped before accessing shadow
- *      registers.  So we do that, then return the needed register.
- *
- *      LOCKING:
- *      Inherited from caller.  FIXME: protect mv_stop_dma with lock?
- */
-static u8 mv_check_err(struct ata_port *ap)
-{
-       mv_stop_dma(ap);                /* can't read shadow regs if DMA on */
-       return readb((void __iomem *) ap->ioaddr.error_addr);
-}
-
 /**
  *      mv_phy_reset - Perform eDMA reset followed by COMRESET
  *      @ap: ATA channel to manipulate
@@ -1312,7 +1296,7 @@ static void mv_eng_timeout(struct ata_port *ap)
                 */
                spin_lock_irqsave(&ap->host_set->lock, flags);
                qc->scsidone = scsi_finish_command;
-               ata_qc_complete(qc, ATA_ERR);
+               ata_qc_complete(qc, AC_ERR_OTHER);
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        }
 }
@@ -1454,9 +1438,9 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
        else
                scc_s = "unknown";
 
-       printk(KERN_INFO DRV_NAME 
-              "(%s) %u slots %u ports %s mode IRQ via %s\n",
-              pci_name(pdev), (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, 
+       dev_printk(KERN_INFO, &pdev->dev,
+              "%u slots %u ports %s mode IRQ via %s\n",
+              (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, 
               scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
 }
 
@@ -1477,9 +1461,8 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        void __iomem *mmio_base;
        int pci_dev_busy = 0, rc;
 
-       if (!printed_version++) {
-               printk(KERN_INFO DRV_NAME " version " DRV_VERSION "\n");
-       }
+       if (!printed_version++)
+               dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc) {
index 1a56d6c79dddfc8fac2e52d4320110977e1ce599..d573888eda761f05041ab771bc6e64891e97c5b2 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -383,7 +384,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        return -ENODEV;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
index 63911f16b6ecda3f6559ed9fc4070f39f5644272..b41c977d6fab1df637b7c5c1c2a72d67c05f708f 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -399,7 +400,8 @@ static void pdc_eng_timeout(struct ata_port *ap)
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-               ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+               drv_stat = ata_wait_idle(ap);
+               ata_qc_complete(qc, __ac_err_mask(drv_stat));
                break;
 
        default:
@@ -408,7 +410,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
                printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
                       ap->id, qc->tf.command, drv_stat);
 
-               ata_qc_complete(qc, drv_stat);
+               ata_qc_complete(qc, ac_err_mask(drv_stat));
                break;
        }
 
@@ -420,24 +422,21 @@ out:
 static inline unsigned int pdc_host_intr( struct ata_port *ap,
                                           struct ata_queued_cmd *qc)
 {
-       u8 status;
-       unsigned int handled = 0, have_err = 0;
+       unsigned int handled = 0, err_mask = 0;
        u32 tmp;
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
 
        tmp = readl(mmio);
        if (tmp & PDC_ERR_MASK) {
-               have_err = 1;
+               err_mask = AC_ERR_DEV;
                pdc_reset_port(ap);
        }
 
        switch (qc->tf.protocol) {
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
-               status = ata_wait_idle(ap);
-               if (have_err)
-                       status |= ATA_ERR;
-               ata_qc_complete(qc, status);
+               err_mask |= ac_err_mask(ata_wait_idle(ap));
+               ata_qc_complete(qc, err_mask);
                handled = 1;
                break;
 
@@ -635,7 +634,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        int rc;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        /*
         * If this driver happens to only be useful on Apple's K2, then
index 1aaf3304d397ebfa43ce1ba493ac2fc1867e8531..9938dae782b6b1b2ba6255e4ba67203a72fc650d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <asm/io.h>
@@ -400,11 +401,12 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set)
                                qc = ata_qc_from_tag(ap, ap->active_tag);
                                if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
                                        switch (sHST) {
-                                       case 0: /* sucessful CPB */
+                                       case 0: /* successful CPB */
                                        case 3: /* device error */
                                                pp->state = qs_state_idle;
                                                qs_enter_reg_mode(qc->ap);
-                                               ata_qc_complete(qc, sDST);
+                                               ata_qc_complete(qc,
+                                                       ac_err_mask(sDST));
                                                break;
                                        default:
                                                break;
@@ -441,7 +443,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set)
 
                                /* complete taskfile transaction */
                                pp->state = qs_state_idle;
-                               ata_qc_complete(qc, status);
+                               ata_qc_complete(qc, ac_err_mask(status));
                                handled = 1;
                        }
                }
@@ -599,25 +601,22 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
                if (rc) {
                        rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                        if (rc) {
-                               printk(KERN_ERR DRV_NAME
-                                       "(%s): 64-bit DMA enable failed\n",
-                                       pci_name(pdev));
+                               dev_printk(KERN_ERR, &pdev->dev,
+                                          "64-bit DMA enable failed\n");
                                return rc;
                        }
                }
        } else {
                rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                if (rc) {
-                       printk(KERN_ERR DRV_NAME
-                               "(%s): 32-bit DMA enable failed\n",
-                               pci_name(pdev));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                               "32-bit DMA enable failed\n");
                        return rc;
                }
                rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                if (rc) {
-                       printk(KERN_ERR DRV_NAME
-                               "(%s): 32-bit consistent DMA enable failed\n",
-                               pci_name(pdev));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                               "32-bit consistent DMA enable failed\n");
                        return rc;
                }
        }
@@ -634,7 +633,7 @@ static int qs_ata_init_one(struct pci_dev *pdev,
        int rc, port_no;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
index 3a056173fb95a2c9a62598906fcec57231e7db76..435f7e0085ec74c460a7a17df0be7276155506a9 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -386,7 +387,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        u8 cls;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        /*
         * If this driver happens to only be useful on Apple's K2, then
@@ -463,8 +464,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        writeb(cls, mmio_base + SIL_FIFO_W3);
                }
        } else
-               printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
-                       pci_name(pdev));
+               dev_printk(KERN_WARNING, &pdev->dev,
+                        "cache line size not set.  Driver may not function\n");
 
        if (ent->driver_data == sil_3114) {
                irq_mask = SIL_MASK_4PORT;
index 51855d3bac64b21d60cffbab0fc4c82ee4a2a2a5..c66548025657e52339ab89d9f0a1914b8ff58111 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/device.h>
 #include <scsi/scsi_host.h>
 #include "scsi.h"
 #include <linux/libata.h>
@@ -225,7 +226,6 @@ struct sil24_host_priv {
 };
 
 static u8 sil24_check_status(struct ata_port *ap);
-static u8 sil24_check_err(struct ata_port *ap);
 static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
 static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
 static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
@@ -280,7 +280,6 @@ static const struct ata_port_operations sil24_ops = {
 
        .check_status           = sil24_check_status,
        .check_altstatus        = sil24_check_status,
-       .check_err              = sil24_check_err,
        .dev_select             = ata_noop_dev_select,
 
        .tf_read                = sil24_tf_read,
@@ -363,12 +362,6 @@ static u8 sil24_check_status(struct ata_port *ap)
        return pp->tf.command;
 }
 
-static u8 sil24_check_err(struct ata_port *ap)
-{
-       struct sil24_port_priv *pp = ap->private_data;
-       return pp->tf.feature;
-}
-
 static int sil24_scr_map[] = {
        [SCR_CONTROL]   = 0,
        [SCR_STATUS]    = 1,
@@ -506,7 +499,7 @@ static void sil24_eng_timeout(struct ata_port *ap)
 
        qc = ata_qc_from_tag(ap, ap->active_tag);
        if (!qc) {
-               printk(KERN_ERR "ata%u: BUG: tiemout without command\n",
+               printk(KERN_ERR "ata%u: BUG: timeout without command\n",
                       ap->id);
                return;
        }
@@ -520,7 +513,7 @@ static void sil24_eng_timeout(struct ata_port *ap)
         */
        printk(KERN_ERR "ata%u: command timeout\n", ap->id);
        qc->scsidone = scsi_finish_command;
-       ata_qc_complete(qc, ATA_ERR);
+       ata_qc_complete(qc, AC_ERR_OTHER);
 
        sil24_reset_controller(ap);
 }
@@ -531,6 +524,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
        struct sil24_port_priv *pp = ap->private_data;
        void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
        u32 irq_stat, cmd_err, sstatus, serror;
+       unsigned int err_mask;
 
        irq_stat = readl(port + PORT_IRQ_STAT);
        writel(irq_stat, port + PORT_IRQ_STAT);         /* clear irq */
@@ -558,17 +552,18 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
                 * Device is reporting error, tf registers are valid.
                 */
                sil24_update_tf(ap);
+               err_mask = ac_err_mask(pp->tf.command);
        } else {
                /*
                 * Other errors.  libata currently doesn't have any
                 * mechanism to report these errors.  Just turn on
                 * ATA_ERR.
                 */
-               pp->tf.command = ATA_ERR;
+               err_mask = AC_ERR_OTHER;
        }
 
        if (qc)
-               ata_qc_complete(qc, pp->tf.command);
+               ata_qc_complete(qc, err_mask);
 
        sil24_reset_controller(ap);
 }
@@ -593,7 +588,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
                sil24_update_tf(ap);
 
                if (qc)
-                       ata_qc_complete(qc, pp->tf.command);
+                       ata_qc_complete(qc, ac_err_mask(pp->tf.command));
        } else
                sil24_error_intr(ap, slot_stat);
 }
@@ -696,7 +691,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        int i, rc;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
@@ -756,14 +751,14 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc) {
-               printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
-                      pci_name(pdev));
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "32-bit DMA enable failed\n");
                goto out_free;
        }
        rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc) {
-               printk(KERN_ERR DRV_NAME "(%s): 32-bit consistent DMA enable failed\n",
-                      pci_name(pdev));
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "32-bit consistent DMA enable failed\n");
                goto out_free;
        }
 
@@ -799,9 +794,8 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                                        break;
                        }
                        if (tmp & PORT_CS_PORT_RST)
-                               printk(KERN_ERR DRV_NAME
-                                      "(%s): failed to clear port RST\n",
-                                      pci_name(pdev));
+                               dev_printk(KERN_ERR, &pdev->dev,
+                                          "failed to clear port RST\n");
                }
 
                /* Zero error counters. */
@@ -830,9 +824,8 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                /* Reset itself */
                if (__sil24_reset_controller(port))
-                       printk(KERN_ERR DRV_NAME
-                              "(%s): failed to reset controller\n",
-                              pci_name(pdev));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "failed to reset controller\n");
        }
 
        /* Turn on interrupts */
index 057f7b98b6c448dea78cc02a4c6688f545c5bb05..42288be0e5618b254b75f6a4ae560133fbf96a53 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -237,6 +238,7 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+       static int printed_version;
        struct ata_probe_ent *probe_ent = NULL;
        int rc;
        u32 genctl;
@@ -245,6 +247,9 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        u8 pmr;
        u8 port2_start;
 
+       if (!printed_version++)
+               dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
@@ -288,16 +293,18 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
        if (ent->device != 0x182) {
                if ((pmr & SIS_PMR_COMBINED) == 0) {
-                       printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Detected SiS 180/181 chipset in SATA mode\n");
                        port2_start = 64;
                }
                else {
-                       printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Detected SiS 180/181 chipset in combined mode\n");
                        port2_start=0;
                }
        }
        else {
-               printk(KERN_INFO "sata_sis: Detected SiS 182 chipset\n");
+               dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n");
                port2_start = 0x20;
        }
 
index 46208f52d0e1136e3562762ef3d51509871e4fb2..db615ff794d8d354d46d3048df95a5c4be58902f 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -362,7 +363,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        int i;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        /*
         * If this driver happens to only be useful on Apple's K2, then
index af08f4f650c1ef6da8526b3524259a4b031fa159..0ec21e09f5d84d04a20a0b32e0f58fbf205f8457 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -718,7 +719,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
                        VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
                                readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
                        /* get drive status; clear intr; complete txn */
-                       ata_qc_complete(qc, ata_wait_idle(ap));
+                       ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
                        pdc20621_pop_hdma(qc);
                }
 
@@ -756,7 +757,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
                        VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
                                readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
                        /* get drive status; clear intr; complete txn */
-                       ata_qc_complete(qc, ata_wait_idle(ap));
+                       ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
                        pdc20621_pop_hdma(qc);
                }
                handled = 1;
@@ -766,7 +767,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
 
                status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
                DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
-               ata_qc_complete(qc, status);
+               ata_qc_complete(qc, ac_err_mask(status));
                handled = 1;
 
        } else {
@@ -881,7 +882,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
                printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-               ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR);
+               ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
                break;
 
        default:
@@ -890,7 +891,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
                printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
                       ap->id, qc->tf.command, drv_stat);
 
-               ata_qc_complete(qc, drv_stat);
+               ata_qc_complete(qc, ac_err_mask(drv_stat));
                break;
        }
 
@@ -1385,7 +1386,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
        int rc;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        /*
         * If this driver happens to only be useful on Apple's K2, then
index d68dc7d3422c4c54384789b24f605db45962e3e9..a5e245c098e1a142b521975eb5d2a09364334dd7 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -178,12 +179,16 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+       static int printed_version;
        struct ata_probe_ent *probe_ent;
        struct ata_port_info *ppi;
        int rc;
        unsigned int board_idx = (unsigned int) ent->driver_data;
        int pci_dev_busy = 0;
 
+       if (!printed_version++)
+               dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
index 80e291a909a972be9dc34366df1ab407689a22fc..b3ecdbe400e9cb897b32343f315b61da44c69063 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -259,15 +260,15 @@ static void svia_configure(struct pci_dev *pdev)
        u8 tmp8;
 
        pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
-       printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
-              pci_name(pdev),
+       dev_printk(KERN_INFO, &pdev->dev, "routed to hard irq line %d\n",
               (int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
 
        /* make sure SATA channels are enabled */
        pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
        if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
-               printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
-                      pci_name(pdev), (int) tmp8);
+               dev_printk(KERN_DEBUG, &pdev->dev,
+                          "enabling SATA channels (0x%x)\n",
+                          (int) tmp8);
                tmp8 |= ALL_PORTS;
                pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
        }
@@ -275,8 +276,9 @@ static void svia_configure(struct pci_dev *pdev)
        /* make sure interrupts for each channel sent to us */
        pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
        if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
-               printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
-                      pci_name(pdev), (int) tmp8);
+               dev_printk(KERN_DEBUG, &pdev->dev,
+                          "enabling SATA channel interrupts (0x%x)\n",
+                          (int) tmp8);
                tmp8 |= ALL_PORTS;
                pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
        }
@@ -284,8 +286,9 @@ static void svia_configure(struct pci_dev *pdev)
        /* make sure native mode is enabled */
        pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
        if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
-               printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
-                      pci_name(pdev), (int) tmp8);
+               dev_printk(KERN_DEBUG, &pdev->dev,
+                          "enabling SATA channel native mode (0x%x)\n",
+                          (int) tmp8);
                tmp8 |= NATIVE_MODE_ALL;
                pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
        }
@@ -303,7 +306,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        u8 tmp8;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
@@ -318,8 +321,9 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (board_id == vt6420) {
                pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
                if (tmp8 & SATA_2DEV) {
-                       printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
-                       pci_name(pdev), (int) tmp8);
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "SATA master/slave not supported (0x%x)\n",
+                                  (int) tmp8);
                        rc = -EIO;
                        goto err_out_regions;
                }
@@ -332,10 +336,11 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
                if ((pci_resource_start(pdev, i) == 0) ||
                    (pci_resource_len(pdev, i) < bar_sizes[i])) {
-                       printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
-                              pci_name(pdev), i,
-                              pci_resource_start(pdev, i),
-                              pci_resource_len(pdev, i));
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
+                                  i,
+                                  pci_resource_start(pdev, i),
+                                  pci_resource_len(pdev, i));
                        rc = -ENODEV;
                        goto err_out_regions;
                }
@@ -353,8 +358,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                probe_ent = vt6421_init_probe_ent(pdev);
 
        if (!probe_ent) {
-               printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
-                      pci_name(pdev));
+               dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
                rc = -ENOMEM;
                goto err_out_regions;
        }
index 54273e0063c77524518e7225935485e0fc483516..bb84ba0c7e83055d1d680eac381e0eaad31fa9ca 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/device.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
@@ -295,7 +296,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
        int rc;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        rc = pci_enable_device(pdev);
        if (rc)
index 771e97ef136e8ad3c27f08eab77c76de77b8a2ac..b856e140e65f9a1ba441fa2d6ef4f9e1b3a3aa6c 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/sched.h>       /* workqueue stuff, HZ */
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h>
index 8bb8222ea58961e8b654621befd41700e5588904..d2caa35059d903625529efe8270916fb769a3303 100644 (file)
@@ -19,6 +19,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
index e753ba27dc591a09977a4df0562103229ee13775..a1a58e1d5ad327330b96603c18afd511bbf9dd40 100644 (file)
@@ -37,6 +37,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
+#include <linux/slab.h>
+
 #include "sym_glue.h"
 #include "sym_nvram.h"
 
index 3131a6bf7ab7e77626be57786a4dde3ac5acf639..3a264a40821646c4db6cf9f965d7374944301afd 100644 (file)
@@ -37,6 +37,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/gfp.h>
+
 #ifndef SYM_HIPD_H
 #define SYM_HIPD_H
 
index f88fdd48068584bae364d291d6eb0f399ce47948..771676abee60195dc07eeabe652719e9cbbc02c4 100644 (file)
@@ -308,6 +308,8 @@ struct ioc4_serial {
 typedef void ioc4_intr_func_f(void *, uint32_t);
 typedef ioc4_intr_func_f *ioc4_intr_func_t;
 
+static unsigned int Num_of_ioc4_cards;
+
 /* defining this will get you LOTS of great debug info */
 //#define DEBUG_INTERRUPTS
 #define DPRINT_CONFIG(_x...)   ;
@@ -317,7 +319,8 @@ typedef ioc4_intr_func_f *ioc4_intr_func_t;
 #define WAKEUP_CHARS   256
 
 /* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 128
+#define IOC4_MAX_CHARS 256
+#define IOC4_FIFO_CHARS        255
 
 /* Device name we're using */
 #define DEVICE_NAME    "ttyIOC"
@@ -1038,6 +1041,7 @@ static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
                        return -ENOMEM;
                }
                memset(port, 0, sizeof(struct ioc4_port));
+               spin_lock_init(&port->ip_lock);
 
                /* we need to remember the previous ones, to point back to
                 * them farther down - setting up the ring buffers.
@@ -1691,12 +1695,14 @@ ioc4_change_speed(struct uart_port *the_port,
                baud = 9600;
 
        if (!the_port->fifosize)
-               the_port->fifosize = IOC4_MAX_CHARS;
+               the_port->fifosize = IOC4_FIFO_CHARS;
        the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
        the_port->timeout += HZ / 50;   /* Add .02 seconds of slop */
 
        the_port->ignore_status_mask = N_ALL_INPUT;
 
+       info->tty->low_latency = 1;
+
        if (I_IGNPAR(info->tty))
                the_port->ignore_status_mask &= ~(N_PARITY_ERROR
                                                | N_FRAMING_ERROR);
@@ -1742,7 +1748,6 @@ ioc4_change_speed(struct uart_port *the_port,
  */
 static inline int ic4_startup_local(struct uart_port *the_port)
 {
-       int retval = 0;
        struct ioc4_port *port;
        struct uart_info *info;
 
@@ -1754,9 +1759,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
                return -1;
 
        info = the_port->info;
-       if (info->flags & UIF_INITIALIZED) {
-               return retval;
-       }
 
        if (info->tty) {
                set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1775,7 +1777,6 @@ static inline int ic4_startup_local(struct uart_port *the_port)
        /* set the speed of the serial port */
        ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0);
 
-       info->flags |= UIF_INITIALIZED;
        return 0;
 }
 
@@ -1785,9 +1786,13 @@ static inline int ic4_startup_local(struct uart_port *the_port)
  */
 static void ioc4_cb_output_lowat(struct ioc4_port *port)
 {
+       unsigned long pflags;
+
        /* ip_lock is set on the call here */
        if (port->ip_port) {
+               spin_lock_irqsave(&port->ip_port->lock, pflags);
                transmit_chars(port->ip_port);
+               spin_unlock_irqrestore(&port->ip_port->lock, pflags);
        }
 }
 
@@ -2064,8 +2069,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
         * available data as long as it returns some.
         */
        /* Re-arm the timer */
-       writel(port->ip_rx_cons | IOC4_SRCIR_ARM,
-                       &port->ip_serial_regs->srcir);
+       writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
 
        prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
        cons_ptr = port->ip_rx_cons;
@@ -2299,6 +2303,7 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
        }
        return total;
 }
+
 /**
  * receive_chars - upper level read. Called with ip_lock.
  * @the_port: port to read from
@@ -2307,9 +2312,11 @@ static void receive_chars(struct uart_port *the_port)
 {
        struct tty_struct *tty;
        unsigned char ch[IOC4_MAX_CHARS];
-       int read_count, request_count;
+       int read_count, request_count = IOC4_MAX_CHARS;
        struct uart_icount *icount;
        struct uart_info *info = the_port->info;
+       int flip = 0;
+       unsigned long pflags;
 
        /* Make sure all the pointers are "good" ones */
        if (!info)
@@ -2317,16 +2324,17 @@ static void receive_chars(struct uart_port *the_port)
        if (!info->tty)
                return;
 
+       spin_lock_irqsave(&the_port->lock, pflags);
        tty = info->tty;
 
-       request_count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+       if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
+               request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
 
        if (request_count > 0) {
-               if (request_count > IOC4_MAX_CHARS - 2)
-                       request_count = IOC4_MAX_CHARS - 2;
                icount = &the_port->icount;
                read_count = do_read(the_port, ch, request_count);
                if (read_count > 0) {
+                       flip = 1;
                        memcpy(tty->flip.char_buf_ptr, ch, read_count);
                        memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
                        tty->flip.char_buf_ptr += read_count;
@@ -2335,7 +2343,11 @@ static void receive_chars(struct uart_port *the_port)
                        icount->rx += read_count;
                }
        }
-       tty_flip_buffer_push(tty);
+
+       spin_unlock_irqrestore(&the_port->lock, pflags);
+
+       if (flip)
+               tty_flip_buffer_push(tty);
 }
 
 /**
@@ -2393,18 +2405,14 @@ static void ic4_shutdown(struct uart_port *the_port)
 
        info = the_port->info;
 
-       if (!(info->flags & UIF_INITIALIZED))
-               return;
-
        wake_up_interruptible(&info->delta_msr_wait);
 
        if (info->tty)
                set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        set_notification(port, N_ALL, 0);
-       info->flags &= ~UIF_INITIALIZED;
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
 }
 
 /**
@@ -2463,12 +2471,10 @@ static unsigned int ic4_get_mctrl(struct uart_port *the_port)
 static void ic4_start_tx(struct uart_port *the_port)
 {
        struct ioc4_port *port = get_ioc4_port(the_port);
-       unsigned long flags;
 
        if (port) {
-               spin_lock_irqsave(&port->ip_lock, flags);
-               transmit_chars(the_port);
-               spin_unlock_irqrestore(&port->ip_lock, flags);
+               set_notification(port, N_OUTPUT_LOWAT, 1);
+               enable_intrs(port, port->ip_hooks->intr_tx_mt);
        }
 }
 
@@ -2510,9 +2516,9 @@ static int ic4_startup(struct uart_port *the_port)
        }
 
        /* Start up the serial port */
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        retval = ic4_startup_local(the_port);
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
        return retval;
 }
 
@@ -2527,12 +2533,11 @@ static void
 ic4_set_termios(struct uart_port *the_port,
                struct termios *termios, struct termios *old_termios)
 {
-       struct ioc4_port *port = get_ioc4_port(the_port);
        unsigned long port_flags;
 
-       spin_lock_irqsave(&port->ip_lock, port_flags);
+       spin_lock_irqsave(&the_port->lock, port_flags);
        ioc4_change_speed(the_port, termios, old_termios);
-       spin_unlock_irqrestore(&port->ip_lock, port_flags);
+       spin_unlock_irqrestore(&the_port->lock, port_flags);
 }
 
 /**
@@ -2607,24 +2612,25 @@ ioc4_serial_core_attach(struct pci_dev *pdev)
                                __FUNCTION__, (void *)the_port,
                                (void *)port));
 
-               spin_lock_init(&the_port->lock);
                /* membase, iobase and mapbase just need to be non-0 */
                the_port->membase = (unsigned char __iomem *)1;
-               the_port->line = the_port->iobase = ii;
+               the_port->iobase = (pdev->bus->number << 16) |  ii;
+               the_port->line = (Num_of_ioc4_cards << 2) | ii;
                the_port->mapbase = 1;
                the_port->type = PORT_16550A;
-               the_port->fifosize = IOC4_MAX_CHARS;
+               the_port->fifosize = IOC4_FIFO_CHARS;
                the_port->ops = &ioc4_ops;
                the_port->irq = control->ic_irq;
                the_port->dev = &pdev->dev;
+               spin_lock_init(&the_port->lock);
                if (uart_add_one_port(&ioc4_uart, the_port) < 0) {
                        printk(KERN_WARNING
-                                      "%s: unable to add port %d\n",
-                                      __FUNCTION__, the_port->line);
+                          "%s: unable to add port %d bus %d\n",
+                              __FUNCTION__, the_port->line, pdev->bus->number);
                } else {
                        DPRINT_CONFIG(
-                                   ("IOC4 serial driver port %d irq = %d\n",
-                                      the_port->line, the_port->irq));
+                           ("IOC4 serial port %d irq = %d, bus %d\n",
+                              the_port->line, the_port->irq, pdev->bus->number));
                }
                /* all ports are rs232 for now */
                ioc4_set_proto(port, PROTO_RS232);
@@ -2734,6 +2740,8 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
        if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
                goto out4;
 
+       Num_of_ioc4_cards++;
+
        return ret;
 
        /* error exits that give back resources */
index efe79b1fd431b8f13c98cdf5150f4aef49759f0b..aec83f577ce6c5c8f7be871af58c9db811a2d0b8 100644 (file)
@@ -1100,6 +1100,8 @@ mpsc_start_rx(struct mpsc_port_info *pi)
 {
        pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
 
+       /* Issue a Receive Abort to clear any receive errors */
+       writel(MPSC_CHR_2_RA, pi->mpsc_base + MPSC_CHR_2);
        if (pi->rcv_data) {
                mpsc_enter_hunt(pi);
                mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
index f056276b08a1ddd393e5285da4b9e152a450d947..28757cb9d246665ad8e4eba116f19679657aea57 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/superhyway.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 static int superhyway_devices;
 
index 45efeed1fcc36faf2a947de55e8ff447345fa236..49815ec4b842374959f3aab35fa388d290196168 100644 (file)
@@ -14,6 +14,9 @@
  * This file is licenced under the GPL.
  */
 
+#include <linux/signal.h>      /* SA_INTERRUPT */
+#include <linux/jiffies.h>
+
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/mach-types.h>
index bf1d5ab4aa3a0cfb58bcef2e08741084f1c64b25..7ce1d9ef0289ed3bba31b89b035d7f7a8a9e9d09 100644 (file)
@@ -14,6 +14,8 @@
  * This file is licenced under the GPL.
  */
  
+#include <linux/jiffies.h>
+
 #ifdef CONFIG_PPC_PMAC
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
index d287dcccd4158c598de9f14bbdabecc6b5f2c98c..f4a4aeda40b7e3f1876f20dfa7371adeaba70db7 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/signal.h>
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
index a00672c96644a06452cf513f3026697998be7dc2..dca5ee93a4efc8e1d2e386354deac8ad129fb33a 100644 (file)
@@ -198,7 +198,7 @@ static int hid_pid_upload_effect(struct input_dev *dev,
                }
 
                effect->id = id;
-               dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
+               dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
                pid_private->effects[id].owner = current->pid;
                pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
                spin_unlock_irqrestore(&pid_private->lock, flags);
index 7e297947a2b2e201423bd296295b987b1dd59ef0..7192b770bfb650a7c68ca2b76a735617f78dec72 100644 (file)
@@ -494,7 +494,7 @@ config FB_TGA
 
 config FB_VESA
        bool "VESA VGA graphics support"
-       depends on (FB = y) && (X86 || X86_64)
+       depends on (FB = y) && X86
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
@@ -712,7 +712,7 @@ config FB_RIVA_DEBUG
 
 config FB_I810
        tristate "Intel 810/815 support (EXPERIMENTAL)"
-       depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+       depends on FB && EXPERIMENTAL && PCI && X86_32
        select AGP
        select AGP_INTEL
        select FB_MODE_HELPERS
@@ -761,7 +761,7 @@ config FB_I810_I2C
 
 config FB_INTEL
        tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
-       depends on FB && EXPERIMENTAL && PCI && X86 && !X86_64
+       depends on FB && EXPERIMENTAL && PCI && X86_32
        select AGP
        select AGP_INTEL
        select FB_MODE_HELPERS
index 7e731691e2a914d08c4cb692fc5e689fe550aaea..6a9ae2b3d1aba76a50a76554b5ab7ee81118e31e 100644 (file)
@@ -28,7 +28,7 @@ config VGA_CONSOLE
 
 config VIDEO_SELECT
        bool "Video mode selection support"
-       depends on  (X86 || X86_64) && VGA_CONSOLE
+       depends on  X86 && VGA_CONSOLE
        ---help---
          This enables support for text mode selection on kernel startup. If
          you want to take advantage of some high-resolution text mode your
index 809fee2140ac16511d638ad62c93bdf0f38212dc..56cd199605f4fa9cfa587389d1d21a9f47e3e9e1 100644 (file)
@@ -579,6 +579,7 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
 {
        int i, j;
 
+       vga_w(state.vgabase, VGA_PEL_MSK, 0xff);
        for (i = j = 0; i < 16; i++) {
                vga_w(state.vgabase, VGA_PEL_IW, table[i]);
                vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
@@ -721,6 +722,7 @@ static void vga_pal_blank(struct vgastate *state)
 {
        int i;
 
+       vga_w(state->vgabase, VGA_PEL_MSK, 0xff);
        for (i = 0; i < 16; i++) {
                vga_w(state->vgabase, VGA_PEL_IW, i);
                vga_w(state->vgabase, VGA_PEL_D, 0);
index 88c517a4c178fa7ed9f884aed5dd55d465c401e3..9e293e139a0e8e05737ebf4d555116aef745c684 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/sched.h>       /* schedule_timeout() */
 #include <linux/delay.h>
 
 #include "w1_family.h"
index 04ca8840acf1c4d394c32bb6bcb6013f19a2d45c..87c29d7b6c17aa969356bd8a67fcefc8ac552615 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/zorro.h>
 #include <linux/stat.h>
+#include <linux/string.h>
 
 #include "zorro.h"
 
index d3c05dfe20d20a9f77278f09c41fbe55f415ae98..0f2b40605b06c4bccb44cc9809de366a0bed8806 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/init.h>
 #include <linux/zorro.h>
 #include <linux/bitops.h>
+#include <linux/string.h>
+
 #include <asm/setup.h>
 #include <asm/amigahw.h>
 
index 48f5422cb19a942e017aad4e334195d53ab83595..01a295232f75dcd53ab1d5a4998e35b92fc47205 100644 (file)
@@ -810,7 +810,7 @@ config TMPFS
 
 config HUGETLBFS
        bool "HugeTLB file system support"
-       depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN
+       depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
 
 config HUGETLB_PAGE
        def_bool HUGETLBFS
index 434c19d076ac040c90845ceef713c03ee71cf907..175b2e8177c13690719ea26e61e6851183430e15 100644 (file)
@@ -57,7 +57,7 @@ config BINFMT_SHARED_FLAT
 
 config BINFMT_AOUT
        tristate "Kernel support for a.out and ECOFF binaries"
-       depends on (X86 && !X86_64) || ALPHA || ARM || M68K || SPARC32
+       depends on X86_32 || ALPHA || ARM || M68K || SPARC32
        ---help---
          A.out (Assembler.OUTput) is a set of formats for libraries and
          executables used in the earliest versions of UNIX.  Linux used
index b1796fb9e524031614a44f26e3ac44d5e1e48c53..67bcd9b14ea58046efa53cef41db47d96f36f9b2 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -117,9 +117,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
        struct timespec now;
        unsigned int ia_valid = attr->ia_valid;
 
-       if (!inode)
-               BUG();
-
        mode = inode->i_mode;
        now = current_fs_time(inode->i_sb);
 
index 918ccc267e4163eb4f9233fadfe073485094252e..6fa6adc409726e8b79038bbdac31e510e248fed7 100644 (file)
@@ -1502,9 +1502,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
        fill_psinfo(psinfo, current->group_leader, current->mm);
        fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
        
-       fill_note(notes +2, "CORE", NT_TASKSTRUCT, sizeof(*current), current);
-  
-       numnote = 3;
+       numnote = 2;
 
        auxv = (elf_addr_t *) current->mm->saved_auxv;
 
index 2066e4cb700ca9671fc0b92b8cc5b87703ee915d..35fa34977e81f5477b492bc6d7694de8d2c4065a 100644 (file)
@@ -1478,8 +1478,10 @@ EXPORT_SYMBOL(__getblk);
 void __breadahead(struct block_device *bdev, sector_t block, int size)
 {
        struct buffer_head *bh = __getblk(bdev, block, size);
-       ll_rw_block(READA, 1, &bh);
-       brelse(bh);
+       if (likely(bh)) {
+               ll_rw_block(READA, 1, &bh);
+               brelse(bh);
+       }
 }
 EXPORT_SYMBOL(__breadahead);
 
@@ -1497,7 +1499,7 @@ __bread(struct block_device *bdev, sector_t block, int size)
 {
        struct buffer_head *bh = __getblk(bdev, block, size);
 
-       if (!buffer_uptodate(bh))
+       if (likely(bh) && !buffer_uptodate(bh))
                bh = __bread_slow(bh);
        return bh;
 }
@@ -1637,6 +1639,15 @@ out:
 }
 EXPORT_SYMBOL(block_invalidatepage);
 
+int do_invalidatepage(struct page *page, unsigned long offset)
+{
+       int (*invalidatepage)(struct page *, unsigned long);
+       invalidatepage = page->mapping->a_ops->invalidatepage;
+       if (invalidatepage == NULL)
+               invalidatepage = block_invalidatepage;
+       return (*invalidatepage)(page, offset);
+}
+
 /*
  * We attach and possibly dirty the buffers atomically wrt
  * __set_page_dirty_buffers() via private_lock.  try_to_free_buffers
@@ -2696,7 +2707,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
                 * they may have been added in ext3_writepage().  Make them
                 * freeable here, so the page does not leak.
                 */
-               block_invalidatepage(page, 0);
+               do_invalidatepage(page, 0);
                unlock_page(page);
                return 0; /* don't care */
        }
index a327e03753ac6bd081d7349480e09a93f7341f70..43dbcb0b21ebcc2ec51cfcc1052fc2879b73cbeb 100644 (file)
@@ -3046,6 +3046,10 @@ HANDLE_IOCTL(RAW_GETBIND, raw_ioctl)
 /* Serial */
 HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
 HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
+#ifdef TIOCGLTC
+COMPATIBLE_IOCTL(TIOCGLTC)
+COMPATIBLE_IOCTL(TIOCSLTC)
+#endif
 /* Usbdevfs */
 HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control)
 HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk)
index 05f3327d64a3f7b93b064af0e323b34dbeff97af..ea7644227a65d7d393758e136d62ca7797235adb 100644 (file)
@@ -662,7 +662,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
 restart:
        file_list_lock();
        list_for_each(p, &sb->s_files) {
-               struct file *filp = list_entry(p, struct file, f_list);
+               struct file *filp = list_entry(p, struct file, f_u.fu_list);
                struct inode *inode = filp->f_dentry->d_inode;
                if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
                        struct dentry *dentry = dget(filp->f_dentry);
index ba73797eb4cbcf628907a5db58a2087cbf6d45c8..10d493fea7ce6a9e4de05ff01facdf162bb9dd8b 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -630,10 +630,9 @@ static inline int de_thread(struct task_struct *tsk)
        /*
         * Account for the thread group leader hanging around:
         */
-       count = 2;
-       if (thread_group_leader(current))
-               count = 1;
-       else {
+       count = 1;
+       if (!thread_group_leader(current)) {
+               count = 2;
                /*
                 * The SIGALRM timer survives the exec, but needs to point
                 * at us as the new group leader now.  We have a race with
@@ -642,8 +641,10 @@ static inline int de_thread(struct task_struct *tsk)
                 * before we can safely let the old group leader die.
                 */
                sig->real_timer.data = (unsigned long)current;
+               spin_unlock_irq(lock);
                if (del_timer_sync(&sig->real_timer))
                        add_timer(&sig->real_timer);
+               spin_lock_irq(lock);
        }
        while (atomic_read(&sig->count) > count) {
                sig->group_exit_task = current;
@@ -655,7 +656,6 @@ static inline int de_thread(struct task_struct *tsk)
        }
        sig->group_exit_task = NULL;
        sig->notify_count = 0;
-       sig->real_timer.data = (unsigned long)current;
        spin_unlock_irq(lock);
 
        /*
@@ -1417,19 +1417,16 @@ static void zap_threads (struct mm_struct *mm)
 static void coredump_wait(struct mm_struct *mm)
 {
        DECLARE_COMPLETION(startup_done);
+       int core_waiters;
 
-       mm->core_waiters++; /* let other threads block */
        mm->core_startup_done = &startup_done;
 
-       /* give other threads a chance to run: */
-       yield();
-
        zap_threads(mm);
-       if (--mm->core_waiters) {
-               up_write(&mm->mmap_sem);
+       core_waiters = mm->core_waiters;
+       up_write(&mm->mmap_sem);
+
+       if (core_waiters)
                wait_for_completion(&startup_done);
-       } else
-               up_write(&mm->mmap_sem);
        BUG_ON(mm->core_waiters);
 }
 
@@ -1463,11 +1460,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                current->fsuid = 0;     /* Dump root private */
        }
        mm->dumpable = 0;
-       init_completion(&mm->core_done);
+
+       retval = -EAGAIN;
        spin_lock_irq(&current->sighand->siglock);
-       current->signal->flags = SIGNAL_GROUP_EXIT;
-       current->signal->group_exit_code = exit_code;
+       if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+               current->signal->flags = SIGNAL_GROUP_EXIT;
+               current->signal->group_exit_code = exit_code;
+               retval = 0;
+       }
        spin_unlock_irq(&current->sighand->siglock);
+       if (retval) {
+               up_write(&mm->mmap_sem);
+               goto fail;
+       }
+
+       init_completion(&mm->core_done);
        coredump_wait(mm);
 
        /*
index fdba4d1d3c60996c438008a479975d46a81d6e3c..e7d3f0522d0165fc1f7d6ceb5aad03b607e168b2 100644 (file)
@@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inode *inode,
                 * the pointer to new one, then send parent to disk.
                 */
                bh = sb_getblk(inode->i_sb, parent);
+               if (!bh) {
+                       err = -EIO;
+                       break;
+               }
                lock_buffer(bh);
                memset(bh->b_data, 0, blocksize);
                branch[n].bh = bh;
index 0213db4911a2adfcd19bb92d33dfc5b0936a192b..7992d21e0e09d96c14413a332b4478b5ed117525 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 
+#include "bitmap.h"
+
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
@@ -1010,7 +1012,7 @@ retry:
  * allocation within the reservation window.
  *
  * This will avoid keeping on searching the reservation list again and
- * again when someboday is looking for a free block (without
+ * again when somebody is looking for a free block (without
  * reservation), and there are lots of free blocks, but they are all
  * being reserved.
  *
@@ -1416,12 +1418,12 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
        unsigned long bitmap_count, x;
        struct buffer_head *bitmap_bh = NULL;
 
-       lock_super(sb);
        es = EXT3_SB(sb)->s_es;
        desc_count = 0;
        bitmap_count = 0;
        gdp = NULL;
 
+       smp_rmb();
        for (i = 0; i < ngroups; i++) {
                gdp = ext3_get_group_desc(sb, i, NULL);
                if (!gdp)
@@ -1440,7 +1442,6 @@ unsigned long ext3_count_free_blocks(struct super_block *sb)
        brelse(bitmap_bh);
        printk("ext3_count_free_blocks: stored = %u, computed = %lu, %lu\n",
               le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count);
-       unlock_super(sb);
        return bitmap_count;
 #else
        desc_count = 0;
index 6c419b9ab0e8165ea89a8425da117596b4d0c052..5b4ba3e246e60ebc72e7c538bf61453d29494a53 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/buffer_head.h>
-
+#include "bitmap.h"
 
 static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
 
diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
new file mode 100644 (file)
index 0000000..6ee503a
--- /dev/null
@@ -0,0 +1,8 @@
+/*  linux/fs/ext3/bitmap.c
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
index 6549945f9ac156ae0523108ffc3b8bfc0cd88448..df3f517c54aca4b9bc3b41e9286cab7166ecd3e6 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <asm/byteorder.h>
 
+#include "bitmap.h"
 #include "xattr.h"
 #include "acl.h"
 
@@ -704,7 +705,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
        unsigned long bitmap_count, x;
        struct buffer_head *bitmap_bh = NULL;
 
-       lock_super (sb);
        es = EXT3_SB(sb)->s_es;
        desc_count = 0;
        bitmap_count = 0;
@@ -727,7 +727,6 @@ unsigned long ext3_count_free_inodes (struct super_block * sb)
        brelse(bitmap_bh);
        printk("ext3_count_free_inodes: stored = %u, computed = %lu, %lu\n",
                le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
-       unlock_super(sb);
        return desc_count;
 #else
        desc_count = 0;
index 8b38f2232796fda9c0f25294654c49a8d25cde11..5d9b00e2883720a8b0e2cc48a72d05a65d696a7b 100644 (file)
@@ -491,7 +491,7 @@ static unsigned long ext3_find_goal(struct inode *inode, long block,
  *     the same format as ext3_get_branch() would do. We are calling it after
  *     we had read the existing part of chain and partial points to the last
  *     triple of that (one with zero ->key). Upon the exit we have the same
- *     picture as after the successful ext3_get_block(), excpet that in one
+ *     picture as after the successful ext3_get_block(), except that in one
  *     place chain is disconnected - *branch->p is still zero (we did not
  *     set the last link), but branch->key contains the number that should
  *     be placed into *branch->p to fill that gap.
@@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
                        if (!nr)
                                break;
                        branch[n].key = cpu_to_le32(nr);
-                       keys = n+1;
 
                        /*
                         * Get buffer_head for parent block, zero it out
@@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
                         * parent to disk.  
                         */
                        bh = sb_getblk(inode->i_sb, parent);
+                       if (!bh)
+                               break;
+                       keys = n+1;
                        branch[n].bh = bh;
                        lock_buffer(bh);
                        BUFFER_TRACE(bh, "call get_create_access");
@@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
        if (!*errp && buffer_mapped(&dummy)) {
                struct buffer_head *bh;
                bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+               if (!bh) {
+                       *errp = -EIO;
+                       goto err;
+               }
                if (buffer_new(&dummy)) {
                        J_ASSERT(create != 0);
                        J_ASSERT(handle != 0);
@@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
                }
                return bh;
        }
+err:
        return NULL;
 }
 
index 50378d8ff84b28cd90318159fb9708cbec9e2e76..b3c690a3b54acc31276794835f34d2ceaa86fa4d 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 #include <linux/smp_lock.h>
+
+#include "namei.h"
 #include "xattr.h"
 #include "acl.h"
 
diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h
new file mode 100644 (file)
index 0000000..f2ce2b0
--- /dev/null
@@ -0,0 +1,8 @@
+/*  linux/fs/ext3/namei.h
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern struct dentry *ext3_get_parent(struct dentry *child);
index 57f79106267ddde2d21ad210caf1903201c4ea31..1be78b4b4de956f7bb9e831a7f3e1c1c489b997b 100644 (file)
@@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
        int err;
 
        bh = sb_getblk(sb, blk);
+       if (!bh)
+               return ERR_PTR(-EIO);
        if ((err = ext3_journal_get_write_access(handle, bh))) {
                brelse(bh);
                bh = ERR_PTR(err);
@@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb,
                ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
 
                gdb = sb_getblk(sb, block);
+               if (!gdb) {
+                       err = -EIO;
+                       goto exit_bh;
+               }
                if ((err = ext3_journal_get_write_access(handle, gdb))) {
                        brelse(gdb);
                        goto exit_bh;
@@ -643,6 +649,10 @@ static void update_backups(struct super_block *sb,
                        break;
 
                bh = sb_getblk(sb, group * bpg + blk_off);
+               if (!bh) {
+                       err = -EIO;
+                       break;
+               }
                ext3_debug("update metadata backup %#04lx\n",
                          (unsigned long)bh->b_blocknr);
                if ((err = ext3_journal_get_write_access(handle, bh)))
index 097383c11154dcfff13f9977f4bb106f396cbe3b..f594989ccb7a248c77be35ab072f3574663524d1 100644 (file)
 #include <linux/namei.h>
 #include <linux/quotaops.h>
 #include <linux/seq_file.h>
+
 #include <asm/uaccess.h>
+
 #include "xattr.h"
 #include "acl.h"
+#include "namei.h"
 
 static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
 static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
@@ -615,7 +618,6 @@ static struct super_operations ext3_sops = {
 #endif
 };
 
-struct dentry *ext3_get_parent(struct dentry *child);
 static struct export_operations ext3_export_ops = {
        .get_parent = ext3_get_parent,
 };
index 269c7b92db9adaee71e4431e79a82dad57dab6c5..430de9f63be3dab35987c9c3ea0c8c9d2d0f70cd 100644 (file)
@@ -210,7 +210,7 @@ ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
        return cmp ? -ENODATA : 0;
 }
 
-int
+static int
 ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
                     void *buffer, size_t buffer_size)
 {
@@ -354,7 +354,7 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
        return buffer_size - rest;
 }
 
-int
+static int
 ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
        struct buffer_head *bh = NULL;
@@ -626,7 +626,7 @@ struct ext3_xattr_block_find {
        struct buffer_head *bh;
 };
 
-int
+static int
 ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
                      struct ext3_xattr_block_find *bs)
 {
@@ -859,7 +859,7 @@ struct ext3_xattr_ibody_find {
        struct ext3_iloc iloc;
 };
 
-int
+static int
 ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
                      struct ext3_xattr_ibody_find *is)
 {
index 895049b2ac9cb65fd58af857e719bc7d8d03115e..ba824964b9bbaf7fec4faa0cf6998675819993ba 100644 (file)
@@ -222,6 +222,80 @@ fat_shortname2uni(struct nls_table *nls, unsigned char *buf, int buf_size,
        return len;
 }
 
+enum { PARSE_INVALID = 1, PARSE_NOT_LONGNAME, PARSE_EOF, };
+
+/**
+ * fat_parse_long - Parse extended directory entry.
+ *
+ * This function returns zero on success, negative value on error, or one of
+ * the following:
+ *
+ * %PARSE_INVALID - Directory entry is invalid.
+ * %PARSE_NOT_LONGNAME - Directory entry does not contain longname.
+ * %PARSE_EOF - Directory has no more entries.
+ */
+static int fat_parse_long(struct inode *dir, loff_t *pos,
+                         struct buffer_head **bh, struct msdos_dir_entry **de,
+                         wchar_t **unicode, unsigned char *nr_slots)
+{
+       struct msdos_dir_slot *ds;
+       unsigned char id, slot, slots, alias_checksum;
+
+       if (!*unicode) {
+               *unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
+               if (!*unicode) {
+                       brelse(*bh);
+                       return -ENOMEM;
+               }
+       }
+parse_long:
+       slots = 0;
+       ds = (struct msdos_dir_slot *)*de;
+       id = ds->id;
+       if (!(id & 0x40))
+               return PARSE_INVALID;
+       slots = id & ~0x40;
+       if (slots > 20 || !slots)       /* ceil(256 * 2 / 26) */
+               return PARSE_INVALID;
+       *nr_slots = slots;
+       alias_checksum = ds->alias_checksum;
+
+       slot = slots;
+       while (1) {
+               int offset;
+
+               slot--;
+               offset = slot * 13;
+               fat16_towchar(*unicode + offset, ds->name0_4, 5);
+               fat16_towchar(*unicode + offset + 5, ds->name5_10, 6);
+               fat16_towchar(*unicode + offset + 11, ds->name11_12, 2);
+
+               if (ds->id & 0x40)
+                       (*unicode)[offset + 13] = 0;
+               if (fat_get_entry(dir, pos, bh, de) < 0)
+                       return PARSE_EOF;
+               if (slot == 0)
+                       break;
+               ds = (struct msdos_dir_slot *)*de;
+               if (ds->attr != ATTR_EXT)
+                       return PARSE_NOT_LONGNAME;
+               if ((ds->id & ~0x40) != slot)
+                       goto parse_long;
+               if (ds->alias_checksum != alias_checksum)
+                       goto parse_long;
+       }
+       if ((*de)->name[0] == DELETED_FLAG)
+               return PARSE_INVALID;
+       if ((*de)->attr == ATTR_EXT)
+               goto parse_long;
+       if (IS_FREE((*de)->name) || ((*de)->attr & ATTR_VOLUME))
+               return PARSE_INVALID;
+       if (fat_checksum((*de)->name) != alias_checksum)
+               *nr_slots = 0;
+
+       return 0;
+}
+
 /*
  * Return values: negative -> error, 0 -> not found, positive -> found,
  * value is the total amount of slots, including the shortname entry.
@@ -259,68 +333,16 @@ parse_record:
                if (de->attr != ATTR_EXT && IS_FREE(de->name))
                        continue;
                if (de->attr == ATTR_EXT) {
-                       struct msdos_dir_slot *ds;
-                       unsigned char id;
-                       unsigned char slot;
-                       unsigned char slots;
-                       unsigned char sum;
-                       unsigned char alias_checksum;
-
-                       if (!unicode) {
-                               unicode = (wchar_t *)
-                                       __get_free_page(GFP_KERNEL);
-                               if (!unicode) {
-                                       brelse(bh);
-                                       return -ENOMEM;
-                               }
-                       }
-parse_long:
-                       slots = 0;
-                       ds = (struct msdos_dir_slot *) de;
-                       id = ds->id;
-                       if (!(id & 0x40))
-                               continue;
-                       slots = id & ~0x40;
-                       if (slots > 20 || !slots)       /* ceil(256 * 2 / 26) */
-                               continue;
-                       nr_slots = slots;
-                       alias_checksum = ds->alias_checksum;
-
-                       slot = slots;
-                       while (1) {
-                               int offset;
-
-                               slot--;
-                               offset = slot * 13;
-                               fat16_towchar(unicode + offset, ds->name0_4, 5);
-                               fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
-                               fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
-                               if (ds->id & 0x40) {
-                                       unicode[offset + 13] = 0;
-                               }
-                               if (fat_get_entry(inode, &cpos, &bh, &de) < 0)
-                                       goto EODir;
-                               if (slot == 0)
-                                       break;
-                               ds = (struct msdos_dir_slot *) de;
-                               if (ds->attr !=  ATTR_EXT)
-                                       goto parse_record;
-                               if ((ds->id & ~0x40) != slot)
-                                       goto parse_long;
-                               if (ds->alias_checksum != alias_checksum)
-                                       goto parse_long;
-                       }
-                       if (de->name[0] == DELETED_FLAG)
-                               continue;
-                       if (de->attr ==  ATTR_EXT)
-                               goto parse_long;
-                       if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
+                       int status = fat_parse_long(inode, &cpos, &bh, &de,
+                                                   &unicode, &nr_slots);
+                       if (status < 0)
+                               return status;
+                       else if (status == PARSE_INVALID)
                                continue;
-                       for (sum = 0, i = 0; i < 11; i++)
-                               sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
-                       if (sum != alias_checksum)
-                               nr_slots = 0;
+                       else if (status == PARSE_NOT_LONGNAME)
+                               goto parse_record;
+                       else if (status == PARSE_EOF)
+                               goto EODir;
                }
 
                memcpy(work, de->name, sizeof(de->name));
@@ -408,8 +430,8 @@ struct fat_ioctl_filldir_callback {
        int short_len;
 };
 
-static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
-                       filldir_t filldir, int short_only, int both)
+static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
+                        filldir_t filldir, int short_only, int both)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -458,9 +480,10 @@ static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
 
        bh = NULL;
 GetNew:
-       long_slots = 0;
        if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
                goto EODir;
+parse_record:
+       long_slots = 0;
        /* Check for long filename entry */
        if (isvfat) {
                if (de->name[0] == DELETED_FLAG)
@@ -475,69 +498,18 @@ GetNew:
        }
 
        if (isvfat && de->attr == ATTR_EXT) {
-               struct msdos_dir_slot *ds;
-               unsigned char id;
-               unsigned char slot;
-               unsigned char slots;
-               unsigned char sum;
-               unsigned char alias_checksum;
-
-               if (!unicode) {
-                       unicode = (wchar_t *)__get_free_page(GFP_KERNEL);
-                       if (!unicode) {
-                               filp->f_pos = cpos;
-                               brelse(bh);
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-               }
-ParseLong:
-               slots = 0;
-               ds = (struct msdos_dir_slot *) de;
-               id = ds->id;
-               if (!(id & 0x40))
-                       goto RecEnd;
-               slots = id & ~0x40;
-               if (slots > 20 || !slots)       /* ceil(256 * 2 / 26) */
+               int status = fat_parse_long(inode, &cpos, &bh, &de,
+                                           &unicode, &long_slots);
+               if (status < 0) {
+                       filp->f_pos = cpos;
+                       ret = status;
+                       goto out;
+               } else if (status == PARSE_INVALID)
                        goto RecEnd;
-               long_slots = slots;
-               alias_checksum = ds->alias_checksum;
-
-               slot = slots;
-               while (1) {
-                       int offset;
-
-                       slot--;
-                       offset = slot * 13;
-                       fat16_towchar(unicode + offset, ds->name0_4, 5);
-                       fat16_towchar(unicode + offset + 5, ds->name5_10, 6);
-                       fat16_towchar(unicode + offset + 11, ds->name11_12, 2);
-
-                       if (ds->id & 0x40) {
-                               unicode[offset + 13] = 0;
-                       }
-                       if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
-                               goto EODir;
-                       if (slot == 0)
-                               break;
-                       ds = (struct msdos_dir_slot *) de;
-                       if (ds->attr !=  ATTR_EXT)
-                               goto RecEnd;    /* XXX */
-                       if ((ds->id & ~0x40) != slot)
-                               goto ParseLong;
-                       if (ds->alias_checksum != alias_checksum)
-                               goto ParseLong;
-               }
-               if (de->name[0] == DELETED_FLAG)
-                       goto RecEnd;
-               if (de->attr ==  ATTR_EXT)
-                       goto ParseLong;
-               if (IS_FREE(de->name) || (de->attr & ATTR_VOLUME))
-                       goto RecEnd;
-               for (sum = 0, i = 0; i < 11; i++)
-                       sum = (((sum&1)<<7)|((sum&0xfe)>>1)) + de->name[i];
-               if (sum != alias_checksum)
-                       long_slots = 0;
+               else if (status == PARSE_NOT_LONGNAME)
+                       goto parse_record;
+               else if (status == PARSE_EOF)
+                       goto EODir;
        }
 
        if (sbi->options.dotsOK) {
@@ -671,7 +643,7 @@ out:
 static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
        struct inode *inode = filp->f_dentry->d_inode;
-       return fat_readdirx(inode, filp, dirent, filldir, 0, 0);
+       return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
 }
 
 static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
@@ -760,8 +732,8 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
        down(&inode->i_sem);
        ret = -ENOENT;
        if (!IS_DEADDIR(inode)) {
-               ret = fat_readdirx(inode, filp, &buf, fat_ioctl_filldir,
-                                  short_only, both);
+               ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
+                                   short_only, both);
        }
        up(&inode->i_sem);
        if (ret >= 0)
index 86ec8ae985b413bd3d8b135ff8dfd9fe305ef5bf..4dc205546547aae35d1cd613ac27146d706e1d09 100644 (file)
@@ -56,13 +56,13 @@ void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
 
 static inline void file_free_rcu(struct rcu_head *head)
 {
-       struct file *f =  container_of(head, struct file, f_rcuhead);
+       struct file *f =  container_of(head, struct file, f_u.fu_rcuhead);
        kmem_cache_free(filp_cachep, f);
 }
 
 static inline void file_free(struct file *f)
 {
-       call_rcu(&f->f_rcuhead, file_free_rcu);
+       call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
 }
 
 /* Find an unused file structure and return a pointer to it.
@@ -95,7 +95,7 @@ struct file *get_empty_filp(void)
        f->f_gid = current->fsgid;
        rwlock_init(&f->f_owner.lock);
        /* f->f_version: 0 */
-       INIT_LIST_HEAD(&f->f_list);
+       INIT_LIST_HEAD(&f->f_u.fu_list);
        return f;
 
 over:
@@ -225,15 +225,15 @@ void file_move(struct file *file, struct list_head *list)
        if (!list)
                return;
        file_list_lock();
-       list_move(&file->f_list, list);
+       list_move(&file->f_u.fu_list, list);
        file_list_unlock();
 }
 
 void file_kill(struct file *file)
 {
-       if (!list_empty(&file->f_list)) {
+       if (!list_empty(&file->f_u.fu_list)) {
                file_list_lock();
-               list_del_init(&file->f_list);
+               list_del_init(&file->f_u.fu_list);
                file_list_unlock();
        }
 }
@@ -245,7 +245,7 @@ int fs_may_remount_ro(struct super_block *sb)
        /* Check that no files are currently opened for writing. */
        file_list_lock();
        list_for_each(p, &sb->s_files) {
-               struct file *file = list_entry(p, struct file, f_list);
+               struct file *file = list_entry(p, struct file, f_u.fu_list);
                struct inode *inode = file->f_dentry->d_inode;
 
                /* File with pending delete? */
index 44082bfdfec960037be53f9cff8a412711bf6e1b..9f1072836c8ea5c940c916d8236365a26c78da84 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/sched.h>       /* for 'current' */
 #include <asm/uaccess.h>
 
 /*
index e94ab398b71763b3caf598dfe8fbeb66e818789d..ffab4783ac644a984b6c0ff7a529b43720e6bc53 100644 (file)
@@ -230,7 +230,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
                         * The inode is clean, unused
                         */
                        list_move(&inode->i_list, &inode_unused);
-                       inodes_stat.nr_unused++;
                }
        }
        wake_up_inode(inode);
@@ -238,14 +237,20 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
 }
 
 /*
- * Write out an inode's dirty pages.  Called under inode_lock.
+ * Write out an inode's dirty pages.  Called under inode_lock.  Either the
+ * caller has ref on the inode (either via __iget or via syscall against an fd)
+ * or the inode has I_WILL_FREE set (via generic_forget_inode)
  */
 static int
-__writeback_single_inode(struct inode *inode,
-                       struct writeback_control *wbc)
+__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 {
        wait_queue_head_t *wqh;
 
+       if (!atomic_read(&inode->i_count))
+               WARN_ON(!(inode->i_state & I_WILL_FREE));
+       else
+               WARN_ON(inode->i_state & I_WILL_FREE);
+
        if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
                list_move(&inode->i_list, &inode->i_sb->s_dirty);
                return 0;
@@ -259,11 +264,9 @@ __writeback_single_inode(struct inode *inode,
 
                wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
                do {
-                       __iget(inode);
                        spin_unlock(&inode_lock);
                        __wait_on_bit(wqh, &wq, inode_wait,
                                                        TASK_UNINTERRUPTIBLE);
-                       iput(inode);
                        spin_lock(&inode_lock);
                } while (inode->i_state & I_LOCK);
        }
@@ -541,14 +544,15 @@ void sync_inodes(int wait)
 }
 
 /**
- *     write_inode_now -       write an inode to disk
- *     @inode: inode to write to disk
- *     @sync: whether the write should be synchronous or not
+ * write_inode_now     -       write an inode to disk
+ * @inode: inode to write to disk
+ * @sync: whether the write should be synchronous or not
+ *
+ * This function commits an inode to disk immediately if it is dirty. This is
+ * primarily needed by knfsd.
  *
- *     This function commits an inode to disk immediately if it is
- *     dirty. This is primarily needed by knfsd.
+ * The caller must either have a ref on the inode or must have set I_WILL_FREE.
  */
 int write_inode_now(struct inode *inode, int sync)
 {
        int ret;
index d4c869c6d01b2f8d1cc9a5e88d54b641678e9e81..a6f90a6c754a1b573ecdaf0eb849cbfc8e802be5 100644 (file)
@@ -151,9 +151,9 @@ void fuse_release_background(struct fuse_req *req)
 /*
  * This function is called when a request is finished.  Either a reply
  * has arrived or it was interrupted (and not yet sent) or some error
- * occured during communication with userspace, or the device file was
- * closed.  It decreases the referece count for the request.  In case
- * of a background request the referece to the stored objects are
+ * occurred during communication with userspace, or the device file was
+ * closed.  It decreases the reference count for the request.  In case
+ * of a background request the reference to the stored objects are
  * released.  The requester thread is woken up (if still waiting), and
  * finally the request is either freed or put on the unused_list
  *
index 29f1e9f6e85c3648c8a3deeb7847d078625e9844..70dba721acabe9992416d66bca1d0becd1411f2f 100644 (file)
@@ -741,13 +741,14 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        if (inode && S_ISDIR(inode->i_mode)) {
                /* Don't allow creating an alias to a directory  */
                struct dentry *alias = d_find_alias(inode);
-               if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
+               if (alias) {
                        dput(alias);
                        iput(inode);
                        return ERR_PTR(-EIO);
                }
        }
-       return d_splice_alias(inode, entry);
+       d_add(entry, inode);
+       return NULL;
 }
 
 static int fuse_setxattr(struct dentry *entry, const char *name,
index 24d761518d864643d0ff1564d4e516b8db4bbeda..5cb456f572c1c97d7bf016b1ac0493dedccbde35 100644 (file)
@@ -349,22 +349,22 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
                      int isdir);
 
 /**
- * Initialise file operations on a regular file
+ * Initialize file operations on a regular file
  */
 void fuse_init_file_inode(struct inode *inode);
 
 /**
- * Initialise inode operations on regular files and special files
+ * Initialize inode operations on regular files and special files
  */
 void fuse_init_common(struct inode *inode);
 
 /**
- * Initialise inode and file operations on a directory
+ * Initialize inode and file operations on a directory
  */
 void fuse_init_dir(struct inode *inode);
 
 /**
- * Initialise inode operations on a symlink
+ * Initialize inode operations on a symlink
  */
 void fuse_init_symlink(struct inode *inode);
 
@@ -411,7 +411,7 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc);
 
 /**
  * Decrement reference count of a request.  If count goes to zero put
- * on unused list (preallocated) or free reqest (not preallocated).
+ * on unused list (preallocated) or free request (not preallocated).
  */
 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
 
@@ -431,7 +431,7 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req);
 void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
 
 /**
- * Release inodes and file assiciated with background request
+ * Release inodes and file associated with background request
  */
 void fuse_release_background(struct fuse_req *req);
 
index 7d3316527767ce9896f5d299d0bb18a7baea6538..d8d04bd72b59514dc39fc9eab62a7c3f54f50f1e 100644 (file)
@@ -1088,6 +1088,7 @@ static void generic_forget_inode(struct inode *inode)
        if (inode->i_data.nrpages)
                truncate_inode_pages(&inode->i_data, 0);
        clear_inode(inode);
+       wake_up_inode(inode);
        destroy_inode(inode);
 }
 
index 0f224384f176fa1d529e9c3feb06d576de1b1096..8210ac16a36827df97a8ae43e04a4efe979892a7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
 #include <linux/completion.h>
+#include <linux/sched.h>
 #include "nodelist.h"
 
 
index 996d922e503e188f2cbd502618833743a402bae0..316133c626b7424fc68ccfce9043c5d92c6e359d 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/crc32.h>
 #include <linux/mtd/nand.h>
+#include <linux/jiffies.h>
+
 #include "nodelist.h"
 
 /* For testing write failures */
index 154f511c724570f9adcf7be2b1dc601cd3da83fb..626a367bcd81145cb6dd4385b098755b58bf2f38 100644 (file)
@@ -454,10 +454,10 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
 {
        struct buffer_head *dotdot_bh;
        struct msdos_dir_entry *dotdot_de;
-       loff_t dotdot_i_pos;
        struct inode *old_inode, *new_inode;
        struct fat_slot_info old_sinfo, sinfo;
        struct timespec ts;
+       loff_t dotdot_i_pos, new_i_pos;
        int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
 
        old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -516,28 +516,24 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
        if (new_inode) {
                if (err)
                        goto out;
-               if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
-                       /* WTF??? Cry and fail. */
-                       printk(KERN_WARNING "msdos_rename: fs corrupted\n");
-                       goto out;
-               }
-
                if (is_dir) {
                        err = fat_dir_empty(new_inode);
                        if (err)
                                goto out;
                }
+               new_i_pos = MSDOS_I(new_inode)->i_pos;
                fat_detach(new_inode);
        } else {
                err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
                                      &ts, &sinfo);
                if (err)
                        goto out;
+               new_i_pos = sinfo.i_pos;
        }
        new_dir->i_version++;
 
        fat_detach(old_inode);
-       fat_attach(old_inode, sinfo.i_pos);
+       fat_attach(old_inode, new_i_pos);
        if (is_hid)
                MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
        else
@@ -604,7 +600,7 @@ error_inode:
        fat_attach(old_inode, old_sinfo.i_pos);
        MSDOS_I(old_inode)->i_attrs = old_attrs;
        if (new_inode) {
-               fat_attach(new_inode, sinfo.i_pos);
+               fat_attach(new_inode, new_i_pos);
                if (corrupt)
                        corrupt |= fat_sync_inode(new_inode);
        } else {
index aaaa810362344af7790e066a47a233100d491542..c5769c4fcab185ea1996e947c5b910abfd155dd5 100644 (file)
@@ -1311,9 +1311,6 @@ static inline int may_create(struct inode *dir, struct dentry *child,
 }
 
 /* 
- * Special case: O_CREAT|O_EXCL implies O_NOFOLLOW for security
- * reasons.
- *
  * O_DIRECTORY translates into forcing a directory lookup.
  */
 static inline int lookup_flags(unsigned int f)
@@ -1323,9 +1320,6 @@ static inline int lookup_flags(unsigned int f)
        if (f & O_NOFOLLOW)
                retval &= ~LOOKUP_FOLLOW;
        
-       if ((f & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
-               retval &= ~LOOKUP_FOLLOW;
-       
        if (f & O_DIRECTORY)
                retval |= LOOKUP_DIRECTORY;
 
index f2781ca42761c885a56ad2ea70effd4ca5f4599a..fc0f12ba89ccfe7ce88d1a7f344f80fe662f4119 100644 (file)
@@ -1274,14 +1274,12 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        }
 
        if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
-               spin_unlock(&inode->i_lock);
                return 0;
        }
 
        /* Has the inode gone and changed behind our back? */
        if (nfsi->fileid != fattr->fileid
                        || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
-               spin_unlock(&inode->i_lock);
                return -EIO;
        }
 
index 8a8c34461d481c115a31d628d8e598bb68c20b26..b638fb500743406a55d3e24c0671882ddec68261 100644 (file)
@@ -533,7 +533,7 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
         */
        file_list_lock();
        list_for_each(p, &sb->s_files) {
-               struct file * filp = list_entry(p, struct file, f_list);
+               struct file * filp = list_entry(p, struct file, f_u.fu_list);
                struct dentry * dentry = filp->f_dentry;
                struct inode * inode;
                struct file_operations *fops;
index effa6c0c467ac083d9b62fb34b56a2946596ef27..e6a818a93f3d75ad0f33f808cd143f068249cf9c 100644 (file)
@@ -156,10 +156,13 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
 
        WARN_ON(de && de->deleted);
 
+       if (de != NULL && !try_module_get(de->owner))
+               goto out_mod;
+
        inode = iget(sb, ino);
        if (!inode)
-               goto out_fail;
-       
+               goto out_ino;
+
        PROC_I(inode)->pde = de;
        if (de) {
                if (de->mode) {
@@ -171,20 +174,20 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
                        inode->i_size = de->size;
                if (de->nlink)
                        inode->i_nlink = de->nlink;
-               if (!try_module_get(de->owner))
-                       goto out_fail;
                if (de->proc_iops)
                        inode->i_op = de->proc_iops;
                if (de->proc_fops)
                        inode->i_fop = de->proc_fops;
        }
 
-out:
        return inode;
 
-out_fail:
+out_ino:
+       if (de != NULL)
+               module_put(de->owner);
+out_mod:
        de_put(de);
-       goto out;
+       return NULL;
 }                      
 
 int proc_fill_super(struct super_block *s, void *data, int silent)
index 44b02fc02ebefa3121b2e2956ac4c35fdd1f48ed..42afb5bef1116020c6c073d1a398a946075af594 100644 (file)
@@ -1024,12 +1024,8 @@ static int reiserfs_parse_options(struct super_block *s, char *options,  /* strin
                                strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
                                *mount_options |= 1 << REISERFS_QUOTA;
                        } else {
-                               if (REISERFS_SB(s)->s_qf_names[qtype]) {
-                                       kfree(REISERFS_SB(s)->
-                                             s_qf_names[qtype]);
-                                       REISERFS_SB(s)->s_qf_names[qtype] =
-                                           NULL;
-                               }
+                               kfree(REISERFS_SB(s)->s_qf_names[qtype]);
+                               REISERFS_SB(s)->s_qf_names[qtype] = NULL;
                        }
                }
                if (c == 'f') {
@@ -1158,11 +1154,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        if (!reiserfs_parse_options
            (s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
 #ifdef CONFIG_QUOTA
-               for (i = 0; i < MAXQUOTAS; i++)
-                       if (REISERFS_SB(s)->s_qf_names[i]) {
-                               kfree(REISERFS_SB(s)->s_qf_names[i]);
-                               REISERFS_SB(s)->s_qf_names[i] = NULL;
-                       }
+               for (i = 0; i < MAXQUOTAS; i++) {
+                       kfree(REISERFS_SB(s)->s_qf_names[i]);
+                       REISERFS_SB(s)->s_qf_names[i] = NULL;
+               }
 #endif
                return -EINVAL;
        }
@@ -1940,13 +1935,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
                brelse(SB_BUFFER_WITH_SB(s));
 #ifdef CONFIG_QUOTA
        for (j = 0; j < MAXQUOTAS; j++) {
-               if (sbi->s_qf_names[j])
-                       kfree(sbi->s_qf_names[j]);
+               kfree(sbi->s_qf_names[j]);
+               sbi->s_qf_names[j] = NULL;
        }
 #endif
-       if (sbi != NULL) {
-               kfree(sbi);
-       }
+       kfree(sbi);
 
        s->s_fs_info = NULL;
        return errval;
index 6703efa3c4308fb6f0e46aa8bcf23c7fd0416d24..a47ac9aac8b2b743c8768091abacdeff0e14ee2c 100644 (file)
@@ -296,8 +296,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
                }
        }
 
-       if (value)
-               kfree(value);
+       kfree(value);
 
        if (!error) {
                /* Release the old one */
index 6e57ee252e14e1cd2982bb865fdebbbe24fb6ef7..f60155ec778010c6468b432fa60b9ebc96b98495 100644 (file)
@@ -513,7 +513,7 @@ static void mark_files_ro(struct super_block *sb)
        struct file *f;
 
        file_list_lock();
-       list_for_each_entry(f, &sb->s_files, f_list) {
+       list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
                if (S_ISREG(f->f_dentry->d_inode->i_mode) && file_count(f))
                        f->f_mode &= ~FMODE_WRITE;
        }
index 1c6f6b57ef1cfcd29f7931ef41a11f23632e41b7..ef46939c0c1a9cdaf1fd643806d14bad77270743 100644 (file)
@@ -621,8 +621,7 @@ static int vfat_build_slots(struct inode *dir, const unsigned char *name,
        }
 
        /* build the entry of long file name */
-       for (cksum = i = 0; i < 11; i++)
-               cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
+       cksum = fat_checksum(msdos_name);
 
        *nr_slots = usize / 13;
        for (ps = slots, i = *nr_slots; i > 0; i--, ps++) {
@@ -888,10 +887,10 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 {
        struct buffer_head *dotdot_bh;
        struct msdos_dir_entry *dotdot_de;
-       loff_t dotdot_i_pos;
        struct inode *old_inode, *new_inode;
        struct fat_slot_info old_sinfo, sinfo;
        struct timespec ts;
+       loff_t dotdot_i_pos, new_i_pos;
        int err, is_dir, update_dotdot, corrupt = 0;
 
        old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
@@ -914,31 +913,24 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        ts = CURRENT_TIME_SEC;
        if (new_inode) {
-               err = vfat_find(new_dir, &new_dentry->d_name, &sinfo);
-               if (err)
-                       goto out;
-               if (MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
-                       /* WTF??? Cry and fail. */
-                       printk(KERN_WARNING "vfat_rename: fs corrupted\n");
-                       goto out;
-               }
-
                if (is_dir) {
                        err = fat_dir_empty(new_inode);
                        if (err)
                                goto out;
                }
+               new_i_pos = MSDOS_I(new_inode)->i_pos;
                fat_detach(new_inode);
        } else {
                err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
                                     &ts, &sinfo);
                if (err)
                        goto out;
+               new_i_pos = sinfo.i_pos;
        }
        new_dir->i_version++;
 
        fat_detach(old_inode);
-       fat_attach(old_inode, sinfo.i_pos);
+       fat_attach(old_inode, new_i_pos);
        if (IS_DIRSYNC(new_dir)) {
                err = fat_sync_inode(old_inode);
                if (err)
@@ -1002,7 +994,7 @@ error_inode:
        fat_detach(old_inode);
        fat_attach(old_inode, old_sinfo.i_pos);
        if (new_inode) {
-               fat_attach(new_inode, sinfo.i_pos);
+               fat_attach(new_inode, new_i_pos);
                if (corrupt)
                        corrupt |= fat_sync_inode(new_inode);
        } else {
index 3f9c64bea151fd7c6df4297e8bfa01b626a02bd5..f6e00c0e114f6225d1f7af66517dd537aa0724bf 100644 (file)
@@ -143,7 +143,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
        if (size) {
                if (size > XATTR_SIZE_MAX)
                        size = XATTR_SIZE_MAX;
-               kvalue = kmalloc(size, GFP_KERNEL);
+               kvalue = kzalloc(size, GFP_KERNEL);
                if (!kvalue)
                        return -ENOMEM;
        }
@@ -154,11 +154,15 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
        error = -EOPNOTSUPP;
        if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
                error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
-       else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
-                         sizeof XATTR_SECURITY_PREFIX - 1)) {
+
+       if (!strncmp(kname, XATTR_SECURITY_PREFIX,
+                    sizeof XATTR_SECURITY_PREFIX - 1)) {
                const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
-               error = security_inode_getsecurity(d->d_inode, suffix, kvalue,
-                                                  size);
+               int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
+                                                   size, error);
+               /* Security module active: overwrite error value */
+               if (rv != -EOPNOTSUPP)
+                       error = rv;
        }
        if (error > 0) {
                if (size && copy_to_user(value, kvalue, error))
index eb2cbd97d40434ba72ce57cdd364bac92ae49f4d..1a6295f2c2d43ddf0cdee488a6585a6ea225f1f0 100644 (file)
@@ -26,9 +26,6 @@ struct semaphore {
        .wait   = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),   \
 }
 
-#define __MUTEX_INITIALIZER(name)                      \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)                \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 366bafbdfbb1b9c26270059afa968d2167c221f7..5a0d19b466b0cd2242bbf6f1fca244ec90d12617 100644 (file)
@@ -397,9 +397,6 @@ static inline pte_t *pmd_page_kernel(pmd_t pmd)
 #define pgd_clear(pgdp)                do { } while (0)
 #define set_pgd(pgd,pgdp)      do { } while (0)
 
-#define page_pte_prot(page,prot)       mk_pte(page, prot)
-#define page_pte(page)         mk_pte(page, __pgprot(0))
-
 /* to find an entry in a page-table-directory */
 #define pgd_index(addr)                ((addr) >> PGDIR_SHIFT)
 
index 60f33e6eb800afc3d63de96dbeb269d8c43c7f57..71ca7d412687f9bb0e1a2c2e61a8857e96cec6f5 100644 (file)
@@ -24,8 +24,6 @@ struct semaphore {
        .wait   = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),   \
 }
 
-#define __MUTEX_INITIALIZER(name) __SEMAPHORE_INIT(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)        \
        struct semaphore name = __SEMAPHORE_INIT(name,count)
 
index c49df635a80f11e6d5202152dee10a30cb6f5cc7..d626e70fadedd520fd342fa49f51cc39b2118014 100644 (file)
@@ -544,7 +544,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
 asmlinkage int sys_fork(struct pt_regs *regs);
 asmlinkage int sys_vfork(struct pt_regs *regs);
 asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index f602cf57241131cfc7c84fb66348e267cd04b20f..a590250277f811631f2ccced4618410404125d3a 100644 (file)
@@ -98,8 +98,6 @@ extern struct page *empty_zero_page;
 #define pfn_pte(pfn,prot)      (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
 #define pages_to_mb(x)         ((x) >> (20 - PAGE_SHIFT))
 #define mk_pte(page,prot)      pfn_pte(page_to_pfn(page),prot)
-#define page_pte_prot(page,prot)       mk_pte(page, prot)
-#define page_pte(page)         mk_pte(page, __pgprot(0))
 
 /*
  * Terminology: PGD = Page Directory, PMD = Page Middle Directory,
index c1b6a1edad92dd349a808f5837540667619fbdae..ccf15e7041092d01f520c22772773678b41b4e73 100644 (file)
@@ -25,9 +25,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),   \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INIT(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)        \
        struct semaphore name = __SEMAPHORE_INIT(name,count)
 
index dfa0b0c30aa3bd32b82708383df805e13c496722..be4c2fb9c04944cdf9a982f4a3b1412001e68edb 100644 (file)
@@ -480,7 +480,6 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
 asmlinkage int sys_fork(struct pt_regs *regs);
 asmlinkage int sys_vfork(struct pt_regs *regs);
 asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 8ed7636ab31127274966641022db9c8580b7313c..39faf69bcf766523a7ad34e019b9ce63e40de2c5 100644 (file)
@@ -33,9 +33,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-        __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
         struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 28232ad2ff34d2c1d6c0cfe0c511e1dfb30e7d04..156a34bfc583b853b1d2970171602e592665c972 100644 (file)
@@ -367,7 +367,6 @@ asmlinkage int sys_fork(long r10, long r11, long r12, long r13,
 asmlinkage int sys_vfork(long r10, long r11, long r12, long r13,
                        long mof, long srp, struct pt_regs *regs);
 asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 473fb4bb6329838a8ece91c055b6b2d67efb38db..b247e99dff49a830ee3af8d3e833d80e6087acde 100644 (file)
@@ -436,8 +436,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        return pte;
 }
 
-#define page_pte(page) page_pte_prot((page), __pgprot(0))
-
 /* to find an entry in a page-table-directory. */
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
 #define pgd_index_k(addr) pgd_index(addr)
index 393545630806246f531aac6636c72e2c75102daf..b18396288df1a0475fe7d28d09189076e2fcf7e4 100644 (file)
@@ -47,9 +47,6 @@ struct semaphore {
 #define __SEMAPHORE_INITIALIZER(name,count) \
 { count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index fe6ef3774297ce03458185b2b0791fec57f78f51..81bae2a99192af8ed1747491f2af24929d8fd59a 100644 (file)
@@ -35,9 +35,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 56a6401886fa14a0742f0094a8516bacb8727eb5..56a4a5686c88197b0e6defc5d9b153944ad631ac 100644 (file)
@@ -528,7 +528,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 asmlinkage int sys_execve(char *name, char **argv, char **envp,
                        int dummy, ...);
 asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 8c454aa58ac6b157441ad2a77f9211e4a30f882e..a515e2aed829212a76fcd462bb775a9fdc8a13dd 100644 (file)
@@ -118,7 +118,8 @@ extern void release_lapic_nmi(void);
 extern void disable_timer_nmi_watchdog(void);
 extern void enable_timer_nmi_watchdog(void);
 extern void nmi_watchdog_tick (struct pt_regs * regs);
-extern int APIC_init_uniprocessor (void);
+extern int APIC_init(void);
+extern void APIC_late_time_init(void);
 extern void disable_APIC_timer(void);
 extern void enable_APIC_timer(void);
 
index 6df1a53c190e48716c46e1c4deabdd5020930950..29b851a18c6ed6f0ba119f0ad5d727e3ae3a8c9f 100644 (file)
@@ -17,6 +17,8 @@
 extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
 DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
 
+#define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu))
+
 DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 
 struct Xgt_desc_struct {
@@ -60,7 +62,7 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
 
 static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr)
 {
-       _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[entry], (int)addr,
+       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr,
                offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89);
 }
 
@@ -68,7 +70,7 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *ad
 
 static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size)
 {
-       _set_tssldt_desc(&per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
+       _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82);
 }
 
 #define LDT_entry_a(info) \
@@ -109,7 +111,7 @@ static inline void write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 en
 
 static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
 {
-#define C(i) per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
+#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
        C(0); C(1); C(2);
 #undef C
 }
index 622815bf3243e00306774bbea1ab01e2bc2a2f3e..9139b89497a1aa494b63203179360124a1c3c983 100644 (file)
@@ -55,6 +55,7 @@ void init_8259A(int aeoi);
 void FASTCALL(send_IPI_self(int vector));
 void init_VISWS_APIC_irqs(void);
 void setup_IO_APIC(void);
+void IO_APIC_late_time_init(void);
 void disable_IO_APIC(void);
 void print_IO_APIC(void);
 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
index 7f45f6311059f5d8e3675dbf6d0e759407ad72fb..d7c70c144f9fa16969286257818063329d7bf5cf 100644 (file)
@@ -1,11 +1,6 @@
 /* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
  * which needs to alter them. */
 
-static inline void smpboot_clear_io_apic_irqs(void)
-{
-       io_apic_irqs = 0;
-}
-
 static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 {
        CMOS_WRITE(0xa, 0xf);
@@ -32,13 +27,3 @@ static inline void smpboot_restore_warm_reset_vector(void)
 
        *((volatile long *) phys_to_virt(0x467)) = 0;
 }
-
-static inline void smpboot_setup_io_apic(void)
-{
-       /*
-        * Here we can be sure that there is an IO-APIC in the system. Let's
-        * go and set it up:
-        */
-       if (!skip_ioapic_setup && nr_ioapics)
-               setup_IO_APIC();
-}
index 28a84f6185a789834bdf753dc4e17e1bba8636c8..4a0637a3e2081e6b51ace484f3d33ec2d9d6c6ce 100644 (file)
@@ -16,7 +16,7 @@ static inline void mpc_oem_pci_bus(struct mpc_config_bus *m,
 
 extern int parse_unisys_oem (char *oemptr);
 extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
-extern void setup_unisys();
+extern void setup_unisys(void);
 
 static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
                char *productid)
index d926471fa3597215d07817defd8866602f0cd7d3..14d8e0375f7ab5c408a7702944146b4759c5543a 100644 (file)
@@ -11,14 +11,7 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
 
 /* for visws do nothing for any of these */
 
-static inline void smpboot_clear_io_apic_irqs(void)
-{
-}
-
 static inline void smpboot_restore_warm_reset_vector(void)
 {
 }
 
-static inline void smpboot_setup_io_apic(void)
-{
-}
index fa07bd6c75294c1e4c148794b18d36cb32562b01..74ef721b534d80911d858c892cb073889bee474b 100644 (file)
 #define pfn_pte(pfn, prot)     __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #define pfn_pmd(pfn, prot)     __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
 /*
  * All present user pages are user-executable:
  */
index 2e3f4a344a2d61e001f82131592830c3e967d547..f1a8b454920afa566ea250fadaf018943a22582a 100644 (file)
@@ -74,11 +74,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
  */
 static inline void pud_clear (pud_t * pud) { }
 
-#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
-
-#define pmd_page_kernel(pmd) \
-((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
-
 #define pud_page(pud) \
 ((struct page *) __va(pud_val(pud) & PAGE_MASK))
 
index 0e3ec809352d45cb3fa3de0d9ce03bcb3e6a66f3..03f3c8ac6383a4d7f874e12869b56f7ba45f1414 100644 (file)
@@ -323,8 +323,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        return pte;
 }
 
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 #define pmd_large(pmd) \
 ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT))
 
@@ -369,6 +367,11 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 #define pte_offset_kernel(dir, address) \
        ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
 
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
+#define pmd_page_kernel(pmd) \
+               ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
 /*
  * Helper function that returns the kernel pagetable entry controlling
  * the virtual address 'address'. NULL means no pagetable entry present.
index ea563da63e24d2c63088f0d749acabd8bb2f0e24..6a42b2142fd609f148b3cac6ea35692bf67dedfb 100644 (file)
@@ -55,9 +55,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index acd5c26b69ba68f9a2964b59cdf01b86daab9fda..97d52ac49e46626eac3018e388695147525c476b 100644 (file)
@@ -167,6 +167,8 @@ struct __xchg_dummy { unsigned long a[100]; };
 #define __xg(x) ((struct __xchg_dummy *)(x))
 
 
+#ifdef CONFIG_X86_CMPXCHG64
+
 /*
  * The semantics of XCHGCMP8B are a bit strange, this is why
  * there is a loop and the loading of %%eax and %%edx has to
@@ -221,6 +223,8 @@ static inline void __set_64bit_var (unsigned long long *ptr,
  __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
  __set_64bit(ptr, ll_low(value), ll_high(value)) )
 
+#endif
+
 /*
  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  * Note 2: xchg has side effect, so that attribute volatile is necessary,
@@ -259,7 +263,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
 
 #ifdef CONFIG_X86_CMPXCHG
 #define __HAVE_ARCH_CMPXCHG 1
-#endif
 
 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
                                      unsigned long new, int size)
@@ -275,13 +278,13 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
        case 2:
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
                                     : "=a"(prev)
-                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
                                     : "memory");
                return prev;
        case 4:
                __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
                                     : "=a"(prev)
-                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "r"(new), "m"(*__xg(ptr)), "0"(old)
                                     : "memory");
                return prev;
        }
@@ -291,6 +294,30 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 #define cmpxchg(ptr,o,n)\
        ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
                                        (unsigned long)(n),sizeof(*(ptr))))
+
+#endif
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
+                                     unsigned long long new)
+{
+       unsigned long long prev;
+       __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
+                            : "=A"(prev)
+                            : "b"((unsigned long)new),
+                              "c"((unsigned long)(new >> 32)),
+                              "m"(*__xg(ptr)),
+                              "0"(old)
+                            : "memory");
+       return prev;
+}
+
+#define cmpxchg64(ptr,o,n)\
+       ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
+                                       (unsigned long long)(n)))
+
+#endif
     
 #ifdef __KERNEL__
 struct alt_instr { 
index fbaf90a3968c1f7c4f5bd11b818a604c625e8923..0f92e78dfea1dde68468098e3aa91e73e28503ae 100644 (file)
@@ -448,7 +448,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
 asmlinkage int sys_fork(struct pt_regs regs);
 asmlinkage int sys_vfork(struct pt_regs regs);
 asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 asmlinkage long sys_iopl(unsigned long unused);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
index 3339c7b55a6f69bf534620c45f7cfc6599a25bce..21e32a06bc82c110e4870358b0d5e913a588ae1a 100644 (file)
@@ -236,9 +236,6 @@ ia64_phys_addr_valid (unsigned long addr)
 #define pte_modify(_pte, newprot) \
        (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
 
-#define page_pte_prot(page,prot)       mk_pte(page, prot)
-#define page_pte(page)                 page_pte_prot(page, __pgprot(0))
-
 #define pte_none(pte)                  (!pte_val(pte))
 #define pte_present(pte)               (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
 #define pte_clear(mm,addr,pte)         (pte_val(*(pte)) = 0UL)
index 3a2f0f3f78f37255d15a0f364031d519fd8add66..bb8906285fab24104df8acf9c7f3ba1c35733ccf 100644 (file)
@@ -24,8 +24,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name)      __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)                                        \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
 
index 3a0c69524656ec4618de0127c2aa11ac20045dfb..6d96a67439be8c5d14081c14c8d2b0d3e47ee4c9 100644 (file)
@@ -383,8 +383,6 @@ struct sigaction;
 long sys_execve(char __user *filename, char __user * __user *argv,
                           char __user * __user *envp, struct pt_regs *regs);
 asmlinkage long sys_pipe(void);
-asmlinkage long sys_ptrace(long request, pid_t pid,
-                          unsigned long addr, unsigned long data);
 asmlinkage long sys_rt_sigaction(int sig,
                                 const struct sigaction __user *act,
                                 struct sigaction __user *oact,
index 388e5ee9fa2717e7bd3d7117a6aaa2d773d89597..1cd5fd4a5b2cea4813f9e58e13db466b114baa4d 100644 (file)
@@ -324,8 +324,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
        return pte;
 }
 
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
index 53e3c60f21ec620c73f9099aa0f3cd91bc1ae5ee..bf447c52a0a126c8a26719885d5e081f73c3c728 100644 (file)
@@ -32,9 +32,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 7a6be7727a9240839b9a094dfcebe30bae77f1b5..0f589363f619cd6f26e08d668e0de604dd7cd6eb 100644 (file)
@@ -95,7 +95,7 @@ static inline struct thread_info *current_thread_info(void)
 }
 
 /* thread information allocation */
-#if CONFIG_DEBUG_STACK_USAGE
+#ifdef CONFIG_DEBUG_STACK_USAGE
 #define alloc_thread_info(tsk)                                 \
        ({                                                      \
                struct thread_info *ret;                        \
index 8552d8f45ab10638e5b518679c885f34d62adf77..ac399e1f7bc02b1d5d109185156a809c47d2c0e5 100644 (file)
@@ -452,7 +452,6 @@ asmlinkage int sys_clone(struct pt_regs regs);
 asmlinkage int sys_fork(struct pt_regs regs);
 asmlinkage int sys_vfork(struct pt_regs regs);
 asmlinkage int sys_pipe(unsigned long __user *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                 const struct sigaction __user *act,
index ab94cf3ed4477b70b3f61c39b0dcec7d4cfffd04..fd4c7cc3d3bebc83605c56e92c0a73a2d250dde8 100644 (file)
@@ -36,9 +36,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 1ed3b787ee0570f1aa656a03cf8e54bf3ae25412..fda1eccf10aa0a27f56797487d5ec20cd1e3206a 100644 (file)
 
 /* We don't need no stinkin' I/O port allocation crap. */
 #undef release_region
-#undef check_region
 #undef request_region
 #define release_region(X, Y)   do { } while(0)
-#define check_region(X, Y)     (0)
 #define request_region(X, Y, Z)        (1)
 
 struct sun3xflop_private {
index cbabde4f8a45b22102d601819c6433deffe7dd8b..c2554bcd17471a43588d0ab3719fbdc70c4a7d17 100644 (file)
@@ -444,7 +444,6 @@ asmlinkage long sys_mmap2(
                        unsigned long fd, unsigned long pgoff);
 asmlinkage int sys_execve(char *name, char **argv, char **envp);
 asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct pt_regs;
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
index b1cbf8bb923244b40fc8804bd8f6cd663b0c4650..836f0721ecf9738f46a41d9be4f88d82ac1fde11 100644 (file)
@@ -163,13 +163,6 @@ ide_free_irq(unsigned int irq, void *dev_id)
 }
 
 
-static IDE_INLINE int
-ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-       return 0;
-}
-
-
 static IDE_INLINE void
 ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
 {
index febe85add5096970d392a7ecea1e5b81e1ae252b..17aee15906a6fb6c77a5adf4db75c5f3fde6afc4 100644 (file)
@@ -35,9 +35,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 84b6fa14459f7e7b3a6c82a94f39ff4f4d3f0e64..5373988a7e519eec5f038c3b792a75960162de16 100644 (file)
@@ -504,7 +504,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
                        unsigned long fd, unsigned long pgoff);
 asmlinkage int sys_execve(char *name, char **argv, char **envp);
 asmlinkage int sys_pipe(unsigned long *fildes);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct pt_regs;
 int sys_request_irq(unsigned int,
                        irqreturn_t (*)(int, void *, struct pt_regs *),
index 3e0a522c0f0ed770f9c62839b8b4984296d20f0a..82166b254b2704d649dc27f1acb725ba07dadf38 100644 (file)
@@ -169,7 +169,6 @@ static inline void pud_clear(pud_t *pudp)
 #define __pgd_offset(address)  pgd_index(address)
 #define __pud_offset(address)  (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
 #define __pmd_offset(address)  pmd_index(address)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, 0)
index 1e8ae2723be439fa61a1a68cebce90d3994a9ff2..34facd9965034d354eb72ea91bc71586759083f6 100644 (file)
@@ -75,7 +75,6 @@ extern void paging_init(void);
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-#define page_pte(page)         page_pte_prot(page, __pgprot(0))
 #define pmd_phys(pmd)          (pmd_val(pmd) - PAGE_OFFSET)
 #define pmd_page(pmd)          (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
 #define pmd_page_kernel(pmd)   pmd_val(pmd)
index c2c97dec661bb56c063eccb12a6095bf48896bba..3d6aa7c7ea818c388a5879cd79a541254f14e6d5 100644 (file)
@@ -45,9 +45,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name, 1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index c9eaf4c104deaa8bd649c62aee28cc2f395d970b..89ea8b60e945cbb6d6660d85d9b02229ce36950f 100644 (file)
@@ -1177,7 +1177,6 @@ asmlinkage long sys_mmap2(
                        unsigned long fd, unsigned long pgoff);
 asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs);
 asmlinkage int sys_pipe(nabi_no_regargs struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 3243cf2cd227661873bdd79c19682827d7eb9332..b27bf7aeb2564697325a3509cee430e9a39a61de 100644 (file)
@@ -22,7 +22,6 @@
 
 #define ide_request_irq(irq,hand,flg,dev,id)   request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)               free_irq((irq), (dev_id))
-#define ide_check_region(from,extent)          check_region((from), (extent))
 #define ide_request_region(from,extent,name)   request_region((from), (extent), (name))
 #define ide_release_region(from,extent)                release_region((from), (extent))
 /* Generic I/O and MEMIO string operations.  */
index f78bb2e3453891fc8e279de31d72c83224b2be3e..c9ee41cd0707948d9b031cbb2587f39b0d2ba973 100644 (file)
@@ -49,9 +49,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index e7a620c5c5e65a22791b559aa318426ecc209d6d..80b7b98c70a150484875767753d35eddbfde4adc 100644 (file)
@@ -1011,7 +1011,6 @@ int sys_clone(unsigned long clone_flags, unsigned long usp,
                struct pt_regs *regs);
 int sys_vfork(struct pt_regs *regs);
 int sys_pipe(int *fildes);
-long sys_ptrace(long request, pid_t pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 89e6e73be08c281e36e492d10530cec9b98e4099..d592937359c5cba7eb6ec3b8907e23c9deee53a6 100644 (file)
@@ -37,9 +37,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name, 1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 3173ab3d2eb9a477af7b308db22ce82b0d3d0421..404c143e643d910aee6711412c56e0d48ecb4658 100644 (file)
@@ -469,7 +469,6 @@ int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
 int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
                struct pt_regs *regs);
 int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 long sys_rt_sigaction(int sig,
                      const struct sigaction __user *act,
index aefe7753ea41698685912a6044112e8e13ddb991..d9ecb9969238fb1576efc62a76a7b744d410789d 100644 (file)
@@ -31,9 +31,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name, 1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 977bc980c1af641681a1283df2094e9ea4733734..6b5fcbadbc5b6d43a2698995358f1e1ad5807609 100644 (file)
@@ -467,7 +467,6 @@ int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
                unsigned long p4, unsigned long p5, unsigned long p6,
                struct pt_regs *regs);
 int sys_pipe(int __user *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 long sys_rt_sigaction(int sig, const struct sigaction __user *act,
                      struct sigaction __user *oact, size_t sigsetsize);
index 873def6f363abf8c7cbf16abc708645d5edd9833..702cf436698c60e77ee5198600df6ad8506c07c4 100644 (file)
@@ -29,9 +29,6 @@ struct semaphore {
 #define __SEMAPHORE_INITIALIZER(name,count) \
        { ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 0d51c484c2eaeb37830ae9693ece5e1ebf763704..348a88137445ecfb326855d8c10763e15c1910c0 100644 (file)
@@ -8,11 +8,14 @@
 #ifndef _ASM_S390_SETUP_H
 #define _ASM_S390_SETUP_H
 
+#include <asm/types.h>
+
 #define PARMAREA               0x10400
 #define COMMAND_LINE_SIZE      896
 #define RAMDISK_ORIGIN         0x800000
 #define RAMDISK_SIZE           0x800000
 #define MEMORY_CHUNKS          16      /* max 0x7fff */
+#define IPL_PARMBLOCK_ORIGIN   0x2000
 
 #ifndef __ASSEMBLY__
 
@@ -64,6 +67,53 @@ extern unsigned int console_irq;
 #define SET_CONSOLE_3215       do { console_mode = 2; } while (0)
 #define SET_CONSOLE_3270       do { console_mode = 3; } while (0)
 
+struct ipl_list_header {
+       u32 length;
+       u8  reserved[3];
+       u8  version;
+} __attribute__((packed));
+
+struct ipl_block_fcp {
+       u32 length;
+       u8  pbt;
+       u8  reserved1[322-1];
+       u16 devno;
+       u8  reserved2[4];
+       u64 wwpn;
+       u64 lun;
+       u32 bootprog;
+       u8  reserved3[12];
+       u64 br_lba;
+       u32 scp_data_len;
+       u8  reserved4[260];
+       u8  scp_data[];
+} __attribute__((packed));
+
+struct ipl_parameter_block {
+       union {
+               u32 length;
+               struct ipl_list_header header;
+       } hdr;
+       struct ipl_block_fcp fcp;
+} __attribute__((packed));
+
+#define IPL_MAX_SUPPORTED_VERSION (0)
+
+#define IPL_TYPE_FCP (0)
+
+/*
+ * IPL validity flags and parameters as detected in head.S
+ */
+extern u32 ipl_parameter_flags;
+extern u16 ipl_devno;
+
+#define IPL_DEVNO_VALID                (ipl_parameter_flags & 1)
+#define IPL_PARMBLOCK_VALID    (ipl_parameter_flags & 2)
+
+#define IPL_PARMBLOCK_START    ((struct ipl_parameter_block *) \
+                                IPL_PARMBLOCK_ORIGIN)
+#define IPL_PARMBLOCK_SIZE     (IPL_PARMBLOCK_START->hdr.length)
+
 #else 
 
 #ifndef __s390x__
index 221e965da9242996e92e755ff13c968905f7cb24..f97d92691f179fc29c2645eda6c742dd108a50ee 100644 (file)
@@ -590,7 +590,6 @@ asmlinkage long sys_clone(struct pt_regs regs);
 asmlinkage long sys_fork(struct pt_regs regs);
 asmlinkage long sys_vfork(struct pt_regs regs);
 asmlinkage long sys_pipe(unsigned long __user *fildes);
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index 0f4bcaae61bd74265361e381356c51bc20fe2c70..aef8ae43de1367de335ee4b698ae76f5a040f33a 100644 (file)
@@ -224,8 +224,6 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
 
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 #define pmd_page_kernel(pmd) \
 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
 
index b923a77a8a7e69a6150e39f3646ca0770765705f..489f7847c5d96f8de23250192d6abe035182c27a 100644 (file)
@@ -33,9 +33,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index ea89e8f223eae1264e6a8fb29e7fb92e6eec6a97..f2c8e14d1fd9c31e65c7d1d9a28a4730c373b43c 100644 (file)
@@ -503,7 +503,6 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
 asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
                        unsigned long r6, unsigned long r7,
                        struct pt_regs regs);
-asmlinkage int sys_ptrace(long request, long pid, long addr, long data);
 asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char *buf,
                                size_t count, long dummy, loff_t pos);
 asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char *buf,
index 51db4307bfaf9fd2be6733490d39be673df2fe17..51b05818e4ebc9cfc848f2992782e43cc0990f6d 100644 (file)
@@ -457,9 +457,6 @@ extern inline pte_t pte_mkhuge(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) | _
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
 
-#define page_pte_prot(page, prot) mk_pte(page, prot)
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 typedef pte_t *pte_addr_t;
 #define pgtable_cache_init()   do { } while (0)
 
index fce22bb9a5465e598b642274afbc1101448dc415..4695264591495d4d7364a89e9cfdefd8c1b0c760 100644 (file)
@@ -40,9 +40,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index caf926116506a2d0980e1e13b30c6c600b02b120..7a941b800b6b42efc00bb80ca3510ad740f4a036 100644 (file)
 
 /* We don't need no stinkin' I/O port allocation crap. */
 #undef release_region
-#undef check_region
 #undef request_region
 #define release_region(X, Y)   do { } while(0)
-#define check_region(X, Y)     (0)
 #define request_region(X, Y, Z)        (1)
 
 /* References:
index a14e9867750047ded9a76449f5a21c7f0b0e5d1d..b33c35411e825ca7cbdc4e1b88d0e542d55d9041 100644 (file)
@@ -255,8 +255,6 @@ BTFIXUPDEF_CALL_CONST(pte_t, pte_mkyoung, pte_t)
 #define pte_mkdirty(pte) BTFIXUP_CALL(pte_mkdirty)(pte)
 #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
 
-#define page_pte_prot(page, prot)      mk_pte(page, prot)
-#define page_pte(page)                 mk_pte(page, __pgprot(0))
 #define pfn_pte(pfn, prot)             mk_pte(pfn_to_page(pfn), prot)
 
 BTFIXUPDEF_CALL(unsigned long,  pte_pfn, pte_t)
index 60ac5fd9eb487c3ece110c3d4fd4793355745cc6..f74ba31e265bd261dde9482bfdbe9bd78d1fcf12 100644 (file)
@@ -22,9 +22,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 8c6dfc6c7af6e6d67ab3e1893cd66421208adbd8..9a02879b235db410cb6d3e465b080eee1daaba5d 100644 (file)
@@ -231,9 +231,6 @@ extern struct page *mem_map_zero;
 #define pte_pfn(x)             ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
 #define pte_page(x)            pfn_to_page(pte_pfn(x))
 
-#define page_pte_prot(page, prot)      mk_pte(page, prot)
-#define page_pte(page)                 page_pte_prot(page, __pgprot(0))
-
 static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
 {
        pte_t __pte;
index 7419dd88b49ed430a0e7978e55ece9388d728617..093dcc6788dbe0309eb380db540da991827e65a4 100644 (file)
@@ -22,9 +22,6 @@ struct semaphore {
        { ATOMIC_INIT(count), \
          __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name, 1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name, count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 4b134fe8504e9eeeb7998fe2410a38286f79b719..a10602a5b2d6395ef697dbe7381278d4997ecf8f 100644 (file)
@@ -1,10 +1,21 @@
 #ifndef __UM_CACHE_H
 #define __UM_CACHE_H
 
-/* These are x86 numbers */
-#define L1_CACHE_SHIFT 5
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#include <linux/config.h>
 
-#define L1_CACHE_SHIFT_MAX 7   /* largest L1 which this arch supports */
+#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+# define L1_CACHE_SHIFT                (CONFIG_X86_L1_CACHE_SHIFT)
+#elif defined(CONFIG_UML_X86) /* 64-bit */
+# define L1_CACHE_SHIFT                6 /* Should be 7 on Intel */
+#else
+/* XXX: this was taken from x86, now it's completely random. Luckily only
+ * affects SMP padding. */
+# define L1_CACHE_SHIFT                5
+#endif
+
+/* XXX: this is valid for x86 and x86_64. */
+#define L1_CACHE_SHIFT_MAX     7       /* largest L1 which this arch supports */
+
+#define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
 
 #endif
index 7dfce37adc8be83424c4463e50a635acfa72650a..e3d62dcbd3565685b110bc9e1f3a76b871a365b3 100644 (file)
@@ -3,4 +3,12 @@
 
 #include "asm/arch/linkage.h"
 
+#include <linux/config.h>
+
+/* <linux/linkage.h> will pick sane defaults */
+#ifdef CONFIG_GPROF
+#undef FASTCALL
+#undef fastcall
+#endif
+
 #endif
index c514062bb69e42fd1e303e1e562204abd99c6f1b..df6cdecf6c1f12522bb3f49ff30ba20ae9811309 100644 (file)
@@ -18,9 +18,6 @@ struct semaphore {
        { ATOMIC_INIT (count), 0,                                             \
          __WAIT_QUEUE_HEAD_INITIALIZER ((name).wait) }
 
-#define __MUTEX_INITIALIZER(name)                                            \
-       __SEMAPHORE_INITIALIZER (name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)        \
        struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
 
index 3b552096c0e8754160d1a88bf04917e749187c46..5a86f8e976ec35b26182abe9c06b366b37949b37 100644 (file)
@@ -452,7 +452,6 @@ unsigned long sys_mmap2(unsigned long addr, size_t len,
 struct pt_regs;
 int sys_execve (char *name, char **argv, char **envp, struct pt_regs *regs);
 int sys_pipe (int *fildes);
-int sys_ptrace(long request, long pid, long addr, long data);
 struct sigaction;
 asmlinkage long sys_rt_sigaction(int sig,
                                const struct sigaction __user *act,
index c5959d6418bbba0c221e9269e1c6e68a22978c74..66ac1c0f27e1d7eba11de129680617d3476a0f33 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/config.h>
 #include <linux/ioctl.h>
+#include <linux/compat.h>
 
 #define        MTRR_IOCTL_BASE 'M'
 
@@ -105,4 +106,36 @@ static __inline__ int mtrr_del_page (int reg, unsigned long base,
 
 #endif
 
+#ifdef CONFIG_COMPAT
+
+struct mtrr_sentry32
+{
+    compat_ulong_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
+};
+
+struct mtrr_gentry32
+{
+    compat_ulong_t regnum;   /*  Register number  */
+    compat_uint_t base;    /*  Base address     */
+    compat_uint_t size;    /*  Size of region   */
+    compat_uint_t type;     /*  Type of region   */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
+
+#endif /* CONFIG_COMPAT */
+
 #endif  /*  _LINUX_MTRR_H  */
index dd8711ecaf2ff71cf1bf0c6fd14d3ba690849465..7a07196a72022f56ebef52ace38ec35d88be7c9e 100644 (file)
@@ -318,8 +318,6 @@ static inline int pmd_large(pmd_t pte) {
  * and a page entry and page directory to the page they refer to.
  */
 
-#define page_pte(page) page_pte_prot(page, __pgprot(0))
-
 /*
  * Level 4 access.
  */
index f325e39bf3b9d2f1db8698c61526a46a57f8b07d..a389aa6fe80f9207b49d4992ebf31f5303310e42 100644 (file)
@@ -56,9 +56,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name) \
-       __SEMAPHORE_INITIALIZER(name,1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
index 11ba931cf82f16336f5356d1ff4a45e356f8f5c6..3c494b65d33a06a5f71e0956e0a69dd1e206b6e3 100644 (file)
@@ -780,8 +780,6 @@ asmlinkage long sys_pipe(int *fildes);
 #include <linux/types.h>
 #include <asm/ptrace.h>
 
-asmlinkage long sys_ptrace(long request, long pid,
-                               unsigned long addr, long data);
 asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
 asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on);
 struct sigaction;
index 09e89ab3eb61ef9a5b189509cae8f201ac1fe032..2a10e193b92972504e12c68199cc5691cd084a04 100644 (file)
@@ -29,9 +29,6 @@ struct semaphore {
        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
 }
 
-#define __MUTEX_INITIALIZER(name)                                      \
-       __SEMAPHORE_INITIALIZER(name, 1)
-
 #define __DECLARE_SEMAPHORE_GENERIC(name,count)                        \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
 
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
new file mode 100644 (file)
index 0000000..26f6ec3
--- /dev/null
@@ -0,0 +1,47 @@
+/* user-type.h: User-defined key type
+ *
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef _KEYS_USER_TYPE_H
+#define _KEYS_USER_TYPE_H
+
+#include <linux/key.h>
+#include <linux/rcupdate.h>
+
+/*****************************************************************************/
+/*
+ * the payload for a key of type "user"
+ * - once filled in and attached to a key:
+ *   - the payload struct is invariant may not be changed, only replaced
+ *   - the payload must be read with RCU procedures or with the key semaphore
+ *     held
+ *   - the payload may only be replaced with the key semaphore write-locked
+ * - the key's data length is the size of the actual data, not including the
+ *   payload wrapper
+ */
+struct user_key_payload {
+       struct rcu_head rcu;            /* RCU destructor */
+       unsigned short  datalen;        /* length of this data */
+       char            data[0];        /* actual data */
+};
+
+extern struct key_type key_type_user;
+
+extern int user_instantiate(struct key *key, const void *data, size_t datalen);
+extern int user_duplicate(struct key *key, const struct key *source);
+extern int user_update(struct key *key, const void *data, size_t datalen);
+extern int user_match(const struct key *key, const void *criterion);
+extern void user_destroy(struct key *key);
+extern void user_describe(const struct key *user, struct seq_file *m);
+extern long user_read(const struct key *key,
+                     char __user *buffer, size_t buflen);
+
+
+#endif /* _KEYS_USER_TYPE_H */
index 86dd5502b05c0196c9265216af8b2b8ec95ceff7..7d8ff97b3e92ed138cc12797ad52ad9224b091c2 100644 (file)
@@ -40,6 +40,8 @@
  * bitmap_weight(src, nbits)                   Hamming Weight: number set bits
  * bitmap_shift_right(dst, src, n, nbits)      *dst = *src >> n
  * bitmap_shift_left(dst, src, n, nbits)       *dst = *src << n
+ * bitmap_remap(dst, src, old, new, nbits)     *dst = map(old, new)(src)
+ * bitmap_bitremap(oldbit, old, new, nbits)    newbit = map(old, new)(oldbit)
  * bitmap_scnprintf(buf, len, src, nbits)      Print bitmap src to buf
  * bitmap_parse(ubuf, ulen, dst, nbits)                Parse bitmap dst from user buf
  * bitmap_scnlistprintf(buf, len, src, nbits)  Print bitmap src as list to buf
@@ -104,6 +106,10 @@ extern int bitmap_scnlistprintf(char *buf, unsigned int len,
                        const unsigned long *src, int nbits);
 extern int bitmap_parselist(const char *buf, unsigned long *maskp,
                        int nmaskbits);
+extern void bitmap_remap(unsigned long *dst, const unsigned long *src,
+               const unsigned long *old, const unsigned long *new, int bits);
+extern int bitmap_bitremap(int oldbit,
+               const unsigned long *old, const unsigned long *new, int bits);
 extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
 extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
 extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
index c937d6e65502e168cd08fe3fbe1bd713637f9953..1db061bb6b08d6278e6eaea43a2493e58bb8165e 100644 (file)
@@ -190,6 +190,7 @@ extern int buffer_heads_over_limit;
  */
 int try_to_release_page(struct page * page, gfp_t gfp_mask);
 int block_invalidatepage(struct page *page, unsigned long offset);
+int do_invalidatepage(struct page *page, unsigned long offset);
 int block_write_full_page(struct page *page, get_block_t *get_block,
                                struct writeback_control *wbc);
 int block_read_full_page(struct page*, get_block_t*);
index 86980c68234aad549fd7d7252da7df5a72139403..1f7b2c097503380692ddb48a33e3d00474f3e71c 100644 (file)
@@ -32,6 +32,7 @@ struct cpu {
 };
 
 extern int register_cpu(struct cpu *, int, struct node *);
+extern struct sys_device *get_cpu_sysdev(int cpu);
 #ifdef CONFIG_HOTPLUG_CPU
 extern void unregister_cpu(struct cpu *, struct node *);
 #endif
index ff7f80f48df1ba2fb87b1fac151d826532b2867d..d068176b7ad7f4d7242e2417f87e3f67043b1d23 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/completion.h>
 #include <linux/workqueue.h>
 #include <linux/cpumask.h>
+#include <asm/div64.h>
 
 #define CPUFREQ_NAME_LEN 16
 
index 9bdba8169b414a3ef945cbb9d13b9e409556320f..13e9f4a3ab26c9e05d05bf0b5a181bab6cb735d4 100644 (file)
@@ -12,6 +12,8 @@
  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
  * For details of cpulist_scnprintf() and cpulist_parse(), see
  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
+ * For details of cpus_remap(), see bitmap_remap in lib/bitmap.c.
  *
  * The available cpumask operations are:
  *
@@ -50,6 +52,8 @@
  * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask
  * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
  * int cpulist_parse(buf, map)         Parse ascii string as cpulist
+ * int cpu_remap(oldbit, old, new)     newbit = map(old, new)(oldbit)
+ * int cpus_remap(dst, src, old, new)  *dst = map(old, new)(src)
  *
  * for_each_cpu_mask(cpu, mask)                for-loop cpu over mask
  *
@@ -294,6 +298,22 @@ static inline int __cpulist_parse(const char *buf, cpumask_t *dstp, int nbits)
        return bitmap_parselist(buf, dstp->bits, nbits);
 }
 
+#define cpu_remap(oldbit, old, new) \
+               __cpu_remap((oldbit), &(old), &(new), NR_CPUS)
+static inline int __cpu_remap(int oldbit,
+               const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+       return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define cpus_remap(dst, src, old, new) \
+               __cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
+static inline void __cpus_remap(cpumask_t *dstp, const cpumask_t *srcp,
+               const cpumask_t *oldp, const cpumask_t *newp, int nbits)
+{
+       bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
 #if NR_CPUS > 1
 #define for_each_cpu_mask(cpu, mask)           \
        for ((cpu) = first_cpu(mask);           \
index a415f1d93e9a4f6c6c647dd851bc19be7ef3035b..05f4132622fc7eeea7972e427cadf72ed1ee068b 100644 (file)
@@ -60,7 +60,7 @@ struct dmi_device {
        void *device_data;      /* Type specific data */
 };
 
-#if defined(CONFIG_X86) && !defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_32)
 
 extern int dmi_check_system(struct dmi_system_id *list);
 extern char * dmi_get_system_info(int field);
index f83d997c55820101385553e780fa5216d2be25fc..6d6226732c93ba96e5edf946e2c934f3e23b390b 100644 (file)
@@ -574,7 +574,14 @@ struct file_ra_state {
 #define RA_FLAG_INCACHE 0x02   /* file is already in cache */
 
 struct file {
-       struct list_head        f_list;
+       /*
+        * fu_list becomes invalid after file_free is called and queued via
+        * fu_rcuhead for RCU freeing
+        */
+       union {
+               struct list_head        fu_list;
+               struct rcu_head         fu_rcuhead;
+       } f_u;
        struct dentry           *f_dentry;
        struct vfsmount         *f_vfsmnt;
        struct file_operations  *f_op;
@@ -598,7 +605,6 @@ struct file {
        spinlock_t              f_ep_lock;
 #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
-       struct rcu_head         f_rcuhead;
 };
 extern spinlock_t files_lock;
 #define file_list_lock() spin_lock(&files_lock);
index acbeb96a3353057de1ba0f7772fe2e2b60585c17..f98854c2abd7a9dffa35a5e091d954e81c34cfb0 100644 (file)
@@ -61,7 +61,6 @@ struct fuse_kstatfs {
 #define FATTR_SIZE     (1 << 3)
 #define FATTR_ATIME    (1 << 4)
 #define FATTR_MTIME    (1 << 5)
-#define FATTR_CTIME    (1 << 6)
 
 /**
  * Flags returned by the OPEN request
index cd623eccdbea61c8e8b8eba1f931645b95c01115..2401dea2b867c798808f0433f575db7e0888f9b6 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/io.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/timer.h>
 
 struct gameport {
 
index f88577ca3b3ad0d2670f3e392edd4d457c0dd10f..5e19a7ba69b2b9ff449ca5d276fdb27bc233fce7 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/i2c-id.h>
 #include <linux/mod_devicetable.h>
 #include <linux/device.h>      /* for struct device */
+#include <linux/sched.h>       /* for completion */
 #include <asm/semaphore.h>
 
 /* --- For i2c-isa ---------------------------------------------------- */
index 92300325dbcd30254b1bc72c0b65cd39c1b35b2d..d79c8a4bc4f854b872552e6a958d4a22291b7b92 100644 (file)
 /* How many different OSM's are we allowing */
 #define I2O_MAX_DRIVERS                8
 
-#include <asm/io.h>
-#include <asm/semaphore.h>     /* Needed for MUTEX init macros */
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>   /* work_struct */
+
+#include <asm/io.h>
+#include <asm/semaphore.h>     /* Needed for MUTEX init macros */
 
 /* message queue empty */
 #define I2O_QUEUE_EMPTY                0xffffffff
index 4367ce4db52a1a427ba3cdc73d6100371c9f67e4..f1925ccc9fe1696496cdad0f9f2bcf583bf2eb5c 100644 (file)
@@ -307,7 +307,7 @@ struct sysinfo {
        char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
 };
 
-/* Force a compilation error if condition is false */
+/* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
 #ifdef CONFIG_SYSCTL
index 7a2e332067c33cdd39e33ad9d83bd7e6cd676f2e..e8b8a7a5c4968b8c3b4e4dc07e8a047fe2a7ec09 100644 (file)
@@ -24,7 +24,8 @@ extern spinlock_t key_serial_lock;
 #define        KEY_WRITE       0x04    /* require permission to update / modify */
 #define        KEY_SEARCH      0x08    /* require permission to search (keyring) or find (key) */
 #define        KEY_LINK        0x10    /* require permission to link */
-#define        KEY_ALL         0x1f    /* all the above permissions */
+#define        KEY_SETATTR     0x20    /* require permission to change attributes */
+#define        KEY_ALL         0x3f    /* all the above permissions */
 
 /*
  * the keyring payload contains a list of the keys to which the keyring is
index f1efa016dbf3c61aa37f8d97cf42ea1185155890..53513a3be53ba745ad900fae33d7727c0dbaca9b 100644 (file)
@@ -40,28 +40,32 @@ struct key;
 #define KEY_POS_WRITE  0x04000000      /* possessor can update key payload / add link to keyring */
 #define KEY_POS_SEARCH 0x08000000      /* possessor can find a key in search / search a keyring */
 #define KEY_POS_LINK   0x10000000      /* possessor can create a link to a key/keyring */
-#define KEY_POS_ALL    0x1f000000
+#define KEY_POS_SETATTR        0x20000000      /* possessor can set key attributes */
+#define KEY_POS_ALL    0x3f000000
 
 #define KEY_USR_VIEW   0x00010000      /* user permissions... */
 #define KEY_USR_READ   0x00020000
 #define KEY_USR_WRITE  0x00040000
 #define KEY_USR_SEARCH 0x00080000
 #define KEY_USR_LINK   0x00100000
-#define KEY_USR_ALL    0x001f0000
+#define KEY_USR_SETATTR        0x00200000
+#define KEY_USR_ALL    0x003f0000
 
 #define KEY_GRP_VIEW   0x00000100      /* group permissions... */
 #define KEY_GRP_READ   0x00000200
 #define KEY_GRP_WRITE  0x00000400
 #define KEY_GRP_SEARCH 0x00000800
 #define KEY_GRP_LINK   0x00001000
-#define KEY_GRP_ALL    0x00001f00
+#define KEY_GRP_SETATTR        0x00002000
+#define KEY_GRP_ALL    0x00003f00
 
 #define KEY_OTH_VIEW   0x00000001      /* third party permissions... */
 #define KEY_OTH_READ   0x00000002
 #define KEY_OTH_WRITE  0x00000004
 #define KEY_OTH_SEARCH 0x00000008
 #define KEY_OTH_LINK   0x00000010
-#define KEY_OTH_ALL    0x0000001f
+#define KEY_OTH_SETATTR        0x00000020
+#define KEY_OTH_ALL    0x0000003f
 
 struct seq_file;
 struct user_struct;
@@ -119,6 +123,7 @@ struct key {
        struct key_type         *type;          /* type of key */
        struct rw_semaphore     sem;            /* change vs change sem */
        struct key_user         *user;          /* owner of this key */
+       void                    *security;      /* security data for this key */
        time_t                  expiry;         /* time at which key expires (or 0) */
        uid_t                   uid;
        gid_t                   gid;
index b6cc10bf8dfca811eeeb0014ca217ebeca419dfc..cbe7d8008042baa9385d3e3ec01aaf48b485b614 100644 (file)
@@ -1,5 +1,7 @@
 #ifdef __KERNEL__
 
+#include <asm/semaphore.h>
+
 typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
 struct kobj_map;
 
index 3fa786448db34edbeaf62e2f5595987ed82ca29f..ebdd41fd1082dfd77c7096e84ac9ec491ed82f8c 100644 (file)
@@ -69,6 +69,18 @@ void kthread_bind(struct task_struct *k, unsigned int cpu);
  * was never called. */
 int kthread_stop(struct task_struct *k);
 
+/**
+ * kthread_stop_sem: stop a thread created by kthread_create().
+ * @k: thread created by kthread_create().
+ * @s: semaphore that @k waits on while idle.
+ *
+ * Does essentially the same thing as kthread_stop() above, but wakes
+ * @k by calling up(@s).
+ *
+ * Returns the result of threadfn(), or -EINTR if wake_up_process()
+ * was never called. */
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
+
 /**
  * kthread_should_stop: should this kthread return now?
  *
index 00a8a5738858bd4e3a13e53cd93c3ec03196f22b..0ba3af7a1236f448ac886878398da323d559309b 100644 (file)
@@ -172,6 +172,13 @@ enum hsm_task_states {
        HSM_ST_ERR,
 };
 
+enum ata_completion_errors {
+       AC_ERR_OTHER            = (1 << 0),
+       AC_ERR_DEV              = (1 << 1),
+       AC_ERR_ATA_BUS          = (1 << 2),
+       AC_ERR_HOST_BUS         = (1 << 3),
+};
+
 /* forward declarations */
 struct scsi_device;
 struct ata_port_operations;
@@ -179,7 +186,7 @@ struct ata_port;
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
 
 struct ata_ioports {
        unsigned long           cmd_addr;
@@ -347,7 +354,6 @@ struct ata_port_operations {
        void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
        u8   (*check_status)(struct ata_port *ap);
        u8   (*check_altstatus)(struct ata_port *ap);
-       u8   (*check_err)(struct ata_port *ap);
        void (*dev_select)(struct ata_port *ap, unsigned int device);
 
        void (*phy_reset) (struct ata_port *ap);
@@ -434,7 +440,6 @@ extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
 extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
 extern u8 ata_check_status(struct ata_port *ap);
 extern u8 ata_altstatus(struct ata_port *ap);
-extern u8 ata_chk_err(struct ata_port *ap);
 extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
@@ -455,7 +460,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
+extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
 extern void ata_eng_timeout(struct ata_port *ap);
 extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
                              void (*done)(struct scsi_cmnd *));
@@ -718,4 +723,21 @@ static inline int ata_try_flush_cache(const struct ata_device *dev)
               ata_id_has_flush_ext(dev->id);
 }
 
+static inline unsigned int ac_err_mask(u8 status)
+{
+       if (status & ATA_BUSY)
+               return AC_ERR_ATA_BUS;
+       if (status & (ATA_ERR | ATA_DF))
+               return AC_ERR_DEV;
+       return 0;
+}
+
+static inline unsigned int __ac_err_mask(u8 status)
+{
+       unsigned int mask = ac_err_mask(status);
+       if (mask == 0)
+               return AC_ERR_OTHER;
+       return mask;
+}
+
 #endif /* __LINUX_LIBATA_H__ */
index 7af8cb836e78df84afa4b1eb36dd3bb3cbe166b9..8b67cf837ca97fd3e819c0fba62e7ab9608eed6b 100644 (file)
@@ -154,6 +154,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
 
 extern void numa_default_policy(void);
 extern void numa_policy_init(void);
+extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new);
 extern struct mempolicy default_policy;
 
 #else
@@ -226,6 +227,11 @@ static inline void numa_default_policy(void)
 {
 }
 
+static inline void numa_policy_rebind(const nodemask_t *old,
+                                       const nodemask_t *new)
+{
+}
+
 #endif /* CONFIG_NUMA */
 #endif /* __KERNEL__ */
 
index f05372b7fe7746a48a838a310b18e3115c0e55ef..84d75f3a8acab027fc1ed4a91c8878808eeb6be2 100644 (file)
@@ -554,7 +554,9 @@ static inline void MODULE_PARM_(void) { }
 #ifdef MODULE
 /* DEPRECATED: Do not use. */
 #define MODULE_PARM(var,type)                                              \
-struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
+extern struct obsolete_modparm __parm_##var \
+__attribute__((section("__obsparm"))); \
+struct obsolete_modparm __parm_##var = \
 { __stringify(var), type, &MODULE_PARM_ }; \
 __MODULE_PARM_TYPE(var, type);
 #else
index 9a3d2725798439e2a745bca4f564f89228e77ae3..941da5c016a01e1434d3291fe1ec466c16adbb45 100644 (file)
@@ -282,6 +282,17 @@ static inline u8 fat_attr(struct inode *inode)
                MSDOS_I(inode)->i_attrs;
 }
 
+static inline unsigned char fat_checksum(const __u8 *name)
+{
+       unsigned char s = name[0];
+       s = (s<<7) + (s>>1) + name[1];  s = (s<<7) + (s>>1) + name[2];
+       s = (s<<7) + (s>>1) + name[3];  s = (s<<7) + (s>>1) + name[4];
+       s = (s<<7) + (s>>1) + name[5];  s = (s<<7) + (s>>1) + name[6];
+       s = (s<<7) + (s>>1) + name[7];  s = (s<<7) + (s>>1) + name[8];
+       s = (s<<7) + (s>>1) + name[9];  s = (s<<7) + (s>>1) + name[10];
+       return s;
+}
+
 static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
 {
        return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
index 142963f01d2947d9c4c2c52c84afc8a8d020f34e..fc28841f340975181d6813c5f5d701921aad9219 100644 (file)
@@ -8,7 +8,10 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/string.h>
+
 #include <linux/mtd/compatmac.h>
+
 #include <asm/unaligned.h>
 #include <asm/system.h>
 #include <asm/io.h>
index e96fe90625003b64556d1c30a17496cee54124d7..4726ef7ba8e8e2fe35d03ef68184173320374ef4 100644 (file)
@@ -12,6 +12,8 @@
  * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
  * For details of nodelist_scnprintf() and nodelist_parse(), see
  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
+ * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
+ * For details of nodes_remap(), see bitmap_remap in lib/bitmap.c.
  *
  * The available nodemask operations are:
  *
@@ -52,6 +54,8 @@
  * int nodemask_parse(ubuf, ulen, mask)        Parse ascii string as nodemask
  * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
  * int nodelist_parse(buf, map)                Parse ascii string as nodelist
+ * int node_remap(oldbit, old, new)    newbit = map(old, new)(oldbit)
+ * int nodes_remap(dst, src, old, new) *dst = map(old, new)(dst)
  *
  * for_each_node_mask(node, mask)      for-loop node over mask
  *
@@ -307,6 +311,22 @@ static inline int __nodelist_parse(const char *buf, nodemask_t *dstp, int nbits)
        return bitmap_parselist(buf, dstp->bits, nbits);
 }
 
+#define node_remap(oldbit, old, new) \
+               __node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
+static inline int __node_remap(int oldbit,
+               const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+       return bitmap_bitremap(oldbit, oldp->bits, newp->bits, nbits);
+}
+
+#define nodes_remap(dst, src, old, new) \
+               __nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
+static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
+               const nodemask_t *oldp, const nodemask_t *newp, int nbits)
+{
+       bitmap_remap(dstp->bits, srcp->bits, oldp->bits, newp->bits, nbits);
+}
+
 #if MAX_NUMNODES > 1
 #define for_each_node_mask(node, mask)                 \
        for ((node) = first_node(mask);                 \
index c61d5de837efaf4fa38829ab417f1993ad70f5b6..1514098d156d897ba02956517bc544f7626f5f87 100644 (file)
@@ -170,6 +170,7 @@ typedef int __bitwise suspend_disk_method_t;
 
 struct pm_ops {
        suspend_disk_method_t pm_disk_mode;
+       int (*valid)(suspend_state_t state);
        int (*prepare)(suspend_state_t state);
        int (*enter)(suspend_state_t state);
        int (*finish)(suspend_state_t state);
index 70191a5a148f560caf5ba08d4fcb7109ea6fb860..cce25591eec2076dae54c0d803e18298935d638a 100644 (file)
@@ -275,6 +275,7 @@ static inline int rcu_pending(int cpu)
 extern void rcu_init(void);
 extern void rcu_check_callbacks(int cpu, int user);
 extern void rcu_restart_cpu(int cpu);
+extern long rcu_batches_completed(void);
 
 /* Exported interfaces */
 extern void FASTCALL(call_rcu(struct rcu_head *head, 
index 1c30bc308ef1baeb4ce0181b76f4d3355a76bc6e..03b68a7b4b82ae7c775a375f1fe3aa0b6a9909ec 100644 (file)
@@ -940,7 +940,7 @@ extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
 #else
 static inline int set_cpus_allowed(task_t *p, cpumask_t new_mask)
 {
-       if (!cpus_intersects(new_mask, cpu_online_map))
+       if (!cpu_isset(0, new_mask))
                return -EINVAL;
        return 0;
 }
@@ -1084,6 +1084,11 @@ extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned lon
 #define SEND_SIG_PRIV  ((struct siginfo *) 1)
 #define SEND_SIG_FORCED        ((struct siginfo *) 2)
 
+static inline int is_si_special(const struct siginfo *info)
+{
+       return info <= SEND_SIG_FORCED;
+}
+
 /* True if we are on the alternate signal stack.  */
 
 static inline int on_sig_stack(unsigned long sp)
@@ -1211,7 +1216,7 @@ extern void unhash_process(struct task_struct *p);
 /*
  * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
  * subscriptions and synchronises with wait4().  Also used in procfs.  Also
- * pins the final release of task.io_context.
+ * pins the final release of task.io_context.  Also protects ->cpuset.
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
index dac956ed98f0a11c217e58512e37a8e1085ffd7a..f7e0ae018712257a11b67ffa6cd12eafb988c34b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/shm.h>
 #include <linux/msg.h>
 #include <linux/sched.h>
+#include <linux/key.h>
 
 struct ctl_table;
 
@@ -385,6 +386,9 @@ struct swap_info_struct;
  *     NULL to request the size of the buffer required.  @size indicates
  *     the size of @buffer in bytes.  Note that @name is the remainder
  *     of the attribute name after the security. prefix has been removed.
+ *     @err is the return value from the preceding fs getxattr call,
+ *     and can be used by the security module to determine whether it
+ *     should try and canonicalize the attribute value.
  *     Return number of bytes used/required on success.
  * @inode_setsecurity:
  *     Set the security label associated with @name for @inode from the
@@ -785,6 +789,27 @@ struct swap_info_struct;
  * @sk_free_security:
  *     Deallocate security structure.
  *
+ * Security hooks affecting all Key Management operations
+ *
+ * @key_alloc:
+ *     Permit allocation of a key and assign security data. Note that key does
+ *     not have a serial number assigned at this point.
+ *     @key points to the key.
+ *     Return 0 if permission is granted, -ve error otherwise.
+ * @key_free:
+ *     Notification of destruction; free security data.
+ *     @key points to the key.
+ *     No return value.
+ * @key_permission:
+ *     See whether a specific operational right is granted to a process on a
+ *      key.
+ *     @key_ref refers to the key (key pointer + possession attribute bit).
+ *     @context points to the process to provide the context against which to
+ *       evaluate the security data on the key.
+ *     @perm describes the combination of permissions required of this key.
+ *     Return 1 if permission granted, 0 if permission denied and -ve it the
+ *      normal permissions model should be effected.
+ *
  * Security hooks affecting all System V IPC operations.
  *
  * @ipc_permission:
@@ -1091,7 +1116,7 @@ struct security_operations {
        int (*inode_getxattr) (struct dentry *dentry, char *name);
        int (*inode_listxattr) (struct dentry *dentry);
        int (*inode_removexattr) (struct dentry *dentry, char *name);
-       int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size);
+       int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
        int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
        int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
 
@@ -1213,6 +1238,17 @@ struct security_operations {
        int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
        void (*sk_free_security) (struct sock *sk);
 #endif /* CONFIG_SECURITY_NETWORK */
+
+       /* key management security hooks */
+#ifdef CONFIG_KEYS
+       int (*key_alloc)(struct key *key);
+       void (*key_free)(struct key *key);
+       int (*key_permission)(key_ref_t key_ref,
+                             struct task_struct *context,
+                             key_perm_t perm);
+
+#endif /* CONFIG_KEYS */
+
 };
 
 /* global variables */
@@ -1580,11 +1616,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
        return security_ops->inode_removexattr (dentry, name);
 }
 
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
 {
        if (unlikely (IS_PRIVATE (inode)))
                return 0;
-       return security_ops->inode_getsecurity(inode, name, buffer, size);
+       return security_ops->inode_getsecurity(inode, name, buffer, size, err);
 }
 
 static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
@@ -2222,7 +2258,7 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
        return cap_inode_removexattr(dentry, name);
 }
 
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
 {
        return -EOPNOTSUPP;
 }
@@ -2761,5 +2797,45 @@ static inline void security_sk_free(struct sock *sk)
 }
 #endif /* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_KEYS
+#ifdef CONFIG_SECURITY
+static inline int security_key_alloc(struct key *key)
+{
+       return security_ops->key_alloc(key);
+}
+
+static inline void security_key_free(struct key *key)
+{
+       security_ops->key_free(key);
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+                                         struct task_struct *context,
+                                         key_perm_t perm)
+{
+       return security_ops->key_permission(key_ref, context, perm);
+}
+
+#else
+
+static inline int security_key_alloc(struct key *key)
+{
+       return 0;
+}
+
+static inline void security_key_free(struct key *key)
+{
+}
+
+static inline int security_key_permission(key_ref_t key_ref,
+                                         struct task_struct *context,
+                                         key_perm_t perm)
+{
+       return 0;
+}
+
+#endif
+#endif /* CONFIG_KEYS */
+
 #endif /* ! __LINUX_SECURITY_H */
 
index 12cd9cf65e8ffe3b6a2b58042336a8e11d5092ef..33fc8cb8ddfbaedf234300c397a87b50895e1ec7 100644 (file)
@@ -11,6 +11,7 @@
 #define _LINUX_SERIAL_H
 
 #ifdef __KERNEL__
+#include <linux/types.h>
 #include <asm/page.h>
 
 /*
index 7be18b5e2fb41a9ec1794028a0364324360a6828..5dd5f02c5c5fd6b1c3f192f13b6b28373763061f 100644 (file)
@@ -25,7 +25,6 @@
 
 struct sigqueue {
        struct list_head list;
-       spinlock_t *lock;
        int flags;
        siginfo_t info;
        struct user_struct *user;
index cdc99a27840d6433cabf5d7a6c5bfa6e43198215..0e9682c9def5e0d1a198486435618978829d33ac 100644 (file)
@@ -171,23 +171,42 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
 #define write_lock_irq(lock)           _write_lock_irq(lock)
 #define write_lock_bh(lock)            _write_lock_bh(lock)
 
-#define spin_unlock(lock)              _spin_unlock(lock)
-#define write_unlock(lock)             _write_unlock(lock)
-#define read_unlock(lock)              _read_unlock(lock)
+/*
+ * We inline the unlock functions in the nondebug case:
+ */
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock(lock)             _spin_unlock(lock)
+# define read_unlock(lock)             _read_unlock(lock)
+# define write_unlock(lock)            _write_unlock(lock)
+#else
+# define spin_unlock(lock)             __raw_spin_unlock(&(lock)->raw_lock)
+# define read_unlock(lock)             __raw_read_unlock(&(lock)->raw_lock)
+# define write_unlock(lock)            __raw_write_unlock(&(lock)->raw_lock)
+#endif
+
+#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
+# define spin_unlock_irq(lock)         _spin_unlock_irq(lock)
+# define read_unlock_irq(lock)         _read_unlock_irq(lock)
+# define write_unlock_irq(lock)                _write_unlock_irq(lock)
+#else
+# define spin_unlock_irq(lock) \
+    do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define read_unlock_irq(lock) \
+    do { __raw_read_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+# define write_unlock_irq(lock) \
+    do { __raw_write_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
+#endif
 
 #define spin_unlock_irqrestore(lock, flags) \
                                        _spin_unlock_irqrestore(lock, flags)
-#define spin_unlock_irq(lock)          _spin_unlock_irq(lock)
 #define spin_unlock_bh(lock)           _spin_unlock_bh(lock)
 
 #define read_unlock_irqrestore(lock, flags) \
                                        _read_unlock_irqrestore(lock, flags)
-#define read_unlock_irq(lock)          _read_unlock_irq(lock)
 #define read_unlock_bh(lock)           _read_unlock_bh(lock)
 
 #define write_unlock_irqrestore(lock, flags) \
                                        _write_unlock_irqrestore(lock, flags)
-#define write_unlock_irq(lock)         _write_unlock_irq(lock)
 #define write_unlock_bh(lock)          _write_unlock_bh(lock)
 
 #define spin_trylock_bh(lock)          __cond_lock(_spin_trylock_bh(lock))
index ba448c760168a8e48cbb2ab59005095ebd1fb6b2..a61c04f804b2b41b4da68ab3d5f0466b51a66452 100644 (file)
@@ -71,7 +71,12 @@ void restore_processor_state(void);
 struct saved_context;
 void __save_processor_state(struct saved_context *ctxt);
 void __restore_processor_state(struct saved_context *ctxt);
-extern unsigned long get_usable_page(gfp_t gfp_mask);
-extern void free_eaten_memory(void);
+unsigned long get_safe_page(gfp_t gfp_mask);
+
+/*
+ * XXX: We try to keep some more pages free so that I/O operations succeed
+ * without paging. Might this be more?
+ */
+#define PAGES_FOR_IO   512
 
 #endif /* _LINUX_SWSUSP_H */
index a6f03e4737377f3437816ed74b7e96c0f87c42de..c7007b1db91d6beece5fd0143c0f519304e629c4 100644 (file)
@@ -491,6 +491,7 @@ asmlinkage long sys_nfsservctl(int cmd,
 asmlinkage long sys_syslog(int type, char __user *buf, int len);
 asmlinkage long sys_uselib(const char __user *library);
 asmlinkage long sys_ni_syscall(void);
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data);
 
 asmlinkage long sys_add_key(const char __user *_type,
                            const char __user *_description,
index fc5bb4e91a5846303ecb9be8a8058768d000d7e1..7dac8f04d28e1aee64cec1a140bd52aded10edd1 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 struct ts_config;
 
index 3340f3bd135daa9c4c42741d98df1a6b469e6ba6..72f3a7781106ab1290198d25edd33a8723588e0b 100644 (file)
@@ -12,16 +12,12 @@ struct timer_list {
        struct list_head entry;
        unsigned long expires;
 
-       unsigned long magic;
-
        void (*function)(unsigned long);
        unsigned long data;
 
        struct timer_base_s *base;
 };
 
-#define TIMER_MAGIC    0x4b87ad6e
-
 extern struct timer_base_s __init_timer_base;
 
 #define TIMER_INITIALIZER(_function, _expires, _data) {                \
@@ -29,7 +25,6 @@ extern struct timer_base_s __init_timer_base;
                .expires = (_expires),                          \
                .data = (_data),                                \
                .base = &__init_timer_base,                     \
-               .magic = TIMER_MAGIC,                           \
        }
 
 #define DEFINE_TIMER(_name, _function, _expires, _data)                \
@@ -38,6 +33,15 @@ extern struct timer_base_s __init_timer_base;
 
 void fastcall init_timer(struct timer_list * timer);
 
+static inline void setup_timer(struct timer_list * timer,
+                               void (*function)(unsigned long),
+                               unsigned long data)
+{
+       timer->function = function;
+       timer->data = data;
+       init_timer(timer);
+}
+
 /***
  * timer_pending - is a timer pending?
  * @timer: the timer in question
@@ -74,8 +78,9 @@ extern unsigned long next_timer_interrupt(void);
  * Timers with an ->expired field in the past will be executed in the next
  * timer tick.
  */
-static inline void add_timer(struct timer_list * timer)
+static inline void add_timer(struct timer_list *timer)
 {
+       BUG_ON(timer_pending(timer));
        __mod_timer(timer, timer->expires);
 }
 
index 7e050a2cc35be69f2685309ff9c445adbba8ae68..04a4a8cb4ed37ab150b6575b3ae9f9268967e5e7 100644 (file)
@@ -282,6 +282,13 @@ static inline int ntp_synced(void)
        return !(time_status & STA_UNSYNC);
 }
 
+/* Required to safely shift negative values */
+#define shift_right(x, s) ({   \
+       __typeof__(x) __x = (x);        \
+       __typeof__(s) __s = (s);        \
+       __x < 0 ? -(-__x >> __s) : __x >> __s;  \
+})
+
 
 #ifdef CONFIG_TIME_INTERPOLATION
 
index c8592c7e8eaa5bc2bb90411d8f7fa5e8134bb854..e788bbc5657d70dd057adaa4658b4307bb77d035 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/config.h>
 #include <linux/device.h>
+#include <linux/sched.h>       /* task_struct, completion */
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
index e6b61fab66ddf69a66adc5f81f6647fe2ad11da9..7529f4388bb46df6655e61364217c78e2199ea18 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/types.h>
+#include <linux/timer.h>
 
 struct request;
 struct scatterlist;
index b0d4454373721da80e76a63e94dd18c20e7494a9..c04405bead2d5f1482c98e3bba0c94657c05b259 100644 (file)
@@ -28,6 +28,7 @@
 #define SCSI_TRANSPORT_FC_H
 
 #include <linux/config.h>
+#include <linux/sched.h>
 
 struct scsi_transport_template;
 
index d5a1a1228fab05632107e53152c954c0033d10f9..3dcbd5bfd49843168d6b45f62d3ae5a7b8cfecdc 100644 (file)
@@ -60,8 +60,8 @@ config INIT_ENV_ARG_LIMIT
        default 32 if !USERMODE
        default 128 if USERMODE
        help
-         This is the value of the two limits on the number of argument and of
-         env.var passed to init from the kernel command line.
+         Maximum of each of the number of arguments and environment
+         variables passed to init from the kernel command line.
 
 endmenu
 
index f142d403534190f4588b3d7eda585112077e0607..4075d97e94b184c4d8b95a1e95057e249cf45f21 100644 (file)
 #endif
 #endif
 
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/smp.h>
-#endif
-
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
@@ -314,14 +310,7 @@ extern void setup_arch(char **);
 
 #ifndef CONFIG_SMP
 
-#ifdef CONFIG_X86_LOCAL_APIC
-static void __init smp_init(void)
-{
-       APIC_init_uniprocessor();
-}
-#else
 #define smp_init()     do { } while (0)
-#endif
 
 static inline void setup_per_cpu_areas(void) { }
 static inline void smp_prepare_cpus(unsigned int maxcpus) { }
index ff4dc02ce17027f22dc4bf4027075653ee7f42bb..4f5a1453093ad0569d3ac417fdda393005eef2ef 100644 (file)
@@ -22,7 +22,6 @@ obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_IKCONFIG) += configs.o
-obj-$(CONFIG_IKCONFIG_PROC) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
 obj-$(CONFIG_AUDIT) += audit.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
@@ -32,6 +31,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
+obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
index 53d8263ae12ebc00483a3ad999177799003467e2..3619e939182e3b75c982e33eace09f1b86fe9b85 100644 (file)
@@ -17,6 +17,7 @@
 
 /* This protects CPUs going up and down... */
 DECLARE_MUTEX(cpucontrol);
+EXPORT_SYMBOL_GPL(cpucontrol);
 
 static struct notifier_block *cpu_chain;
 
index 28176d083f7baadca422dfd510fdd7dbfd892c00..5a737ed9dac79d8cf2fe184e6a79574680afa01b 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
+#include <linux/mempolicy.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/mount.h>
@@ -60,6 +61,9 @@ struct cpuset {
        cpumask_t cpus_allowed;         /* CPUs allowed to tasks in cpuset */
        nodemask_t mems_allowed;        /* Memory Nodes allowed to tasks */
 
+       /*
+        * Count is atomic so can incr (fork) or decr (exit) without a lock.
+        */
        atomic_t count;                 /* count tasks using this cpuset */
 
        /*
@@ -142,80 +146,91 @@ static struct vfsmount *cpuset_mount;
 static struct super_block *cpuset_sb = NULL;
 
 /*
- * cpuset_sem should be held by anyone who is depending on the children
- * or sibling lists of any cpuset, or performing non-atomic operations
- * on the flags or *_allowed values of a cpuset, such as raising the
- * CS_REMOVED flag bit iff it is not already raised, or reading and
- * conditionally modifying the *_allowed values.  One kernel global
- * cpuset semaphore should be sufficient - these things don't change
- * that much.
- *
- * The code that modifies cpusets holds cpuset_sem across the entire
- * operation, from cpuset_common_file_write() down, single threading
- * all cpuset modifications (except for counter manipulations from
- * fork and exit) across the system.  This presumes that cpuset
- * modifications are rare - better kept simple and safe, even if slow.
- *
- * The code that reads cpusets, such as in cpuset_common_file_read()
- * and below, only holds cpuset_sem across small pieces of code, such
- * as when reading out possibly multi-word cpumasks and nodemasks, as
- * the risks are less, and the desire for performance a little greater.
- * The proc_cpuset_show() routine needs to hold cpuset_sem to insure
- * that no cs->dentry is NULL, as it walks up the cpuset tree to root.
- *
- * The hooks from fork and exit, cpuset_fork() and cpuset_exit(), don't
- * (usually) grab cpuset_sem.  These are the two most performance
- * critical pieces of code here.  The exception occurs on exit(),
- * when a task in a notify_on_release cpuset exits.  Then cpuset_sem
+ * We have two global cpuset semaphores below.  They can nest.
+ * It is ok to first take manage_sem, then nest callback_sem.  We also
+ * require taking task_lock() when dereferencing a tasks cpuset pointer.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold both semaphores to modify cpusets.  If a task
+ * holds manage_sem, then it blocks others wanting that semaphore,
+ * ensuring that it is the only task able to also acquire callback_sem
+ * and be able to modify cpusets.  It can perform various checks on
+ * the cpuset structure first, knowing nothing will change.  It can
+ * also allocate memory while just holding manage_sem.  While it is
+ * performing these checks, various callback routines can briefly
+ * acquire callback_sem to query cpusets.  Once it is ready to make
+ * the changes, it takes callback_sem, blocking everyone else.
+ *
+ * Calls to the kernel memory allocator can not be made while holding
+ * callback_sem, as that would risk double tripping on callback_sem
+ * from one of the callbacks into the cpuset code from within
+ * __alloc_pages().
+ *
+ * If a task is only holding callback_sem, then it has read-only
+ * access to cpusets.
+ *
+ * The task_struct fields mems_allowed and mems_generation may only
+ * be accessed in the context of that task, so require no locks.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding manage_sem or callback_sem can't rely
+ * on the count field not changing.  However, if the count goes to
+ * zero, then only attach_task(), which holds both semaphores, can
+ * increment it again.  Because a count of zero means that no tasks
+ * are currently attached, therefore there is no way a task attached
+ * to that cpuset can fork (the other way to increment the count).
+ * So code holding manage_sem or callback_sem can safely assume that
+ * if the count is zero, it will stay zero.  Similarly, if a task
+ * holds manage_sem or callback_sem on a cpuset with zero count, it
+ * knows that the cpuset won't be removed, as cpuset_rmdir() needs
+ * both of those semaphores.
+ *
+ * A possible optimization to improve parallelism would be to make
+ * callback_sem a R/W semaphore (rwsem), allowing the callback routines
+ * to proceed in parallel, with read access, until the holder of
+ * manage_sem needed to take this rwsem for exclusive write access
+ * and modify some cpusets.
+ *
+ * The cpuset_common_file_write handler for operations that modify
+ * the cpuset hierarchy holds manage_sem across the entire operation,
+ * single threading all such cpuset modifications across the system.
+ *
+ * The cpuset_common_file_read() handlers only hold callback_sem across
+ * small pieces of code, such as when reading out possibly multi-word
+ * cpumasks and nodemasks.
+ *
+ * The fork and exit callbacks cpuset_fork() and cpuset_exit(), don't
+ * (usually) take either semaphore.  These are the two most performance
+ * critical pieces of code here.  The exception occurs on cpuset_exit(),
+ * when a task in a notify_on_release cpuset exits.  Then manage_sem
  * is taken, and if the cpuset count is zero, a usermode call made
  * to /sbin/cpuset_release_agent with the name of the cpuset (path
  * relative to the root of cpuset file system) as the argument.
  *
- * A cpuset can only be deleted if both its 'count' of using tasks is
- * zero, and its list of 'children' cpusets is empty.  Since all tasks
- * in the system use _some_ cpuset, and since there is always at least
- * one task in the system (init, pid == 1), therefore, top_cpuset
- * always has either children cpusets and/or using tasks.  So no need
- * for any special hack to ensure that top_cpuset cannot be deleted.
+ * A cpuset can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cpusets is empty.  Since all
+ * tasks in the system use _some_ cpuset, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cpuset
+ * always has either children cpusets and/or using tasks.  So we don't
+ * need a special hack to ensure that top_cpuset cannot be deleted.
+ *
+ * The above "Tale of Two Semaphores" would be complete, but for:
+ *
+ *     The task_lock() exception
+ *
+ * The need for this exception arises from the action of attach_task(),
+ * which overwrites one tasks cpuset pointer with another.  It does
+ * so using both semaphores, however there are several performance
+ * critical places that need to reference task->cpuset without the
+ * expense of grabbing a system global semaphore.  Therefore except as
+ * noted below, when dereferencing or, as in attach_task(), modifying
+ * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
+ * (task->alloc_lock) already in the task_struct routinely used for
+ * such matters.
  */
 
-static DECLARE_MUTEX(cpuset_sem);
-static struct task_struct *cpuset_sem_owner;
-static int cpuset_sem_depth;
-
-/*
- * The global cpuset semaphore cpuset_sem can be needed by the
- * memory allocator to update a tasks mems_allowed (see the calls
- * to cpuset_update_current_mems_allowed()) or to walk up the
- * cpuset hierarchy to find a mem_exclusive cpuset see the calls
- * to cpuset_excl_nodes_overlap()).
- *
- * But if the memory allocation is being done by cpuset.c code, it
- * usually already holds cpuset_sem.  Double tripping on a kernel
- * semaphore deadlocks the current task, and any other task that
- * subsequently tries to obtain the lock.
- *
- * Run all up's and down's on cpuset_sem through the following
- * wrappers, which will detect this nested locking, and avoid
- * deadlocking.
- */
-
-static inline void cpuset_down(struct semaphore *psem)
-{
-       if (cpuset_sem_owner != current) {
-               down(psem);
-               cpuset_sem_owner = current;
-       }
-       cpuset_sem_depth++;
-}
-
-static inline void cpuset_up(struct semaphore *psem)
-{
-       if (--cpuset_sem_depth == 0) {
-               cpuset_sem_owner = NULL;
-               up(psem);
-       }
-}
+static DECLARE_MUTEX(manage_sem);
+static DECLARE_MUTEX(callback_sem);
 
 /*
  * A couple of forward declarations required, due to cyclic reference loop:
@@ -390,7 +405,7 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
 }
 
 /*
- * Call with cpuset_sem held.  Writes path of cpuset into buf.
+ * Call with manage_sem held.  Writes path of cpuset into buf.
  * Returns 0 on success, -errno on error.
  */
 
@@ -442,10 +457,11 @@ static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
  * status of the /sbin/cpuset_release_agent task, so no sense holding
  * our caller up for that.
  *
- * The simple act of forking that task might require more memory,
- * which might need cpuset_sem.  So this routine must be called while
- * cpuset_sem is not held, to avoid a possible deadlock.  See also
- * comments for check_for_release(), below.
+ * When we had only one cpuset semaphore, we had to call this
+ * without holding it, to avoid deadlock when call_usermodehelper()
+ * allocated memory.  With two locks, we could now call this while
+ * holding manage_sem, but we still don't, so as to minimize
+ * the time manage_sem is held.
  */
 
 static void cpuset_release_agent(const char *pathbuf)
@@ -477,15 +493,15 @@ static void cpuset_release_agent(const char *pathbuf)
  * cs is notify_on_release() and now both the user count is zero and
  * the list of children is empty, prepare cpuset path in a kmalloc'd
  * buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
- * Call here with cpuset_sem held.
+ * cpuset_release_agent() with it later on, once manage_sem is dropped.
+ * Call here with manage_sem held.
  *
  * This check_for_release() routine is responsible for kmalloc'ing
  * pathbuf.  The above cpuset_release_agent() is responsible for
  * kfree'ing pathbuf.  The caller of these routines is responsible
  * for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with cpuset_sem held and the address
- * of the pathbuf pointer, then dropping cpuset_sem, then calling
+ * calling check_for_release() with manage_sem held and the address
+ * of the pathbuf pointer, then dropping manage_sem, then calling
  * cpuset_release_agent() with pathbuf, as set by check_for_release().
  */
 
@@ -516,7 +532,7 @@ static void check_for_release(struct cpuset *cs, char **ppathbuf)
  * One way or another, we guarantee to return some non-empty subset
  * of cpu_online_map.
  *
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
  */
 
 static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
@@ -540,7 +556,7 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
  * One way or another, we guarantee to return some non-empty subset
  * of node_online_map.
  *
- * Call with cpuset_sem held.
+ * Call with callback_sem held.
  */
 
 static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
@@ -555,22 +571,47 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
 }
 
 /*
- * Refresh current tasks mems_allowed and mems_generation from
- * current tasks cpuset.  Call with cpuset_sem held.
+ * Refresh current tasks mems_allowed and mems_generation from current
+ * tasks cpuset.
  *
- * This routine is needed to update the per-task mems_allowed
- * data, within the tasks context, when it is trying to allocate
- * memory (in various mm/mempolicy.c routines) and notices
- * that some other task has been modifying its cpuset.
+ * Call without callback_sem or task_lock() held.  May be called with
+ * or without manage_sem held.  Will acquire task_lock() and might
+ * acquire callback_sem during call.
+ *
+ * The task_lock() is required to dereference current->cpuset safely.
+ * Without it, we could pick up the pointer value of current->cpuset
+ * in one instruction, and then attach_task could give us a different
+ * cpuset, and then the cpuset we had could be removed and freed,
+ * and then on our next instruction, we could dereference a no longer
+ * valid cpuset pointer to get its mems_generation field.
+ *
+ * This routine is needed to update the per-task mems_allowed data,
+ * within the tasks context, when it is trying to allocate memory
+ * (in various mm/mempolicy.c routines) and notices that some other
+ * task has been modifying its cpuset.
  */
 
 static void refresh_mems(void)
 {
-       struct cpuset *cs = current->cpuset;
+       int my_cpusets_mem_gen;
+
+       task_lock(current);
+       my_cpusets_mem_gen = current->cpuset->mems_generation;
+       task_unlock(current);
 
-       if (current->cpuset_mems_generation != cs->mems_generation) {
+       if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
+               struct cpuset *cs;
+               nodemask_t oldmem = current->mems_allowed;
+
+               down(&callback_sem);
+               task_lock(current);
+               cs = current->cpuset;
                guarantee_online_mems(cs, &current->mems_allowed);
                current->cpuset_mems_generation = cs->mems_generation;
+               task_unlock(current);
+               up(&callback_sem);
+               if (!nodes_equal(oldmem, current->mems_allowed))
+                       numa_policy_rebind(&oldmem, &current->mems_allowed);
        }
 }
 
@@ -579,7 +620,7 @@ static void refresh_mems(void)
  *
  * One cpuset is a subset of another if all its allowed CPUs and
  * Memory Nodes are a subset of the other, and its exclusive flags
- * are only set if the other's are set.
+ * are only set if the other's are set.  Call holding manage_sem.
  */
 
 static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@ -597,7 +638,7 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
  * If we replaced the flag and mask values of the current cpuset
  * (cur) with those values in the trial cpuset (trial), would
  * our various subset and exclusive rules still be valid?  Presumes
- * cpuset_sem held.
+ * manage_sem held.
  *
  * 'cur' is the address of an actual, in-use cpuset.  Operations
  * such as list traversal that depend on the actual address of the
@@ -651,7 +692,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
  *    exclusive child cpusets
  * Build these two partitions by calling partition_sched_domains
  *
- * Call with cpuset_sem held.  May nest a call to the
+ * Call with manage_sem held.  May nest a call to the
  * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
  */
 
@@ -696,6 +737,10 @@ static void update_cpu_domains(struct cpuset *cur)
        unlock_cpu_hotplug();
 }
 
+/*
+ * Call with manage_sem held.  May take callback_sem during call.
+ */
+
 static int update_cpumask(struct cpuset *cs, char *buf)
 {
        struct cpuset trialcs;
@@ -712,12 +757,18 @@ static int update_cpumask(struct cpuset *cs, char *buf)
        if (retval < 0)
                return retval;
        cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
+       down(&callback_sem);
        cs->cpus_allowed = trialcs.cpus_allowed;
+       up(&callback_sem);
        if (is_cpu_exclusive(cs) && !cpus_unchanged)
                update_cpu_domains(cs);
        return 0;
 }
 
+/*
+ * Call with manage_sem held.  May take callback_sem during call.
+ */
+
 static int update_nodemask(struct cpuset *cs, char *buf)
 {
        struct cpuset trialcs;
@@ -732,9 +783,11 @@ static int update_nodemask(struct cpuset *cs, char *buf)
                return -ENOSPC;
        retval = validate_change(cs, &trialcs);
        if (retval == 0) {
+               down(&callback_sem);
                cs->mems_allowed = trialcs.mems_allowed;
                atomic_inc(&cpuset_mems_generation);
                cs->mems_generation = atomic_read(&cpuset_mems_generation);
+               up(&callback_sem);
        }
        return retval;
 }
@@ -745,6 +798,8 @@ static int update_nodemask(struct cpuset *cs, char *buf)
  *                                             CS_NOTIFY_ON_RELEASE)
  * cs: the cpuset to update
  * buf:        the buffer where we read the 0 or 1
+ *
+ * Call with manage_sem held.
  */
 
 static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
@@ -766,16 +821,27 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
                return err;
        cpu_exclusive_changed =
                (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
+       down(&callback_sem);
        if (turning_on)
                set_bit(bit, &cs->flags);
        else
                clear_bit(bit, &cs->flags);
+       up(&callback_sem);
 
        if (cpu_exclusive_changed)
                 update_cpu_domains(cs);
        return 0;
 }
 
+/*
+ * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
+ * writing the path of the old cpuset in 'ppathbuf' if it needs to be
+ * notified on release.
+ *
+ * Call holding manage_sem.  May take callback_sem and task_lock of
+ * the task 'pid' during call.
+ */
+
 static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
 {
        pid_t pid;
@@ -792,7 +858,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
                read_lock(&tasklist_lock);
 
                tsk = find_task_by_pid(pid);
-               if (!tsk) {
+               if (!tsk || tsk->flags & PF_EXITING) {
                        read_unlock(&tasklist_lock);
                        return -ESRCH;
                }
@@ -810,10 +876,13 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
                get_task_struct(tsk);
        }
 
+       down(&callback_sem);
+
        task_lock(tsk);
        oldcs = tsk->cpuset;
        if (!oldcs) {
                task_unlock(tsk);
+               up(&callback_sem);
                put_task_struct(tsk);
                return -ESRCH;
        }
@@ -824,6 +893,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
        guarantee_online_cpus(cs, &cpus);
        set_cpus_allowed(tsk, cpus);
 
+       up(&callback_sem);
        put_task_struct(tsk);
        if (atomic_dec_and_test(&oldcs->count))
                check_for_release(oldcs, ppathbuf);
@@ -867,7 +937,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
        }
        buffer[nbytes] = 0;     /* nul-terminate */
 
-       cpuset_down(&cpuset_sem);
+       down(&manage_sem);
 
        if (is_removed(cs)) {
                retval = -ENODEV;
@@ -901,7 +971,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
        if (retval == 0)
                retval = nbytes;
 out2:
-       cpuset_up(&cpuset_sem);
+       up(&manage_sem);
        cpuset_release_agent(pathbuf);
 out1:
        kfree(buffer);
@@ -941,9 +1011,9 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
 {
        cpumask_t mask;
 
-       cpuset_down(&cpuset_sem);
+       down(&callback_sem);
        mask = cs->cpus_allowed;
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
 
        return cpulist_scnprintf(page, PAGE_SIZE, mask);
 }
@@ -952,9 +1022,9 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
 {
        nodemask_t mask;
 
-       cpuset_down(&cpuset_sem);
+       down(&callback_sem);
        mask = cs->mems_allowed;
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
 
        return nodelist_scnprintf(page, PAGE_SIZE, mask);
 }
@@ -995,7 +1065,6 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
                goto out;
        }
        *s++ = '\n';
-       *s = '\0';
 
        retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
 out:
@@ -1048,6 +1117,21 @@ static int cpuset_file_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+/*
+ * cpuset_rename - Only allow simple rename of directories in place.
+ */
+static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
+                  struct inode *new_dir, struct dentry *new_dentry)
+{
+       if (!S_ISDIR(old_dentry->d_inode->i_mode))
+               return -ENOTDIR;
+       if (new_dentry->d_inode)
+               return -EEXIST;
+       if (old_dir != new_dir)
+               return -EIO;
+       return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
 static struct file_operations cpuset_file_operations = {
        .read = cpuset_file_read,
        .write = cpuset_file_write,
@@ -1060,6 +1144,7 @@ static struct inode_operations cpuset_dir_inode_operations = {
        .lookup = simple_lookup,
        .mkdir = cpuset_mkdir,
        .rmdir = cpuset_rmdir,
+       .rename = cpuset_rename,
 };
 
 static int cpuset_create_file(struct dentry *dentry, int mode)
@@ -1163,7 +1248,9 @@ struct ctr_struct {
 
 /*
  * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded.
+ * Return actual number of pids loaded.  No need to task_lock(p)
+ * when reading out p->cpuset, as we don't really care if it changes
+ * on the next cycle, and we are not going to try to dereference it.
  */
 static inline int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
 {
@@ -1205,6 +1292,12 @@ static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
        return cnt;
 }
 
+/*
+ * Handle an open on 'tasks' file.  Prepare a buffer listing the
+ * process id's of tasks currently attached to the cpuset being opened.
+ *
+ * Does not require any specific cpuset semaphores, and does not take any.
+ */
 static int cpuset_tasks_open(struct inode *unused, struct file *file)
 {
        struct cpuset *cs = __d_cs(file->f_dentry->d_parent);
@@ -1352,7 +1445,8 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
        if (!cs)
                return -ENOMEM;
 
-       cpuset_down(&cpuset_sem);
+       down(&manage_sem);
+       refresh_mems();
        cs->flags = 0;
        if (notify_on_release(parent))
                set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1366,25 +1460,27 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
 
        cs->parent = parent;
 
+       down(&callback_sem);
        list_add(&cs->sibling, &cs->parent->children);
+       up(&callback_sem);
 
        err = cpuset_create_dir(cs, name, mode);
        if (err < 0)
                goto err;
 
        /*
-        * Release cpuset_sem before cpuset_populate_dir() because it
+        * Release manage_sem before cpuset_populate_dir() because it
         * will down() this new directory's i_sem and if we race with
         * another mkdir, we might deadlock.
         */
-       cpuset_up(&cpuset_sem);
+       up(&manage_sem);
 
        err = cpuset_populate_dir(cs->dentry);
        /* If err < 0, we have a half-filled directory - oh well ;) */
        return 0;
 err:
        list_del(&cs->sibling);
-       cpuset_up(&cpuset_sem);
+       up(&manage_sem);
        kfree(cs);
        return err;
 }
@@ -1406,29 +1502,32 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
 
        /* the vfs holds both inode->i_sem already */
 
-       cpuset_down(&cpuset_sem);
+       down(&manage_sem);
+       refresh_mems();
        if (atomic_read(&cs->count) > 0) {
-               cpuset_up(&cpuset_sem);
+               up(&manage_sem);
                return -EBUSY;
        }
        if (!list_empty(&cs->children)) {
-               cpuset_up(&cpuset_sem);
+               up(&manage_sem);
                return -EBUSY;
        }
        parent = cs->parent;
+       down(&callback_sem);
        set_bit(CS_REMOVED, &cs->flags);
        if (is_cpu_exclusive(cs))
                update_cpu_domains(cs);
        list_del(&cs->sibling); /* delete my sibling from parent->children */
-       if (list_empty(&parent->children))
-               check_for_release(parent, &pathbuf);
        spin_lock(&cs->dentry->d_lock);
        d = dget(cs->dentry);
        cs->dentry = NULL;
        spin_unlock(&d->d_lock);
        cpuset_d_remove_dir(d);
        dput(d);
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
+       if (list_empty(&parent->children))
+               check_for_release(parent, &pathbuf);
+       up(&manage_sem);
        cpuset_release_agent(pathbuf);
        return 0;
 }
@@ -1488,16 +1587,26 @@ void __init cpuset_init_smp(void)
  * cpuset_fork - attach newly forked task to its parents cpuset.
  * @tsk: pointer to task_struct of forking parent process.
  *
- * Description: By default, on fork, a task inherits its
- * parent's cpuset.  The pointer to the shared cpuset is
- * automatically copied in fork.c by dup_task_struct().
- * This cpuset_fork() routine need only increment the usage
- * counter in that cpuset.
+ * Description: A task inherits its parent's cpuset at fork().
+ *
+ * A pointer to the shared cpuset was automatically copied in fork.c
+ * by dup_task_struct().  However, we ignore that copy, since it was
+ * not made under the protection of task_lock(), so might no longer be
+ * a valid cpuset pointer.  attach_task() might have already changed
+ * current->cpuset, allowing the previously referenced cpuset to
+ * be removed and freed.  Instead, we task_lock(current) and copy
+ * its present value of current->cpuset for our freshly forked child.
+ *
+ * At the point that cpuset_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
  **/
 
-void cpuset_fork(struct task_struct *tsk)
+void cpuset_fork(struct task_struct *child)
 {
-       atomic_inc(&tsk->cpuset->count);
+       task_lock(current);
+       child->cpuset = current->cpuset;
+       atomic_inc(&child->cpuset->count);
+       task_unlock(current);
 }
 
 /**
@@ -1506,35 +1615,42 @@ void cpuset_fork(struct task_struct *tsk)
  *
  * Description: Detach cpuset from @tsk and release it.
  *
- * Note that cpusets marked notify_on_release force every task
- * in them to take the global cpuset_sem semaphore when exiting.
- * This could impact scaling on very large systems.  Be reluctant
- * to use notify_on_release cpusets where very high task exit
- * scaling is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use
- * count goes to zero, except inside a critical section guarded
- * by the cpuset_sem semaphore.  If you don't hold cpuset_sem,
- * then a zero cpuset use count is a license to any other task to
- * nuke the cpuset immediately.
+ * Note that cpusets marked notify_on_release force every task in
+ * them to take the global manage_sem semaphore when exiting.
+ * This could impact scaling on very large systems.  Be reluctant to
+ * use notify_on_release cpusets where very high task exit scaling
+ * is required on large systems.
+ *
+ * Don't even think about derefencing 'cs' after the cpuset use count
+ * goes to zero, except inside a critical section guarded by manage_sem
+ * or callback_sem.   Otherwise a zero cpuset use count is a license to
+ * any other task to nuke the cpuset immediately, via cpuset_rmdir().
+ *
+ * This routine has to take manage_sem, not callback_sem, because
+ * it is holding that semaphore while calling check_for_release(),
+ * which calls kmalloc(), so can't be called holding callback__sem().
+ *
+ * We don't need to task_lock() this reference to tsk->cpuset,
+ * because tsk is already marked PF_EXITING, so attach_task() won't
+ * mess with it.
  **/
 
 void cpuset_exit(struct task_struct *tsk)
 {
        struct cpuset *cs;
 
-       task_lock(tsk);
+       BUG_ON(!(tsk->flags & PF_EXITING));
+
        cs = tsk->cpuset;
        tsk->cpuset = NULL;
-       task_unlock(tsk);
 
        if (notify_on_release(cs)) {
                char *pathbuf = NULL;
 
-               cpuset_down(&cpuset_sem);
+               down(&manage_sem);
                if (atomic_dec_and_test(&cs->count))
                        check_for_release(cs, &pathbuf);
-               cpuset_up(&cpuset_sem);
+               up(&manage_sem);
                cpuset_release_agent(pathbuf);
        } else {
                atomic_dec(&cs->count);
@@ -1555,11 +1671,11 @@ cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk)
 {
        cpumask_t mask;
 
-       cpuset_down(&cpuset_sem);
+       down(&callback_sem);
        task_lock((struct task_struct *)tsk);
        guarantee_online_cpus(tsk->cpuset, &mask);
        task_unlock((struct task_struct *)tsk);
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
 
        return mask;
 }
@@ -1575,19 +1691,28 @@ void cpuset_init_current_mems_allowed(void)
  * If the current tasks cpusets mems_allowed changed behind our backs,
  * update current->mems_allowed and mems_generation to the new value.
  * Do not call this routine if in_interrupt().
+ *
+ * Call without callback_sem or task_lock() held.  May be called
+ * with or without manage_sem held.  Unless exiting, it will acquire
+ * task_lock().  Also might acquire callback_sem during call to
+ * refresh_mems().
  */
 
 void cpuset_update_current_mems_allowed(void)
 {
-       struct cpuset *cs = current->cpuset;
+       struct cpuset *cs;
+       int need_to_refresh = 0;
 
+       task_lock(current);
+       cs = current->cpuset;
        if (!cs)
-               return;         /* task is exiting */
-       if (current->cpuset_mems_generation != cs->mems_generation) {
-               cpuset_down(&cpuset_sem);
+               goto done;
+       if (current->cpuset_mems_generation != cs->mems_generation)
+               need_to_refresh = 1;
+done:
+       task_unlock(current);
+       if (need_to_refresh)
                refresh_mems();
-               cpuset_up(&cpuset_sem);
-       }
 }
 
 /**
@@ -1621,7 +1746,7 @@ int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
 
 /*
  * nearest_exclusive_ancestor() - Returns the nearest mem_exclusive
- * ancestor to the specified cpuset.  Call while holding cpuset_sem.
+ * ancestor to the specified cpuset.  Call holding callback_sem.
  * If no ancestor is mem_exclusive (an unusual configuration), then
  * returns the root cpuset.
  */
@@ -1648,12 +1773,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
  * GFP_KERNEL allocations are not so marked, so can escape to the
  * nearest mem_exclusive ancestor cpuset.
  *
- * Scanning up parent cpusets requires cpuset_sem.  The __alloc_pages()
+ * Scanning up parent cpusets requires callback_sem.  The __alloc_pages()
  * routine only calls here with __GFP_HARDWALL bit _not_ set if
  * it's a GFP_KERNEL allocation, and all nodes in the current tasks
  * mems_allowed came up empty on the first pass over the zonelist.
  * So only GFP_KERNEL allocations, if all nodes in the cpuset are
- * short of memory, might require taking the cpuset_sem semaphore.
+ * short of memory, might require taking the callback_sem semaphore.
  *
  * The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
  * calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
@@ -1685,14 +1810,16 @@ int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
                return 0;
 
        /* Not hardwall and node outside mems_allowed: scan up cpusets */
-       cpuset_down(&cpuset_sem);
-       cs = current->cpuset;
-       if (!cs)
-               goto done;              /* current task exiting */
-       cs = nearest_exclusive_ancestor(cs);
+       down(&callback_sem);
+
+       if (current->flags & PF_EXITING) /* Let dying task have memory */
+               return 1;
+       task_lock(current);
+       cs = nearest_exclusive_ancestor(current->cpuset);
+       task_unlock(current);
+
        allowed = node_isset(node, cs->mems_allowed);
-done:
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
        return allowed;
 }
 
@@ -1705,7 +1832,7 @@ done:
  * determine if task @p's memory usage might impact the memory
  * available to the current task.
  *
- * Acquires cpuset_sem - not suitable for calling from a fast path.
+ * Acquires callback_sem - not suitable for calling from a fast path.
  **/
 
 int cpuset_excl_nodes_overlap(const struct task_struct *p)
@@ -1713,18 +1840,27 @@ int cpuset_excl_nodes_overlap(const struct task_struct *p)
        const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
        int overlap = 0;                /* do cpusets overlap? */
 
-       cpuset_down(&cpuset_sem);
-       cs1 = current->cpuset;
-       if (!cs1)
-               goto done;              /* current task exiting */
-       cs2 = p->cpuset;
-       if (!cs2)
-               goto done;              /* task p is exiting */
-       cs1 = nearest_exclusive_ancestor(cs1);
-       cs2 = nearest_exclusive_ancestor(cs2);
+       down(&callback_sem);
+
+       task_lock(current);
+       if (current->flags & PF_EXITING) {
+               task_unlock(current);
+               goto done;
+       }
+       cs1 = nearest_exclusive_ancestor(current->cpuset);
+       task_unlock(current);
+
+       task_lock((struct task_struct *)p);
+       if (p->flags & PF_EXITING) {
+               task_unlock((struct task_struct *)p);
+               goto done;
+       }
+       cs2 = nearest_exclusive_ancestor(p->cpuset);
+       task_unlock((struct task_struct *)p);
+
        overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
 done:
-       cpuset_up(&cpuset_sem);
+       up(&callback_sem);
 
        return overlap;
 }
@@ -1733,6 +1869,10 @@ done:
  * proc_cpuset_show()
  *  - Print tasks cpuset path into seq_file.
  *  - Used for /proc/<pid>/cpuset.
+ *  - No need to task_lock(tsk) on this tsk->cpuset reference, as it
+ *    doesn't really matter if tsk->cpuset changes after we read it,
+ *    and we take manage_sem, keeping attach_task() from changing it
+ *    anyway.
  */
 
 static int proc_cpuset_show(struct seq_file *m, void *v)
@@ -1747,10 +1887,8 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
                return -ENOMEM;
 
        tsk = m->private;
-       cpuset_down(&cpuset_sem);
-       task_lock(tsk);
+       down(&manage_sem);
        cs = tsk->cpuset;
-       task_unlock(tsk);
        if (!cs) {
                retval = -EINVAL;
                goto out;
@@ -1762,7 +1900,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
        seq_puts(m, buf);
        seq_putc(m, '\n');
 out:
-       cpuset_up(&cpuset_sem);
+       up(&manage_sem);
        kfree(buf);
        return retval;
 }
index 79f52b85d6ed92eb80bec6f9d677aecd1b39ef22..537394b25e8d9a6d1e108ae0f78cbb3fab317769 100644 (file)
@@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
 
        if (p->pdeath_signal)
                /* We already hold the tasklist_lock here.  */
-               group_send_sig_info(p->pdeath_signal, (void *) 0, p);
+               group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
 
        /* Move the child from its dying parent to the new one.  */
        if (unlikely(traced)) {
@@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced)
                int pgrp = process_group(p);
 
                if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) {
-                       __kill_pg_info(SIGHUP, (void *)1, pgrp);
-                       __kill_pg_info(SIGCONT, (void *)1, pgrp);
+                       __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp);
+                       __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp);
                }
        }
 }
@@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk)
            (t->signal->session == tsk->signal->session) &&
            will_become_orphaned_pgrp(process_group(tsk), tsk) &&
            has_stopped_jobs(process_group(tsk))) {
-               __kill_pg_info(SIGHUP, (void *)1, process_group(tsk));
-               __kill_pg_info(SIGCONT, (void *)1, process_group(tsk));
+               __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk));
+               __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk));
        }
 
        /* Let father know we died 
@@ -783,10 +783,6 @@ static void exit_notify(struct task_struct *tsk)
        /* If the process is dead, release it - nobody will wait for it */
        if (state == EXIT_DEAD)
                release_task(tsk);
-
-       /* PF_DEAD causes final put_task_struct after we schedule. */
-       preempt_disable();
-       tsk->flags |= PF_DEAD;
 }
 
 fastcall NORET_TYPE void do_exit(long code)
@@ -873,7 +869,11 @@ fastcall NORET_TYPE void do_exit(long code)
        tsk->mempolicy = NULL;
 #endif
 
-       BUG_ON(!(current->flags & PF_DEAD));
+       /* PF_DEAD causes final put_task_struct after we schedule. */
+       preempt_disable();
+       BUG_ON(tsk->flags & PF_DEAD);
+       tsk->flags |= PF_DEAD;
+
        schedule();
        BUG();
        /* Avoid "noreturn function does return".  */
@@ -1383,6 +1383,15 @@ repeat:
 
                        switch (p->state) {
                        case TASK_TRACED:
+                               /*
+                                * When we hit the race with PTRACE_ATTACH,
+                                * we will not report this child.  But the
+                                * race means it has not yet been moved to
+                                * our ptrace_children list, so we need to
+                                * set the flag here to avoid a spurious ECHILD
+                                * when the race happens with the only child.
+                                */
+                               flag = 1;
                                if (!my_ptrace_child(p))
                                        continue;
                                /*FALLTHROUGH*/
index 13bcec151b57f8ebc68f1665a688f200f8c63d89..39277dd6bf90911916db77f2370e2db3a6e070f4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/err.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>       /* for cond_resched */
 #include <linux/mm.h>
 
 #include <asm/sections.h>
index 44166e3bb8afab469a61575946b46da45e215cc7..51a892063aaaa2f5b1dfa1cf9f6667dcef88cd68 100644 (file)
@@ -131,14 +131,14 @@ struct subprocess_info {
 static int ____call_usermodehelper(void *data)
 {
        struct subprocess_info *sub_info = data;
-       struct key *old_session;
+       struct key *new_session, *old_session;
        int retval;
 
        /* Unblock all signals and set the session keyring. */
-       key_get(sub_info->ring);
+       new_session = key_get(sub_info->ring);
        flush_signals(current);
        spin_lock_irq(&current->sighand->siglock);
-       old_session = __install_session_keyring(current, sub_info->ring);
+       old_session = __install_session_keyring(current, new_session);
        flush_signal_handlers(current, 1);
        sigemptyset(&current->blocked);
        recalc_sigpending();
index f3ea492ab44dfcfc05e2fad4027e303f9b69d9dd..ce4915dd683a3f35b120a31e1b1a356beb2fb94c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/hash.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/moduleloader.h>
 #include <asm-generic/sections.h>
index f50f174e92da1d6414c127fb0b8ee7567faa26dd..e75950a1092c6b2063ea24a1f196f987e7f21bf5 100644 (file)
@@ -164,6 +164,12 @@ void kthread_bind(struct task_struct *k, unsigned int cpu)
 EXPORT_SYMBOL(kthread_bind);
 
 int kthread_stop(struct task_struct *k)
+{
+       return kthread_stop_sem(k, NULL);
+}
+EXPORT_SYMBOL(kthread_stop);
+
+int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
 {
        int ret;
 
@@ -178,7 +184,10 @@ int kthread_stop(struct task_struct *k)
 
        /* Now set kthread_should_stop() to true, and wake it up. */
        kthread_stop_info.k = k;
-       wake_up_process(k);
+       if (s)
+               up(s);
+       else
+               wake_up_process(k);
        put_task_struct(k);
 
        /* Once it dies, reset stop ptr, gather result and we're done. */
@@ -189,7 +198,7 @@ int kthread_stop(struct task_struct *k)
 
        return ret;
 }
-EXPORT_SYMBOL(kthread_stop);
+EXPORT_SYMBOL(kthread_stop_sem);
 
 static __init int helper_init(void)
 {
index 1a8614bac5d5c819110ae67bd21efca75845b600..47ba69547945a7ffcec55a7fc72f8ae35a9c4c77 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #if 0
 #define DEBUGP printk
index bf374fceb39c3718315a73eed65cbd0e960a5e7f..91a8942649413f48916196f4aed68deed9a1ae2b 100644 (file)
@@ -1225,7 +1225,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                /*
                 * The task was cleaned up already, no future firings.
                 */
-               return;
+               goto out;
 
        /*
         * Fetch the current sample and update the timer's expiry time.
@@ -1235,7 +1235,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                bump_cpu_timer(timer, now);
                if (unlikely(p->exit_state)) {
                        clear_dead_task(timer, now);
-                       return;
+                       goto out;
                }
                read_lock(&tasklist_lock); /* arm_timer needs it.  */
        } else {
@@ -1248,8 +1248,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                        put_task_struct(p);
                        timer->it.cpu.task = p = NULL;
                        timer->it.cpu.expires.sched = 0;
-                       read_unlock(&tasklist_lock);
-                       return;
+                       goto out_unlock;
                } else if (unlikely(p->exit_state) && thread_group_empty(p)) {
                        /*
                         * We've noticed that the thread is dead, but
@@ -1257,8 +1256,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                         * drop our task ref.
                         */
                        clear_dead_task(timer, now);
-                       read_unlock(&tasklist_lock);
-                       return;
+                       goto out_unlock;
                }
                cpu_clock_sample_group(timer->it_clock, p, &now);
                bump_cpu_timer(timer, now);
@@ -1270,7 +1268,13 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
         */
        arm_timer(timer, now);
 
+out_unlock:
        read_unlock(&tasklist_lock);
+
+out:
+       timer->it_overrun_last = timer->it_overrun;
+       timer->it_overrun = -1;
+       ++timer->it_requeue_pending;
 }
 
 /*
index dda3cda73c77c2be60611c6650d4b82e171cdd45..ea55c7a1cd75a3dbaa50040b3d55255c12a5786f 100644 (file)
@@ -1295,13 +1295,6 @@ sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
        return error;
 }
 
-static void nanosleep_wake_up(unsigned long __data)
-{
-       struct task_struct *p = (struct task_struct *) __data;
-
-       wake_up_process(p);
-}
-
 /*
  * The standard says that an absolute nanosleep call MUST wake up at
  * the requested time in spite of clock settings.  Here is what we do:
@@ -1442,7 +1435,6 @@ static int common_nsleep(clockid_t which_clock,
                         int flags, struct timespec *tsave)
 {
        struct timespec t, dum;
-       struct timer_list new_timer;
        DECLARE_WAITQUEUE(abs_wqueue, current);
        u64 rq_time = (u64)0;
        s64 left;
@@ -1451,10 +1443,6 @@ static int common_nsleep(clockid_t which_clock,
            &current_thread_info()->restart_block;
 
        abs_wqueue.flags = 0;
-       init_timer(&new_timer);
-       new_timer.expires = 0;
-       new_timer.data = (unsigned long) current;
-       new_timer.function = nanosleep_wake_up;
        abs = flags & TIMER_ABSTIME;
 
        if (restart_block->fn == clock_nanosleep_restart) {
@@ -1490,13 +1478,8 @@ static int common_nsleep(clockid_t which_clock,
                if (left < (s64)0)
                        break;
 
-               new_timer.expires = jiffies + left;
-               __set_current_state(TASK_INTERRUPTIBLE);
-               add_timer(&new_timer);
-
-               schedule();
+               schedule_timeout_interruptible(left);
 
-               del_timer_sync(&new_timer);
                left = rq_time - get_jiffies_64();
        } while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
 
index 2f438d0eaa13640a91ec78acc086c559bc523060..c71eb4579c079040265dced9de7e97a82d7c27f3 100644 (file)
@@ -4,7 +4,7 @@ EXTRA_CFLAGS    +=      -DDEBUG
 endif
 
 obj-y                          := main.o process.o console.o pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o
 
 obj-$(CONFIG_SUSPEND_SMP)      += smp.o
 
index 761956e813f51b8dd37f3670a9ab74e1f4536cf7..027322a564f48ac2c79c08ab9240a5db7b42751f 100644 (file)
@@ -30,7 +30,6 @@ extern int swsusp_check(void);
 extern int swsusp_read(void);
 extern void swsusp_close(void);
 extern int swsusp_resume(void);
-extern int swsusp_free(void);
 
 
 static int noresume = 0;
@@ -93,10 +92,7 @@ static void free_some_memory(void)
        printk("Freeing memory...  ");
        while ((tmp = shrink_all_memory(10000))) {
                pages += tmp;
-               printk("\b%c", p[i]);
-               i++;
-               if (i > 3)
-                       i = 0;
+               printk("\b%c", p[i++ % 4]);
        }
        printk("\bdone (%li pages freed)\n", pages);
 }
@@ -178,13 +174,12 @@ int pm_suspend_disk(void)
                goto Done;
 
        if (in_suspend) {
+               device_resume();
                pr_debug("PM: writing image.\n");
                error = swsusp_write();
                if (!error)
                        power_down(pm_disk_mode);
                else {
-               /* swsusp_write can not fail in device_resume,
-                  no need to do second device_resume */
                        swsusp_free();
                        unprepare_processes();
                        return error;
@@ -252,14 +247,17 @@ static int software_resume(void)
 
        pr_debug("PM: Reading swsusp image.\n");
 
-       if ((error = swsusp_read()))
-               goto Cleanup;
+       if ((error = swsusp_read())) {
+               swsusp_free();
+               goto Thaw;
+       }
 
        pr_debug("PM: Preparing devices for restore.\n");
 
        if ((error = device_suspend(PMSG_FREEZE))) {
                printk("Some devices failed to suspend\n");
-               goto Free;
+               swsusp_free();
+               goto Thaw;
        }
 
        mb();
@@ -268,9 +266,7 @@ static int software_resume(void)
        swsusp_resume();
        pr_debug("PM: Restore failed, recovering.n");
        device_resume();
- Free:
-       swsusp_free();
- Cleanup:
+ Thaw:
        unprepare_processes();
  Done:
        /* For success case, the suspend path will release the lock */
index 22bdc93cc03885096a5e29755e5f3f5aeadee68a..18d7d693fbba852c48acc40de4ad8809baf5d36e 100644 (file)
@@ -167,6 +167,8 @@ static int enter_state(suspend_state_t state)
 {
        int error;
 
+       if (pm_ops->valid && !pm_ops->valid(state))
+               return -ENODEV;
        if (down_trylock(&pm_sem))
                return -EBUSY;
 
@@ -236,7 +238,8 @@ static ssize_t state_show(struct subsystem * subsys, char * buf)
        char * s = buf;
 
        for (i = 0; i < PM_SUSPEND_MAX; i++) {
-               if (pm_states[i])
+               if (pm_states[i] && pm_ops && (!pm_ops->valid
+                       ||(pm_ops->valid && pm_ops->valid(i))))
                        s += sprintf(s,"%s ",pm_states[i]);
        }
        s += sprintf(s,"\n");
index 6748de23e83ce95f011061507e441ebb38a45498..d4fd96a135abeb7f1e84314469934976bae018f5 100644 (file)
@@ -53,3 +53,20 @@ extern void thaw_processes(void);
 
 extern int pm_prepare_console(void);
 extern void pm_restore_console(void);
+
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+extern unsigned int nr_copy_pages;
+extern suspend_pagedir_t *pagedir_nosave;
+extern suspend_pagedir_t *pagedir_save;
+
+extern asmlinkage int swsusp_arch_suspend(void);
+extern asmlinkage int swsusp_arch_resume(void);
+
+extern int restore_highmem(void);
+extern struct pbe * alloc_pagedir(unsigned nr_pages);
+extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
+extern void swsusp_free(void);
+extern int enough_swap(unsigned nr_pages);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
new file mode 100644 (file)
index 0000000..42a6287
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * linux/kernel/power/snapshot.c
+ *
+ * This file provide system snapshot/restore functionality.
+ *
+ * Copyright (C) 1998-2005 Pavel Machek <pavel@suse.cz>
+ *
+ * This file is released under the GPLv2, and is based on swsusp.c.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/bootmem.h>
+#include <linux/syscalls.h>
+#include <linux/console.h>
+#include <linux/highmem.h>
+
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/io.h>
+
+#include "power.h"
+
+#ifdef CONFIG_HIGHMEM
+struct highmem_page {
+       char *data;
+       struct page *page;
+       struct highmem_page *next;
+};
+
+static struct highmem_page *highmem_copy;
+
+static int save_highmem_zone(struct zone *zone)
+{
+       unsigned long zone_pfn;
+       mark_free_pages(zone);
+       for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+               struct page *page;
+               struct highmem_page *save;
+               void *kaddr;
+               unsigned long pfn = zone_pfn + zone->zone_start_pfn;
+
+               if (!(pfn%1000))
+                       printk(".");
+               if (!pfn_valid(pfn))
+                       continue;
+               page = pfn_to_page(pfn);
+               /*
+                * This condition results from rvmalloc() sans vmalloc_32()
+                * and architectural memory reservations. This should be
+                * corrected eventually when the cases giving rise to this
+                * are better understood.
+                */
+               if (PageReserved(page)) {
+                       printk("highmem reserved page?!\n");
+                       continue;
+               }
+               BUG_ON(PageNosave(page));
+               if (PageNosaveFree(page))
+                       continue;
+               save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
+               if (!save)
+                       return -ENOMEM;
+               save->next = highmem_copy;
+               save->page = page;
+               save->data = (void *) get_zeroed_page(GFP_ATOMIC);
+               if (!save->data) {
+                       kfree(save);
+                       return -ENOMEM;
+               }
+               kaddr = kmap_atomic(page, KM_USER0);
+               memcpy(save->data, kaddr, PAGE_SIZE);
+               kunmap_atomic(kaddr, KM_USER0);
+               highmem_copy = save;
+       }
+       return 0;
+}
+
+
+static int save_highmem(void)
+{
+       struct zone *zone;
+       int res = 0;
+
+       pr_debug("swsusp: Saving Highmem\n");
+       for_each_zone (zone) {
+               if (is_highmem(zone))
+                       res = save_highmem_zone(zone);
+               if (res)
+                       return res;
+       }
+       return 0;
+}
+
+int restore_highmem(void)
+{
+       printk("swsusp: Restoring Highmem\n");
+       while (highmem_copy) {
+               struct highmem_page *save = highmem_copy;
+               void *kaddr;
+               highmem_copy = save->next;
+
+               kaddr = kmap_atomic(save->page, KM_USER0);
+               memcpy(kaddr, save->data, PAGE_SIZE);
+               kunmap_atomic(kaddr, KM_USER0);
+               free_page((long) save->data);
+               kfree(save);
+       }
+       return 0;
+}
+#else
+static int save_highmem(void) { return 0; }
+int restore_highmem(void) { return 0; }
+#endif /* CONFIG_HIGHMEM */
+
+
+static int pfn_is_nosave(unsigned long pfn)
+{
+       unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+       unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+       return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
+
+/**
+ *     saveable - Determine whether a page should be cloned or not.
+ *     @pfn:   The page
+ *
+ *     We save a page if it's Reserved, and not in the range of pages
+ *     statically defined as 'unsaveable', or if it isn't reserved, and
+ *     isn't part of a free chunk of pages.
+ */
+
+static int saveable(struct zone *zone, unsigned long *zone_pfn)
+{
+       unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
+       struct page *page;
+
+       if (!pfn_valid(pfn))
+               return 0;
+
+       page = pfn_to_page(pfn);
+       BUG_ON(PageReserved(page) && PageNosave(page));
+       if (PageNosave(page))
+               return 0;
+       if (PageReserved(page) && pfn_is_nosave(pfn)) {
+               pr_debug("[nosave pfn 0x%lx]", pfn);
+               return 0;
+       }
+       if (PageNosaveFree(page))
+               return 0;
+
+       return 1;
+}
+
+static unsigned count_data_pages(void)
+{
+       struct zone *zone;
+       unsigned long zone_pfn;
+       unsigned n;
+
+       n = 0;
+       for_each_zone (zone) {
+               if (is_highmem(zone))
+                       continue;
+               mark_free_pages(zone);
+               for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+                       n += saveable(zone, &zone_pfn);
+       }
+       return n;
+}
+
+static void copy_data_pages(struct pbe *pblist)
+{
+       struct zone *zone;
+       unsigned long zone_pfn;
+       struct pbe *pbe, *p;
+
+       pbe = pblist;
+       for_each_zone (zone) {
+               if (is_highmem(zone))
+                       continue;
+               mark_free_pages(zone);
+               /* This is necessary for swsusp_free() */
+               for_each_pb_page (p, pblist)
+                       SetPageNosaveFree(virt_to_page(p));
+               for_each_pbe (p, pblist)
+                       SetPageNosaveFree(virt_to_page(p->address));
+               for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
+                       if (saveable(zone, &zone_pfn)) {
+                               struct page *page;
+                               page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+                               BUG_ON(!pbe);
+                               pbe->orig_address = (unsigned long)page_address(page);
+                               /* copy_page is not usable for copying task structs. */
+                               memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
+                               pbe = pbe->next;
+                       }
+               }
+       }
+       BUG_ON(pbe);
+}
+
+
+/**
+ *     free_pagedir - free pages allocated with alloc_pagedir()
+ */
+
+static void free_pagedir(struct pbe *pblist)
+{
+       struct pbe *pbe;
+
+       while (pblist) {
+               pbe = (pblist + PB_PAGE_SKIP)->next;
+               ClearPageNosave(virt_to_page(pblist));
+               ClearPageNosaveFree(virt_to_page(pblist));
+               free_page((unsigned long)pblist);
+               pblist = pbe;
+       }
+}
+
+/**
+ *     fill_pb_page - Create a list of PBEs on a given memory page
+ */
+
+static inline void fill_pb_page(struct pbe *pbpage)
+{
+       struct pbe *p;
+
+       p = pbpage;
+       pbpage += PB_PAGE_SKIP;
+       do
+               p->next = p + 1;
+       while (++p < pbpage);
+}
+
+/**
+ *     create_pbe_list - Create a list of PBEs on top of a given chain
+ *     of memory pages allocated with alloc_pagedir()
+ */
+
+void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
+{
+       struct pbe *pbpage, *p;
+       unsigned num = PBES_PER_PAGE;
+
+       for_each_pb_page (pbpage, pblist) {
+               if (num >= nr_pages)
+                       break;
+
+               fill_pb_page(pbpage);
+               num += PBES_PER_PAGE;
+       }
+       if (pbpage) {
+               for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
+                       p->next = p + 1;
+               p->next = NULL;
+       }
+       pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
+}
+
+static void *alloc_image_page(void)
+{
+       void *res = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
+       if (res) {
+               SetPageNosave(virt_to_page(res));
+               SetPageNosaveFree(virt_to_page(res));
+       }
+       return res;
+}
+
+/**
+ *     alloc_pagedir - Allocate the page directory.
+ *
+ *     First, determine exactly how many pages we need and
+ *     allocate them.
+ *
+ *     We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
+ *     struct pbe elements (pbes) and the last element in the page points
+ *     to the next page.
+ *
+ *     On each page we set up a list of struct_pbe elements.
+ */
+
+struct pbe *alloc_pagedir(unsigned nr_pages)
+{
+       unsigned num;
+       struct pbe *pblist, *pbe;
+
+       if (!nr_pages)
+               return NULL;
+
+       pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
+       pblist = alloc_image_page();
+       /* FIXME: rewrite this ugly loop */
+       for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
+                       pbe = pbe->next, num += PBES_PER_PAGE) {
+               pbe += PB_PAGE_SKIP;
+               pbe->next = alloc_image_page();
+       }
+       if (!pbe) { /* get_zeroed_page() failed */
+               free_pagedir(pblist);
+               pblist = NULL;
+        }
+       return pblist;
+}
+
+/**
+ * Free pages we allocated for suspend. Suspend pages are alocated
+ * before atomic copy, so we need to free them after resume.
+ */
+
+void swsusp_free(void)
+{
+       struct zone *zone;
+       unsigned long zone_pfn;
+
+       for_each_zone(zone) {
+               for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+                       if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
+                               struct page * page;
+                               page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
+                               if (PageNosave(page) && PageNosaveFree(page)) {
+                                       ClearPageNosave(page);
+                                       ClearPageNosaveFree(page);
+                                       free_page((long) page_address(page));
+                               }
+                       }
+       }
+}
+
+
+/**
+ *     enough_free_mem - Make sure we enough free memory to snapshot.
+ *
+ *     Returns TRUE or FALSE after checking the number of available
+ *     free pages.
+ */
+
+static int enough_free_mem(unsigned nr_pages)
+{
+       pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
+       return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
+               (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
+
+static struct pbe *swsusp_alloc(unsigned nr_pages)
+{
+       struct pbe *pblist, *p;
+
+       if (!(pblist = alloc_pagedir(nr_pages))) {
+               printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
+               return NULL;
+       }
+       create_pbe_list(pblist, nr_pages);
+
+       for_each_pbe (p, pblist) {
+               p->address = (unsigned long)alloc_image_page();
+               if (!p->address) {
+                       printk(KERN_ERR "suspend: Allocating image pages failed.\n");
+                       swsusp_free();
+                       return NULL;
+               }
+       }
+
+       return pblist;
+}
+
+asmlinkage int swsusp_save(void)
+{
+       unsigned nr_pages;
+
+       pr_debug("swsusp: critical section: \n");
+       if (save_highmem()) {
+               printk(KERN_CRIT "swsusp: Not enough free pages for highmem\n");
+               restore_highmem();
+               return -ENOMEM;
+       }
+
+       drain_local_pages();
+       nr_pages = count_data_pages();
+       printk("swsusp: Need to copy %u pages\n", nr_pages);
+
+       pr_debug("swsusp: pages needed: %u + %lu + %u, free: %u\n",
+                nr_pages,
+                (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
+                PAGES_FOR_IO, nr_free_pages());
+
+       /* This is needed because of the fixed size of swsusp_info */
+       if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE)
+               return -ENOSPC;
+
+       if (!enough_free_mem(nr_pages)) {
+               printk(KERN_ERR "swsusp: Not enough free memory\n");
+               return -ENOMEM;
+       }
+
+       if (!enough_swap(nr_pages)) {
+               printk(KERN_ERR "swsusp: Not enough free swap\n");
+               return -ENOSPC;
+       }
+
+       pagedir_nosave = swsusp_alloc(nr_pages);
+       if (!pagedir_nosave)
+               return -ENOMEM;
+
+       /* During allocating of suspend pagedir, new cold pages may appear.
+        * Kill them.
+        */
+       drain_local_pages();
+       copy_data_pages(pagedir_nosave);
+
+       /*
+        * End of critical section. From now on, we can write to memory,
+        * but we should not touch disk. This specially means we must _not_
+        * touch swap space! Except we must write out our image of course.
+        */
+
+       nr_copy_pages = nr_pages;
+
+       printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages);
+       return 0;
+}
index 016504ccfccf4e6e37d97015d0f4026a51d52299..12db1d2ad61f89e5667f21f339b2bd9c3fd3969f 100644 (file)
@@ -1,11 +1,10 @@
 /*
  * linux/kernel/power/swsusp.c
  *
- * This file is to realize architecture-independent
- * machine suspend feature using pretty near only high-level routines
+ * This file provides code to write suspend image to swap and read it back.
  *
  * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
- * Copyright (C) 1998,2001-2004 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
  *
  * This file is released under the GPLv2.
  *
 #include <linux/utsname.h>
 #include <linux/version.h>
 #include <linux/delay.h>
-#include <linux/reboot.h>
 #include <linux/bitops.h>
-#include <linux/vt_kern.h>
-#include <linux/kbd_kern.h>
-#include <linux/keyboard.h>
 #include <linux/spinlock.h>
 #include <linux/genhd.h>
 #include <linux/kernel.h>
 #include <linux/swapops.h>
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
-#include <linux/console.h>
 #include <linux/highmem.h>
 #include <linux/bio.h>
-#include <linux/mount.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #define MAXKEY 32
 #define MAXIV  32
 
-/* References to section boundaries */
-extern const void __nosave_begin, __nosave_end;
-
-/* Variables to be preserved over suspend */
-static int nr_copy_pages_check;
-
 extern char resume_file[];
 
 /* Local variables that should not be affected by save */
-static unsigned int nr_copy_pages __nosavedata = 0;
+unsigned int nr_copy_pages __nosavedata = 0;
 
 /* Suspend pagedir is allocated before final copy, therefore it
    must be freed after resume
@@ -109,7 +96,7 @@ static unsigned int nr_copy_pages __nosavedata = 0;
    MMU hardware.
  */
 suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-static suspend_pagedir_t *pagedir_save;
+suspend_pagedir_t *pagedir_save;
 
 #define SWSUSP_SIG     "S1SUSPEND"
 
@@ -123,12 +110,6 @@ static struct swsusp_header {
 
 static struct swsusp_info swsusp_info;
 
-/*
- * XXX: We try to keep some more pages free so that I/O operations succeed
- * without paging. Might this be more?
- */
-#define PAGES_FOR_IO   512
-
 /*
  * Saving part...
  */
@@ -552,353 +533,6 @@ static int write_suspend_image(void)
        goto Done;
 }
 
-
-#ifdef CONFIG_HIGHMEM
-struct highmem_page {
-       char *data;
-       struct page *page;
-       struct highmem_page *next;
-};
-
-static struct highmem_page *highmem_copy;
-
-static int save_highmem_zone(struct zone *zone)
-{
-       unsigned long zone_pfn;
-       mark_free_pages(zone);
-       for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
-               struct page *page;
-               struct highmem_page *save;
-               void *kaddr;
-               unsigned long pfn = zone_pfn + zone->zone_start_pfn;
-
-               if (!(pfn%1000))
-                       printk(".");
-               if (!pfn_valid(pfn))
-                       continue;
-               page = pfn_to_page(pfn);
-               /*
-                * PageReserved results from rvmalloc() sans vmalloc_32()
-                * and architectural memory reservations.
-                *
-                * rvmalloc should not cause this, because all implementations
-                * appear to always be using vmalloc_32 on architectures with
-                * highmem. This is a good thing, because we would like to save
-                * rvmalloc pages.
-                *
-                * It appears to be triggered by pages which do not point to
-                * valid memory (see arch/i386/mm/init.c:one_highpage_init(),
-                * which sets PageReserved if the page does not point to valid
-                * RAM.
-                *
-                * XXX: must remove usage of PageReserved!
-                */
-               if (PageReserved(page))
-                       continue;
-               BUG_ON(PageNosave(page));
-               if (PageNosaveFree(page))
-                       continue;
-               save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
-               if (!save)
-                       return -ENOMEM;
-               save->next = highmem_copy;
-               save->page = page;
-               save->data = (void *) get_zeroed_page(GFP_ATOMIC);
-               if (!save->data) {
-                       kfree(save);
-                       return -ENOMEM;
-               }
-               kaddr = kmap_atomic(page, KM_USER0);
-               memcpy(save->data, kaddr, PAGE_SIZE);
-               kunmap_atomic(kaddr, KM_USER0);
-               highmem_copy = save;
-       }
-       return 0;
-}
-#endif /* CONFIG_HIGHMEM */
-
-
-static int save_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
-       struct zone *zone;
-       int res = 0;
-
-       pr_debug("swsusp: Saving Highmem\n");
-       for_each_zone (zone) {
-               if (is_highmem(zone))
-                       res = save_highmem_zone(zone);
-               if (res)
-                       return res;
-       }
-#endif
-       return 0;
-}
-
-static int restore_highmem(void)
-{
-#ifdef CONFIG_HIGHMEM
-       printk("swsusp: Restoring Highmem\n");
-       while (highmem_copy) {
-               struct highmem_page *save = highmem_copy;
-               void *kaddr;
-               highmem_copy = save->next;
-
-               kaddr = kmap_atomic(save->page, KM_USER0);
-               memcpy(kaddr, save->data, PAGE_SIZE);
-               kunmap_atomic(kaddr, KM_USER0);
-               free_page((long) save->data);
-               kfree(save);
-       }
-#endif
-       return 0;
-}
-
-
-static int pfn_is_nosave(unsigned long pfn)
-{
-       unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
-       unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
-       return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
-}
-
-/**
- *     saveable - Determine whether a page should be cloned or not.
- *     @pfn:   The page
- *
- *     We save a page if it's Reserved, and not in the range of pages
- *     statically defined as 'unsaveable', or if it isn't reserved, and
- *     isn't part of a free chunk of pages.
- */
-
-static int saveable(struct zone * zone, unsigned long * zone_pfn)
-{
-       unsigned long pfn = *zone_pfn + zone->zone_start_pfn;
-       struct page * page;
-
-       if (!pfn_valid(pfn))
-               return 0;
-
-       page = pfn_to_page(pfn);
-       if (PageNosave(page))
-               return 0;
-       if (pfn_is_nosave(pfn)) {
-               pr_debug("[nosave pfn 0x%lx]", pfn);
-               return 0;
-       }
-       if (PageNosaveFree(page))
-               return 0;
-
-       return 1;
-}
-
-static void count_data_pages(void)
-{
-       struct zone *zone;
-       unsigned long zone_pfn;
-
-       nr_copy_pages = 0;
-
-       for_each_zone (zone) {
-               if (is_highmem(zone))
-                       continue;
-               mark_free_pages(zone);
-               for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
-                       nr_copy_pages += saveable(zone, &zone_pfn);
-       }
-}
-
-
-static void copy_data_pages(void)
-{
-       struct zone *zone;
-       unsigned long zone_pfn;
-       struct pbe * pbe = pagedir_nosave;
-
-       pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
-       for_each_zone (zone) {
-               if (is_highmem(zone))
-                       continue;
-               mark_free_pages(zone);
-               for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) {
-                       if (saveable(zone, &zone_pfn)) {
-                               struct page * page;
-                               page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
-                               BUG_ON(!pbe);
-                               pbe->orig_address = (long) page_address(page);
-                               /* copy_page is not usable for copying task structs. */
-                               memcpy((void *)pbe->address, (void *)pbe->orig_address, PAGE_SIZE);
-                               pbe = pbe->next;
-                       }
-               }
-       }
-       BUG_ON(pbe);
-}
-
-
-/**
- *     calc_nr - Determine the number of pages needed for a pbe list.
- */
-
-static int calc_nr(int nr_copy)
-{
-       return nr_copy + (nr_copy+PBES_PER_PAGE-2)/(PBES_PER_PAGE-1);
-}
-
-/**
- *     free_pagedir - free pages allocated with alloc_pagedir()
- */
-
-static inline void free_pagedir(struct pbe *pblist)
-{
-       struct pbe *pbe;
-
-       while (pblist) {
-               pbe = (pblist + PB_PAGE_SKIP)->next;
-               free_page((unsigned long)pblist);
-               pblist = pbe;
-       }
-}
-
-/**
- *     fill_pb_page - Create a list of PBEs on a given memory page
- */
-
-static inline void fill_pb_page(struct pbe *pbpage)
-{
-       struct pbe *p;
-
-       p = pbpage;
-       pbpage += PB_PAGE_SKIP;
-       do
-               p->next = p + 1;
-       while (++p < pbpage);
-}
-
-/**
- *     create_pbe_list - Create a list of PBEs on top of a given chain
- *     of memory pages allocated with alloc_pagedir()
- */
-
-static void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
-{
-       struct pbe *pbpage, *p;
-       unsigned num = PBES_PER_PAGE;
-
-       for_each_pb_page (pbpage, pblist) {
-               if (num >= nr_pages)
-                       break;
-
-               fill_pb_page(pbpage);
-               num += PBES_PER_PAGE;
-       }
-       if (pbpage) {
-               for (num -= PBES_PER_PAGE - 1, p = pbpage; num < nr_pages; p++, num++)
-                       p->next = p + 1;
-               p->next = NULL;
-       }
-       pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
-}
-
-/**
- *     alloc_pagedir - Allocate the page directory.
- *
- *     First, determine exactly how many pages we need and
- *     allocate them.
- *
- *     We arrange the pages in a chain: each page is an array of PBES_PER_PAGE
- *     struct pbe elements (pbes) and the last element in the page points
- *     to the next page.
- *
- *     On each page we set up a list of struct_pbe elements.
- */
-
-static struct pbe * alloc_pagedir(unsigned nr_pages)
-{
-       unsigned num;
-       struct pbe *pblist, *pbe;
-
-       if (!nr_pages)
-               return NULL;
-
-       pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
-       pblist = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
-       for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
-                       pbe = pbe->next, num += PBES_PER_PAGE) {
-               pbe += PB_PAGE_SKIP;
-               pbe->next = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
-       }
-       if (!pbe) { /* get_zeroed_page() failed */
-               free_pagedir(pblist);
-               pblist = NULL;
-        }
-       return pblist;
-}
-
-/**
- *     free_image_pages - Free pages allocated for snapshot
- */
-
-static void free_image_pages(void)
-{
-       struct pbe * p;
-
-       for_each_pbe (p, pagedir_save) {
-               if (p->address) {
-                       ClearPageNosave(virt_to_page(p->address));
-                       free_page(p->address);
-                       p->address = 0;
-               }
-       }
-}
-
-/**
- *     alloc_image_pages - Allocate pages for the snapshot.
- */
-
-static int alloc_image_pages(void)
-{
-       struct pbe * p;
-
-       for_each_pbe (p, pagedir_save) {
-               p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
-               if (!p->address)
-                       return -ENOMEM;
-               SetPageNosave(virt_to_page(p->address));
-       }
-       return 0;
-}
-
-/* Free pages we allocated for suspend. Suspend pages are alocated
- * before atomic copy, so we need to free them after resume.
- */
-void swsusp_free(void)
-{
-       BUG_ON(PageNosave(virt_to_page(pagedir_save)));
-       BUG_ON(PageNosaveFree(virt_to_page(pagedir_save)));
-       free_image_pages();
-       free_pagedir(pagedir_save);
-}
-
-
-/**
- *     enough_free_mem - Make sure we enough free memory to snapshot.
- *
- *     Returns TRUE or FALSE after checking the number of available
- *     free pages.
- */
-
-static int enough_free_mem(void)
-{
-       if (nr_free_pages() < (nr_copy_pages + PAGES_FOR_IO)) {
-               pr_debug("swsusp: Not enough free pages: Have %d\n",
-                        nr_free_pages());
-               return 0;
-       }
-       return 1;
-}
-
-
 /**
  *     enough_swap - Make sure we have enough swap to save the image.
  *
@@ -909,87 +543,14 @@ static int enough_free_mem(void)
  *     We should only consider resume_device.
  */
 
-static int enough_swap(void)
+int enough_swap(unsigned nr_pages)
 {
        struct sysinfo i;
 
        si_swapinfo(&i);
-       if (i.freeswap < (nr_copy_pages + PAGES_FOR_IO))  {
-               pr_debug("swsusp: Not enough swap. Need %ld\n",i.freeswap);
-               return 0;
-       }
-       return 1;
-}
-
-static int swsusp_alloc(void)
-{
-       int error;
-
-       pagedir_nosave = NULL;
-       nr_copy_pages = calc_nr(nr_copy_pages);
-       nr_copy_pages_check = nr_copy_pages;
-
-       pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
-                nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
-
-       if (!enough_free_mem())
-               return -ENOMEM;
-
-       if (!enough_swap())
-               return -ENOSPC;
-
-       if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE +
-           !!(nr_copy_pages % PBES_PER_PAGE))
-               return -ENOSPC;
-
-       if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
-               printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
-               return -ENOMEM;
-       }
-       create_pbe_list(pagedir_save, nr_copy_pages);
-       pagedir_nosave = pagedir_save;
-       if ((error = alloc_image_pages())) {
-               printk(KERN_ERR "suspend: Allocating image pages failed.\n");
-               swsusp_free();
-               return error;
-       }
-
-       return 0;
-}
-
-static int suspend_prepare_image(void)
-{
-       int error;
-
-       pr_debug("swsusp: critical section: \n");
-       if (save_highmem()) {
-               printk(KERN_CRIT "Suspend machine: Not enough free pages for highmem\n");
-               restore_highmem();
-               return -ENOMEM;
-       }
-
-       drain_local_pages();
-       count_data_pages();
-       printk("swsusp: Need to copy %u pages\n", nr_copy_pages);
-
-       error = swsusp_alloc();
-       if (error)
-               return error;
-
-       /* During allocating of suspend pagedir, new cold pages may appear.
-        * Kill them.
-        */
-       drain_local_pages();
-       copy_data_pages();
-
-       /*
-        * End of critical section. From now on, we can write to memory,
-        * but we should not touch disk. This specially means we must _not_
-        * touch swap space! Except we must write out our image of course.
-        */
-
-       printk("swsusp: critical section/: done (%d pages copied)\n", nr_copy_pages );
-       return 0;
+       pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
+       return i.freeswap > (nr_pages + PAGES_FOR_IO +
+               (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
 }
 
 
@@ -1001,7 +562,7 @@ static int suspend_prepare_image(void)
 int swsusp_write(void)
 {
        int error;
-       device_resume();
+
        lock_swapdevices();
        error = write_suspend_image();
        /* This will unlock ignored swap devices since writing is finished */
@@ -1011,14 +572,6 @@ int swsusp_write(void)
 }
 
 
-extern asmlinkage int swsusp_arch_suspend(void);
-extern asmlinkage int swsusp_arch_resume(void);
-
-
-asmlinkage int swsusp_save(void)
-{
-       return suspend_prepare_image();
-}
 
 int swsusp_suspend(void)
 {
@@ -1050,7 +603,6 @@ int swsusp_suspend(void)
                printk(KERN_ERR "Error %d suspending\n", error);
        /* Restore control flow magically appears here */
        restore_processor_state();
-       BUG_ON (nr_copy_pages_check != nr_copy_pages);
        restore_highmem();
        device_power_up();
        local_irq_enable();
@@ -1070,6 +622,11 @@ int swsusp_resume(void)
         * execution continues at place where swsusp_arch_suspend was called
          */
        BUG_ON(!error);
+       /* The only reason why swsusp_arch_resume() can fail is memory being
+        * very tight, so we have to free it as soon as we can to avoid
+        * subsequent failures
+        */
+       swsusp_free();
        restore_processor_state();
        restore_highmem();
        touch_softlockup_watchdog();
@@ -1085,54 +642,28 @@ int swsusp_resume(void)
  *
  *     We don't know which pages are usable until we allocate them.
  *
- *     Allocated but unusable (ie eaten) memory pages are linked together
- *     to create a list, so that we can free them easily
- *
- *     We could have used a type other than (void *)
- *     for this purpose, but ...
+ *     Allocated but unusable (ie eaten) memory pages are marked so that
+ *     swsusp_free() can release them
  */
-static void **eaten_memory = NULL;
-
-static inline void eat_page(void *page)
-{
-       void **c;
-
-       c = eaten_memory;
-       eaten_memory = page;
-       *eaten_memory = c;
-}
 
-unsigned long get_usable_page(gfp_t gfp_mask)
+unsigned long get_safe_page(gfp_t gfp_mask)
 {
        unsigned long m;
 
-       m = get_zeroed_page(gfp_mask);
-       while (!PageNosaveFree(virt_to_page(m))) {
-               eat_page((void *)m);
+       do {
                m = get_zeroed_page(gfp_mask);
-               if (!m)
-                       break;
+               if (m && PageNosaveFree(virt_to_page(m)))
+                       /* This is for swsusp_free() */
+                       SetPageNosave(virt_to_page(m));
+       } while (m && PageNosaveFree(virt_to_page(m)));
+       if (m) {
+               /* This is for swsusp_free() */
+               SetPageNosave(virt_to_page(m));
+               SetPageNosaveFree(virt_to_page(m));
        }
        return m;
 }
 
-void free_eaten_memory(void)
-{
-       unsigned long m;
-       void **c;
-       int i = 0;
-
-       c = eaten_memory;
-       while (c) {
-               m = (unsigned long)c;
-               c = *c;
-               free_page(m);
-               i++;
-       }
-       eaten_memory = NULL;
-       pr_debug("swsusp: %d unused pages freed\n", i);
-}
-
 /**
  *     check_pagedir - We ensure here that pages that the PBEs point to
  *     won't collide with pages where we're going to restore from the loaded
@@ -1150,7 +681,7 @@ static int check_pagedir(struct pbe *pblist)
                p->address = 0UL;
 
        for_each_pbe (p, pblist) {
-               p->address = get_usable_page(GFP_ATOMIC);
+               p->address = get_safe_page(GFP_ATOMIC);
                if (!p->address)
                        return -ENOMEM;
        }
@@ -1169,7 +700,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
        unsigned long zone_pfn;
        struct pbe *pbpage, *tail, *p;
        void *m;
-       int rel = 0, error = 0;
+       int rel = 0;
 
        if (!pblist) /* a sanity check */
                return NULL;
@@ -1177,41 +708,37 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
        pr_debug("swsusp: Relocating pagedir (%lu pages to check)\n",
                        swsusp_info.pagedir_pages);
 
-       /* Set page flags */
+       /* Clear page flags */
 
        for_each_zone (zone) {
                for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
-                       SetPageNosaveFree(pfn_to_page(zone_pfn +
+                       if (pfn_valid(zone_pfn + zone->zone_start_pfn))
+                               ClearPageNosaveFree(pfn_to_page(zone_pfn +
                                        zone->zone_start_pfn));
        }
 
-       /* Clear orig addresses */
+       /* Mark orig addresses */
 
        for_each_pbe (p, pblist)
-               ClearPageNosaveFree(virt_to_page(p->orig_address));
+               SetPageNosaveFree(virt_to_page(p->orig_address));
 
        tail = pblist + PB_PAGE_SKIP;
 
        /* Relocate colliding pages */
 
        for_each_pb_page (pbpage, pblist) {
-               if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
-                       m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
-                       if (!m) {
-                               error = -ENOMEM;
-                               break;
-                       }
+               if (PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
+                       m = (void *)get_safe_page(GFP_ATOMIC | __GFP_COLD);
+                       if (!m)
+                               return NULL;
                        memcpy(m, (void *)pbpage, PAGE_SIZE);
                        if (pbpage == pblist)
                                pblist = (struct pbe *)m;
                        else
                                tail->next = (struct pbe *)m;
-
-                       eat_page((void *)pbpage);
                        pbpage = (struct pbe *)m;
 
                        /* We have to link the PBEs again */
-
                        for (p = pbpage; p < pbpage + PB_PAGE_SKIP; p++)
                                if (p->next) /* needed to save the end */
                                        p->next = p + 1;
@@ -1221,15 +748,13 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
                tail = pbpage + PB_PAGE_SKIP;
        }
 
-       if (error) {
-               printk("\nswsusp: Out of memory\n\n");
-               free_pagedir(pblist);
-               free_eaten_memory();
-               pblist = NULL;
-               /* Is this even worth handling? It should never ever happen, and we
-                  have just lost user's state, anyway... */
-       } else
-               printk("swsusp: Relocated %d pages\n", rel);
+       /* This is for swsusp_free() */
+       for_each_pb_page (pbpage, pblist) {
+               SetPageNosave(virt_to_page(pbpage));
+               SetPageNosaveFree(virt_to_page(pbpage));
+       }
+
+       printk("swsusp: Relocated %d pages\n", rel);
 
        return pblist;
 }
@@ -1447,9 +972,7 @@ static int read_pagedir(struct pbe *pblist)
                        break;
        }
 
-       if (error)
-               free_pagedir(pblist);
-       else
+       if (!error)
                BUG_ON(i != swsusp_info.pagedir_pages);
 
        return error;
@@ -1492,15 +1015,6 @@ static int read_suspend_image(void)
        if (!error)
                error = data_read(pagedir_nosave);
 
-       if (error) { /* We fail cleanly */
-               free_eaten_memory();
-               for_each_pbe (p, pagedir_nosave)
-                       if (p->address) {
-                               free_page(p->address);
-                               p->address = 0UL;
-                       }
-               free_pagedir(pagedir_nosave);
-       }
        return error;
 }
 
index 4b8f0f9230a46870aaebcf11b9c844bf32990dd9..3cb9708209bcb94a9d30a4c807f760ae485bf0c4 100644 (file)
@@ -10,7 +10,7 @@
  * elsewhere, in preparation for a serial line console (someday).
  * Ted Ts'o, 2/11/93.
  * Modified for sysctl support, 1/8/97, Chris Horn.
- * Fixed SMP synchronization, 08/08/99, Manfred Spraul 
+ * Fixed SMP synchronization, 08/08/99, Manfred Spraul
  *     manfreds@colorfullife.com
  * Rewrote bits to get rid of console_lock
  *     01Mar01 Andrew Morton <andrewm@uow.edu.au>
@@ -148,7 +148,7 @@ static int __init console_setup(char *str)
        if (!strcmp(str, "ttyb"))
                strcpy(name, "ttyS1");
 #endif
-       for(s = name; *s; s++)
+       for (s = name; *s; s++)
                if ((*s >= '0' && *s <= '9') || *s == ',')
                        break;
        idx = simple_strtoul(s, NULL, 10);
@@ -169,11 +169,11 @@ static int __init log_buf_len_setup(char *str)
                size = roundup_pow_of_two(size);
        if (size > log_buf_len) {
                unsigned long start, dest_idx, offset;
-               char * new_log_buf;
+               char *new_log_buf;
 
                new_log_buf = alloc_bootmem(size);
                if (!new_log_buf) {
-                       printk("log_buf_len: allocation failed\n");
+                       printk(KERN_WARNING "log_buf_len: allocation failed\n");
                        goto out;
                }
 
@@ -193,10 +193,9 @@ static int __init log_buf_len_setup(char *str)
                log_end -= offset;
                spin_unlock_irqrestore(&logbuf_lock, flags);
 
-               printk("log_buf_len: %d\n", log_buf_len);
+               printk(KERN_NOTICE "log_buf_len: %d\n", log_buf_len);
        }
 out:
-
        return 1;
 }
 
@@ -217,7 +216,7 @@ __setup("log_buf_len=", log_buf_len_setup);
  *     9 -- Return number of unread characters in the log buffer
  *     10 -- Return size of the log buffer
  */
-int do_syslog(int type, char __user * buf, int len)
+int do_syslog(int type, char __user *buf, int len)
 {
        unsigned long i, j, limit, count;
        int do_clear = 0;
@@ -244,7 +243,8 @@ int do_syslog(int type, char __user * buf, int len)
                        error = -EFAULT;
                        goto out;
                }
-               error = wait_event_interruptible(log_wait, (log_start - log_end));
+               error = wait_event_interruptible(log_wait,
+                                                       (log_start - log_end));
                if (error)
                        goto out;
                i = 0;
@@ -264,7 +264,7 @@ int do_syslog(int type, char __user * buf, int len)
                        error = i;
                break;
        case 4:         /* Read/clear last kernel messages */
-               do_clear = 1; 
+               do_clear = 1;
                /* FALL THRU */
        case 3:         /* Read last kernel messages */
                error = -EINVAL;
@@ -288,11 +288,11 @@ int do_syslog(int type, char __user * buf, int len)
                limit = log_end;
                /*
                 * __put_user() could sleep, and while we sleep
-                * printk() could overwrite the messages 
+                * printk() could overwrite the messages
                 * we try to copy to user space. Therefore
                 * the messages are copied in reverse. <manfreds>
                 */
-               for(i = 0; i < count && !error; i++) {
+               for (i = 0; i < count && !error; i++) {
                        j = limit-1-i;
                        if (j + log_buf_len < log_end)
                                break;
@@ -306,10 +306,10 @@ int do_syslog(int type, char __user * buf, int len)
                if (error)
                        break;
                error = i;
-               if(i != count) {
+               if (i != count) {
                        int offset = count-error;
                        /* buffer overflow during copy, correct user buffer. */
-                       for(i=0;i<error;i++) {
+                       for (i = 0; i < error; i++) {
                                if (__get_user(c,&buf[i+offset]) ||
                                    __put_user(c,&buf[i])) {
                                        error = -EFAULT;
@@ -351,7 +351,7 @@ out:
        return error;
 }
 
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
 {
        return do_syslog(type, buf, len);
 }
@@ -404,21 +404,19 @@ static void call_console_drivers(unsigned long start, unsigned long end)
        cur_index = start;
        start_print = start;
        while (cur_index != end) {
-               if (    msg_level < 0 &&
-                       ((end - cur_index) > 2) &&
-                       LOG_BUF(cur_index + 0) == '<' &&
-                       LOG_BUF(cur_index + 1) >= '0' &&
-                       LOG_BUF(cur_index + 1) <= '7' &&
-                       LOG_BUF(cur_index + 2) == '>')
-               {
+               if (msg_level < 0 && ((end - cur_index) > 2) &&
+                               LOG_BUF(cur_index + 0) == '<' &&
+                               LOG_BUF(cur_index + 1) >= '0' &&
+                               LOG_BUF(cur_index + 1) <= '7' &&
+                               LOG_BUF(cur_index + 2) == '>') {
                        msg_level = LOG_BUF(cur_index + 1) - '0';
                        cur_index += 3;
                        start_print = cur_index;
                }
                while (cur_index != end) {
                        char c = LOG_BUF(cur_index);
-                       cur_index++;
 
+                       cur_index++;
                        if (c == '\n') {
                                if (msg_level < 0) {
                                        /*
@@ -461,7 +459,7 @@ static void zap_locks(void)
        static unsigned long oops_timestamp;
 
        if (time_after_eq(jiffies, oops_timestamp) &&
-                       !time_after(jiffies, oops_timestamp + 30*HZ))
+                       !time_after(jiffies, oops_timestamp + 30 * HZ))
                return;
 
        oops_timestamp = jiffies;
@@ -495,7 +493,7 @@ __attribute__((weak)) unsigned long long printk_clock(void)
 
 /*
  * This is printk.  It can be called from any context.  We want it to work.
- * 
+ *
  * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
  * call the console drivers.  If we fail to get the semaphore we place the output
  * into the log buffer and return.  The current holder of the console_sem will
@@ -639,13 +637,19 @@ EXPORT_SYMBOL(vprintk);
 
 #else
 
-asmlinkage long sys_syslog(int type, char __user * buf, int len)
+asmlinkage long sys_syslog(int type, char __user *buf, int len)
 {
        return 0;
 }
 
-int do_syslog(int type, char __user * buf, int len) { return 0; }
-static void call_console_drivers(unsigned long start, unsigned long end) {}
+int do_syslog(int type, char __user *buf, int len)
+{
+       return 0;
+}
+
+static void call_console_drivers(unsigned long start, unsigned long end)
+{
+}
 
 #endif
 
@@ -851,9 +855,9 @@ EXPORT_SYMBOL(console_start);
  * print any messages that were printed by the kernel before the
  * console driver was initialized.
  */
-void register_console(struct console * console)
+void register_console(struct console *console)
 {
-       int     i;
+       int i;
        unsigned long flags;
 
        if (preferred_console < 0)
@@ -878,7 +882,8 @@ void register_console(struct console * console)
         *      See if this console matches one we selected on
         *      the command line.
         */
-       for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
+       for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0];
+                       i++) {
                if (strcmp(console_cmdline[i].name, console->name) != 0)
                        continue;
                if (console->index >= 0 &&
@@ -933,9 +938,9 @@ void register_console(struct console * console)
 }
 EXPORT_SYMBOL(register_console);
 
-int unregister_console(struct console * console)
+int unregister_console(struct console *console)
 {
-        struct console *a,*b;
+        struct console *a, *b;
        int res = 1;
 
        acquire_console_sem();
@@ -949,10 +954,10 @@ int unregister_console(struct console * console)
                                b->next = a->next;
                                res = 0;
                                break;
-                       }  
+                       }
                }
        }
-       
+
        /* If last console is removed, we re-enable picking the first
         * one that gets registered. Without that, pmac early boot console
         * would prevent fbcon from taking over.
@@ -994,7 +999,7 @@ void tty_write_message(struct tty_struct *tty, char *msg)
 int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 {
        static DEFINE_SPINLOCK(ratelimit_lock);
-       static unsigned long toks = 10*5*HZ;
+       static unsigned long toks = 10 * 5 * HZ;
        static unsigned long last_msg;
        static int missed;
        unsigned long flags;
@@ -1007,6 +1012,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
                toks = ratelimit_burst * ratelimit_jiffies;
        if (toks >= ratelimit_jiffies) {
                int lost = missed;
+
                missed = 0;
                toks -= ratelimit_jiffies;
                spin_unlock_irqrestore(&ratelimit_lock, flags);
@@ -1021,7 +1027,7 @@ int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 EXPORT_SYMBOL(__printk_ratelimit);
 
 /* minimum time in jiffies between messages */
-int printk_ratelimit_jiffies = 5*HZ;
+int printk_ratelimit_jiffies = 5 * HZ;
 
 /* number of messages we send before ratelimiting */
 int printk_ratelimit_burst = 10;
index 019e04ec065a55d8f28157d3a1f7ba06cafd347f..863eee8bff4763d949489d17bdfd9cef33cbca6c 100644 (file)
@@ -56,6 +56,10 @@ void ptrace_untrace(task_t *child)
                        signal_wake_up(child, 1);
                }
        }
+       if (child->signal->flags & SIGNAL_GROUP_EXIT) {
+               sigaddset(&child->pending.signal, SIGKILL);
+               signal_wake_up(child, 1);
+       }
        spin_unlock(&child->sighand->siglock);
 }
 
@@ -77,8 +81,7 @@ void __ptrace_unlink(task_t *child)
                SET_LINKS(child);
        }
 
-       if (child->state == TASK_TRACED)
-               ptrace_untrace(child);
+       ptrace_untrace(child);
 }
 
 /*
index 2559d4b8f23f6ef005db9825952afa0936d22951..c4d159a21e042cc184a6d04e64b7b2273dfb5872 100644 (file)
@@ -153,6 +153,15 @@ void fastcall call_rcu_bh(struct rcu_head *head,
        local_irq_restore(flags);
 }
 
+/*
+ * Return the number of RCU batches processed thus far.  Useful
+ * for debug and statistics.
+ */
+long rcu_batches_completed(void)
+{
+       return rcu_ctrlblk.completed;
+}
+
 /*
  * Invoke the completed RCU callbacks. They are expected to be in
  * a per-cpu list.
@@ -501,6 +510,7 @@ void synchronize_kernel(void)
 }
 
 module_param(maxbatch, int, 0);
+EXPORT_SYMBOL_GPL(rcu_batches_completed);
 EXPORT_SYMBOL(call_rcu);  /* WARNING: GPL-only in April 2006. */
 EXPORT_SYMBOL(call_rcu_bh);  /* WARNING: GPL-only in April 2006. */
 EXPORT_SYMBOL_GPL(synchronize_rcu);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
new file mode 100644 (file)
index 0000000..9b58f1e
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * Read-Copy Update /proc-based torture test facility
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2005
+ *
+ * Authors: Paul E. McKenney <paulmck@us.ibm.com>
+ *
+ * See also:  Documentation/RCU/torture.txt
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/rcupdate.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/moduleparam.h>
+#include <linux/percpu.h>
+#include <linux/notifier.h>
+#include <linux/rcuref.h>
+#include <linux/cpu.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/byteorder/swabb.h>
+#include <linux/stat.h>
+
+MODULE_LICENSE("GPL");
+
+static int nreaders = -1;      /* # reader threads, defaults to 4*ncpus */
+static int stat_interval = 0;  /* Interval between stats, in seconds. */
+                               /*  Defaults to "only at end of test". */
+static int verbose = 0;                /* Print more debug info. */
+
+MODULE_PARM(nreaders, "i");
+MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
+MODULE_PARM(stat_interval, "i");
+MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
+MODULE_PARM(verbose, "i");
+MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
+#define TORTURE_FLAG "rcutorture: "
+#define PRINTK_STRING(s) \
+       do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_STRING(s) \
+       do { if (verbose) printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
+#define VERBOSE_PRINTK_ERRSTRING(s) \
+       do { if (verbose) printk(KERN_ALERT TORTURE_FLAG "!!! " s "\n"); } while (0)
+
+static char printk_buf[4096];
+
+static int nrealreaders;
+static struct task_struct *writer_task;
+static struct task_struct **reader_tasks;
+static struct task_struct *stats_task;
+
+#define RCU_TORTURE_PIPE_LEN 10
+
+struct rcu_torture {
+       struct rcu_head rtort_rcu;
+       int rtort_pipe_count;
+       struct list_head rtort_free;
+};
+
+static int fullstop = 0;       /* stop generating callbacks at test end. */
+static LIST_HEAD(rcu_torture_freelist);
+static struct rcu_torture *rcu_torture_current = NULL;
+static long rcu_torture_current_version = 0;
+static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
+static DEFINE_SPINLOCK(rcu_torture_lock);
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
+       { 0 };
+static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_batch) =
+       { 0 };
+static atomic_t rcu_torture_wcount[RCU_TORTURE_PIPE_LEN + 1];
+atomic_t n_rcu_torture_alloc;
+atomic_t n_rcu_torture_alloc_fail;
+atomic_t n_rcu_torture_free;
+
+/*
+ * Allocate an element from the rcu_tortures pool.
+ */
+struct rcu_torture *
+rcu_torture_alloc(void)
+{
+       struct list_head *p;
+
+       spin_lock(&rcu_torture_lock);
+       if (list_empty(&rcu_torture_freelist)) {
+               atomic_inc(&n_rcu_torture_alloc_fail);
+               spin_unlock(&rcu_torture_lock);
+               return NULL;
+       }
+       atomic_inc(&n_rcu_torture_alloc);
+       p = rcu_torture_freelist.next;
+       list_del_init(p);
+       spin_unlock(&rcu_torture_lock);
+       return container_of(p, struct rcu_torture, rtort_free);
+}
+
+/*
+ * Free an element to the rcu_tortures pool.
+ */
+static void
+rcu_torture_free(struct rcu_torture *p)
+{
+       atomic_inc(&n_rcu_torture_free);
+       spin_lock(&rcu_torture_lock);
+       list_add_tail(&p->rtort_free, &rcu_torture_freelist);
+       spin_unlock(&rcu_torture_lock);
+}
+
+static void
+rcu_torture_cb(struct rcu_head *p)
+{
+       int i;
+       struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
+
+       if (fullstop) {
+               /* Test is ending, just drop callbacks on the floor. */
+               /* The next initialization will pick up the pieces. */
+               return;
+       }
+       i = rp->rtort_pipe_count;
+       if (i > RCU_TORTURE_PIPE_LEN)
+               i = RCU_TORTURE_PIPE_LEN;
+       atomic_inc(&rcu_torture_wcount[i]);
+       if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN)
+               rcu_torture_free(rp);
+       else
+               call_rcu(p, rcu_torture_cb);
+}
+
+struct rcu_random_state {
+       unsigned long rrs_state;
+       unsigned long rrs_count;
+};
+
+#define RCU_RANDOM_MULT 39916801  /* prime */
+#define RCU_RANDOM_ADD 479001701 /* prime */
+#define RCU_RANDOM_REFRESH 10000
+
+#define DEFINE_RCU_RANDOM(name) struct rcu_random_state name = { 0, 0 }
+
+/*
+ * Crude but fast random-number generator.  Uses a linear congruential
+ * generator, with occasional help from get_random_bytes().
+ */
+static long
+rcu_random(struct rcu_random_state *rrsp)
+{
+       long refresh;
+
+       if (--rrsp->rrs_count < 0) {
+               get_random_bytes(&refresh, sizeof(refresh));
+               rrsp->rrs_state += refresh;
+               rrsp->rrs_count = RCU_RANDOM_REFRESH;
+       }
+       rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
+       return swahw32(rrsp->rrs_state);
+}
+
+/*
+ * RCU torture writer kthread.  Repeatedly substitutes a new structure
+ * for that pointed to by rcu_torture_current, freeing the old structure
+ * after a series of grace periods (the "pipeline").
+ */
+static int
+rcu_torture_writer(void *arg)
+{
+       int i;
+       long oldbatch = rcu_batches_completed();
+       struct rcu_torture *rp;
+       struct rcu_torture *old_rp;
+       static DEFINE_RCU_RANDOM(rand);
+
+       VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
+       do {
+               schedule_timeout_uninterruptible(1);
+               if (rcu_batches_completed() == oldbatch)
+                       continue;
+               if ((rp = rcu_torture_alloc()) == NULL)
+                       continue;
+               rp->rtort_pipe_count = 0;
+               udelay(rcu_random(&rand) & 0x3ff);
+               old_rp = rcu_torture_current;
+               rcu_assign_pointer(rcu_torture_current, rp);
+               smp_wmb();
+               if (old_rp != NULL) {
+                       i = old_rp->rtort_pipe_count;
+                       if (i > RCU_TORTURE_PIPE_LEN)
+                               i = RCU_TORTURE_PIPE_LEN;
+                       atomic_inc(&rcu_torture_wcount[i]);
+                       old_rp->rtort_pipe_count++;
+                       call_rcu(&old_rp->rtort_rcu, rcu_torture_cb);
+               }
+               rcu_torture_current_version++;
+               oldbatch = rcu_batches_completed();
+       } while (!kthread_should_stop() && !fullstop);
+       VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+/*
+ * RCU torture reader kthread.  Repeatedly dereferences rcu_torture_current,
+ * incrementing the corresponding element of the pipeline array.  The
+ * counter in the element should never be greater than 1, otherwise, the
+ * RCU implementation is broken.
+ */
+static int
+rcu_torture_reader(void *arg)
+{
+       int completed;
+       DEFINE_RCU_RANDOM(rand);
+       struct rcu_torture *p;
+       int pipe_count;
+
+       VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
+       do {
+               rcu_read_lock();
+               completed = rcu_batches_completed();
+               p = rcu_dereference(rcu_torture_current);
+               if (p == NULL) {
+                       /* Wait for rcu_torture_writer to get underway */
+                       rcu_read_unlock();
+                       schedule_timeout_interruptible(HZ);
+                       continue;
+               }
+               udelay(rcu_random(&rand) & 0x7f);
+               preempt_disable();
+               pipe_count = p->rtort_pipe_count;
+               if (pipe_count > RCU_TORTURE_PIPE_LEN) {
+                       /* Should not happen, but... */
+                       pipe_count = RCU_TORTURE_PIPE_LEN;
+               }
+               ++__get_cpu_var(rcu_torture_count)[pipe_count];
+               completed = rcu_batches_completed() - completed;
+               if (completed > RCU_TORTURE_PIPE_LEN) {
+                       /* Should not happen, but... */
+                       completed = RCU_TORTURE_PIPE_LEN;
+               }
+               ++__get_cpu_var(rcu_torture_batch)[completed];
+               preempt_enable();
+               rcu_read_unlock();
+               schedule();
+       } while (!kthread_should_stop() && !fullstop);
+       VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
+       while (!kthread_should_stop())
+               schedule_timeout_uninterruptible(1);
+       return 0;
+}
+
+/*
+ * Create an RCU-torture statistics message in the specified buffer.
+ */
+static int
+rcu_torture_printk(char *page)
+{
+       int cnt = 0;
+       int cpu;
+       int i;
+       long pipesummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+       long batchsummary[RCU_TORTURE_PIPE_LEN + 1] = { 0 };
+
+       for_each_cpu(cpu) {
+               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+                       pipesummary[i] += per_cpu(rcu_torture_count, cpu)[i];
+                       batchsummary[i] += per_cpu(rcu_torture_batch, cpu)[i];
+               }
+       }
+       for (i = RCU_TORTURE_PIPE_LEN - 1; i >= 0; i--) {
+               if (pipesummary[i] != 0)
+                       break;
+       }
+       cnt += sprintf(&page[cnt], "rcutorture: ");
+       cnt += sprintf(&page[cnt],
+                      "rtc: %p ver: %ld tfle: %d rta: %d rtaf: %d rtf: %d",
+                      rcu_torture_current,
+                      rcu_torture_current_version,
+                      list_empty(&rcu_torture_freelist),
+                      atomic_read(&n_rcu_torture_alloc),
+                      atomic_read(&n_rcu_torture_alloc_fail),
+                      atomic_read(&n_rcu_torture_free));
+       cnt += sprintf(&page[cnt], "\nrcutorture: ");
+       if (i > 1)
+               cnt += sprintf(&page[cnt], "!!! ");
+       cnt += sprintf(&page[cnt], "Reader Pipe: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+               cnt += sprintf(&page[cnt], " %ld", pipesummary[i]);
+       cnt += sprintf(&page[cnt], "\nrcutorture: ");
+       cnt += sprintf(&page[cnt], "Reader Batch: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+               cnt += sprintf(&page[cnt], " %ld", batchsummary[i]);
+       cnt += sprintf(&page[cnt], "\nrcutorture: ");
+       cnt += sprintf(&page[cnt], "Free-Block Circulation: ");
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+               cnt += sprintf(&page[cnt], " %d",
+                              atomic_read(&rcu_torture_wcount[i]));
+       }
+       cnt += sprintf(&page[cnt], "\n");
+       return cnt;
+}
+
+/*
+ * Print torture statistics.  Caller must ensure that there is only
+ * one call to this function at a given time!!!  This is normally
+ * accomplished by relying on the module system to only have one copy
+ * of the module loaded, and then by giving the rcu_torture_stats
+ * kthread full control (or the init/cleanup functions when rcu_torture_stats
+ * thread is not running).
+ */
+static void
+rcu_torture_stats_print(void)
+{
+       int cnt;
+
+       cnt = rcu_torture_printk(printk_buf);
+       printk(KERN_ALERT "%s", printk_buf);
+}
+
+/*
+ * Periodically prints torture statistics, if periodic statistics printing
+ * was specified via the stat_interval module parameter.
+ *
+ * No need to worry about fullstop here, since this one doesn't reference
+ * volatile state or register callbacks.
+ */
+static int
+rcu_torture_stats(void *arg)
+{
+       VERBOSE_PRINTK_STRING("rcu_torture_stats task started");
+       do {
+               schedule_timeout_interruptible(stat_interval * HZ);
+               rcu_torture_stats_print();
+       } while (!kthread_should_stop());
+       VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
+       return 0;
+}
+
+static void
+rcu_torture_cleanup(void)
+{
+       int i;
+
+       fullstop = 1;
+       if (writer_task != NULL) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
+               kthread_stop(writer_task);
+       }
+       writer_task = NULL;
+
+       if (reader_tasks != NULL) {
+               for (i = 0; i < nrealreaders; i++) {
+                       if (reader_tasks[i] != NULL) {
+                               VERBOSE_PRINTK_STRING(
+                                       "Stopping rcu_torture_reader task");
+                               kthread_stop(reader_tasks[i]);
+                       }
+                       reader_tasks[i] = NULL;
+               }
+               kfree(reader_tasks);
+               reader_tasks = NULL;
+       }
+       rcu_torture_current = NULL;
+
+       if (stats_task != NULL) {
+               VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
+               kthread_stop(stats_task);
+       }
+       stats_task = NULL;
+
+       /* Wait for all RCU callbacks to fire.  */
+
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
+               synchronize_rcu();
+       rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
+       PRINTK_STRING("--- End of test");
+}
+
+static int
+rcu_torture_init(void)
+{
+       int i;
+       int cpu;
+       int firsterr = 0;
+
+       /* Process args and tell the world that the torturer is on the job. */
+
+       if (nreaders >= 0)
+               nrealreaders = nreaders;
+       else
+               nrealreaders = 2 * num_online_cpus();
+       printk(KERN_ALERT TORTURE_FLAG
+              "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n",
+              nrealreaders, stat_interval, verbose);
+       fullstop = 0;
+
+       /* Set up the freelist. */
+
+       INIT_LIST_HEAD(&rcu_torture_freelist);
+       for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
+               list_add_tail(&rcu_tortures[i].rtort_free,
+                             &rcu_torture_freelist);
+       }
+
+       /* Initialize the statistics so that each run gets its own numbers. */
+
+       rcu_torture_current = NULL;
+       rcu_torture_current_version = 0;
+       atomic_set(&n_rcu_torture_alloc, 0);
+       atomic_set(&n_rcu_torture_alloc_fail, 0);
+       atomic_set(&n_rcu_torture_free, 0);
+       for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++)
+               atomic_set(&rcu_torture_wcount[i], 0);
+       for_each_cpu(cpu) {
+               for (i = 0; i < RCU_TORTURE_PIPE_LEN + 1; i++) {
+                       per_cpu(rcu_torture_count, cpu)[i] = 0;
+                       per_cpu(rcu_torture_batch, cpu)[i] = 0;
+               }
+       }
+
+       /* Start up the kthreads. */
+
+       VERBOSE_PRINTK_STRING("Creating rcu_torture_writer task");
+       writer_task = kthread_run(rcu_torture_writer, NULL,
+                                 "rcu_torture_writer");
+       if (IS_ERR(writer_task)) {
+               firsterr = PTR_ERR(writer_task);
+               VERBOSE_PRINTK_ERRSTRING("Failed to create writer");
+               writer_task = NULL;
+               goto unwind;
+       }
+       reader_tasks = kmalloc(nrealreaders * sizeof(reader_tasks[0]),
+                              GFP_KERNEL);
+       if (reader_tasks == NULL) {
+               VERBOSE_PRINTK_ERRSTRING("out of memory");
+               firsterr = -ENOMEM;
+               goto unwind;
+       }
+       for (i = 0; i < nrealreaders; i++) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_reader task");
+               reader_tasks[i] = kthread_run(rcu_torture_reader, NULL,
+                                             "rcu_torture_reader");
+               if (IS_ERR(reader_tasks[i])) {
+                       firsterr = PTR_ERR(reader_tasks[i]);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create reader");
+                       reader_tasks[i] = NULL;
+                       goto unwind;
+               }
+       }
+       if (stat_interval > 0) {
+               VERBOSE_PRINTK_STRING("Creating rcu_torture_stats task");
+               stats_task = kthread_run(rcu_torture_stats, NULL,
+                                       "rcu_torture_stats");
+               if (IS_ERR(stats_task)) {
+                       firsterr = PTR_ERR(stats_task);
+                       VERBOSE_PRINTK_ERRSTRING("Failed to create stats");
+                       stats_task = NULL;
+                       goto unwind;
+               }
+       }
+       return 0;
+
+unwind:
+       rcu_torture_cleanup();
+       return firsterr;
+}
+
+module_init(rcu_torture_init);
+module_exit(rcu_torture_cleanup);
index 4f26c544d02c3c308693c92116c46b1d5ce2b76b..340dd238c16da8044acf88527e3c07feb9472c20 100644 (file)
@@ -3877,7 +3877,6 @@ EXPORT_SYMBOL(cpu_present_map);
 
 #ifndef CONFIG_SMP
 cpumask_t cpu_online_map = CPU_MASK_ALL;
-EXPORT_SYMBOL_GPL(cpu_online_map);
 cpumask_t cpu_possible_map = CPU_MASK_ALL;
 #endif
 
index 6904bbbfe116985d1710f04fcfd5792a536d382f..1bf3c39d61092209bd66c51e9ba53e7bd24b7d04 100644 (file)
@@ -277,7 +277,6 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
        } else {
                INIT_LIST_HEAD(&q->list);
                q->flags = 0;
-               q->lock = NULL;
                q->user = get_uid(t->user);
        }
        return(q);
@@ -652,8 +651,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
        if (!valid_signal(sig))
                return error;
        error = -EPERM;
-       if ((!info || ((unsigned long)info != 1 &&
-                       (unsigned long)info != 2 && SI_FROMUSER(info)))
+       if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
            && ((sig != SIGCONT) ||
                (current->signal->session != t->signal->session))
            && (current->euid ^ t->suid) && (current->euid ^ t->uid)
@@ -790,7 +788,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
         * fast-pathed signals for kernel-internal things like SIGSTOP
         * or SIGKILL.
         */
-       if ((unsigned long)info == 2)
+       if (info == SEND_SIG_FORCED)
                goto out_set;
 
        /* Real-time signals must be queued if sent by sigqueue, or
@@ -802,19 +800,19 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
           pass on the info struct.  */
 
        q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
-                                            ((unsigned long) info < 2 ||
+                                            (is_si_special(info) ||
                                              info->si_code >= 0)));
        if (q) {
                list_add_tail(&q->list, &signals->list);
                switch ((unsigned long) info) {
-               case 0:
+               case (unsigned long) SEND_SIG_NOINFO:
                        q->info.si_signo = sig;
                        q->info.si_errno = 0;
                        q->info.si_code = SI_USER;
                        q->info.si_pid = current->pid;
                        q->info.si_uid = current->uid;
                        break;
-               case 1:
+               case (unsigned long) SEND_SIG_PRIV:
                        q->info.si_signo = sig;
                        q->info.si_errno = 0;
                        q->info.si_code = SI_KERNEL;
@@ -825,20 +823,13 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
                        copy_siginfo(&q->info, info);
                        break;
                }
-       } else {
-               if (sig >= SIGRTMIN && info && (unsigned long)info != 1
-                  && info->si_code != SI_USER)
+       } else if (!is_si_special(info)) {
+               if (sig >= SIGRTMIN && info->si_code != SI_USER)
                /*
                 * Queue overflow, abort.  We may abort if the signal was rt
                 * and sent by user using something other than kill().
                 */
                        return -EAGAIN;
-               if (((unsigned long)info > 1) && (info->si_code == SI_TIMER))
-                       /*
-                        * Set up a return to indicate that we dropped 
-                        * the signal.
-                        */
-                       ret = info->si_sys_private;
        }
 
 out_set:
@@ -859,12 +850,6 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
                BUG();
        assert_spin_locked(&t->sighand->siglock);
 
-       if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
-               /*
-                * Set up a return to indicate that we dropped the signal.
-                */
-               ret = info->si_sys_private;
-
        /* Short-circuit ignored signals.  */
        if (sig_ignored(t, sig))
                goto out;
@@ -894,11 +879,13 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
        int ret;
 
        spin_lock_irqsave(&t->sighand->siglock, flags);
-       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
+       if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
                t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
+       }
+       if (sigismember(&t->blocked, sig)) {
                sigdelset(&t->blocked, sig);
-               recalc_sigpending_tsk(t);
        }
+       recalc_sigpending_tsk(t);
        ret = specific_send_sig_info(sig, info, t);
        spin_unlock_irqrestore(&t->sighand->siglock, flags);
 
@@ -908,15 +895,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
 void
 force_sig_specific(int sig, struct task_struct *t)
 {
-       unsigned long int flags;
-
-       spin_lock_irqsave(&t->sighand->siglock, flags);
-       if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN)
-               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
-       sigdelset(&t->blocked, sig);
-       recalc_sigpending_tsk(t);
-       specific_send_sig_info(sig, (void *)2, t);
-       spin_unlock_irqrestore(&t->sighand->siglock, flags);
+       force_sig_info(sig, SEND_SIG_FORCED, t);
 }
 
 /*
@@ -1051,12 +1030,6 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        assert_spin_locked(&p->sighand->siglock);
        handle_stop_signal(sig, p);
 
-       if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
-               /*
-                * Set up a return to indicate that we dropped the signal.
-                */
-               ret = info->si_sys_private;
-
        /* Short-circuit ignored signals.  */
        if (sig_ignored(p, sig))
                return ret;
@@ -1109,8 +1082,8 @@ void zap_other_threads(struct task_struct *p)
                if (t != p->group_leader)
                        t->exit_signal = -1;
 
+               /* SIGKILL will be handled before any pending SIGSTOP */
                sigaddset(&t->pending.signal, SIGKILL);
-               rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
                signal_wake_up(t, 1);
        }
 }
@@ -1286,10 +1259,13 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        return ret;
 }
 
+#define __si_special(priv) \
+       ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)
+
 int
 send_sig(int sig, struct task_struct *p, int priv)
 {
-       return send_sig_info(sig, (void*)(long)(priv != 0), p);
+       return send_sig_info(sig, __si_special(priv), p);
 }
 
 /*
@@ -1309,7 +1285,7 @@ send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 void
 force_sig(int sig, struct task_struct *p)
 {
-       force_sig_info(sig, (void*)1L, p);
+       force_sig_info(sig, SEND_SIG_PRIV, p);
 }
 
 /*
@@ -1334,13 +1310,13 @@ force_sigsegv(int sig, struct task_struct *p)
 int
 kill_pg(pid_t pgrp, int sig, int priv)
 {
-       return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp);
+       return kill_pg_info(sig, __si_special(priv), pgrp);
 }
 
 int
 kill_proc(pid_t pid, int sig, int priv)
 {
-       return kill_proc_info(sig, (void *)(long)(priv != 0), pid);
+       return kill_proc_info(sig, __si_special(priv), pid);
 }
 
 /*
@@ -1371,11 +1347,12 @@ void sigqueue_free(struct sigqueue *q)
         * pending queue.
         */
        if (unlikely(!list_empty(&q->list))) {
-               read_lock(&tasklist_lock);  
-               spin_lock_irqsave(q->lock, flags);
+               spinlock_t *lock = &current->sighand->siglock;
+               read_lock(&tasklist_lock);
+               spin_lock_irqsave(lock, flags);
                if (!list_empty(&q->list))
                        list_del_init(&q->list);
-               spin_unlock_irqrestore(q->lock, flags);
+               spin_unlock_irqrestore(lock, flags);
                read_unlock(&tasklist_lock);
        }
        q->flags &= ~SIGQUEUE_PREALLOC;
@@ -1414,7 +1391,6 @@ send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
                goto out;
        }
 
-       q->lock = &p->sighand->siglock;
        list_add_tail(&q->list, &p->pending.list);
        sigaddset(&p->pending.signal, sig);
        if (!sigismember(&p->blocked, sig))
@@ -1462,7 +1438,6 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
         * We always use the shared queue for process-wide signals,
         * to avoid several races.
         */
-       q->lock = &p->sighand->siglock;
        list_add_tail(&q->list, &p->signal->shared_pending.list);
        sigaddset(&p->signal->shared_pending.signal, sig);
 
@@ -1881,9 +1856,9 @@ relock:
                        /* Let the debugger run.  */
                        ptrace_stop(signr, signr, info);
 
-                       /* We're back.  Did the debugger cancel the sig */
+                       /* We're back.  Did the debugger cancel the sig or group_exit? */
                        signr = current->exit_code;
-                       if (signr == 0)
+                       if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT)
                                continue;
 
                        current->exit_code = 0;
@@ -2285,26 +2260,13 @@ sys_kill(int pid, int sig)
        return kill_something_info(sig, &info, pid);
 }
 
-/**
- *  sys_tgkill - send signal to one specific thread
- *  @tgid: the thread group ID of the thread
- *  @pid: the PID of the thread
- *  @sig: signal to be sent
- *
- *  This syscall also checks the tgid and returns -ESRCH even if the PID
- *  exists but it's not belonging to the target process anymore. This
- *  method solves the problem of threads exiting and PIDs getting reused.
- */
-asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+static int do_tkill(int tgid, int pid, int sig)
 {
-       struct siginfo info;
        int error;
+       struct siginfo info;
        struct task_struct *p;
 
-       /* This is only valid for single tasks */
-       if (pid <= 0 || tgid <= 0)
-               return -EINVAL;
-
+       error = -ESRCH;
        info.si_signo = sig;
        info.si_errno = 0;
        info.si_code = SI_TKILL;
@@ -2313,8 +2275,7 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
 
        read_lock(&tasklist_lock);
        p = find_task_by_pid(pid);
-       error = -ESRCH;
-       if (p && (p->tgid == tgid)) {
+       if (p && (tgid <= 0 || p->tgid == tgid)) {
                error = check_kill_permission(sig, &info, p);
                /*
                 * The null signal is a permissions and process existence
@@ -2328,47 +2289,40 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
                }
        }
        read_unlock(&tasklist_lock);
+
        return error;
 }
 
+/**
+ *  sys_tgkill - send signal to one specific thread
+ *  @tgid: the thread group ID of the thread
+ *  @pid: the PID of the thread
+ *  @sig: signal to be sent
+ *
+ *  This syscall also checks the tgid and returns -ESRCH even if the PID
+ *  exists but it's not belonging to the target process anymore. This
+ *  method solves the problem of threads exiting and PIDs getting reused.
+ */
+asmlinkage long sys_tgkill(int tgid, int pid, int sig)
+{
+       /* This is only valid for single tasks */
+       if (pid <= 0 || tgid <= 0)
+               return -EINVAL;
+
+       return do_tkill(tgid, pid, sig);
+}
+
 /*
  *  Send a signal to only one task, even if it's a CLONE_THREAD task.
  */
 asmlinkage long
 sys_tkill(int pid, int sig)
 {
-       struct siginfo info;
-       int error;
-       struct task_struct *p;
-
        /* This is only valid for single tasks */
        if (pid <= 0)
                return -EINVAL;
 
-       info.si_signo = sig;
-       info.si_errno = 0;
-       info.si_code = SI_TKILL;
-       info.si_pid = current->tgid;
-       info.si_uid = current->uid;
-
-       read_lock(&tasklist_lock);
-       p = find_task_by_pid(pid);
-       error = -ESRCH;
-       if (p) {
-               error = check_kill_permission(sig, &info, p);
-               /*
-                * The null signal is a permissions and process existence
-                * probe.  No signal is actually delivered.
-                */
-               if (!error && sig && p->sighand) {
-                       spin_lock_irq(&p->sighand->siglock);
-                       handle_stop_signal(sig, p);
-                       error = specific_send_sig_info(sig, &info, p);
-                       spin_unlock_irq(&p->sighand->siglock);
-               }
-       }
-       read_unlock(&tasklist_lock);
-       return error;
+       return do_tkill(0, pid, sig);
 }
 
 asmlinkage long
index a3c2100470e106becb5155d091e2bf9c6d1dee7c..245d595a13cb9f566f67c2ac6ab6dfb8c0af1143 100644 (file)
@@ -338,30 +338,20 @@ int do_adjtimex(struct timex *txc)
                        if (mtemp >= MINSEC) {
                            ltemp = (time_offset / mtemp) << (SHIFT_USEC -
                                                              SHIFT_UPDATE);
-                           if (ltemp < 0)
-                               time_freq -= -ltemp >> SHIFT_KH;
-                           else
-                               time_freq += ltemp >> SHIFT_KH;
+                           time_freq += shift_right(ltemp, SHIFT_KH);
                        } else /* calibration interval too short (p. 12) */
                                result = TIME_ERROR;
                    } else {    /* PLL mode */
                        if (mtemp < MAXSEC) {
                            ltemp *= mtemp;
-                           if (ltemp < 0)
-                               time_freq -= -ltemp >> (time_constant +
-                                                       time_constant +
-                                                       SHIFT_KF - SHIFT_USEC);
-                           else
-                               time_freq += ltemp >> (time_constant +
+                           time_freq += shift_right(ltemp,(time_constant +
                                                       time_constant +
-                                                      SHIFT_KF - SHIFT_USEC);
+                                                      SHIFT_KF - SHIFT_USEC));
                        } else /* calibration interval too long (p. 12) */
                                result = TIME_ERROR;
                    }
-                   if (time_freq > time_tolerance)
-                       time_freq = time_tolerance;
-                   else if (time_freq < -time_tolerance)
-                       time_freq = -time_tolerance;
+                   time_freq = min(time_freq, time_tolerance);
+                   time_freq = max(time_freq, -time_tolerance);
                } /* STA_PLL || STA_PPSTIME */
            } /* txc->modes & ADJ_OFFSET */
            if (txc->modes & ADJ_TICK) {
@@ -384,10 +374,7 @@ leave:     if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
        if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
            txc->offset    = save_adjust;
        else {
-           if (time_offset < 0)
-               txc->offset = -(-time_offset >> SHIFT_UPDATE);
-           else
-               txc->offset = time_offset >> SHIFT_UPDATE;
+           txc->offset = shift_right(time_offset, SHIFT_UPDATE);
        }
        txc->freq          = time_freq + pps_freq;
        txc->maxerror      = time_maxerror;
index 6a2e5f8dc725ffea0b73bb60036838b6ca628c5f..fd74268d8663ca8734814f175c1f0735d020d7a0 100644 (file)
@@ -46,6 +46,10 @@ static void time_interpolator_update(long delta_nsec);
 #define time_interpolator_update(x)
 #endif
 
+u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
 /*
  * per-CPU timer vector definitions:
  */
@@ -91,30 +95,6 @@ static inline void set_running_timer(tvec_base_t *base,
 #endif
 }
 
-static void check_timer_failed(struct timer_list *timer)
-{
-       static int whine_count;
-       if (whine_count < 16) {
-               whine_count++;
-               printk("Uninitialised timer!\n");
-               printk("This is just a warning.  Your computer is OK\n");
-               printk("function=0x%p, data=0x%lx\n",
-                       timer->function, timer->data);
-               dump_stack();
-       }
-       /*
-        * Now fix it up
-        */
-       timer->magic = TIMER_MAGIC;
-}
-
-static inline void check_timer(struct timer_list *timer)
-{
-       if (timer->magic != TIMER_MAGIC)
-               check_timer_failed(timer);
-}
-
-
 static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
 {
        unsigned long expires = timer->expires;
@@ -177,7 +157,6 @@ void fastcall init_timer(struct timer_list *timer)
 {
        timer->entry.next = NULL;
        timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
-       timer->magic = TIMER_MAGIC;
 }
 EXPORT_SYMBOL(init_timer);
 
@@ -230,7 +209,6 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
        int ret = 0;
 
        BUG_ON(!timer->function);
-       check_timer(timer);
 
        base = lock_timer_base(timer, &flags);
 
@@ -283,9 +261,6 @@ void add_timer_on(struct timer_list *timer, int cpu)
        unsigned long flags;
 
        BUG_ON(timer_pending(timer) || !timer->function);
-
-       check_timer(timer);
-
        spin_lock_irqsave(&base->t_base.lock, flags);
        timer->base = &base->t_base;
        internal_add_timer(base, timer);
@@ -316,8 +291,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
 {
        BUG_ON(!timer->function);
 
-       check_timer(timer);
-
        /*
         * This is a common optimization triggered by the
         * networking code - if the timer is re-modified
@@ -348,8 +321,6 @@ int del_timer(struct timer_list *timer)
        unsigned long flags;
        int ret = 0;
 
-       check_timer(timer);
-
        if (timer_pending(timer)) {
                base = lock_timer_base(timer, &flags);
                if (timer_pending(timer)) {
@@ -412,8 +383,6 @@ out:
  */
 int del_timer_sync(struct timer_list *timer)
 {
-       check_timer(timer);
-
        for (;;) {
                int ret = try_to_del_timer_sync(timer);
                if (ret >= 0)
@@ -632,143 +601,118 @@ long time_next_adjust;
  */
 static void second_overflow(void)
 {
-    long ltemp;
-
-    /* Bump the maxerror field */
-    time_maxerror += time_tolerance >> SHIFT_USEC;
-    if ( time_maxerror > NTP_PHASE_LIMIT ) {
-       time_maxerror = NTP_PHASE_LIMIT;
-       time_status |= STA_UNSYNC;
-    }
-
-    /*
-     * Leap second processing. If in leap-insert state at
-     * the end of the day, the system clock is set back one
-     * second; if in leap-delete state, the system clock is
-     * set ahead one second. The microtime() routine or
-     * external clock driver will insure that reported time
-     * is always monotonic. The ugly divides should be
-     * replaced.
-     */
-    switch (time_state) {
-
-    case TIME_OK:
-       if (time_status & STA_INS)
-           time_state = TIME_INS;
-       else if (time_status & STA_DEL)
-           time_state = TIME_DEL;
-       break;
-
-    case TIME_INS:
-       if (xtime.tv_sec % 86400 == 0) {
-           xtime.tv_sec--;
-           wall_to_monotonic.tv_sec++;
-           /* The timer interpolator will make time change gradually instead
-            * of an immediate jump by one second.
-            */
-           time_interpolator_update(-NSEC_PER_SEC);
-           time_state = TIME_OOP;
-           clock_was_set();
-           printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
+       long ltemp;
+
+       /* Bump the maxerror field */
+       time_maxerror += time_tolerance >> SHIFT_USEC;
+       if (time_maxerror > NTP_PHASE_LIMIT) {
+               time_maxerror = NTP_PHASE_LIMIT;
+               time_status |= STA_UNSYNC;
        }
-       break;
-
-    case TIME_DEL:
-       if ((xtime.tv_sec + 1) % 86400 == 0) {
-           xtime.tv_sec++;
-           wall_to_monotonic.tv_sec--;
-           /* Use of time interpolator for a gradual change of time */
-           time_interpolator_update(NSEC_PER_SEC);
-           time_state = TIME_WAIT;
-           clock_was_set();
-           printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
+
+       /*
+        * Leap second processing. If in leap-insert state at the end of the
+        * day, the system clock is set back one second; if in leap-delete
+        * state, the system clock is set ahead one second. The microtime()
+        * routine or external clock driver will insure that reported time is
+        * always monotonic. The ugly divides should be replaced.
+        */
+       switch (time_state) {
+       case TIME_OK:
+               if (time_status & STA_INS)
+                       time_state = TIME_INS;
+               else if (time_status & STA_DEL)
+                       time_state = TIME_DEL;
+               break;
+       case TIME_INS:
+               if (xtime.tv_sec % 86400 == 0) {
+                       xtime.tv_sec--;
+                       wall_to_monotonic.tv_sec++;
+                       /*
+                        * The timer interpolator will make time change
+                        * gradually instead of an immediate jump by one second
+                        */
+                       time_interpolator_update(-NSEC_PER_SEC);
+                       time_state = TIME_OOP;
+                       clock_was_set();
+                       printk(KERN_NOTICE "Clock: inserting leap second "
+                                       "23:59:60 UTC\n");
+               }
+               break;
+       case TIME_DEL:
+               if ((xtime.tv_sec + 1) % 86400 == 0) {
+                       xtime.tv_sec++;
+                       wall_to_monotonic.tv_sec--;
+                       /*
+                        * Use of time interpolator for a gradual change of
+                        * time
+                        */
+                       time_interpolator_update(NSEC_PER_SEC);
+                       time_state = TIME_WAIT;
+                       clock_was_set();
+                       printk(KERN_NOTICE "Clock: deleting leap second "
+                                       "23:59:59 UTC\n");
+               }
+               break;
+       case TIME_OOP:
+               time_state = TIME_WAIT;
+               break;
+       case TIME_WAIT:
+               if (!(time_status & (STA_INS | STA_DEL)))
+               time_state = TIME_OK;
        }
-       break;
-
-    case TIME_OOP:
-       time_state = TIME_WAIT;
-       break;
-
-    case TIME_WAIT:
-       if (!(time_status & (STA_INS | STA_DEL)))
-           time_state = TIME_OK;
-    }
-
-    /*
-     * Compute the phase adjustment for the next second. In
-     * PLL mode, the offset is reduced by a fixed factor
-     * times the time constant. In FLL mode the offset is
-     * used directly. In either mode, the maximum phase
-     * adjustment for each second is clamped so as to spread
-     * the adjustment over not more than the number of
-     * seconds between updates.
-     */
-    if (time_offset < 0) {
-       ltemp = -time_offset;
-       if (!(time_status & STA_FLL))
-           ltemp >>= SHIFT_KG + time_constant;
-       if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
-           ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
-       time_offset += ltemp;
-       time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
-    } else {
+
+       /*
+        * Compute the phase adjustment for the next second. In PLL mode, the
+        * offset is reduced by a fixed factor times the time constant. In FLL
+        * mode the offset is used directly. In either mode, the maximum phase
+        * adjustment for each second is clamped so as to spread the adjustment
+        * over not more than the number of seconds between updates.
+        */
        ltemp = time_offset;
        if (!(time_status & STA_FLL))
-           ltemp >>= SHIFT_KG + time_constant;
-       if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
-           ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
+               ltemp = shift_right(ltemp, SHIFT_KG + time_constant);
+       ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
+       ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
        time_offset -= ltemp;
        time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
-    }
-
-    /*
-     * Compute the frequency estimate and additional phase
-     * adjustment due to frequency error for the next
-     * second. When the PPS signal is engaged, gnaw on the
-     * watchdog counter and update the frequency computed by
-     * the pll and the PPS signal.
-     */
-    pps_valid++;
-    if (pps_valid == PPS_VALID) {      /* PPS signal lost */
-       pps_jitter = MAXTIME;
-       pps_stabil = MAXFREQ;
-       time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
-                        STA_PPSWANDER | STA_PPSERROR);
-    }
-    ltemp = time_freq + pps_freq;
-    if (ltemp < 0)
-       time_adj -= -ltemp >>
-           (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
-    else
-       time_adj += ltemp >>
-           (SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
+
+       /*
+        * Compute the frequency estimate and additional phase adjustment due
+        * to frequency error for the next second. When the PPS signal is
+        * engaged, gnaw on the watchdog counter and update the frequency
+        * computed by the pll and the PPS signal.
+        */
+       pps_valid++;
+       if (pps_valid == PPS_VALID) {   /* PPS signal lost */
+               pps_jitter = MAXTIME;
+               pps_stabil = MAXFREQ;
+               time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+                               STA_PPSWANDER | STA_PPSERROR);
+       }
+       ltemp = time_freq + pps_freq;
+       time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
 
 #if HZ == 100
-    /* Compensate for (HZ==100) != (1 << SHIFT_HZ).
-     * Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
-     */
-    if (time_adj < 0)
-       time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
-    else
-       time_adj += (time_adj >> 2) + (time_adj >> 5);
+       /*
+        * Compensate for (HZ==100) != (1 << SHIFT_HZ).  Add 25% and 3.125% to
+        * get 128.125; => only 0.125% error (p. 14)
+        */
+       time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
 #endif
 #if HZ == 250
-    /* Compensate for (HZ==250) != (1 << SHIFT_HZ).
-     * Add 1.5625% and 0.78125% to get 255.85938; => only 0.05% error (p. 14)
-     */
-    if (time_adj < 0)
-       time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
-    else
-       time_adj += (time_adj >> 6) + (time_adj >> 7);
+       /*
+        * Compensate for (HZ==250) != (1 << SHIFT_HZ).  Add 1.5625% and
+        * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
+        */
+       time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
 #endif
 #if HZ == 1000
-    /* Compensate for (HZ==1000) != (1 << SHIFT_HZ).
-     * Add 1.5625% and 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
-     */
-    if (time_adj < 0)
-       time_adj -= (-time_adj >> 6) + (-time_adj >> 7);
-    else
-       time_adj += (time_adj >> 6) + (time_adj >> 7);
+       /*
+        * Compensate for (HZ==1000) != (1 << SHIFT_HZ).  Add 1.5625% and
+        * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
+        */
+       time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
 #endif
 }
 
@@ -777,23 +721,20 @@ static void update_wall_time_one_tick(void)
 {
        long time_adjust_step, delta_nsec;
 
-       if ( (time_adjust_step = time_adjust) != 0 ) {
-           /* We are doing an adjtime thing. 
-            *
-            * Prepare time_adjust_step to be within bounds.
-            * Note that a positive time_adjust means we want the clock
-            * to run faster.
-            *
-            * Limit the amount of the step to be in the range
-            * -tickadj .. +tickadj
-            */
-            if (time_adjust > tickadj)
-               time_adjust_step = tickadj;
-            else if (time_adjust < -tickadj)
-               time_adjust_step = -tickadj;
-
-           /* Reduce by this step the amount of time left  */
-           time_adjust -= time_adjust_step;
+       if ((time_adjust_step = time_adjust) != 0 ) {
+               /*
+                * We are doing an adjtime thing.  Prepare time_adjust_step to
+                * be within bounds.  Note that a positive time_adjust means we
+                * want the clock to run faster.
+                *
+                * Limit the amount of the step to be in the range
+                * -tickadj .. +tickadj
+                */
+               time_adjust_step = min(time_adjust_step, (long)tickadj);
+               time_adjust_step = max(time_adjust_step, (long)-tickadj);
+
+               /* Reduce by this step the amount of time left  */
+               time_adjust -= time_adjust_step;
        }
        delta_nsec = tick_nsec + time_adjust_step * 1000;
        /*
@@ -801,13 +742,8 @@ static void update_wall_time_one_tick(void)
         * advance the tick more.
         */
        time_phase += time_adj;
-       if (time_phase <= -FINENSEC) {
-               long ltemp = -time_phase >> (SHIFT_SCALE - 10);
-               time_phase += ltemp << (SHIFT_SCALE - 10);
-               delta_nsec -= ltemp;
-       }
-       else if (time_phase >= FINENSEC) {
-               long ltemp = time_phase >> (SHIFT_SCALE - 10);
+       if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
+               long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
                time_phase -= ltemp << (SHIFT_SCALE - 10);
                delta_nsec += ltemp;
        }
@@ -1137,8 +1073,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
                if (timeout < 0)
                {
                        printk(KERN_ERR "schedule_timeout: wrong timeout "
-                              "value %lx from %p\n", timeout,
-                              __builtin_return_address(0));
+                               "value %lx from %p\n", timeout,
+                               __builtin_return_address(0));
                        current->state = TASK_RUNNING;
                        goto out;
                }
@@ -1146,12 +1082,8 @@ fastcall signed long __sched schedule_timeout(signed long timeout)
 
        expire = timeout + jiffies;
 
-       init_timer(&timer);
-       timer.expires = expire;
-       timer.data = (unsigned long) current;
-       timer.function = process_timeout;
-
-       add_timer(&timer);
+       setup_timer(&timer, process_timeout, (unsigned long)current);
+       __mod_timer(&timer, expire);
        schedule();
        del_singleshot_timer_sync(&timer);
 
@@ -1168,15 +1100,15 @@ EXPORT_SYMBOL(schedule_timeout);
  */
 signed long __sched schedule_timeout_interruptible(signed long timeout)
 {
-       __set_current_state(TASK_INTERRUPTIBLE);
-       return schedule_timeout(timeout);
+       __set_current_state(TASK_INTERRUPTIBLE);
+       return schedule_timeout(timeout);
 }
 EXPORT_SYMBOL(schedule_timeout_interruptible);
 
 signed long __sched schedule_timeout_uninterruptible(signed long timeout)
 {
-       __set_current_state(TASK_UNINTERRUPTIBLE);
-       return schedule_timeout(timeout);
+       __set_current_state(TASK_UNINTERRUPTIBLE);
+       return schedule_timeout(timeout);
 }
 EXPORT_SYMBOL(schedule_timeout_uninterruptible);
 
@@ -1516,16 +1448,18 @@ static void time_interpolator_update(long delta_nsec)
        if (!time_interpolator)
                return;
 
-       /* The interpolator compensates for late ticks by accumulating
-         * the late time in time_interpolator->offset. A tick earlier than
-        * expected will lead to a reset of the offset and a corresponding
-        * jump of the clock forward. Again this only works if the
-        * interpolator clock is running slightly slower than the regular clock
-        * and the tuning logic insures that.
-         */
+       /*
+        * The interpolator compensates for late ticks by accumulating the late
+        * time in time_interpolator->offset. A tick earlier than expected will
+        * lead to a reset of the offset and a corresponding jump of the clock
+        * forward. Again this only works if the interpolator clock is running
+        * slightly slower than the regular clock and the tuning logic insures
+        * that.
+        */
 
        counter = time_interpolator_get_counter(1);
-       offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);
+       offset = time_interpolator->offset +
+                       GET_TI_NSECS(counter, time_interpolator);
 
        if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
                time_interpolator->offset = offset - delta_nsec;
index 91bacb13a7e2fec56f5067f12e0b97c1043c30b7..7cee222231bc46843d7d5b68acbb82f375c1af71 100644 (file)
@@ -12,6 +12,8 @@
  *   Andrew Morton <andrewm@uow.edu.au>
  *   Kai Petzke <wpp@marie.physik.tu-berlin.de>
  *   Theodore Ts'o <tytso@mit.edu>
+ *
+ * Made to use alloc_percpu by Christoph Lameter <clameter@sgi.com>.
  */
 
 #include <linux/module.h>
@@ -57,7 +59,7 @@ struct cpu_workqueue_struct {
  * per-CPU workqueues:
  */
 struct workqueue_struct {
-       struct cpu_workqueue_struct cpu_wq[NR_CPUS];
+       struct cpu_workqueue_struct *cpu_wq;
        const char *name;
        struct list_head list;  /* Empty if single thread */
 };
@@ -102,7 +104,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work)
                if (unlikely(is_single_threaded(wq)))
                        cpu = 0;
                BUG_ON(!list_empty(&work->entry));
-               __queue_work(wq->cpu_wq + cpu, work);
+               __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
                ret = 1;
        }
        put_cpu();
@@ -118,7 +120,7 @@ static void delayed_work_timer_fn(unsigned long __data)
        if (unlikely(is_single_threaded(wq)))
                cpu = 0;
 
-       __queue_work(wq->cpu_wq + cpu, work);
+       __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
 }
 
 int fastcall queue_delayed_work(struct workqueue_struct *wq,
@@ -265,13 +267,13 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
 
        if (is_single_threaded(wq)) {
                /* Always use cpu 0's area. */
-               flush_cpu_workqueue(wq->cpu_wq + 0);
+               flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
        } else {
                int cpu;
 
                lock_cpu_hotplug();
                for_each_online_cpu(cpu)
-                       flush_cpu_workqueue(wq->cpu_wq + cpu);
+                       flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
                unlock_cpu_hotplug();
        }
 }
@@ -279,7 +281,7 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
 static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
                                                   int cpu)
 {
-       struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+       struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
        struct task_struct *p;
 
        spin_lock_init(&cwq->lock);
@@ -312,6 +314,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
        if (!wq)
                return NULL;
 
+       wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
        wq->name = name;
        /* We don't need the distraction of CPUs appearing and vanishing. */
        lock_cpu_hotplug();
@@ -353,7 +356,7 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
        unsigned long flags;
        struct task_struct *p;
 
-       cwq = wq->cpu_wq + cpu;
+       cwq = per_cpu_ptr(wq->cpu_wq, cpu);
        spin_lock_irqsave(&cwq->lock, flags);
        p = cwq->thread;
        cwq->thread = NULL;
@@ -380,6 +383,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
                spin_unlock(&workqueue_lock);
        }
        unlock_cpu_hotplug();
+       free_percpu(wq->cpu_wq);
        kfree(wq);
 }
 
@@ -458,7 +462,7 @@ int current_is_keventd(void)
 
        BUG_ON(!keventd_wq);
 
-       cwq = keventd_wq->cpu_wq + cpu;
+       cwq = per_cpu_ptr(keventd_wq->cpu_wq, cpu);
        if (current == cwq->thread)
                ret = 1;
 
@@ -470,7 +474,7 @@ int current_is_keventd(void)
 /* Take the work from this (downed) CPU. */
 static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
 {
-       struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+       struct cpu_workqueue_struct *cwq = per_cpu_ptr(wq->cpu_wq, cpu);
        LIST_HEAD(list);
        struct work_struct *work;
 
@@ -481,7 +485,7 @@ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu)
                printk("Taking work for %s\n", wq->name);
                work = list_entry(list.next,struct work_struct,entry);
                list_del(&work->entry);
-               __queue_work(wq->cpu_wq + smp_processor_id(), work);
+               __queue_work(per_cpu_ptr(wq->cpu_wq, smp_processor_id()), work);
        }
        spin_unlock_irq(&cwq->lock);
 }
@@ -508,15 +512,18 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
        case CPU_ONLINE:
                /* Kick off worker threads. */
                list_for_each_entry(wq, &workqueues, list) {
-                       kthread_bind(wq->cpu_wq[hotcpu].thread, hotcpu);
-                       wake_up_process(wq->cpu_wq[hotcpu].thread);
+                       struct cpu_workqueue_struct *cwq;
+
+                       cwq = per_cpu_ptr(wq->cpu_wq, hotcpu);
+                       kthread_bind(cwq->thread, hotcpu);
+                       wake_up_process(cwq->thread);
                }
                break;
 
        case CPU_UP_CANCELED:
                list_for_each_entry(wq, &workqueues, list) {
                        /* Unbind so it can run. */
-                       kthread_bind(wq->cpu_wq[hotcpu].thread,
+                       kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
                                     smp_processor_id());
                        cleanup_workqueue_thread(wq, hotcpu);
                }
index 016e89a44ac8defe6c753bd73d6bc74aa4e48e0f..156822e3cc797c80406e3516355a53e3d703d0a7 100644 (file)
@@ -128,7 +128,7 @@ config DEBUG_HIGHMEM
 config DEBUG_BUGVERBOSE
        bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
        depends on BUG
-       depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || (X86 && !X86_64) || FRV
+       depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
        default !EMBEDDED
        help
          Say Y here to make BUG() panics output the file name and line number
@@ -168,13 +168,34 @@ config DEBUG_FS
 
          If unsure, say N.
 
+config DEBUG_VM
+       bool "Debug VM"
+       depends on DEBUG_KERNEL
+       help
+         Enable this to debug the virtual-memory system.
+
+         If unsure, say N.
+
 config FRAME_POINTER
        bool "Compile the kernel with frame pointers"
        depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
        default y if DEBUG_INFO && UML
        help
          If you say Y here the resulting kernel image will be slightly larger
-         and slower, but it might give very useful debugging information
-         on some architectures or you use external debuggers.
+         and slower, but it might give very useful debugging information on
+         some architectures or if you use external debuggers.
          If you don't debug the kernel, you can say N.
 
+config RCU_TORTURE_TEST
+       tristate "torture tests for RCU"
+       depends on DEBUG_KERNEL
+       default n
+       help
+         This option provides a kernel module that runs torture tests
+         on the RCU infrastructure.  The kernel module may be built
+         after the fact on the running kernel to be tested, if desired.
+
+         Say Y here if you want RCU torture tests to start automatically
+         at boot time (you probably don't).
+         Say M if you want the RCU torture tests to build as a module.
+         Say N if you are unsure.
index fb9371fdd44a43c4e8e4fc9304f0ee00d3b4df8c..23d3b1147fe93aa282a2d772493c64dde9d4dd50 100644 (file)
@@ -511,6 +511,172 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
 }
 EXPORT_SYMBOL(bitmap_parselist);
 
+/*
+ * bitmap_pos_to_ord(buf, pos, bits)
+ *     @buf: pointer to a bitmap
+ *     @pos: a bit position in @buf (0 <= @pos < @bits)
+ *     @bits: number of valid bit positions in @buf
+ *
+ * Map the bit at position @pos in @buf (of length @bits) to the
+ * ordinal of which set bit it is.  If it is not set or if @pos
+ * is not a valid bit position, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @pos
+ * values 4 through 7 will get mapped to 0 through 3, respectively,
+ * and other @pos values will get mapped to 0.  When @pos value 7
+ * gets mapped to (returns) @ord value 3 in this example, that means
+ * that bit 7 is the 3rd (starting with 0th) set bit in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
+{
+       int ord = 0;
+
+       if (pos >= 0 && pos < bits) {
+               int i;
+
+               for (i = find_first_bit(buf, bits);
+                    i < pos;
+                    i = find_next_bit(buf, bits, i + 1))
+                       ord++;
+               if (i > pos)
+                       ord = 0;
+       }
+       return ord;
+}
+
+/**
+ * bitmap_ord_to_pos(buf, ord, bits)
+ *     @buf: pointer to bitmap
+ *     @ord: ordinal bit position (n-th set bit, n >= 0)
+ *     @bits: number of valid bit positions in @buf
+ *
+ * Map the ordinal offset of bit @ord in @buf to its position in @buf.
+ * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
+ *
+ * If for example, just bits 4 through 7 are set in @buf, then @ord
+ * values 0 through 3 will get mapped to 4 through 7, respectively,
+ * and all other @ord valuds will get mapped to 0.  When @ord value 3
+ * gets mapped to (returns) @pos value 7 in this example, that means
+ * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
+ *
+ * The bit positions 0 through @bits are valid positions in @buf.
+ */
+static int bitmap_ord_to_pos(const unsigned long *buf, int ord, int bits)
+{
+       int pos = 0;
+
+       if (ord >= 0 && ord < bits) {
+               int i;
+
+               for (i = find_first_bit(buf, bits);
+                    i < bits && ord > 0;
+                    i = find_next_bit(buf, bits, i + 1))
+                       ord--;
+               if (i < bits && ord == 0)
+                       pos = i;
+       }
+
+       return pos;
+}
+
+/**
+ * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
+ *     @src: subset to be remapped
+ *     @dst: remapped result
+ *     @old: defines domain of map
+ *     @new: defines range of map
+ *     @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new.  In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * If either of the @old and @new bitmaps are empty, or if@src and @dst
+ * point to the same location, then this routine does nothing.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to @src, placing the result in
+ * @dst, clearing any bits previously set in @dst.
+ *
+ * The resulting value of @dst will have either the same weight as
+ * @src, or less weight in the general case that the mapping wasn't
+ * injective due to the weight of @new being less than that of @old.
+ * The resulting value of @dst will never have greater weight than
+ * that of @src, except perhaps in the case that one of the above
+ * conditions was not met and this routine just returned.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set.  This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new.  So if say @src
+ * comes into this routine with bits 1, 5 and 7 set, then @dst should
+ * leave with bits 12, 13 and 15 set.
+ */
+void bitmap_remap(unsigned long *dst, const unsigned long *src,
+               const unsigned long *old, const unsigned long *new,
+               int bits)
+{
+       int s;
+
+       if (bitmap_weight(old, bits) == 0)
+               return;
+       if (bitmap_weight(new, bits) == 0)
+               return;
+       if (dst == src)         /* following doesn't handle inplace remaps */
+               return;
+
+       bitmap_zero(dst, bits);
+       for (s = find_first_bit(src, bits);
+            s < bits;
+            s = find_next_bit(src, bits, s + 1)) {
+               int x = bitmap_pos_to_ord(old, s, bits);
+               int y = bitmap_ord_to_pos(new, x, bits);
+               set_bit(y, dst);
+       }
+}
+EXPORT_SYMBOL(bitmap_remap);
+
+/**
+ * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
+ *     @oldbit - bit position to be mapped
+ *      @old: defines domain of map
+ *      @new: defines range of map
+ *      @bits: number of bits in each of these bitmaps
+ *
+ * Let @old and @new define a mapping of bit positions, such that
+ * whatever position is held by the n-th set bit in @old is mapped
+ * to the n-th set bit in @new.  In the more general case, allowing
+ * for the possibility that the weight 'w' of @new is less than the
+ * weight of @old, map the position of the n-th set bit in @old to
+ * the position of the m-th set bit in @new, where m == n % w.
+ *
+ * The positions of unset bits in @old are mapped to the position of
+ * the first set bit in @new.
+ *
+ * Apply the above specified mapping to bit position @oldbit, returning
+ * the new bit position.
+ *
+ * For example, lets say that @old has bits 4 through 7 set, and
+ * @new has bits 12 through 15 set.  This defines the mapping of bit
+ * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
+ * bit positions to 12 (the first set bit in @new.  So if say @oldbit
+ * is 5, then this routine returns 13.
+ */
+int bitmap_bitremap(int oldbit, const unsigned long *old,
+                               const unsigned long *new, int bits)
+{
+       int x = bitmap_pos_to_ord(old, oldbit, bits);
+       return bitmap_ord_to_pos(new, x, bits);
+}
+EXPORT_SYMBOL(bitmap_bitremap);
+
 /**
  *     bitmap_find_free_region - find a contiguous aligned mem region
  *     @bitmap: an array of unsigned longs corresponding to the bitmap
index 3f677a8f0c3c101421a4003fd286260b771a6a6b..18df57c029df1d702f4d1a4bb748b74e3ff82750 100644 (file)
@@ -16,9 +16,6 @@
 #include <linux/sort.h>
 #include <asm/uaccess.h>
 
-extern struct exception_table_entry __start___ex_table[];
-extern struct exception_table_entry __stop___ex_table[];
-
 #ifndef ARCH_HAS_SORT_EXTABLE
 /*
  * The exception table needs to be sorted so that the binary
index 6414b2fb482d48255e0e54e23dcead7ee849658c..d226259c3c28e5f8406123ff048367aed5d0aa60 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -6,20 +6,20 @@
  * Modified by George Anzinger to reuse immediately and to use
  * find bit instructions.  Also removed _irq on spinlocks.
  *
- * Small id to pointer translation service.  
+ * Small id to pointer translation service.
  *
- * It uses a radix tree like structure as a sparse array indexed 
+ * It uses a radix tree like structure as a sparse array indexed
  * by the id to obtain the pointer.  The bitmap makes allocating
- * a new id quick.  
+ * a new id quick.
  *
  * You call it to allocate an id (an int) an associate with that id a
  * pointer or what ever, we treat it as a (void *).  You can pass this
  * id to a user for him to pass back at a later time.  You then pass
  * that id to this code and it returns your pointer.
 
- * You can release ids at any time. When all ids are released, most of 
+ * You can release ids at any time. When all ids are released, most of
  * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we
- * don't need to go to the memory "store" during an id allocate, just 
+ * don't need to go to the memory "store" during an id allocate, just
  * so you don't need to be too concerned about locking and conflicts
  * with the slab allocator.
  */
@@ -77,7 +77,7 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
        while (idp->id_free_cnt < IDR_FREE_MAX) {
                struct idr_layer *new;
                new = kmem_cache_alloc(idr_layer_cache, gfp_mask);
-               if(new == NULL)
+               if (new == NULL)
                        return (0);
                free_layer(idp, new);
        }
@@ -107,7 +107,7 @@ static int sub_alloc(struct idr *idp, void *ptr, int *starting_id)
                if (m == IDR_SIZE) {
                        /* no space available go back to previous layer. */
                        l++;
-                       id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+                       id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
                        if (!(p = pa[l])) {
                                *starting_id = id;
                                return -2;
@@ -161,7 +161,7 @@ static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
 {
        struct idr_layer *p, *new;
        int layers, v, id;
-       
+
        id = starting_id;
 build_up:
        p = idp->top;
@@ -225,6 +225,7 @@ build_up:
 int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 {
        int rv;
+
        rv = idr_get_new_above_int(idp, ptr, starting_id);
        /*
         * This is a cheap hack until the IDR code can be fixed to
@@ -259,6 +260,7 @@ EXPORT_SYMBOL(idr_get_new_above);
 int idr_get_new(struct idr *idp, void *ptr, int *id)
 {
        int rv;
+
        rv = idr_get_new_above_int(idp, ptr, 0);
        /*
         * This is a cheap hack until the IDR code can be fixed to
@@ -306,11 +308,10 @@ static void sub_remove(struct idr *idp, int shift, int id)
                        free_layer(idp, **paa);
                        **paa-- = NULL;
                }
-               if ( ! *paa )
+               if (!*paa)
                        idp->layers = 0;
-       } else {
+       } else
                idr_remove_warning(id);
-       }
 }
 
 /**
@@ -326,9 +327,8 @@ void idr_remove(struct idr *idp, int id)
        id &= MAX_ID_MASK;
 
        sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
-       if ( idp->top && idp->top->count == 1 && 
-            (idp->layers > 1) &&
-            idp->top->ary[0]){  // We can drop a layer
+       if (idp->top && idp->top->count == 1 && (idp->layers > 1) &&
+           idp->top->ary[0]) {  // We can drop a layer
 
                p = idp->top->ary[0];
                idp->top->bitmap = idp->top->count = 0;
@@ -337,7 +337,6 @@ void idr_remove(struct idr *idp, int id)
                --idp->layers;
        }
        while (idp->id_free_cnt >= IDR_FREE_MAX) {
-               
                p = alloc_layer(idp);
                kmem_cache_free(idr_layer_cache, p);
                return;
@@ -391,8 +390,8 @@ void *idr_find(struct idr *idp, int id)
 }
 EXPORT_SYMBOL(idr_find);
 
-static void idr_cache_ctor(void * idr_layer, 
-                          kmem_cache_t *idr_layer_cache, unsigned long flags)
+static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
+               unsigned long flags)
 {
        memset(idr_layer, 0, sizeof(struct idr_layer));
 }
@@ -400,7 +399,7 @@ static void idr_cache_ctor(void * idr_layer,
 static  int init_id_cache(void)
 {
        if (!idr_layer_cache)
-               idr_layer_cache = kmem_cache_create("idr_layer_cache", 
+               idr_layer_cache = kmem_cache_create("idr_layer_cache",
                        sizeof(struct idr_layer), 0, 0, idr_cache_ctor, NULL);
        return 0;
 }
index 253d3004ace90edae789bb23f16c2919a4e6830c..a181abed89f6f119687e5082208f8debe11dd383 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/module.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 
 /**
  *     populate_dir - populate directory with attributes.
index 42c08ef828c55e940cdc226e7ed19811e1b75562..eddc9b3d38762ed17b06da35f26450f34c9ffd1a 100644 (file)
@@ -5,6 +5,7 @@
  */
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/sched.h>
 
 unsigned int debug_smp_processor_id(void)
 {
index ddc4d35df289cff02a996ba41d0d560ce9ccdead..5f3b51ffa1dc2a6897b09b42cee81ef2870b9ec8 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sort.h>
+#include <linux/slab.h>
 
 static void u32_swap(void *a, void *b, int size)
 {
index d886ef157c121ffb04fec4db267ee9af69e01f60..037a48acedbb21aae00269c87ef9f1821fb1bb67 100644 (file)
@@ -36,11 +36,13 @@ int strnicmp(const char *s1, const char *s2, size_t len)
        /* Yes, Virginia, it had better be unsigned */
        unsigned char c1, c2;
 
-       c1 = 0; c2 = 0;
+       c1 = c2 = 0;
        if (len) {
                do {
-                       c1 = *s1; c2 = *s2;
-                       s1++; s2++;
+                       c1 = *s1;
+                       c2 = *s2;
+                       s1++;
+                       s2++;
                        if (!c1)
                                break;
                        if (!c2)
@@ -55,7 +57,6 @@ int strnicmp(const char *s1, const char *s2, size_t len)
        }
        return (int)c1 - (int)c2;
 }
-
 EXPORT_SYMBOL(strnicmp);
 #endif
 
@@ -66,7 +67,7 @@ EXPORT_SYMBOL(strnicmp);
  * @src: Where to copy the string from
  */
 #undef strcpy
-char * strcpy(char * dest,const char *src)
+char *strcpy(char *dest, const char *src)
 {
        char *tmp = dest;
 
@@ -91,12 +92,13 @@ EXPORT_SYMBOL(strcpy);
  * count, the remainder of @dest will be padded with %NUL.
  *
  */
-char * strncpy(char * dest,const char *src,size_t count)
+char *strncpy(char *dest, const char *src, size_t count)
 {
        char *tmp = dest;
 
        while (count) {
-               if ((*tmp = *src) != 0) src++;
+               if ((*tmp = *src) != 0)
+                       src++;
                tmp++;
                count--;
        }
@@ -122,7 +124,7 @@ size_t strlcpy(char *dest, const char *src, size_t size)
        size_t ret = strlen(src);
 
        if (size) {
-               size_t len = (ret >= size) ? size-1 : ret;
+               size_t len = (ret >= size) ? size - 1 : ret;
                memcpy(dest, src, len);
                dest[len] = '\0';
        }
@@ -138,7 +140,7 @@ EXPORT_SYMBOL(strlcpy);
  * @src: The string to append to it
  */
 #undef strcat
-char * strcat(char * dest, const char * src)
+char *strcat(char *dest, const char *src)
 {
        char *tmp = dest;
 
@@ -146,7 +148,6 @@ char * strcat(char * dest, const char * src)
                dest++;
        while ((*dest++ = *src++) != '\0')
                ;
-
        return tmp;
 }
 EXPORT_SYMBOL(strcat);
@@ -162,7 +163,7 @@ EXPORT_SYMBOL(strcat);
  * Note that in contrast to strncpy, strncat ensures the result is
  * terminated.
  */
-char * strncat(char *dest, const char *src, size_t count)
+char *strncat(char *dest, const char *src, size_t count)
 {
        char *tmp = dest;
 
@@ -176,7 +177,6 @@ char * strncat(char *dest, const char *src, size_t count)
                        }
                }
        }
-
        return tmp;
 }
 EXPORT_SYMBOL(strncat);
@@ -216,15 +216,14 @@ EXPORT_SYMBOL(strlcat);
  * @ct: Another string
  */
 #undef strcmp
-int strcmp(const char * cs,const char * ct)
+int strcmp(const char *cs, const char *ct)
 {
-       register signed char __res;
+       signed char __res;
 
        while (1) {
                if ((__res = *cs - *ct++) != 0 || !*cs++)
                        break;
        }
-
        return __res;
 }
 EXPORT_SYMBOL(strcmp);
@@ -237,16 +236,15 @@ EXPORT_SYMBOL(strcmp);
  * @ct: Another string
  * @count: The maximum number of bytes to compare
  */
-int strncmp(const char * cs,const char * ct,size_t count)
+int strncmp(const char *cs, const char *ct, size_t count)
 {
-       register signed char __res = 0;
+       signed char __res = 0;
 
        while (count) {
                if ((__res = *cs - *ct++) != 0 || !*cs++)
                        break;
                count--;
        }
-
        return __res;
 }
 EXPORT_SYMBOL(strncmp);
@@ -258,12 +256,12 @@ EXPORT_SYMBOL(strncmp);
  * @s: The string to be searched
  * @c: The character to search for
  */
-char * strchr(const char * s, int c)
+char *strchr(const char *s, int c)
 {
-       for(; *s != (char) c; ++s)
+       for (; *s != (char)c; ++s)
                if (*s == '\0')
                        return NULL;
-       return (char *) s;
+       return (char *)s;
 }
 EXPORT_SYMBOL(strchr);
 #endif
@@ -274,7 +272,7 @@ EXPORT_SYMBOL(strchr);
  * @s: The string to be searched
  * @c: The character to search for
  */
-char * strrchr(const char * s, int c)
+char *strrchr(const char *s, int c)
 {
        const char *p = s + strlen(s);
        do {
@@ -296,8 +294,8 @@ EXPORT_SYMBOL(strrchr);
 char *strnchr(const char *s, size_t count, int c)
 {
        for (; count-- && *s != '\0'; ++s)
-               if (*s == (char) c)
-                       return (char *) s;
+               if (*s == (char)c)
+                       return (char *)s;
        return NULL;
 }
 EXPORT_SYMBOL(strnchr);
@@ -308,7 +306,7 @@ EXPORT_SYMBOL(strnchr);
  * strlen - Find the length of a string
  * @s: The string to be sized
  */
-size_t strlen(const char * s)
+size_t strlen(const char *s)
 {
        const char *sc;
 
@@ -325,7 +323,7 @@ EXPORT_SYMBOL(strlen);
  * @s: The string to be sized
  * @count: The maximum number of bytes to search
  */
-size_t strnlen(const char * s, size_t count)
+size_t strnlen(const char *s, size_t count)
 {
        const char *sc;
 
@@ -358,7 +356,6 @@ size_t strspn(const char *s, const char *accept)
                        return count;
                ++count;
        }
-
        return count;
 }
 
@@ -384,9 +381,8 @@ size_t strcspn(const char *s, const char *reject)
                }
                ++count;
        }
-
        return count;
-}      
+}
 EXPORT_SYMBOL(strcspn);
 
 #ifndef __HAVE_ARCH_STRPBRK
@@ -395,14 +391,14 @@ EXPORT_SYMBOL(strcspn);
  * @cs: The string to be searched
  * @ct: The characters to search for
  */
-char * strpbrk(const char * cs,const char * ct)
+char *strpbrk(const char *cs, const char *ct)
 {
-       const char *sc1,*sc2;
+       const char *sc1, *sc2;
 
-       forsc1 = cs; *sc1 != '\0'; ++sc1) {
-               forsc2 = ct; *sc2 != '\0'; ++sc2) {
+       for (sc1 = cs; *sc1 != '\0'; ++sc1) {
+               for (sc2 = ct; *sc2 != '\0'; ++sc2) {
                        if (*sc1 == *sc2)
-                               return (char *) sc1;
+                               return (char *)sc1;
                }
        }
        return NULL;
@@ -422,9 +418,10 @@ EXPORT_SYMBOL(strpbrk);
  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
  * Same semantics, slimmer shape. ;)
  */
-char * strsep(char **s, const char *ct)
+char *strsep(char **s, const char *ct)
 {
-       char *sbegin = *s, *end;
+       char *sbegin = *s;
+       char *end;
 
        if (sbegin == NULL)
                return NULL;
@@ -433,10 +430,8 @@ char * strsep(char **s, const char *ct)
        if (end)
                *end++ = '\0';
        *s = end;
-
        return sbegin;
 }
-
 EXPORT_SYMBOL(strsep);
 #endif
 
@@ -449,13 +444,12 @@ EXPORT_SYMBOL(strsep);
  *
  * Do not use memset() to access IO space, use memset_io() instead.
  */
-void * memset(void * s,int c,size_t count)
+void *memset(void *s, int c, size_t count)
 {
-       char *xs = (char *) s;
+       char *xs = s;
 
        while (count--)
                *xs++ = c;
-
        return s;
 }
 EXPORT_SYMBOL(memset);
@@ -471,13 +465,13 @@ EXPORT_SYMBOL(memset);
  * You should not use this function to access IO space, use memcpy_toio()
  * or memcpy_fromio() instead.
  */
-void * memcpy(void * dest,const void *src,size_t count)
+void *memcpy(void *dest, const void *src, size_t count)
 {
-       char *tmp = (char *) dest, *s = (char *) src;
+       char *tmp = dest;
+       char *s = src;
 
        while (count--)
                *tmp++ = *s++;
-
        return dest;
 }
 EXPORT_SYMBOL(memcpy);
@@ -492,23 +486,24 @@ EXPORT_SYMBOL(memcpy);
  *
  * Unlike memcpy(), memmove() copes with overlapping areas.
  */
-void * memmove(void * dest,const void *src,size_t count)
+void *memmove(void *dest, const void *src, size_t count)
 {
-       char *tmp, *s;
+       char *tmp;
+       const char *s;
 
        if (dest <= src) {
-               tmp = (char *) dest;
-               s = (char *) src;
+               tmp = dest;
+               s = src;
                while (count--)
                        *tmp++ = *s++;
-               }
-       else {
-               tmp = (char *) dest + count;
-               s = (char *) src + count;
+       } else {
+               tmp = dest;
+               tmp += count;
+               s = src;
+               s += count;
                while (count--)
                        *--tmp = *--s;
-               }
-
+       }
        return dest;
 }
 EXPORT_SYMBOL(memmove);
@@ -522,12 +517,12 @@ EXPORT_SYMBOL(memmove);
  * @count: The size of the area.
  */
 #undef memcmp
-int memcmp(const void * cs,const void * ct,size_t count)
+int memcmp(const void *cs, const void *ct, size_t count)
 {
        const unsigned char *su1, *su2;
        int res = 0;
 
-       forsu1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+       for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
                if ((res = *su1 - *su2) != 0)
                        break;
        return res;
@@ -545,17 +540,17 @@ EXPORT_SYMBOL(memcmp);
  * returns the address of the first occurrence of @c, or 1 byte past
  * the area if @c is not found
  */
-void * memscan(void * addr, int c, size_t size)
+void *memscan(void *addr, int c, size_t size)
 {
-       unsigned char * p = (unsigned char *) addr;
+       unsigned char *p = addr;
 
        while (size) {
                if (*p == c)
-                       return (void *) p;
+                       return (void *)p;
                p++;
                size--;
        }
-       return (void *) p;
+       return (void *)p;
 }
 EXPORT_SYMBOL(memscan);
 #endif
@@ -566,18 +561,18 @@ EXPORT_SYMBOL(memscan);
  * @s1: The string to be searched
  * @s2: The string to search for
  */
-char * strstr(const char * s1,const char * s2)
+char *strstr(const char *s1, const char *s2)
 {
        int l1, l2;
 
        l2 = strlen(s2);
        if (!l2)
-               return (char *) s1;
+               return (char *)s1;
        l1 = strlen(s1);
        while (l1 >= l2) {
                l1--;
-               if (!memcmp(s1,s2,l2))
-                       return (char *) s1;
+               if (!memcmp(s1, s2, l2))
+                       return (char *)s1;
                s1++;
        }
        return NULL;
@@ -600,7 +595,7 @@ void *memchr(const void *s, int c, size_t n)
        const unsigned char *p = s;
        while (n-- != 0) {
                if ((unsigned char)c == *p++) {
-                       return (void *)(p-1);
+                       return (void *)(p - 1);
                }
        }
        return NULL;
index e4e9031dd9c38709b82fd7de2da931ada0cec248..b07db5ca3f66febf20041ac5a6606d097dea2a15 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/ctype.h>
 #include <linux/kernel.h>
 
+#include <asm/page.h>          /* for PAGE_SIZE */
 #include <asm/div64.h>
 
 /**
index 768687f1d46bb7c92345914f267fb6bbcc7803d7..5d6e4c2000dc674bd0456f6fa92dd2c5f1b0acfe 100644 (file)
@@ -1030,8 +1030,8 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                        desc.error = 0;
                        do_generic_file_read(filp,ppos,&desc,file_read_actor);
                        retval += desc.written;
-                       if (!retval) {
-                               retval = desc.error;
+                       if (desc.error) {
+                               retval = retval ?: desc.error;
                                break;
                        }
                }
index 2076b1542b8ac9ce32beba96e051bd70a62ebf96..5abc57c2b8bdd3804708267832fd20d29a65be71 100644 (file)
@@ -457,6 +457,7 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
        struct vm_area_struct *vma = NULL;
        struct mempolicy *pol = current->mempolicy;
 
+       cpuset_update_current_mems_allowed();
        if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
                return -EINVAL;
        if (flags & MPOL_F_ADDR) {
@@ -1206,3 +1207,66 @@ void numa_default_policy(void)
 {
        do_set_mempolicy(MPOL_DEFAULT, NULL);
 }
+
+/* Migrate a policy to a different set of nodes */
+static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
+                                                       const nodemask_t *new)
+{
+       nodemask_t tmp;
+
+       if (!pol)
+               return;
+
+       switch (pol->policy) {
+       case MPOL_DEFAULT:
+               break;
+       case MPOL_INTERLEAVE:
+               nodes_remap(tmp, pol->v.nodes, *old, *new);
+               pol->v.nodes = tmp;
+               current->il_next = node_remap(current->il_next, *old, *new);
+               break;
+       case MPOL_PREFERRED:
+               pol->v.preferred_node = node_remap(pol->v.preferred_node,
+                                                               *old, *new);
+               break;
+       case MPOL_BIND: {
+               nodemask_t nodes;
+               struct zone **z;
+               struct zonelist *zonelist;
+
+               nodes_clear(nodes);
+               for (z = pol->v.zonelist->zones; *z; z++)
+                       node_set((*z)->zone_pgdat->node_id, nodes);
+               nodes_remap(tmp, nodes, *old, *new);
+               nodes = tmp;
+
+               zonelist = bind_zonelist(&nodes);
+
+               /* If no mem, then zonelist is NULL and we keep old zonelist.
+                * If that old zonelist has no remaining mems_allowed nodes,
+                * then zonelist_policy() will "FALL THROUGH" to MPOL_DEFAULT.
+                */
+
+               if (zonelist) {
+                       /* Good - got mem - substitute new zonelist */
+                       kfree(pol->v.zonelist);
+                       pol->v.zonelist = zonelist;
+               }
+               break;
+       }
+       default:
+               BUG();
+               break;
+       }
+}
+
+/*
+ * Someone moved this task to different nodes.  Fixup mempolicies.
+ *
+ * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well,
+ * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
+ */
+void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new)
+{
+       rebind_policy(current->mempolicy, old, new);
+}
index 5ecc2cf3e1d7fe27ef49787cb0909d1c3f96eebf..320dda1778c3b3489aea3a44e12251f939e75e3c 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1840,7 +1840,7 @@ asmlinkage long sys_munmap(unsigned long addr, size_t len)
 
 static inline void verify_mm_writelocked(struct mm_struct *mm)
 {
-#ifdef CONFIG_DEBUG_KERNEL
+#ifdef CONFIG_DEBUG_VM
        if (unlikely(down_read_trylock(&mm->mmap_sem))) {
                WARN_ON(1);
                up_read(&mm->mmap_sem);
index d6781951267eb654a522529658aaa06199d1772f..52822c98c489c36bc30e24871eef936766b5c784 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/fs.h>          // Needed by writeback.h
 #include <linux/writeback.h>   // Prototypes pdflush_operation()
 #include <linux/kthread.h>
+#include <linux/cpuset.h>
 
 
 /*
@@ -170,12 +171,24 @@ static int __pdflush(struct pdflush_work *my_work)
 static int pdflush(void *dummy)
 {
        struct pdflush_work my_work;
+       cpumask_t cpus_allowed;
 
        /*
         * pdflush can spend a lot of time doing encryption via dm-crypt.  We
         * don't want to do that at keventd's priority.
         */
        set_user_nice(current, 0);
+
+       /*
+        * Some configs put our parent kthread in a limited cpuset,
+        * which kthread() overrides, forcing cpus_allowed == CPU_MASK_ALL.
+        * Our needs are more modest - cut back to our cpusets cpus_allowed.
+        * This is needed as pdflush's are dynamically created and destroyed.
+        * The boottime pdflush's are easily placed w/o these 2 lines.
+        */
+       cpus_allowed = cpuset_cpus_allowed(current);
+       set_cpus_allowed(current, cpus_allowed);
+
        return __pdflush(&my_work);
 }
 
index b89512877ec2645da210c3e43e5a9c7e0f3cfb97..96387e20184ab85971794daeb524ed07de6f8e18 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -270,7 +270,6 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
        struct pagevec pages_to_free;
 
        pagevec_init(&pages_to_free, pvec->cold);
-       pages_to_free.cold = pvec->cold;
        for (i = 0; i < pagevec_count(pvec); i++) {
                struct page *page = pvec->pages[i];
 
index c13a2161bca286fd65f75ee087c9990c22d8d744..b58abcf44ed658e0a44b129a216a16e5cfc6f2d7 100644 (file)
@@ -31,11 +31,14 @@ static struct vfsmount *shm_mnt;
 
 static int __init init_tmpfs(void)
 {
-       register_filesystem(&tmpfs_fs_type);
+       BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
+
 #ifdef CONFIG_TMPFS
        devfs_mk_dir("shm");
 #endif
        shm_mnt = kern_mount(&tmpfs_fs_type);
+       BUG_ON(IS_ERR(shm_mnt));
+
        return 0;
 }
 module_init(init_tmpfs)
index 60c8764bfac2e20ff8f6f4420b0b8391e7dfa26d..29c18f68dc35cd9b1cc17ee6e5f21bf05d3658e7 100644 (file)
 #include <linux/pagemap.h>
 #include <linux/pagevec.h>
 #include <linux/buffer_head.h> /* grr. try_to_release_page,
-                                  block_invalidatepage */
+                                  do_invalidatepage */
 
 
-static int do_invalidatepage(struct page *page, unsigned long offset)
-{
-       int (*invalidatepage)(struct page *, unsigned long);
-       invalidatepage = page->mapping->a_ops->invalidatepage;
-       if (invalidatepage == NULL)
-               invalidatepage = block_invalidatepage;
-       return (*invalidatepage)(page, offset);
-}
-
 static inline void truncate_partial_page(struct page *page, unsigned partial)
 {
        memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
index f5909a4c3fc7852f2a34b040d870fa512cb8bbab..e19c2a52d00cb537e5783aeaa3e0fdd25005b744 100644 (file)
@@ -48,7 +48,7 @@ static int checkentry(const char *tablename, const struct ipt_ip *ip,
                      unsigned int hook_mask)
 {
        if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
-               printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.",
+               printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
                       matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
                return 0;
        }
index 2fcb244a9e180abe89d5783f189d3b09a18bc2a7..0dd96919de3e859894281454ebef491b296dc877 100644 (file)
@@ -116,6 +116,15 @@ endif
 clean-files    := lkc_defs.h qconf.moc .tmp_qtcheck \
                   .tmp_gtkcheck zconf.tab.c zconf.tab.h lex.zconf.c
 
+# Needed for systems without gettext
+KBUILD_HAVE_NLS := $(shell \
+     if echo "\#include <libint.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+     then echo yes ; \
+     else echo no ; fi)
+ifeq ($(KBUILD_HAVE_NLS),no)
+HOSTCFLAGS     += -DKBUILD_NO_NLS
+endif
+
 # generated files seem to need this to find local include files
 HOSTCFLAGS_lex.zconf.o := -I$(src)
 HOSTCFLAGS_zconf.tab.o := -I$(src)
index c3d25786a64dcec385e437867682069bcf18deda..5fba1feff2a813cdee2b8126b981ce898f854a0e 100644 (file)
@@ -8,7 +8,13 @@
 
 #include "expr.h"
 
-#include <libintl.h>
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+#endif
 
 #ifdef __cplusplus
 extern "C" {
index 457bec29511dfb60d47428d9a18029353aef92e1..d1ad40531ee5a681b63c3d142f556acac8eb02f3 100644 (file)
@@ -219,6 +219,7 @@ save_config_help[] = N_(
 search_help[] = N_(
        "\n"
        "Search for CONFIG_ symbols and display their relations.\n"
+       "Regular expressions are allowed.\n"
        "Example: search for \"^FOO\"\n"
        "Result:\n"
        "-----------------------------------------------------------------\n"
@@ -531,7 +532,7 @@ again:
        cprint("--title");
        cprint(_("Search Configuration Parameter"));
        cprint("--inputbox");
-       cprint(_("Enter Keyword"));
+       cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)"));
        cprint("10");
        cprint("75");
        cprint("");
index 3d34f3de7e82d06e646b1e79f1f1b18f377ec1d8..3ca5f2b828a0d84780c8ec223b1a62e954a7ff10 100644 (file)
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
        return 0;
 }
 
-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
 {
        return -EOPNOTSUPP;
 }
@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
        return -EINVAL;
 }
 
+#ifdef CONFIG_KEYS
+static inline int dummy_key_alloc(struct key *key)
+{
+       return 0;
+}
+
+static inline void dummy_key_free(struct key *key)
+{
+}
+
+static inline int dummy_key_permission(key_ref_t key_ref,
+                                      struct task_struct *context,
+                                      key_perm_t perm)
+{
+       return 0;
+}
+#endif /* CONFIG_KEYS */
 
 struct security_operations dummy_security_ops;
 
@@ -954,5 +971,11 @@ void security_fixup_ops (struct security_operations *ops)
        set_to_dummy_if_null(ops, sk_alloc_security);
        set_to_dummy_if_null(ops, sk_free_security);
 #endif /* CONFIG_SECURITY_NETWORK */
+#ifdef CONFIG_KEYS
+       set_to_dummy_if_null(ops, key_alloc);
+       set_to_dummy_if_null(ops, key_free);
+       set_to_dummy_if_null(ops, key_permission);
+#endif /* CONFIG_KEYS */
+
 }
 
index 2182be9e93093d87596ea965c301812de88484ba..ccde17aff6167848388ce263c4fddec30c8131e5 100644 (file)
@@ -1,6 +1,6 @@
 /* key.c: basic authentication token and access key management
  *
- * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/security.h>
 #include <linux/workqueue.h>
 #include <linux/err.h>
 #include "internal.h"
@@ -253,6 +254,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        struct key_user *user = NULL;
        struct key *key;
        size_t desclen, quotalen;
+       int ret;
 
        key = ERR_PTR(-EINVAL);
        if (!desc || !*desc)
@@ -305,6 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        key->flags = 0;
        key->expiry = 0;
        key->payload.data = NULL;
+       key->security = NULL;
 
        if (!not_in_quota)
                key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -315,16 +318,34 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        key->magic = KEY_DEBUG_MAGIC;
 #endif
 
+       /* let the security module know about the key */
+       ret = security_key_alloc(key);
+       if (ret < 0)
+               goto security_error;
+
        /* publish the key by giving it a serial number */
        atomic_inc(&user->nkeys);
        key_alloc_serial(key);
 
- error:
+error:
        return key;
 
- no_memory_3:
+security_error:
+       kfree(key->description);
+       kmem_cache_free(key_jar, key);
+       if (!not_in_quota) {
+               spin_lock(&user->lock);
+               user->qnkeys--;
+               user->qnbytes -= quotalen;
+               spin_unlock(&user->lock);
+       }
+       key_user_put(user);
+       key = ERR_PTR(ret);
+       goto error;
+
+no_memory_3:
        kmem_cache_free(key_jar, key);
- no_memory_2:
+no_memory_2:
        if (!not_in_quota) {
                spin_lock(&user->lock);
                user->qnkeys--;
@@ -332,11 +353,11 @@ struct key *key_alloc(struct key_type *type, const char *desc,
                spin_unlock(&user->lock);
        }
        key_user_put(user);
- no_memory_1:
+no_memory_1:
        key = ERR_PTR(-ENOMEM);
        goto error;
 
- no_quota:
+no_quota:
        spin_unlock(&user->lock);
        key_user_put(user);
        key = ERR_PTR(-EDQUOT);
@@ -556,6 +577,8 @@ static void key_cleanup(void *data)
 
        key_check(key);
 
+       security_key_free(key);
+
        /* deal with the user's key tracking and quota */
        if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
                spin_lock(&key->user->lock);
@@ -700,8 +723,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
        int ret;
 
        /* need write permission on the key to update it */
-       ret = -EACCES;
-       if (!key_permission(key_ref, KEY_WRITE))
+       ret = key_permission(key_ref, KEY_WRITE);
+       if (ret < 0)
                goto error;
 
        ret = -EEXIST;
@@ -711,7 +734,6 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
        down_write(&key->sem);
 
        ret = key->type->update(key, payload, plen);
-
        if (ret == 0)
                /* updating a negative key instantiates it */
                clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -768,9 +790,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
 
        /* if we're going to allocate a new key, we're going to have
         * to modify the keyring */
-       key_ref = ERR_PTR(-EACCES);
-       if (!key_permission(keyring_ref, KEY_WRITE))
+       ret = key_permission(keyring_ref, KEY_WRITE);
+       if (ret < 0) {
+               key_ref = ERR_PTR(ret);
                goto error_3;
+       }
 
        /* search for an existing key of the same type and description in the
         * destination keyring
@@ -780,8 +804,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                goto found_matching_key;
 
        /* decide on the permissions we want */
-       perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
-       perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
+       perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+       perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
 
        if (ktype->read)
                perm |= KEY_POS_READ | KEY_USR_READ;
@@ -840,16 +864,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
        key_check(key);
 
        /* the key must be writable */
-       ret = -EACCES;
-       if (!key_permission(key_ref, KEY_WRITE))
+       ret = key_permission(key_ref, KEY_WRITE);
+       if (ret < 0)
                goto error;
 
        /* attempt to update it if supported */
        ret = -EOPNOTSUPP;
        if (key->type->update) {
                down_write(&key->sem);
-               ret = key->type->update(key, payload, plen);
 
+               ret = key->type->update(key, payload, plen);
                if (ret == 0)
                        /* updating a negative key instantiates it */
                        clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
index 4c670ee6acf94ac0d936e6051346b27ff646d499..b7a468fabdf9a22e4ca1eecfc6da96f055512a58 100644 (file)
@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t ringid,
 
        /* link the resulting key to the destination keyring if we can */
        if (dest_ref) {
-               ret = -EACCES;
-               if (!key_permission(key_ref, KEY_LINK))
+               ret = key_permission(key_ref, KEY_LINK);
+               if (ret < 0)
                        goto error6;
 
                ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
        key = key_ref_to_ptr(key_ref);
 
        /* see if we can read it directly */
-       if (key_permission(key_ref, KEY_READ))
+       ret = key_permission(key_ref, KEY_READ);
+       if (ret == 0)
                goto can_read_key;
+       if (ret != -EACCES)
+               goto error;
 
        /* we can't; see if it's searchable from this process's keyrings
         * - we automatically take account of the fact that it may be
@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
        if (uid == (uid_t) -1 && gid == (gid_t) -1)
                goto error;
 
-       key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+       key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
                goto error;
@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
        if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
                goto error;
 
-       key_ref = lookup_user_key(NULL, id, 1, 1, 0);
+       key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
        if (IS_ERR(key_ref)) {
                ret = PTR_ERR(key_ref);
                goto error;
index 0639396dd441eabdc27418b66df7673a749419e8..e1cc4dd7901221352185e71daeffe1f3f779e325 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/security.h>
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <asm/uaccess.h>
@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
        int ret;
 
        keyring = key_alloc(&key_type_keyring, description,
-                           uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota);
+                           uid, gid,
+                           (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+                           not_in_quota);
 
        if (!IS_ERR(keyring)) {
                ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        key_check(keyring);
 
        /* top keyring must have search permission to begin the search */
-       key_ref = ERR_PTR(-EACCES);
-       if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
+        err = key_task_permission(keyring_ref, context, KEY_SEARCH);
+       if (err < 0) {
+               key_ref = ERR_PTR(err);
                goto error;
+       }
 
        key_ref = ERR_PTR(-ENOTDIR);
        if (keyring->type != &key_type_keyring)
@@ -402,8 +407,8 @@ descend:
                        continue;
 
                /* key must have search permissions */
-               if (!key_task_permission(make_key_ref(key, possessed),
-                                        context, KEY_SEARCH))
+               if (key_task_permission(make_key_ref(key, possessed),
+                                       context, KEY_SEARCH) < 0)
                        continue;
 
                /* we set a different error code if we find a negative key */
@@ -430,7 +435,7 @@ ascend:
                        continue;
 
                if (!key_task_permission(make_key_ref(key, possessed),
-                                        context, KEY_SEARCH))
+                                        context, KEY_SEARCH) < 0)
                        continue;
 
                /* stack the current position */
@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
                            (!key->type->match ||
                             key->type->match(key, description)) &&
                            key_permission(make_key_ref(key, possessed),
-                                          perm) &&
+                                          perm) < 0 &&
                            !test_bit(KEY_FLAG_REVOKED, &key->flags)
                            )
                                goto found;
@@ -617,7 +622,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
                                continue;
 
                        if (!key_permission(make_key_ref(keyring, 0),
-                                           KEY_SEARCH))
+                                           KEY_SEARCH) < 0)
                                continue;
 
                        /* found a potential candidate, but we still need to
index 03db073ba45c526ef82979babcc4abff47ea8438..e7f579c0eaf541e393df94815eecffc565dcde3d 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/security.h>
 #include "internal.h"
 
 /*****************************************************************************/
@@ -63,7 +64,11 @@ use_these_perms:
 
        kperm = kperm & perm & KEY_ALL;
 
-       return kperm == perm;
+       if (kperm != perm)
+               return -EACCES;
+
+       /* let LSM be the final arbiter */
+       return security_key_permission(key_ref, context, perm);
 
 } /* end key_task_permission() */
 
index d42d2158ce13beba31fb2753356e244a18e3a2a1..566b1cc0118afabcfa051a9d1402144eb9ace0b2 100644 (file)
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
        .type           = &key_type_keyring,
        .user           = &root_key_user,
        .sem            = __RWSEM_INITIALIZER(root_user_keyring.sem),
-       .perm           = KEY_POS_ALL | KEY_USR_ALL,
+       .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
        .flags          = 1 << KEY_FLAG_INSTANTIATED,
        .description    = "_uid.0",
 #ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
        .type           = &key_type_keyring,
        .user           = &root_key_user,
        .sem            = __RWSEM_INITIALIZER(root_session_keyring.sem),
-       .perm           = KEY_POS_ALL | KEY_USR_ALL,
+       .perm           = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
        .flags          = 1 << KEY_FLAG_INSTANTIATED,
        .description    = "_uid_ses.0",
 #ifdef KEY_DEBUGGING
@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
                goto invalid_key;
 
        /* check the permissions */
-       ret = -EACCES;
-
-       if (!key_task_permission(key_ref, context, perm))
+       ret = key_task_permission(key_ref, context, perm);
+       if (ret < 0)
                goto invalid_key;
 
 error:
index e446acba73d325a1d222a0a130c7f23f6a4232a9..cbda3b2780a100696b38e7ce47dec9e3eb46cf33 100644 (file)
 #include <linux/slab.h>
 #include <linux/seq_file.h>
 #include <linux/err.h>
+#include <keys/user-type.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
-static int user_instantiate(struct key *key, const void *data, size_t datalen);
-static int user_duplicate(struct key *key, const struct key *source);
-static int user_update(struct key *key, const void *data, size_t datalen);
-static int user_match(const struct key *key, const void *criterion);
-static void user_destroy(struct key *key);
-static void user_describe(const struct key *user, struct seq_file *m);
-static long user_read(const struct key *key,
-                     char __user *buffer, size_t buflen);
-
 /*
  * user defined keys take an arbitrary string as the description and an
  * arbitrary blob of data as the payload
@@ -42,19 +34,13 @@ struct key_type key_type_user = {
        .read           = user_read,
 };
 
-struct user_key_payload {
-       struct rcu_head rcu;            /* RCU destructor */
-       unsigned short  datalen;        /* length of this data */
-       char            data[0];        /* actual data */
-};
-
 EXPORT_SYMBOL_GPL(key_type_user);
 
 /*****************************************************************************/
 /*
  * instantiate a user defined key
  */
-static int user_instantiate(struct key *key, const void *data, size_t datalen)
+int user_instantiate(struct key *key, const void *data, size_t datalen)
 {
        struct user_key_payload *upayload;
        int ret;
@@ -78,18 +64,20 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
        rcu_assign_pointer(key->payload.data, upayload);
        ret = 0;
 
- error:
+error:
        return ret;
 
 } /* end user_instantiate() */
 
+EXPORT_SYMBOL_GPL(user_instantiate);
+
 /*****************************************************************************/
 /*
  * duplicate a user defined key
  * - both keys' semaphores are locked against further modification
  * - the new key cannot yet be accessed
  */
-static int user_duplicate(struct key *key, const struct key *source)
+int user_duplicate(struct key *key, const struct key *source)
 {
        struct user_key_payload *upayload, *spayload;
        int ret;
@@ -112,6 +100,8 @@ static int user_duplicate(struct key *key, const struct key *source)
 
 } /* end user_duplicate() */
 
+EXPORT_SYMBOL_GPL(user_duplicate);
+
 /*****************************************************************************/
 /*
  * dispose of the old data from an updated user defined key
@@ -131,7 +121,7 @@ static void user_update_rcu_disposal(struct rcu_head *rcu)
  * update a user defined key
  * - the key's semaphore is write-locked
  */
-static int user_update(struct key *key, const void *data, size_t datalen)
+int user_update(struct key *key, const void *data, size_t datalen)
 {
        struct user_key_payload *upayload, *zap;
        int ret;
@@ -163,26 +153,30 @@ static int user_update(struct key *key, const void *data, size_t datalen)
 
        call_rcu(&zap->rcu, user_update_rcu_disposal);
 
- error:
+error:
        return ret;
 
 } /* end user_update() */
 
+EXPORT_SYMBOL_GPL(user_update);
+
 /*****************************************************************************/
 /*
  * match users on their name
  */
-static int user_match(const struct key *key, const void *description)
+int user_match(const struct key *key, const void *description)
 {
        return strcmp(key->description, description) == 0;
 
 } /* end user_match() */
 
+EXPORT_SYMBOL_GPL(user_match);
+
 /*****************************************************************************/
 /*
  * dispose of the data dangling from the corpse of a user
  */
-static void user_destroy(struct key *key)
+void user_destroy(struct key *key)
 {
        struct user_key_payload *upayload = key->payload.data;
 
@@ -190,11 +184,13 @@ static void user_destroy(struct key *key)
 
 } /* end user_destroy() */
 
+EXPORT_SYMBOL_GPL(user_destroy);
+
 /*****************************************************************************/
 /*
  * describe the user key
  */
-static void user_describe(const struct key *key, struct seq_file *m)
+void user_describe(const struct key *key, struct seq_file *m)
 {
        seq_puts(m, key->description);
 
@@ -202,13 +198,14 @@ static void user_describe(const struct key *key, struct seq_file *m)
 
 } /* end user_describe() */
 
+EXPORT_SYMBOL_GPL(user_describe);
+
 /*****************************************************************************/
 /*
  * read the key data
  * - the key's semaphore is read-locked
  */
-static long user_read(const struct key *key,
-                     char __user *buffer, size_t buflen)
+long user_read(const struct key *key, char __user *buffer, size_t buflen)
 {
        struct user_key_payload *upayload;
        long ret;
@@ -228,3 +225,5 @@ static long user_read(const struct key *key,
        return ret;
 
 } /* end user_read() */
+
+EXPORT_SYMBOL_GPL(user_read);
index 447a1e0f48cb1c9bdfa520f874a76b3877b054bb..45c41490d521e22b07219345fe195f02e171ac27 100644 (file)
@@ -122,11 +122,10 @@ static int task_alloc_security(struct task_struct *task)
 {
        struct task_security_struct *tsec;
 
-       tsec = kmalloc(sizeof(struct task_security_struct), GFP_KERNEL);
+       tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
        if (!tsec)
                return -ENOMEM;
 
-       memset(tsec, 0, sizeof(struct task_security_struct));
        tsec->magic = SELINUX_MAGIC;
        tsec->task = task;
        tsec->osid = tsec->sid = tsec->ptrace_sid = SECINITSID_UNLABELED;
@@ -151,11 +150,10 @@ static int inode_alloc_security(struct inode *inode)
        struct task_security_struct *tsec = current->security;
        struct inode_security_struct *isec;
 
-       isec = kmalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
+       isec = kzalloc(sizeof(struct inode_security_struct), GFP_KERNEL);
        if (!isec)
                return -ENOMEM;
 
-       memset(isec, 0, sizeof(struct inode_security_struct));
        init_MUTEX(&isec->sem);
        INIT_LIST_HEAD(&isec->list);
        isec->magic = SELINUX_MAGIC;
@@ -193,11 +191,10 @@ static int file_alloc_security(struct file *file)
        struct task_security_struct *tsec = current->security;
        struct file_security_struct *fsec;
 
-       fsec = kmalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
+       fsec = kzalloc(sizeof(struct file_security_struct), GFP_ATOMIC);
        if (!fsec)
                return -ENOMEM;
 
-       memset(fsec, 0, sizeof(struct file_security_struct));
        fsec->magic = SELINUX_MAGIC;
        fsec->file = file;
        if (tsec && tsec->magic == SELINUX_MAGIC) {
@@ -227,11 +224,10 @@ static int superblock_alloc_security(struct super_block *sb)
 {
        struct superblock_security_struct *sbsec;
 
-       sbsec = kmalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
+       sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
        if (!sbsec)
                return -ENOMEM;
 
-       memset(sbsec, 0, sizeof(struct superblock_security_struct));
        init_MUTEX(&sbsec->sem);
        INIT_LIST_HEAD(&sbsec->list);
        INIT_LIST_HEAD(&sbsec->isec_head);
@@ -269,11 +265,10 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
        if (family != PF_UNIX)
                return 0;
 
-       ssec = kmalloc(sizeof(*ssec), priority);
+       ssec = kzalloc(sizeof(*ssec), priority);
        if (!ssec)
                return -ENOMEM;
 
-       memset(ssec, 0, sizeof(*ssec));
        ssec->magic = SELINUX_MAGIC;
        ssec->sk = sk;
        ssec->peer_sid = SECINITSID_UNLABELED;
@@ -1483,11 +1478,10 @@ static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
 {
        struct bprm_security_struct *bsec;
 
-       bsec = kmalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
+       bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
        if (!bsec)
                return -ENOMEM;
 
-       memset(bsec, 0, sizeof *bsec);
        bsec->magic = SELINUX_MAGIC;
        bsec->bprm = bprm;
        bsec->sid = SECINITSID_UNLABELED;
@@ -1615,7 +1609,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
 
        if (tty) {
                file_list_lock();
-               file = list_entry(tty->tty_files.next, typeof(*file), f_list);
+               file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
                if (file) {
                        /* Revalidate access to controlling tty.
                           Use inode_has_perm on the tty inode directly rather
@@ -2211,12 +2205,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
 
 static int selinux_inode_getxattr (struct dentry *dentry, char *name)
 {
-       struct inode *inode = dentry->d_inode;
-       struct superblock_security_struct *sbsec = inode->i_sb->s_security;
-
-       if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
-               return -EOPNOTSUPP;
-
        return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
 }
 
@@ -2247,33 +2235,54 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
        return -EACCES;
 }
 
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
+/*
+ * Copy the in-core inode security context value to the user.  If the
+ * getxattr() prior to this succeeded, check to see if we need to
+ * canonicalize the value to be finally returned to the user.
+ *
+ * Permission check is handled by selinux_inode_getxattr hook.
+ */
+static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
 {
        struct inode_security_struct *isec = inode->i_security;
        char *context;
        unsigned len;
        int rc;
 
-       /* Permission check handled by selinux_inode_getxattr hook.*/
-
-       if (strcmp(name, XATTR_SELINUX_SUFFIX))
-               return -EOPNOTSUPP;
+       if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
+               rc = -EOPNOTSUPP;
+               goto out;
+       }
 
        rc = security_sid_to_context(isec->sid, &context, &len);
        if (rc)
-               return rc;
+               goto out;
 
+       /* Probe for required buffer size */
        if (!buffer || !size) {
-               kfree(context);
-               return len;
+               rc = len;
+               goto out_free;
        }
+
        if (size < len) {
-               kfree(context);
-               return -ERANGE;
+               rc = -ERANGE;
+               goto out_free;
+       }
+
+       if (err > 0) {
+               if ((len == err) && !(memcmp(context, buffer, len))) {
+                       /* Don't need to canonicalize value */
+                       rc = err;
+                       goto out_free;
+               }
+               memset(buffer, 0, size);
        }
        memcpy(buffer, context, len);
+       rc = len;
+out_free:
        kfree(context);
-       return len;
+out:
+       return rc;
 }
 
 static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -2704,8 +2713,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
        if (rc)
                return rc;
 
-       if (info && ((unsigned long)info == 1 ||
-                    (unsigned long)info == 2 || SI_FROMKERNEL(info)))
+       if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
                return 0;
 
        if (!sig)
@@ -3599,11 +3607,10 @@ static int ipc_alloc_security(struct task_struct *task,
        struct task_security_struct *tsec = task->security;
        struct ipc_security_struct *isec;
 
-       isec = kmalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
+       isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
        if (!isec)
                return -ENOMEM;
 
-       memset(isec, 0, sizeof(struct ipc_security_struct));
        isec->magic = SELINUX_MAGIC;
        isec->sclass = sclass;
        isec->ipc_perm = perm;
@@ -3631,11 +3638,10 @@ static int msg_msg_alloc_security(struct msg_msg *msg)
 {
        struct msg_security_struct *msec;
 
-       msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
+       msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
        if (!msec)
                return -ENOMEM;
 
-       memset(msec, 0, sizeof(struct msg_security_struct));
        msec->magic = SELINUX_MAGIC;
        msec->msg = msg;
        msec->sid = SECINITSID_UNLABELED;
index 718d7be9f4dd4b8077998d076345af9a785212dc..b10c34e8a74344f97afce95012a41ebaf7157242 100644 (file)
@@ -114,13 +114,12 @@ static struct sel_netif *sel_netif_lookup(struct net_device *dev)
        if (likely(netif != NULL))
                goto out;
        
-       new = kmalloc(sizeof(*new), GFP_ATOMIC);
+       new = kzalloc(sizeof(*new), GFP_ATOMIC);
        if (!new) {
                netif = ERR_PTR(-ENOMEM);
                goto out;
        }
        
-       memset(new, 0, sizeof(*new));
        nsec = &new->nsec;
 
        ret = security_netif_sid(dev->name, &nsec->if_sid, &nsec->msg_sid);
index a45cc971e73588bdc0c2e5a74774736c854f713d..fdc3823897207284fafe407546b40cdc7edd7899 100644 (file)
@@ -105,7 +105,7 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
        ssize_t length;
        int new_value;
 
-       if (count < 0 || count >= PAGE_SIZE)
+       if (count >= PAGE_SIZE)
                return -ENOMEM;
        if (*ppos != 0) {
                /* No partial writes. */
@@ -155,7 +155,7 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
        int new_value;
        extern int selinux_disable(void);
 
-       if (count < 0 || count >= PAGE_SIZE)
+       if (count >= PAGE_SIZE)
                return -ENOMEM;
        if (*ppos != 0) {
                /* No partial writes. */
@@ -242,7 +242,7 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
                goto out;
        }
 
-       if ((count < 0) || (count > 64 * 1024 * 1024)
+       if ((count > 64 * 1024 * 1024)
            || (data = vmalloc(count)) == NULL) {
                length = -ENOMEM;
                goto out;
@@ -284,7 +284,7 @@ static ssize_t sel_write_context(struct file * file, const char __user * buf,
        if (length)
                return length;
 
-       if (count < 0 || count >= PAGE_SIZE)
+       if (count >= PAGE_SIZE)
                return -ENOMEM;
        if (*ppos != 0) {
                /* No partial writes. */
@@ -332,7 +332,7 @@ static ssize_t sel_write_checkreqprot(struct file * file, const char __user * bu
        if (length)
                return length;
 
-       if (count < 0 || count >= PAGE_SIZE)
+       if (count >= PAGE_SIZE)
                return -ENOMEM;
        if (*ppos != 0) {
                /* No partial writes. */
@@ -424,15 +424,13 @@ static ssize_t sel_write_access(struct file * file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kmalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size+1, GFP_KERNEL);
        if (!scon)
                return length;
-       memset(scon, 0, size+1);
 
-       tcon = kmalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size+1, GFP_KERNEL);
        if (!tcon)
                goto out;
-       memset(tcon, 0, size+1);
 
        length = -EINVAL;
        if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
@@ -475,15 +473,13 @@ static ssize_t sel_write_create(struct file * file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kmalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size+1, GFP_KERNEL);
        if (!scon)
                return length;
-       memset(scon, 0, size+1);
 
-       tcon = kmalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size+1, GFP_KERNEL);
        if (!tcon)
                goto out;
-       memset(tcon, 0, size+1);
 
        length = -EINVAL;
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -536,15 +532,13 @@ static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kmalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size+1, GFP_KERNEL);
        if (!scon)
                return length;
-       memset(scon, 0, size+1);
 
-       tcon = kmalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size+1, GFP_KERNEL);
        if (!tcon)
                goto out;
-       memset(tcon, 0, size+1);
 
        length = -EINVAL;
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -595,15 +589,13 @@ static ssize_t sel_write_user(struct file * file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       con = kmalloc(size+1, GFP_KERNEL);
+       con = kzalloc(size+1, GFP_KERNEL);
        if (!con)
                return length;
-       memset(con, 0, size+1);
 
-       user = kmalloc(size+1, GFP_KERNEL);
+       user = kzalloc(size+1, GFP_KERNEL);
        if (!user)
                goto out;
-       memset(user, 0, size+1);
 
        length = -EINVAL;
        if (sscanf(buf, "%s %s", con, user) != 2)
@@ -658,15 +650,13 @@ static ssize_t sel_write_member(struct file * file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kmalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size+1, GFP_KERNEL);
        if (!scon)
                return length;
-       memset(scon, 0, size+1);
 
-       tcon = kmalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size+1, GFP_KERNEL);
        if (!tcon)
                goto out;
-       memset(tcon, 0, size+1);
 
        length = -EINVAL;
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
@@ -739,7 +729,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
        if (!filep->f_op)
                goto out;
 
-       if (count < 0 || count > PAGE_SIZE) {
+       if (count > PAGE_SIZE) {
                ret = -EINVAL;
                goto out;
        }
@@ -800,7 +790,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
        if (!filep->f_op)
                goto out;
 
-       if (count < 0 || count >= PAGE_SIZE) {
+       if (count >= PAGE_SIZE) {
                length = -ENOMEM;
                goto out;
        }
@@ -858,7 +848,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
        if (!filep->f_op)
                goto out;
 
-       if (count < 0 || count >= PAGE_SIZE) {
+       if (count >= PAGE_SIZE) {
                length = -ENOMEM;
                goto out;
        }
@@ -924,7 +914,7 @@ static void sel_remove_bools(struct dentry *de)
 
        file_list_lock();
        list_for_each(p, &sb->s_files) {
-               struct file * filp = list_entry(p, struct file, f_list);
+               struct file * filp = list_entry(p, struct file, f_u.fu_list);
                struct dentry * dentry = filp->f_dentry;
 
                if (dentry->d_parent != de) {
@@ -1032,7 +1022,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file * file,
        ssize_t ret;
        int new_value;
 
-       if (count < 0 || count >= PAGE_SIZE) {
+       if (count >= PAGE_SIZE) {
                ret = -ENOMEM;
                goto out;
        }
index daf2880074607fd535080ed6a08bebd3a36a3082..d2737edba5414598a5be034e652e66c52990b6de 100644 (file)
@@ -220,10 +220,9 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
        u32 len;
        int rc;
 
-       booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
+       booldatum = kzalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
        if (!booldatum)
                return -1;
-       memset(booldatum, 0, sizeof(struct cond_bool_datum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -321,10 +320,9 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
                goto err;
        }
 
-       list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
+       list = kzalloc(sizeof(struct cond_av_list), GFP_KERNEL);
        if (!list)
                goto err;
-       memset(list, 0, sizeof(*list));
 
        list->node = node_ptr;
        if (!data->head)
@@ -414,11 +412,10 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
                if (rc < 0)
                        goto err;
 
-               expr = kmalloc(sizeof(struct cond_expr), GFP_KERNEL);
+               expr = kzalloc(sizeof(struct cond_expr), GFP_KERNEL);
                if (!expr) {
                        goto err;
                }
-               memset(expr, 0, sizeof(struct cond_expr));
 
                expr->expr_type = le32_to_cpu(buf[0]);
                expr->bool = le32_to_cpu(buf[1]);
@@ -460,10 +457,9 @@ int cond_read_list(struct policydb *p, void *fp)
        len = le32_to_cpu(buf[0]);
 
        for (i = 0; i < len; i++) {
-               node = kmalloc(sizeof(struct cond_node), GFP_KERNEL);
+               node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
                if (!node)
                        goto err;
-               memset(node, 0, sizeof(struct cond_node));
 
                if (cond_read_node(p, node, fp) != 0)
                        goto err;
index d515154128cc613bcdc916191f44936a411029fc..47024a6e18440dafe797c1e648726f9c30e59a87 100644 (file)
@@ -39,12 +39,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
        n = src->node;
        prev = NULL;
        while (n) {
-               new = kmalloc(sizeof(*new), GFP_ATOMIC);
+               new = kzalloc(sizeof(*new), GFP_ATOMIC);
                if (!new) {
                        ebitmap_destroy(dst);
                        return -ENOMEM;
                }
-               memset(new, 0, sizeof(*new));
                new->startbit = n->startbit;
                new->map = n->map;
                new->next = NULL;
@@ -150,10 +149,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
        if (!value)
                return 0;
 
-       new = kmalloc(sizeof(*new), GFP_ATOMIC);
+       new = kzalloc(sizeof(*new), GFP_ATOMIC);
        if (!new)
                return -ENOMEM;
-       memset(new, 0, sizeof(*new));
 
        new->startbit = bit & ~(MAPSIZE - 1);
        new->map = (MAPBIT << (bit - new->startbit));
@@ -232,13 +230,12 @@ int ebitmap_read(struct ebitmap *e, void *fp)
                        printk(KERN_ERR "security: ebitmap: truncated map\n");
                        goto bad;
                }
-               n = kmalloc(sizeof(*n), GFP_KERNEL);
+               n = kzalloc(sizeof(*n), GFP_KERNEL);
                if (!n) {
                        printk(KERN_ERR "security: ebitmap: out of memory\n");
                        rc = -ENOMEM;
                        goto bad;
                }
-               memset(n, 0, sizeof(*n));
 
                n->startbit = le32_to_cpu(buf[0]);
 
index 26661fcc00ce3ef710552adc929d1b6f250384f3..24e5ec957630a752c270d8583ac4a2b6f797d31b 100644 (file)
@@ -15,11 +15,10 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, void *key),
        struct hashtab *p;
        u32 i;
 
-       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (p == NULL)
                return p;
 
-       memset(p, 0, sizeof(*p));
        p->size = size;
        p->nel = 0;
        p->hash_value = hash_value;
@@ -55,10 +54,9 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum)
        if (cur && (h->keycmp(h, key, cur->key) == 0))
                return -EEXIST;
 
-       newnode = kmalloc(sizeof(*newnode), GFP_KERNEL);
+       newnode = kzalloc(sizeof(*newnode), GFP_KERNEL);
        if (newnode == NULL)
                return -ENOMEM;
-       memset(newnode, 0, sizeof(*newnode));
        newnode->key = key;
        newnode->datum = datum;
        if (prev) {
index 8e6262d12aa9bfaa97d3641946d6ae32fa132e54..2f5f539875f2d0e60b780b407deef7fb64aeecdb 100644 (file)
@@ -121,12 +121,11 @@ static int roles_init(struct policydb *p)
        int rc;
        struct role_datum *role;
 
-       role = kmalloc(sizeof(*role), GFP_KERNEL);
+       role = kzalloc(sizeof(*role), GFP_KERNEL);
        if (!role) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(role, 0, sizeof(*role));
        role->value = ++p->p_roles.nprim;
        if (role->value != OBJECT_R_VAL) {
                rc = -EINVAL;
@@ -851,12 +850,11 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[2];
        u32 len;
 
-       perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
+       perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
        if (!perdatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(perdatum, 0, sizeof(*perdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -893,12 +891,11 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
        u32 len, nel;
        int i, rc;
 
-       comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
+       comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
        if (!comdatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(comdatum, 0, sizeof(*comdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -950,10 +947,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
 
        lc = NULL;
        for (i = 0; i < ncons; i++) {
-               c = kmalloc(sizeof(*c), GFP_KERNEL);
+               c = kzalloc(sizeof(*c), GFP_KERNEL);
                if (!c)
                        return -ENOMEM;
-               memset(c, 0, sizeof(*c));
 
                if (lc) {
                        lc->next = c;
@@ -969,10 +965,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
                le = NULL;
                depth = -1;
                for (j = 0; j < nexpr; j++) {
-                       e = kmalloc(sizeof(*e), GFP_KERNEL);
+                       e = kzalloc(sizeof(*e), GFP_KERNEL);
                        if (!e)
                                return -ENOMEM;
-                       memset(e, 0, sizeof(*e));
 
                        if (le) {
                                le->next = e;
@@ -1033,12 +1028,11 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
        u32 len, len2, ncons, nel;
        int i, rc;
 
-       cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
+       cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
        if (!cladatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(cladatum, 0, sizeof(*cladatum));
 
        rc = next_entry(buf, fp, sizeof(u32)*6);
        if (rc < 0)
@@ -1127,12 +1121,11 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[2];
        u32 len;
 
-       role = kmalloc(sizeof(*role), GFP_KERNEL);
+       role = kzalloc(sizeof(*role), GFP_KERNEL);
        if (!role) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(role, 0, sizeof(*role));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -1188,12 +1181,11 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[3];
        u32 len;
 
-       typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
+       typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL);
        if (!typdatum) {
                rc = -ENOMEM;
                return rc;
        }
-       memset(typdatum, 0, sizeof(*typdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -1261,12 +1253,11 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[2];
        u32 len;
 
-       usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
+       usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
        if (!usrdatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(usrdatum, 0, sizeof(*usrdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -1316,12 +1307,11 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[2];
        u32 len;
 
-       levdatum = kmalloc(sizeof(*levdatum), GFP_ATOMIC);
+       levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
        if (!levdatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(levdatum, 0, sizeof(*levdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -1368,12 +1358,11 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
        __le32 buf[3];
        u32 len;
 
-       catdatum = kmalloc(sizeof(*catdatum), GFP_ATOMIC);
+       catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
        if (!catdatum) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(catdatum, 0, sizeof(*catdatum));
 
        rc = next_entry(buf, fp, sizeof buf);
        if (rc < 0)
@@ -1567,12 +1556,11 @@ int policydb_read(struct policydb *p, void *fp)
        nel = le32_to_cpu(buf[0]);
        ltr = NULL;
        for (i = 0; i < nel; i++) {
-               tr = kmalloc(sizeof(*tr), GFP_KERNEL);
+               tr = kzalloc(sizeof(*tr), GFP_KERNEL);
                if (!tr) {
                        rc = -ENOMEM;
                        goto bad;
                }
-               memset(tr, 0, sizeof(*tr));
                if (ltr) {
                        ltr->next = tr;
                } else {
@@ -1593,12 +1581,11 @@ int policydb_read(struct policydb *p, void *fp)
        nel = le32_to_cpu(buf[0]);
        lra = NULL;
        for (i = 0; i < nel; i++) {
-               ra = kmalloc(sizeof(*ra), GFP_KERNEL);
+               ra = kzalloc(sizeof(*ra), GFP_KERNEL);
                if (!ra) {
                        rc = -ENOMEM;
                        goto bad;
                }
-               memset(ra, 0, sizeof(*ra));
                if (lra) {
                        lra->next = ra;
                } else {
@@ -1627,12 +1614,11 @@ int policydb_read(struct policydb *p, void *fp)
                nel = le32_to_cpu(buf[0]);
                l = NULL;
                for (j = 0; j < nel; j++) {
-                       c = kmalloc(sizeof(*c), GFP_KERNEL);
+                       c = kzalloc(sizeof(*c), GFP_KERNEL);
                        if (!c) {
                                rc = -ENOMEM;
                                goto bad;
                        }
-                       memset(c, 0, sizeof(*c));
                        if (l) {
                                l->next = c;
                        } else {
@@ -1743,12 +1729,11 @@ int policydb_read(struct policydb *p, void *fp)
                if (rc < 0)
                        goto bad;
                len = le32_to_cpu(buf[0]);
-               newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
+               newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
                if (!newgenfs) {
                        rc = -ENOMEM;
                        goto bad;
                }
-               memset(newgenfs, 0, sizeof(*newgenfs));
 
                newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL);
                if (!newgenfs->fstype) {
@@ -1790,12 +1775,11 @@ int policydb_read(struct policydb *p, void *fp)
                                goto bad;
                        len = le32_to_cpu(buf[0]);
 
-                       newc = kmalloc(sizeof(*newc), GFP_KERNEL);
+                       newc = kzalloc(sizeof(*newc), GFP_KERNEL);
                        if (!newc) {
                                rc = -ENOMEM;
                                goto bad;
                        }
-                       memset(newc, 0, sizeof(*newc));
 
                        newc->u.name = kmalloc(len + 1,GFP_KERNEL);
                        if (!newc->u.name) {
@@ -1843,12 +1827,11 @@ int policydb_read(struct policydb *p, void *fp)
                nel = le32_to_cpu(buf[0]);
                lrt = NULL;
                for (i = 0; i < nel; i++) {
-                       rt = kmalloc(sizeof(*rt), GFP_KERNEL);
+                       rt = kzalloc(sizeof(*rt), GFP_KERNEL);
                        if (!rt) {
                                rc = -ENOMEM;
                                goto bad;
                        }
-                       memset(rt, 0, sizeof(*rt));
                        if (lrt)
                                lrt->next = rt;
                        else
index aecdded55e74aa04d4c2f9bcb05b2f39df8617fe..44eb4d74908d196beafdda585590c80efb245503 100644 (file)
@@ -1531,12 +1531,11 @@ int security_get_user_sids(u32 fromsid,
        }
        usercon.user = user->value;
 
-       mysids = kmalloc(maxnel*sizeof(*mysids), GFP_ATOMIC);
+       mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
        if (!mysids) {
                rc = -ENOMEM;
                goto out_unlock;
        }
-       memset(mysids, 0, maxnel*sizeof(*mysids));
 
        ebitmap_for_each_bit(&user->roles, rnode, i) {
                if (!ebitmap_node_get_bit(rnode, i))
@@ -1566,13 +1565,12 @@ int security_get_user_sids(u32 fromsid,
                                mysids[mynel++] = sid;
                        } else {
                                maxnel += SIDS_NEL;
-                               mysids2 = kmalloc(maxnel*sizeof(*mysids2), GFP_ATOMIC);
+                               mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
                                if (!mysids2) {
                                        rc = -ENOMEM;
                                        kfree(mysids);
                                        goto out_unlock;
                                }
-                               memset(mysids2, 0, maxnel*sizeof(*mysids2));
                                memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
                                kfree(mysids);
                                mysids = mysids2;
@@ -1714,12 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
                goto out;
        }
 
-       *names = (char**)kmalloc(sizeof(char*) * *len, GFP_ATOMIC);
+       *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
        if (!*names)
                goto err;
-       memset(*names, 0, sizeof(char*) * *len);
 
-       *values = (int*)kmalloc(sizeof(int) * *len, GFP_ATOMIC);
+       *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
        if (!*values)
                goto err;
 
index 3ecef4689f1b23d6a2454f443413c447e2a72bbc..fd25aca251200dd63c469b464945849192d4d2e4 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/pci.h>
 #include <linux/ac97_codec.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 
 #define CODEC_ID_BUFSZ 14
 
index d2b9beda8ace8910ae1d2ae985913ec26e72dd1c..b3ea719d33db0b737a6fb64c5d7d311b14014f99 100644 (file)
@@ -6062,7 +6062,7 @@ static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id
        io1 = pnp_port_start(dev,0);
        io2 = pnp_port_start(dev,1);
        io3 = pnp_port_start(dev,2);
-       printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
+       printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
               io1, io2, io3);
        setup_ports(io1, io2, io3);
 
index 6ec308f5d9352b72043fa718c27e3100770716b3..7c59e2d4003a7ff7f27542d7d1dc746286653106 100644 (file)
@@ -195,10 +195,12 @@ static int __init probe_cs4232(struct address_info *hw_config, int isapnp_config
                CS_OUT2(0x15, 0x00);    /* Select logical device 0 (WSS/SB/FM) */
                CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */
 
-               if (check_region(0x388, 4))     /* Not free */
+               if (!request_region(0x388, 4, "FM"))    /* Not free */
                        CS_OUT3(0x48, 0x00, 0x00)       /* FM base off */
-               else
+               else {
+                       release_region(0x388, 4);
                        CS_OUT3(0x48, 0x03, 0x88);      /* FM base 0x388 */
+               }
 
                CS_OUT3(0x42, 0x00, 0x00);      /* SB base off */
                CS_OUT2(0x22, irq);             /* SB+WSS IRQ */
index b92ba89216389ad4bc9b2896964fc856e5de6b00..b1a4eeb9dc083fb3dff34e48be328e64a48b1d50 100644 (file)
@@ -2434,7 +2434,7 @@ static int __init detect_wavefront (int irq, int io_base)
           consumes 16.
        */
 
-       if (check_region (io_base, 16)) {
+       if (!request_region (io_base, 16, "wavfront")) {
                printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
                        "already in use - ignored\n", dev.base,
                        dev.base+15);
@@ -2466,10 +2466,13 @@ static int __init detect_wavefront (int irq, int io_base)
                } else {
                        printk (KERN_WARNING LOGNAME "not raw, but no "
                                "hardware version!\n");
+                       release_region (io_base, 16);
                        return 0;
                }
 
                if (!wf_raw) {
+                       /* will re-acquire region in install_wavefront() */
+                       release_region (io_base, 16);
                        return 1;
                } else {
                        printk (KERN_INFO LOGNAME
@@ -2489,6 +2492,7 @@ static int __init detect_wavefront (int irq, int io_base)
 
        if (wavefront_hw_reset ()) {
                printk (KERN_WARNING LOGNAME "hardware reset failed\n");
+               release_region (io_base, 16);
                return 0;
        }
 
@@ -2496,6 +2500,8 @@ static int __init detect_wavefront (int irq, int io_base)
 
        dev.has_fx = (detect_wffx () == 0);
 
+       /* will re-acquire region in install_wavefront() */
+       release_region (io_base, 16);
        return 1;
 }
 
@@ -2804,17 +2810,27 @@ static int __init wavefront_init (int atboot)
 }
 
 static int __init install_wavefront (void)
-
 {
+       if (!request_region (dev.base+2, 6, "wavefront synth"))
+               return -1;
+
+       if (dev.has_fx) {
+               if (!request_region (dev.base+8, 8, "wavefront fx")) {
+                       release_region (dev.base+2, 6);
+                       return -1;
+               }
+       }
+
        if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
                printk (KERN_ERR LOGNAME "cannot register raw synth\n");
-               return -1;
+               goto err_out;
        }
 
 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
        if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
                printk (KERN_ERR LOGNAME "Too many sequencers\n");
-               return -1;
+               /* FIXME: leak: should unregister sound synth */
+               goto err_out;
        } else {
                synth_devs[dev.oss_dev] = &wavefront_operations;
        }
@@ -2827,20 +2843,20 @@ static int __init install_wavefront (void)
                sound_unload_synthdev (dev.oss_dev);
 #endif /* OSS_SUPPORT_SEQ */ 
 
-               return -1;
+               goto err_out;
        }
     
-       request_region (dev.base+2, 6, "wavefront synth");
-
-       if (dev.has_fx) {
-               request_region (dev.base+8, 8, "wavefront fx");
-       }
-
        if (wavefront_config_midi ()) {
                printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
        }
 
        return dev.oss_dev;
+
+err_out:
+       release_region (dev.base+2, 6);
+       if (dev.has_fx)
+               release_region (dev.base+8, 8);
+       return -1;
 }
 
 static void __exit uninstall_wavefront (void)