]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'release' of master.kernel.org:/home/ftp/pub/scm/linux/kernel/git/aegl...
authorLinus Torvalds <torvalds@woody.osdl.org>
Wed, 13 Dec 2006 23:57:58 +0000 (15:57 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Wed, 13 Dec 2006 23:57:58 +0000 (15:57 -0800)
* 'release' of master.kernel.org:/home/ftp/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] Move sg_dma_{len,address} from pci.h to scatterlist.h

433 files changed:
Documentation/cachetlb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/bfs.txt
Documentation/hwmon/f71805f
Documentation/hwmon/it87
Documentation/hwmon/k8temp
Documentation/hwmon/pc87427 [new file with mode: 0644]
Documentation/hwmon/sysfs-interface
Documentation/hwmon/w83627ehf
Documentation/hwmon/w83791d
Documentation/hwmon/w83793 [new file with mode: 0644]
Documentation/kernel-parameters.txt
MAINTAINERS
Makefile
arch/arm/kernel/apm.c
arch/arm/kernel/ecard.c
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/board-osk.c
arch/arm26/kernel/ecard.c
arch/arm26/kernel/irq.c
arch/cris/arch-v10/drivers/axisflashmap.c
arch/cris/arch-v10/drivers/gpio.c
arch/cris/arch-v32/drivers/axisflashmap.c
arch/cris/arch-v32/drivers/gpio.c
arch/cris/arch-v32/kernel/signal.c
arch/cris/kernel/profile.c
arch/h8300/kernel/ints.c
arch/h8300/platform/h8s/ints.c
arch/i386/kernel/apm.c
arch/i386/kernel/microcode.c
arch/i386/kernel/smpboot.c
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/m68k/mm/kmap.c
arch/mips/kernel/apm.c
arch/mips/mm/init.c
arch/parisc/hpux/sys_hpux.c
arch/parisc/kernel/unwind.c
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/mm/imalloc.c
arch/powerpc/platforms/pseries/eeh_cache.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8xx_io/cs4218_tdm.c
arch/s390/Kconfig
arch/s390/kernel/debug.c
arch/s390/kernel/s390_ext.c
arch/sparc/kernel/irq.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc64/kernel/sys_sunos32.c
arch/um/drivers/net_kern.c
arch/um/include/net_kern.h
arch/um/sys-i386/ldt.c
arch/xtensa/kernel/Makefile
arch/xtensa/kernel/syscall.c
block/as-iosched.c
block/cfq-iosched.c
block/ll_rw_blk.c
crypto/blkcipher.c
drivers/acorn/block/fd1772.c
drivers/ata/pdc_adma.c
drivers/atm/eni.c
drivers/atm/he.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/zatm.c
drivers/base/class.c
drivers/base/dmapool.c
drivers/base/platform.c
drivers/block/Kconfig
drivers/block/Makefile
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/swim_iop.c [deleted file]
drivers/cdrom/cdrom.c
drivers/cdrom/cm206.c
drivers/char/Kconfig
drivers/char/consolemap.c
drivers/char/lcd.c
drivers/char/lp.c
drivers/char/mxser_new.c
drivers/char/n_r3964.c
drivers/char/n_tty.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/rio/riocmd.c
drivers/char/rtc.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/char/sysrq.c
drivers/char/tty_io.c
drivers/char/viocons.c
drivers/char/vt.c
drivers/char/vt_ioctl.c
drivers/fc4/fc.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/ams/Makefile [new file with mode: 0644]
drivers/hwmon/ams/ams-core.c [new file with mode: 0644]
drivers/hwmon/ams/ams-i2c.c [new file with mode: 0644]
drivers/hwmon/ams/ams-input.c [new file with mode: 0644]
drivers/hwmon/ams/ams-pmu.c [new file with mode: 0644]
drivers/hwmon/ams/ams.h [new file with mode: 0644]
drivers/hwmon/f71805f.c
drivers/hwmon/hdaps.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/it87.c
drivers/hwmon/k8temp.c
drivers/hwmon/pc87360.c
drivers/hwmon/pc87427.c [new file with mode: 0644]
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83792d.c
drivers/hwmon/w83793.c [new file with mode: 0644]
drivers/i2c/busses/i2c-ali1563.c
drivers/i2c/chips/tps65010.c
drivers/ide/ide-floppy.c
drivers/ide/ide-tape.c
drivers/ide/pci/hpt366.c
drivers/input/keyboard/hilkbd.c
drivers/isdn/act2000/act2000_isa.c
drivers/isdn/capi/capidrv.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/divert/isdn_divert.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/hysdn/hysdn_procconf.c
drivers/isdn/hysdn/hysdn_proclog.c
drivers/isdn/i4l/isdn_audio.c
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/pcbit/layer2.c
drivers/kvm/Kconfig
drivers/kvm/kvm.h
drivers/kvm/kvm_main.c
drivers/kvm/kvm_svm.h
drivers/kvm/kvm_vmx.h
drivers/kvm/mmu.c
drivers/kvm/paging_tmpl.h
drivers/kvm/svm.c
drivers/kvm/vmx.c
drivers/kvm/x86_emulate.c
drivers/kvm/x86_emulate.h
drivers/macintosh/adb.c
drivers/macintosh/apm_emu.c
drivers/macintosh/smu.c
drivers/macintosh/via-pmu68k.c
drivers/md/faulty.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/ttusb-dec/ttusbdecfe.c
drivers/media/video/dabusb.c
drivers/media/video/planb.c
drivers/media/video/usbvideo/usbvideo.c
drivers/media/video/videocodec.c
drivers/message/i2o/core.h
drivers/message/i2o/driver.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/i2o_config.c
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/rfd_ftl.c
drivers/net/appletalk/ipddp.c
drivers/net/bsd_comp.c
drivers/net/irda/donauboe.c
drivers/net/irda/irda-usb.c
drivers/net/irda/irport.c
drivers/net/lp486e.c
drivers/net/phy/phy_device.c
drivers/net/ppp_deflate.c
drivers/net/ppp_mppe.c
drivers/net/skge.c
drivers/net/slip.c
drivers/net/wan/hostess_sv11.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/pc300_tty.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_download.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/parisc/iosapic.c
drivers/pci/hotplug/cpqphp_nvram.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pcmcia/at91_cf.c
drivers/pcmcia/omap_cf.c
drivers/pnp/isapnp/core.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/pnpbios/core.c
drivers/pnp/pnpbios/proc.c
drivers/pnp/pnpbios/rsparser.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-proc.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sysfs.c
drivers/s390/char/con3215.c
drivers/s390/char/keyboard.c
drivers/s390/char/sclp_cpi.c
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_pcica.c
drivers/s390/crypto/zcrypt_pcixcc.c
drivers/s390/net/ctcmain.c
drivers/s390/net/iucv.c
drivers/s390/scsi/zfcp_aux.c
drivers/sbus/char/vfc_dev.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/comminit.c
drivers/scsi/aha1542.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/initio.c
drivers/scsi/osst.c
drivers/scsi/pluto.c
drivers/scsi/sr_ioctl.c
drivers/scsi/sr_vendor.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/serial/8250_pci.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/serial.c
drivers/usb/host/hc_crisv10.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/uss720.c
drivers/usb/net/rndis_host.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/sddr09.c
drivers/video/amba-clcd.c
drivers/video/amifb.c
drivers/video/aty/atyfb_base.c
drivers/video/matrox/i2c-matroxfb.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/sstfb.c
drivers/w1/slaves/Kconfig
fs/aio.c
fs/autofs4/inode.c
fs/befs/btree.c
fs/befs/debug.c
fs/bfs/inode.c
fs/binfmt_misc.c
fs/bio.c
fs/block_dev.c
fs/cifs/cifssmb.c
fs/debugfs/inode.c
fs/inode.c
fs/jffs/inode-v23.c
fs/jffs/intrep.c
fs/jfs/jfs_dtree.c
fs/jfs/jfs_imap.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/svclock.c
fs/lockd/svcshare.c
fs/lockd/xdr.c
fs/lockd/xdr4.c
fs/namespace.c
fs/ncpfs/inode.c
fs/nfs/nfs4proc.c
fs/nfsd/export.c
fs/nfsd/lockd.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsfh.c
fs/nfsd/vfs.c
fs/ocfs2/alloc.c
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/file.c
fs/ocfs2/localalloc.c
fs/ocfs2/slot_map.c
fs/ocfs2/suballoc.c
fs/ocfs2/super.c
fs/ocfs2/vote.c
fs/pipe.c
fs/read_write.c
fs/reiserfs/xattr_acl.c
fs/smbfs/inode.c
fs/smbfs/proc.c
fs/smbfs/smbiod.c
fs/splice.c
include/asm-alpha/cacheflush.h
include/asm-arm/cacheflush.h
include/asm-arm/thread_info.h
include/asm-arm26/cacheflush.h
include/asm-avr32/cacheflush.h
include/asm-avr32/pgalloc.h
include/asm-cris/cacheflush.h
include/asm-frv/cacheflush.h
include/asm-frv/thread_info.h
include/asm-h8300/cacheflush.h
include/asm-i386/cacheflush.h
include/asm-i386/thread_info.h
include/asm-ia64/cacheflush.h
include/asm-ia64/thread_info.h
include/asm-m32r/cacheflush.h
include/asm-m68k/cacheflush.h
include/asm-m68k/swim_iop.h [deleted file]
include/asm-m68knommu/cacheflush.h
include/asm-mips/cacheflush.h
include/asm-mips/page.h
include/asm-parisc/cacheflush.h
include/asm-powerpc/cacheflush.h
include/asm-powerpc/thread_info.h
include/asm-s390/cacheflush.h
include/asm-sh/cpu-sh2/cacheflush.h
include/asm-sh/cpu-sh3/cacheflush.h
include/asm-sh/cpu-sh4/cacheflush.h
include/asm-sh/thread_info.h
include/asm-sh64/cacheflush.h
include/asm-sh64/pgalloc.h
include/asm-sparc/cacheflush.h
include/asm-sparc64/cacheflush.h
include/asm-v850/cacheflush.h
include/asm-x86_64/cacheflush.h
include/asm-x86_64/thread_info.h
include/asm-xtensa/cacheflush.h
include/asm-xtensa/termbits.h
include/asm-xtensa/uaccess.h
include/linux/aio.h
include/linux/bio.h
include/linux/coda_linux.h
include/linux/cpuset.h
include/linux/fb.h
include/linux/freezer.h
include/linux/fs.h
include/linux/gameport.h
include/linux/highmem.h
include/linux/i2c-id.h
include/linux/init_task.h
include/linux/lockd/bind.h
include/linux/lockd/lockd.h
include/linux/lockd/sm_inter.h
include/linux/lockd/xdr.h
include/linux/lockdep.h
include/linux/mount.h
include/linux/n_r3964.h
include/linux/ncp_mount.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/state.h
include/linux/nfsd/xdr4.h
include/linux/nsproxy.h
include/linux/pci_ids.h
include/linux/pipe_fs_i.h
include/linux/platform_device.h
include/linux/reciprocal_div.h [new file with mode: 0644]
include/linux/sched.h
include/linux/slab.h
include/linux/slab_def.h [new file with mode: 0644]
include/linux/smb_fs_sb.h
include/linux/sysrq.h
include/net/bluetooth/hci.h
include/video/sstfb.h
ipc/msgutil.c
kernel/cpuset.c
kernel/fork.c
kernel/lockdep.c
kernel/module.c
kernel/nsproxy.c
kernel/power/Kconfig
kernel/power/process.c
kernel/relay.c
kernel/sched.c
kernel/signal.c
kernel/sysctl.c
kernel/timer.c
lib/Kconfig
lib/Makefile
lib/ioremap.c
lib/reciprocal_div.c [new file with mode: 0644]
mm/hugetlb.c
mm/memory.c
mm/oom_kill.c
mm/page_alloc.c
mm/slab.c
mm/slob.c
mm/vmscan.c
net/bluetooth/hci_sock.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/svc.c
net/sunrpc/svcauth_unix.c
net/tipc/config.c
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/gconf.c
scripts/kconfig/gconf.glade
scripts/kconfig/lkc.h
scripts/kconfig/lkc_proto.h
scripts/kconfig/mconf.c
scripts/kconfig/qconf.cc
scripts/kconfig/qconf.h
scripts/kconfig/symbol.c
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y
scripts/mod/modpost.c
sound/core/oss/mixer_oss.c
sound/oss/ad1848.c
sound/oss/cs4232.c
sound/oss/emu10k1/audio.c
sound/oss/emu10k1/cardmi.c
sound/oss/emu10k1/cardmo.c
sound/oss/emu10k1/midi.c
sound/oss/emu10k1/mixer.c
sound/oss/hal2.c
sound/oss/mpu401.c
sound/oss/opl3.c
sound/oss/sb_common.c
sound/oss/sb_midi.c
sound/oss/sb_mixer.c
sound/oss/v_midi.c
sound/oss/waveartist.c

index 53245c429f7d9f13999803ea4ced0813437fceb5..73e794f0ff0924e2432e305cb5520345f776160b 100644 (file)
@@ -179,10 +179,21 @@ Here are the routines, one by one:
        lines associated with 'mm'.
 
        This interface is used to handle whole address space
-       page table operations such as what happens during
-       fork, exit, and exec.
+       page table operations such as what happens during exit and exec.
+
+2) void flush_cache_dup_mm(struct mm_struct *mm)
+
+       This interface flushes an entire user address space from
+       the caches.  That is, after running, there will be no cache
+       lines associated with 'mm'.
+
+       This interface is used to handle whole address space
+       page table operations such as what happens during fork.
+
+       This option is separate from flush_cache_mm to allow some
+       optimizations for VIPT caches.
 
-2) void flush_cache_range(struct vm_area_struct *vma,
+3) void flush_cache_range(struct vm_area_struct *vma,
                          unsigned long start, unsigned long end)
 
        Here we are flushing a specific range of (user) virtual
@@ -199,7 +210,7 @@ Here are the routines, one by one:
        call flush_cache_page (see below) for each entry which may be
        modified.
 
-3) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+4) void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
 
        This time we need to remove a PAGE_SIZE sized range
        from the cache.  The 'vma' is the backing structure used by
@@ -220,7 +231,7 @@ Here are the routines, one by one:
 
        This is used primarily during fault processing.
 
-4) void flush_cache_kmaps(void)
+5) void flush_cache_kmaps(void)
 
        This routine need only be implemented if the platform utilizes
        highmem.  It will be called right before all of the kmaps
@@ -232,7 +243,7 @@ Here are the routines, one by one:
 
        This routing should be implemented in asm/highmem.h
 
-5) void flush_cache_vmap(unsigned long start, unsigned long end)
+6) void flush_cache_vmap(unsigned long start, unsigned long end)
    void flush_cache_vunmap(unsigned long start, unsigned long end)
 
        Here in these two interfaces we are flushing a specific range
index 64ce44da59366bb044c1a30850d94a1c2eab6d3d..040f437c421bc1bb410ce2253369fa5e1cd33e64 100644 (file)
@@ -151,15 +151,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  I2C interface of the it87 driver
-When:  January 2007
-Why:   The ISA interface is faster and should be always available. The I2C
-       probing is also known to cause trouble in at least one case (see
-       bug #5889.)
-Who:   Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
 What:  Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
        (temporary transition config option provided until then)
        The transition config option will also be removed at the same time.
index d2841e0bcf0258cb9b06b0fec372bae14b0ff3ba..ea825e178e797b3b8af53d8d6d5fa2c1f1974a0d 100644 (file)
@@ -54,4 +54,4 @@ The first 4 bytes should be 0x1badface.
 If you have any patches, questions or suggestions regarding this BFS
 implementation please contact the author:
 
-Tigran A. Aivazian <tigran@veritas.com>
+Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
index 2ca69df669c3a615601aec996fb8f977aa485180..bfd0f154959cce0e3398e899e7b5a0619f2abcce 100644 (file)
@@ -6,6 +6,10 @@ Supported chips:
     Prefix: 'f71805f'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Provided by Fintek on request
+  * Fintek F71872F/FG
+    Prefix: 'f71872f'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Provided by Fintek on request
 
 Author: Jean Delvare <khali@linux-fr.org>
 
@@ -13,8 +17,8 @@ Thanks to Denis Kieft from Barracuda Networks for the donation of a
 test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
 for providing initial documentation.
 
-Thanks to Kris Chen from Fintek for answering technical questions and
-providing additional documentation.
+Thanks to Kris Chen and Aaron Huang from Fintek for answering technical
+questions and providing additional documentation.
 
 Thanks to Chris Lin from Jetway for providing wiring schematics and
 answering technical questions.
@@ -28,8 +32,11 @@ capabilities. It can monitor up to 9 voltages (counting its own power
 source), 3 fans and 3 temperature sensors.
 
 This chip also has fan controlling features, using either DC or PWM, in
-three different modes (one manual, two automatic). The driver doesn't
-support these features yet.
+three different modes (one manual, two automatic).
+
+The Fintek F71872F/FG Super I/O chip is almost the same, with two
+additional internal voltages monitored (VSB and battery). It also features
+6 VID inputs. The VID inputs are not yet supported by this driver.
 
 The driver assumes that no more than one chip is present, which seems
 reasonable.
@@ -42,7 +49,8 @@ Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
 range is thus from 0 to 2.040 V. Voltage values outside of this range
 need external resistors. An exception is in0, which is used to monitor
 the chip's own power source (+3.3V), and is divided internally by a
-factor 2.
+factor 2. For the F71872F/FG, in9 (VSB) and in10 (battery) are also
+divided internally by a factor 2.
 
 The two LSB of the voltage limit registers are not used (always 0), so
 you can only set the limits in steps of 32 mV (before scaling).
@@ -61,9 +69,12 @@ in5     VIN5    +12V        200K     20K       11.00    1.05 V
 in6     VIN6    VCC1.5V      10K       -        1.00    1.50 V
 in7     VIN7    VCORE        10K       -        1.00   ~1.40 V (1)
 in8     VIN8    VSB5V       200K     47K        1.00    0.95 V
+in10    VSB     VSB3.3V     int.    int.        2.00    1.65 V (3)
+in9     VBAT    VBATTERY    int.    int.        2.00    1.50 V (3)
 
 (1) Depends on your hardware setup.
 (2) Obviously not correct, swapping R1 and R2 would make more sense.
+(3) F71872F/FG only.
 
 These values can be used as hints at best, as motherboard manufacturers
 are free to use a completely different setup. As a matter of fact, the
@@ -103,3 +114,38 @@ sensor. Each channel can be used for connecting either a thermal diode
 or a thermistor. The driver reports the currently selected mode, but
 doesn't allow changing it. In theory, the BIOS should have configured
 everything properly.
+
+
+Fan Control
+-----------
+
+Both PWM (pulse-width modulation) and DC fan speed control methods are
+supported. The right one to use depends on external circuitry on the
+motherboard, so the driver assumes that the BIOS set the method
+properly. The driver will report the method, but won't let you change
+it.
+
+When the PWM method is used, you can select the operating frequency,
+from 187.5 kHz (default) to 31 Hz. The best frequency depends on the
+fan model. As a rule of thumb, lower frequencies seem to give better
+control, but may generate annoying high-pitch noise. Fintek recommends
+not going below 1 kHz, as the fan tachometers get confused by lower
+frequencies as well.
+
+When the DC method is used, Fintek recommends not going below 5 V, which
+corresponds to a pwm value of 106 for the driver. The driver doesn't
+enforce this limit though.
+
+Three different fan control modes are supported:
+
+* Manual mode
+  You ask for a specific PWM duty cycle or DC voltage.
+
+* Fan speed mode
+  You ask for a specific fan speed. This mode assumes that pwm1
+  corresponds to fan1, pwm2 to fan2 and pwm3 to fan3.
+
+* Temperature mode
+  You define 3 temperature/fan speed trip points, and the fan speed is
+  adjusted depending on the measured temperature, using interpolation.
+  This mode is not yet supported by the driver.
index e783fd62e3085a5abb7a965d83fa3b462d990e8d..74a80992d237c49c13e858313a5c004d351d7e3f 100644 (file)
@@ -9,8 +9,7 @@ Supported chips:
                http://www.ite.com.tw/
   * IT8712F
     Prefix: 'it8712'
-    Addresses scanned: I2C 0x2d
-                       from Super I/O config space (8 I/O ports)
+    Addresses scanned: from Super I/O config space (8 I/O ports)
     Datasheet: Publicly available at the ITE website
                http://www.ite.com.tw/
   * IT8716F
@@ -53,6 +52,18 @@ Module Parameters
   misconfigured by BIOS - PWM values would be inverted. This option tries
   to fix this. Please contact your BIOS manufacturer and ask him for fix.
 
+
+Hardware Interfaces
+-------------------
+
+All the chips suported by this driver are LPC Super-I/O chips, accessed
+through the LPC bus (ISA-like I/O ports). The IT8712F additionally has an
+SMBus interface to the hardware monitoring functions. This driver no
+longer supports this interface though, as it is slower and less reliable
+than the ISA access, and was only available on a small number of
+motherboard models.
+
+
 Description
 -----------
 
index 30d123b8d92022180b4f0cd2ae32cffc47ba4f6e..0005c71661467f5592592ca3b464a9a6c63b4c93 100644 (file)
@@ -8,7 +8,7 @@ Supported chips:
     Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
 
 Author: Rudolf Marek
-Contact: Rudolf Marek <r.marek@sh.cvut.cz>
+Contact: Rudolf Marek <r.marek@assembler.cz>
 
 Description
 -----------
diff --git a/Documentation/hwmon/pc87427 b/Documentation/hwmon/pc87427
new file mode 100644 (file)
index 0000000..9a0708f
--- /dev/null
@@ -0,0 +1,38 @@
+Kernel driver pc87427
+=====================
+
+Supported chips:
+  * National Semiconductor PC87427
+    Prefix: 'pc87427'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/apc_007.html
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Amir Habibi at Candelis for setting up a test system, and to
+Michael Kress for testing several iterations of this driver.
+
+
+Description
+-----------
+
+The National Semiconductor Super I/O chip includes complete hardware
+monitoring capabilities. It can monitor up to 18 voltages, 8 fans and
+6 temperature sensors. Only the fans are supported at the moment.
+
+This chip also has fan controlling features, which are not yet supported
+by this driver either.
+
+The driver assumes that no more than one chip is present, which seems
+reasonable.
+
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported as 14-bit values from a gated clock
+signal. Speeds down to 83 RPM can be measured.
+
+An alarm is triggered if the rotation speed drops below a programmable
+limit. Another alarm is triggered if the speed is too low to to be measured
+(including stalled or missing fan).
index d1d390aaf6205c8ac30d9ddb7c34813fca306d15..efef3b962cd3eb86f586e811b77ad7b6eadee648 100644 (file)
@@ -208,12 +208,14 @@ temp[1-*]_auto_point[1-*]_temp_hyst
 ****************
 
 temp[1-*]_type Sensor type selection.
-               Integers 1 to 4 or thermistor Beta value (typically 3435)
+               Integers 1 to 6 or thermistor Beta value (typically 3435)
                RW
                1: PII/Celeron Diode
                2: 3904 transistor
                3: thermal diode
                4: thermistor (default/unknown Beta)
+               5: AMD AMDSI
+               6: Intel PECI
                Not all types are supported by all chips
 
 temp[1-*]_max  Temperature max value.
index caa610a297e8a349f586f15a4b1279903179e47d..8a15a7408753bc6dda49353966b699992279e4f2 100644 (file)
@@ -10,7 +10,7 @@ Supported chips:
 Authors:
         Jean Delvare <khali@linux-fr.org>
         Yuan Mu (Winbond)
-        Rudolf Marek <r.marek@sh.cvut.cz>
+        Rudolf Marek <r.marek@assembler.cz>
 
 Description
 -----------
index 19b2ed739fa1325e09ab91cb629ce69b3331a2af..db9881df88a54cfe5c8a87965ddca58bb121eb28 100644 (file)
@@ -18,7 +18,7 @@ Credits:
     and Mark Studebaker <mdsxyz123@yahoo.com>
   w83792d.c:
     Chunhao Huang <DZShen@Winbond.com.tw>,
-    Rudolf Marek <r.marek@sh.cvut.cz>
+    Rudolf Marek <r.marek@assembler.cz>
 
 Additional contributors:
     Sven Anders <anders@anduras.de>
diff --git a/Documentation/hwmon/w83793 b/Documentation/hwmon/w83793
new file mode 100644 (file)
index 0000000..45e5408
--- /dev/null
@@ -0,0 +1,110 @@
+Kernel driver w83793
+====================
+
+Supported chips:
+  * Winbond W83793G/W83793R
+    Prefix: 'w83793'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: Still not published
+
+Authors:
+    Yuan Mu (Winbond Electronics)
+    Rudolf Marek <r.marek@assembler.cz>
+
+
+Module parameters
+-----------------
+
+* reset int
+  (default 0)
+  This parameter is not recommended, it will lose motherboard specific
+  settings. Use 'reset=1' to reset the chip when loading this module.
+
+* force_subclients=bus,caddr,saddr1,saddr2
+  This is used to force the i2c addresses for subclients of
+  a certain chip. Typical usage is `force_subclients=0,0x2f,0x4a,0x4b'
+  to force the subclients of chip 0x2f on bus 0 to i2c addresses
+  0x4a and 0x4b.
+
+
+Description
+-----------
+
+This driver implements support for Winbond W83793G/W83793R chips.
+
+* Exported features
+  This driver exports 10 voltage sensors, up to 12 fan tachometer inputs,
+  6 remote temperatures, up to 8 sets of PWM fan controls, SmartFan
+  (automatic fan speed control) on all temperature/PWM combinations, 2
+  sets of 6-pin CPU VID input.
+
+* Sensor resolutions
+  If your motherboard maker used the reference design, the resolution of
+  voltage0-2 is 2mV, resolution of voltage3/4/5 is 16mV, 8mV for voltage6,
+  24mV for voltage7/8. Temp1-4 have a 0.25 degree Celsius resolution,
+  temp5-6 have a 1 degree Celsiis resolution.
+
+* Temperature sensor types
+  Temp1-4 have 3 possible types. It can be read from (and written to)
+  temp[1-4]_type.
+  - If the value of 0, the related temperature channel stops
+    monitoring.
+  - If the value is 3, it starts monitoring using a remote termal diode
+    (default).
+  - If the value is 5, it starts monitoring using the temperature sensor
+    in AMD CPU and get result by AMDSI.
+  - If the value is 6, it starts monitoring using the temperature sensor
+    in Intel CPU and get result by PECI.
+  Temp5-6 can be connected to external thermistors (value of
+  temp[5-6]_type is 4). They can also be disabled (value is 0).
+
+* Alarm mechanism
+  For voltage sensors, an alarm triggers if the measured value is below
+  the low voltage limit or over the high voltage limit.
+  For temperature sensors, an alarm triggers if the measured value goes
+  above the high temperature limit, and wears off only after the measured
+  value drops below the hysteresis value.
+  For fan sensors, an alarm triggers if the measured value is below the
+  low speed limit.
+
+* SmartFan/PWM control
+  If you want to set a pwm fan to manual mode, you just need to make sure it
+  is not controlled by any temp channel, for example, you want to set fan1
+  to manual mode, you need to check the value of temp[1-6]_fan_map, make
+  sure bit 0 is cleared in the 6 values. And then set the pwm1 value to
+  control the fan.
+
+  Each temperature channel can control all the 8 PWM outputs (by setting the
+  corresponding bit in tempX_fan_map), you can set the temperature channel
+  mode using temp[1-6]_pwm_enable, 2 is Thermal Cruise mode and 3
+  is the SmartFanII mode. Temperature channels will try to speed up or
+  slow down all controlled fans, this means one fan can receive different
+  PWM value requests from different temperature channels, but the chip
+  will always pick the safest (max) PWM value for each fan.
+
+  In Thermal Cruise mode, the chip attempts to keep the temperature at a
+  predefined value, within a tolerance margin. So if tempX_input >
+  thermal_cruiseX + toleranceX, the chip will increase the PWM value,
+  if tempX_input < thermal_cruiseX - toleranceX, the chip will decrease
+  the PWM value. If the temperature is within the tolerance range, the PWM
+  value is left unchanged.
+
+  SmartFanII works differently, you have to define up to 7 PWM, temperature
+  trip points, defining a PWM/temperature curve which the chip will follow.
+  While not fundamentally different from the Thermal Cruise mode, the
+  implementation is quite different, giving you a finer-grained control.
+
+* Chassis
+  If the case open alarm triggers, it will stay in this state unless cleared
+  by any write to the sysfs file "chassis".
+
+* VID and VRM
+  The VRM version is detected automatically, don't modify the it unless you
+  *do* know the cpu VRM version and it's not properly detected.
+
+
+Notes
+-----
+
+  Only Fan1-5 and PWM1-3 are guaranteed to always exist, other fan inputs and
+  PWM outputs may or may not exist depending on the chip pin configuration.
index d8323b8893c3709170d3e79c09a975f6bac42864..ef69c75780bf4e5ca4650411033f8711b0771fd2 100644 (file)
@@ -1656,6 +1656,12 @@ and is between 256 and 4096 characters. It is defined in the file
        sym53c416=      [HW,SCSI]
                        See header of drivers/scsi/sym53c416.c.
 
+       sysrq_always_enabled
+                       [KNL]
+                       Ignore sysrq setting - this boot parameter will
+                       neutralize any effect of /proc/sys/kernel/sysrq.
+                       Useful for debugging.
+
        t128=           [HW,SCSI]
                        See header of drivers/scsi/t128.c.
 
index 8a0bfeca55c9d0a1e330dfedfce0b9a725fab6a9..dea5b2a6de0a8becde3fdba5e0c48f7cfcd0917c 100644 (file)
@@ -277,7 +277,7 @@ S:  Maintained
 
 ALI1563 I2C DRIVER
 P:     Rudolf Marek
-M:     r.marek@sh.cvut.cz
+M:     r.marek@assembler.cz
 L:     i2c@lm-sensors.org
 S:     Maintained
 
@@ -296,6 +296,13 @@ L: info-linux@geode.amd.com
 W:     http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
 S:     Supported
 
+AMS (Apple Motion Sensor) DRIVER
+P:     Stelian Pop
+M:     stelian@popies.net
+P:     Michael Hanselmann
+M:     linux-kernel@hansmi.ch
+S:     Supported
+
 AMSO1100 RNIC DRIVER
 P:     Tom Tucker
 M:     tom@opengridcomputing.com
@@ -1747,6 +1754,13 @@ W:       http://nfs.sourceforge.net/
 W:     http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
 S:     Maintained
 
+KERNEL VIRTUAL MACHINE (KVM)
+P:     Avi Kivity
+M:     avi@qumranet.com
+L:     kvm-devel@lists.sourceforge.net
+W:     kvm.sourceforge.net
+S:     Supported
+
 KEXEC
 P:     Eric Biederman
 M:     ebiederm@xmission.com
@@ -3429,6 +3443,12 @@ M:       bezaur@gmail.com
 L:     lm-sensors@lm-sensors.org
 S:     Maintained
 
+W83793 HARDWARE MONITORING DRIVER
+P:     Rudolf Marek
+M:     r.marek@assembler.cz
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
 W83L51xD SD/MMC CARD INTERFACE DRIVER
 P:     Pierre Ossman
 M:     drzeus-wbsd@drzeus.cx
index 4eabaa8afbfff4b4d82abe95258bb7fdad27a243..f732e75be43d1dd9449efbd99f7e646da26393c0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1390,12 +1390,18 @@ endif #ifeq ($(mixed-targets),1)
 
 PHONY += checkstack kernelrelease kernelversion
 
-# Use $(SUBARCH) here instead of $(ARCH) so that this works for UML.
-# In the UML case, $(SUBARCH) is the name of the underlying
-# architecture, while for all other arches, it is the same as $(ARCH).
+# UML needs a little special treatment here.  It wants to use the host
+# toolchain, so needs $(SUBARCH) passed to checkstack.pl.  Everyone
+# else wants $(ARCH), including people doing cross-builds, which means
+# that $(SUBARCH) doesn't work here.
+ifeq ($(ARCH), um)
+CHECKSTACK_ARCH := $(SUBARCH)
+else
+CHECKSTACK_ARCH := $(ARCH)
+endif
 checkstack:
        $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
-       $(PERL) $(src)/scripts/checkstack.pl $(SUBARCH)
+       $(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
 
 kernelrelease:
        $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
index a11fb9a40c04f0c16e9d46e1e2d17cfbe934b91c..2c37b70b17ab45087ff7c43d30aea6006d3f4e81 100644 (file)
@@ -423,7 +423,7 @@ static int apm_open(struct inode * inode, struct file * filp)
 {
        struct apm_user *as;
 
-       as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL);
+       as = kzalloc(sizeof(*as), GFP_KERNEL);
        if (as) {
                /*
                 * XXX - this is a tiny bit broken, when we consider BSD
index a786f769035d1a8c46197dae1124b40345dddb32..71257e3d513f4604ed1d01c3db5eb8fb565bcf47 100644 (file)
@@ -353,7 +353,7 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
                }
                if (c_id(&excd) == 0x80) { /* loader */
                        if (!ec->loader) {
-                               ec->loader = (loader_t)kmalloc(c_len(&excd),
+                               ec->loader = kmalloc(c_len(&excd),
                                                               GFP_KERNEL);
                                if (ec->loader)
                                        ecard_readbytes(ec->loader, ec,
index d135568dc9e7698e3c7ca99db7d9a083be50ef83..8781aaeb576b2d2738ead294ba6c21a182030b58 100644 (file)
@@ -43,6 +43,7 @@ config MACH_OMAP_H3
 config MACH_OMAP_OSK
        bool "TI OSK Support"
        depends on ARCH_OMAP1 && ARCH_OMAP16XX
+       select TPS65010
        help
          TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
           if you have such a board.
index 3a622801d7b0f1548a98056250860a5cea4bac37..7d0cf7af88ceb8c420b5fdb912edf3f3358170f8 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 43dd41be71fb80ac1ac7f0898924c77902b9bd5f..9dbc17247c6fdfd6a3b00b2fdc734b02aaae02f9 100644 (file)
@@ -215,7 +215,7 @@ int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
                }
                if (c_id(&excd) == 0x80) { /* loader */
                        if (!ec->loader) {
-                               ec->loader = (loader_t)kmalloc(c_len(&excd),
+                               ec->loader = kmalloc(c_len(&excd),
                                                               GFP_KERNEL);
                                if (ec->loader)
                                        ecard_readbytes(ec->loader, ec,
index d87d68b77d6678d97cbf2df175cca889b5e09123..d53382c83bf9fdb05ddfb66122313bfda0e9268a 100644 (file)
@@ -545,7 +545,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_
            (irq_flags & IRQF_SHARED && !dev_id))
                return -EINVAL;
 
-       action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+       action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;
 
index 4fa81abab0c762f62c1a92f9884f9769ff6c4780..ffade19a14e6f0b974dbea77034bacc329ebd795 100644 (file)
@@ -516,7 +516,7 @@ static int __init init_axis_flash(void)
 #else
                struct mtd_info *mtd_ram;
 
-               mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
+               mtd_ram = kmalloc(sizeof(struct mtd_info),
                                                     GFP_KERNEL);
                if (!mtd_ram) {
                        panic("axisflashmap couldn't allocate memory for "
index fcba6632ed7b72ef774f423bd3dae1012ca3104b..9aba18b931dddcf91c01d44452079a0442b3cde3 100644 (file)
@@ -440,7 +440,7 @@ gpio_open(struct inode *inode, struct file *filp)
        if (p > GPIO_MINOR_LAST)
                return -EINVAL;
 
-       priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
+       priv = kmalloc(sizeof(struct gpio_private),
                                              GFP_KERNEL);
 
        if (!priv)
index 41952320e00ab67f911cc82b3faa5a629218e6ba..5180d45412fc55db169dc132988e5f7b93cadedc 100644 (file)
@@ -427,7 +427,7 @@ static int __init init_axis_flash(void)
 #else
                struct mtd_info *mtd_ram;
 
-               mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
+               mtd_ram = kmalloc(sizeof(struct mtd_info),
                                                     GFP_KERNEL);
                if (!mtd_ram) {
                        panic("axisflashmap couldn't allocate memory for "
index c3f876b4da6b4210d1aafa814549bd626b944d04..08d36f0955c6789ced9bafa4283cf99546a69ef2 100644 (file)
@@ -423,7 +423,7 @@ gpio_open(struct inode *inode, struct file *filp)
        if (p > GPIO_MINOR_LAST)
                return -EINVAL;
 
-       priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
+       priv = kmalloc(sizeof(struct gpio_private),
                                              GFP_KERNEL);
 
        if (!priv)
index 99e59b3eacf8fd5cd4616108873be9afbc460401..7cd6ac80340940300defd4f75ce48be1629461e9 100644 (file)
@@ -686,7 +686,7 @@ keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
 int __init
 cris_init_signal(void)
 {
-       u16* data = (u16*)kmalloc(PAGE_SIZE, GFP_KERNEL);
+       u16* data = kmalloc(PAGE_SIZE, GFP_KERNEL);
 
        /* This is movu.w __NR_sigreturn, r9; break 13; */
        data[0] = 0x9c5f;
index 69c52189f044702cce5f4db9cc1c19e2a4fd7af2..f60ab785f235dbd105ca7a40a467409fcc2636bf 100644 (file)
@@ -59,7 +59,7 @@ static int
 __init init_cris_profile(void)
 {
   struct proc_dir_entry *entry;
-  sample_buffer = (char*)kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+  sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
   sample_buffer_pos = sample_buffer;
   entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
   if (entry) {
index 1bfc77e391d5ade64e9b71c7848c804d5022f2b9..587ef7f4fcc777394d7d8fc08cd80f9974077cff 100644 (file)
@@ -141,7 +141,7 @@ int request_irq(unsigned int irq,
                return -EBUSY;
 
        if (use_kmalloc)
-               irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+               irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
        else {
                /* use bootmem allocater */
                irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
index 270440de4610c3eb7187e93d304328a05aa405bc..567f681ddfec4051aafe0e8cc4d90dcfbb389653 100644 (file)
@@ -176,7 +176,7 @@ int request_irq(unsigned int irq,
        }               
 
        if (use_kmalloc)
-               irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
+               irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
        else {
                /* use bootmem allocater */
                irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
index a97847da9ed59e85508ace8f5a77be90260d8c6a..b75cff25de4b105b7c4c510d4de9752f053c2488 100644 (file)
@@ -1604,7 +1604,7 @@ static int do_open(struct inode * inode, struct file * filp)
 {
        struct apm_user *       as;
 
-       as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
+       as = kmalloc(sizeof(*as), GFP_KERNEL);
        if (as == NULL) {
                printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
                       sizeof(*as));
index 972346604f9d1b7d23841e317ff46c7559f49851..47ffec57c0cb28f4aa0ef6a74fbe665f9c42824f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Intel CPU Microcode Update Driver for Linux
  *
- *     Copyright (C) 2000-2004 Tigran Aivazian
+ *     Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
  *                   2006      Shaohua Li <shaohua.li@intel.com>
  *
  *     This driver allows to upgrade microcode on Intel processors
@@ -92,7 +92,7 @@
 #include <asm/processor.h>
 
 MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
-MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
 MODULE_LICENSE("GPL");
 
 #define MICROCODE_VERSION      "1.14a"
@@ -752,7 +752,7 @@ static int __init microcode_init (void)
        register_hotcpu_notifier(&mc_cpu_notifier);
 
        printk(KERN_INFO 
-               "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n");
+               "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
        return 0;
 }
 
index b0f84e5778ad89304bd8bf34a1c5c4022454a515..aef39be813614f0e2591836a4f1fa7aefb5ee9d3 100644 (file)
@@ -69,9 +69,7 @@ static int __devinitdata smp_b_stepping;
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
-#ifdef CONFIG_SMP
 EXPORT_SYMBOL(smp_num_siblings);
-#endif
 
 /* Last level cache ID of each logical CPU */
 int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
index 462ea178f49abadfed37375141629013fda98e62..33367996d72d595b180179977b4a20e6c3b929bc 100644 (file)
@@ -189,7 +189,7 @@ static void print_pci_topology(struct seq_file *s)
        int e;
 
        for (sz = PAGE_SIZE; sz < 16 * PAGE_SIZE; sz += PAGE_SIZE) {
-               if (!(p = (char *)kmalloc(sz, GFP_KERNEL)))
+               if (!(p = kmalloc(sz, GFP_KERNEL)))
                        break;
                e = ia64_sn_ioif_get_pci_topology(__pa(p), sz);
                if (e == SALRET_OK)
index b54ef1726c557f827665ae3055eb2c1f8868c2c7..46b7d6035aabaab6a299f5c2cef9fee411c96bb4 100644 (file)
@@ -59,7 +59,7 @@ static struct vm_struct *get_io_area(unsigned long size)
        unsigned long addr;
        struct vm_struct **p, *tmp, *area;
 
-       area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
+       area = kmalloc(sizeof(*area), GFP_KERNEL);
        if (!area)
                return NULL;
        addr = KMAP_START;
index 528e731049c123c2a77886d573a2001458405901..ba16d07588cb88ad540d04ab307df20cd3d2283c 100644 (file)
@@ -356,7 +356,7 @@ static int apm_open(struct inode * inode, struct file * filp)
 {
        struct apm_user *as;
 
-       as = (struct apm_user *)kzalloc(sizeof(*as), GFP_KERNEL);
+       as = kzalloc(sizeof(*as), GFP_KERNEL);
        if (as) {
                /*
                 * XXX - this is a tiny bit broken, when we consider BSD
index ea2d15370bb72ecef36f99656049b092073bff9c..30245c09d0258e224475b0ceeb9e50d7c6c797a1 100644 (file)
@@ -203,6 +203,31 @@ static inline void kunmap_coherent(struct page *page)
        preempt_check_resched();
 }
 
+void copy_user_highpage(struct page *to, struct page *from,
+       unsigned long vaddr, struct vm_area_struct *vma)
+{
+       void *vfrom, *vto;
+
+       vto = kmap_atomic(to, KM_USER1);
+       if (cpu_has_dc_aliases) {
+               vfrom = kmap_coherent(from, vaddr);
+               copy_page(vto, vfrom);
+               kunmap_coherent(from);
+       } else {
+               vfrom = kmap_atomic(from, KM_USER0);
+               copy_page(vto, vfrom);
+               kunmap_atomic(vfrom, KM_USER0);
+       }
+       if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) ||
+           pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+               flush_data_cache_page((unsigned long)vto);
+       kunmap_atomic(vto, KM_USER1);
+       /* Make sure this page is cleared on other CPU's too before using it */
+       smp_wmb();
+}
+
+EXPORT_SYMBOL(copy_user_highpage);
+
 void copy_to_user_page(struct vm_area_struct *vma,
        struct page *page, unsigned long vaddr, void *dst, const void *src,
        unsigned long len)
index d88309209f568815de1aa3bba81f2744fba2c4ac..04c2ff444396b56cb38438c65c217bc6f9980e0b 100644 (file)
@@ -475,7 +475,7 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
                printk(KERN_DEBUG "len of arg1 = %d\n", len);
                if (len == 0)
                        return 0;
-               fsname = (char *) kmalloc(len, GFP_KERNEL);
+               fsname = kmalloc(len, GFP_KERNEL);
                if ( !fsname ) {
                        printk(KERN_DEBUG "failed to kmalloc fsname\n");
                        return 0;
index 920bdbf8404fa3c50768c7d628c4cb9d0cf174f1..c10ab47d81fabc434f1e938194ee5a4fe92c523c 100644 (file)
@@ -343,7 +343,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
        struct pt_regs *r = &t->thread.regs;
        struct pt_regs *r2;
 
-       r2 = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
+       r2 = kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
        if (!r2)
                return;
        *r2 = *r;
index 6960f090991ed2fcabc318bd1743a04c6d9550d4..869cebbba967cf6f56b54a80550034e801f303ae 100644 (file)
@@ -505,7 +505,7 @@ static int nvram_scan_partitions(void)
                return -ENODEV;
        total_size = ppc_md.nvram_size();
        
-       header = (char *) kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL);
+       header = kmalloc(NVRAM_HEADER_LEN, GFP_KERNEL);
        if (!header) {
                printk(KERN_ERR "nvram_scan_partitions: Failed kmalloc\n");
                return -ENOMEM;
@@ -574,7 +574,7 @@ static int __init nvram_init(void)
        }
        
        /* initialize our anchor for the nvram partition list */
-       nvram_part = (struct nvram_partition *) kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+       nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
        if (!nvram_part) {
                printk(KERN_ERR "nvram_init: Failed kmalloc\n");
                return -ENOMEM;
index 8336deafc624fd7973c9a36e412787f890e8aeb1..2847cd51a2d7c8c3dbee81184494d1dbc37ebcbe 100644 (file)
@@ -670,7 +670,7 @@ pcibios_make_OF_bus_map(void)
        struct pci_controller* hose;
        struct property *map_prop;
 
-       pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
+       pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL);
        if (!pci_to_OF_bus_map) {
                printk(KERN_ERR "Can't allocate OF bus map !\n");
                return;
index add8c1a9af68ae12db88b1501f7b3f5d1c2ad1e4..c831815c31f0e5a1c572e19a5a3c706721ee8b9a 100644 (file)
@@ -138,7 +138,7 @@ static struct vm_struct * split_im_region(unsigned long v_addr,
        struct vm_struct *vm2 = NULL;
        struct vm_struct *new_vm = NULL;
        
-       vm1 = (struct vm_struct *) kmalloc(sizeof(*vm1), GFP_KERNEL);
+       vm1 = kmalloc(sizeof(*vm1), GFP_KERNEL);
        if (vm1 == NULL) {
                printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
                return NULL;
@@ -172,7 +172,7 @@ static struct vm_struct * split_im_region(unsigned long v_addr,
                 * uppermost remainder, and use existing parent one for the
                 * lower remainder of parent range
                 */
-               vm2 = (struct vm_struct *) kmalloc(sizeof(*vm2), GFP_KERNEL);
+               vm2 = kmalloc(sizeof(*vm2), GFP_KERNEL);
                if (vm2 == NULL) {
                        printk(KERN_ERR "%s() out of memory\n", __FUNCTION__);
                        kfree(vm1);
@@ -206,7 +206,7 @@ static struct vm_struct * __add_new_im_area(unsigned long req_addr,
                        break;
        }
        
-       area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+       area = kmalloc(sizeof(*area), GFP_KERNEL);
        if (!area)
                return NULL;
        area->flags = 0;
index b6b462d3c6046540cd51824f4f524125fd5f0f4b..f2bae04424f8a3933e8b49a4a261c7147de3ec75 100644 (file)
@@ -153,7 +153,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
                        return piar;
                }
        }
-       piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+       piar = kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
        if (!piar)
                return NULL;
 
index 709952c25f2948c197acdbc6947c3b2493f2b1d1..06b84c372e58d2a4c23826ee1347db67d391cad2 100644 (file)
@@ -1892,10 +1892,10 @@ init_fcc_param(fcc_info_t *fip, struct net_device *dev,
        /* Allocate space for the buffer descriptors from regular memory.
         * Initialize base addresses for the buffer descriptors.
         */
-       cep->rx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * RX_RING_SIZE,
+       cep->rx_bd_base = kmalloc(sizeof(cbd_t) * RX_RING_SIZE,
                        GFP_KERNEL | GFP_DMA);
        ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base);
-       cep->tx_bd_base = (cbd_t *)kmalloc(sizeof(cbd_t) * TX_RING_SIZE,
+       cep->tx_bd_base = kmalloc(sizeof(cbd_t) * TX_RING_SIZE,
                        GFP_KERNEL | GFP_DMA);
        ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base);
 
index c71ef3c2e7bf4459dbf565e70287a8b01e6e96fa..b7bb5f0b3c5f68a56fa0dde50392daec418c778f 100644 (file)
@@ -2601,7 +2601,7 @@ int __init tdm8xx_sound_init(void)
        /* Initialize beep stuff */
        orig_mksound = kd_mksound;
        kd_mksound = cs_mksound;
-       beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
+       beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
        if (beep_buf == NULL)
                printk(KERN_WARNING "dmasound: no memory for "
                       "beep buffer\n");
index ff690564edbd329181e2310c0b6ed8a4364565b6..12272361c018c41b1b34c2f33a526e80646cc8b1 100644 (file)
@@ -407,7 +407,7 @@ config APPLDATA_BASE
 
 config APPLDATA_MEM
        tristate "Monitor memory management statistics"
-       depends on APPLDATA_BASE
+       depends on APPLDATA_BASE && VM_EVENT_COUNTERS
        help
          This provides memory management related data to the Linux - VM Monitor
          Stream, like paging/swapping rate, memory utilisation, etc.
index ef5266fbce62105e2574dc916ab87dbba2f08b70..bb57bc0e3fc8d760a17a75cd555d29bd6683dcda 100644 (file)
@@ -191,13 +191,13 @@ debug_areas_alloc(int pages_per_area, int nr_areas)
        debug_entry_t*** areas;
        int i,j;
 
-       areas = (debug_entry_t ***) kmalloc(nr_areas *
+       areas = kmalloc(nr_areas *
                                        sizeof(debug_entry_t**),
                                        GFP_KERNEL);
        if (!areas)
                goto fail_malloc_areas;
        for (i = 0; i < nr_areas; i++) {
-               areas[i] = (debug_entry_t**) kmalloc(pages_per_area *
+               areas[i] = kmalloc(pages_per_area *
                                sizeof(debug_entry_t*),GFP_KERNEL);
                if (!areas[i]) {
                        goto fail_malloc_areas2;
@@ -242,7 +242,7 @@ debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size,
 
        /* alloc everything */
 
-       rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL);
+       rc = kmalloc(sizeof(debug_info_t), GFP_KERNEL);
        if(!rc)
                goto fail_malloc_rc;
        rc->active_entries = kcalloc(nr_areas, sizeof(int), GFP_KERNEL);
@@ -634,7 +634,7 @@ found:
                rc = -ENOMEM;
                goto out;
        }
-       p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t),
+       p_info = kmalloc(sizeof(file_private_info_t),
                                                GFP_KERNEL);
        if(!p_info){
                if(debug_info_snapshot)
index 4faf96f8a83414ddf7f36eb46aa8bb21b4e50b90..bc5beaa8f98e13a0278dad9e612b9d41bef48383 100644 (file)
@@ -37,7 +37,7 @@ int register_external_interrupt(__u16 code, ext_int_handler_t handler)
         ext_int_info_t *p;
         int index;
 
-       p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
+       p = kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
         if (p == NULL)
                 return -ENOMEM;
         p->code = code;
index c8cb211b90728741877f0326a96803c37ba07527..5b4841d067c16ccf906149fd3c73b87ea5d16325 100644 (file)
@@ -425,7 +425,7 @@ int request_fast_irq(unsigned int irq,
        }
        
        if (action == NULL)
-           action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+           action = kmalloc(sizeof(struct irqaction),
                                                 GFP_ATOMIC);
        
        if (!action) { 
@@ -528,7 +528,7 @@ int request_irq(unsigned int irq,
        }
        
        if (action == NULL)
-               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+               action = kmalloc(sizeof(struct irqaction),
                                                     GFP_ATOMIC);
        
        if (!action) { 
index cf1b8baa57eafd4c8b9ae3f7e45fdab3564aa6a1..0e27e226e0e2e1a291f9a79fde94dd9a4511cc7c 100644 (file)
@@ -327,7 +327,7 @@ int sun4d_request_irq(unsigned int irq,
        }
        
        if (action == NULL)
-               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+               action = kmalloc(sizeof(struct irqaction),
                                                     GFP_ATOMIC);
        
        if (!action) { 
index 4446f66590fac2f10485b76e11b3f3c6752499ce..2ebc2c0513832ad64ec09b9266d245eef0028622 100644 (file)
@@ -1055,7 +1055,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
                break;
        case 2:
                rval = -EFAULT;
-               kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+               kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
                                                 GFP_KERNEL);
                if (!kmbuf)
                        break;
@@ -1078,7 +1078,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
                break;
        case 3:
                rval = -EFAULT;
-               kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+               kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
                                                 GFP_KERNEL);
                if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
                                               kmbuf, arg3))
index b2e9762e13c5af974caf06c8c9116071835ecdaf..afe3d427ddfae510b29135453dcfa3217252c308 100644 (file)
@@ -72,9 +72,11 @@ static int uml_net_rx(struct net_device *dev)
        return pkt_len;
 }
 
-static void uml_dev_close(void* dev)
+static void uml_dev_close(struct work_struct *work)
 {
-       dev_close( (struct net_device *) dev);
+       struct uml_net_private *lp =
+               container_of(work, struct uml_net_private, work);
+       dev_close(lp->dev);
 }
 
 irqreturn_t uml_net_interrupt(int irq, void *dev_id)
@@ -89,7 +91,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
        spin_lock(&lp->lock);
        while((err = uml_net_rx(dev)) > 0) ;
        if(err < 0) {
-               DECLARE_WORK(close_work, uml_dev_close, dev);
                printk(KERN_ERR 
                       "Device '%s' read returned %d, shutting it down\n", 
                       dev->name, err);
@@ -97,9 +98,10 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
                 * again lp->lock.
                 * And dev_close() can be safely called multiple times on the
                 * same device, since it tests for (dev->flags & IFF_UP). So
-                * there's no harm in delaying the device shutdown. */
-               schedule_work(&close_work);
-#error this is not permitted - close_work will go out of scope
+                * there's no harm in delaying the device shutdown.
+                * Furthermore, the workqueue will not re-enqueue an already
+                * enqueued work item. */
+               schedule_work(&lp->work);
                goto out;
        }
        reactivate_fd(lp->fd, UM_ETH_IRQ);
@@ -365,6 +367,7 @@ static int eth_configure(int n, void *init, char *mac,
        /* This points to the transport private data. It's still clear, but we
         * must memset it to 0 *now*. Let's help the drivers. */
        memset(lp, 0, size);
+       INIT_WORK(&lp->work, uml_dev_close);
 
        /* sysfs register */
        if (!driver_registered) {
index 280459fb0b2619ded00ce874565a5d6c93ef6c49..218f8b47fdcd7ea80543acca85bc4e2b0bd9e972 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/skbuff.h>
 #include <linux/socket.h>
 #include <linux/list.h>
+#include <linux/workqueue.h>
 
 struct uml_net {
        struct list_head list;
@@ -26,6 +27,7 @@ struct uml_net_private {
        struct net_device *dev;
        struct timer_list tl;
        struct net_device_stats stats;
+       struct work_struct work;
        int fd;
        unsigned char mac[ETH_ALEN];
        unsigned short (*protocol)(struct sk_buff *);
index 49057d8bc668b88a5ac4a45a3559171253abfaed..5db7737df0ff1bc594856588b592c860a023c006 100644 (file)
@@ -166,7 +166,7 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
        struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
                        .func = 0,
                        .bytecount = bytecount,
-                       .ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
+                       .ptr = kmalloc(bytecount, GFP_KERNEL)};
        u32 cpu;
 
        if(ptrace_ldt.ptr == NULL)
@@ -426,7 +426,7 @@ void ldt_get_host_info(void)
                host_ldt_entries = dummy_list;
        else {
                size = (size + 1) * sizeof(dummy_list[0]);
-               host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
+               host_ldt_entries = kmalloc(size, GFP_KERNEL);
                if(host_ldt_entries == NULL) {
                        printk("ldt_get_host_info: couldn't allocate host ldt list\n");
                        goto out_free;
index d573017a5ddef17187b1eea8dbbd68fb3f61b3cf..71f733c4f66db346b17255c6bbbe798380804f20 100644 (file)
@@ -6,7 +6,7 @@ extra-y := head.o vmlinux.lds
 
 
 obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o  \
-        setup.o signal.o syscalls.o time.o traps.o vectors.o platform.o  \
+        setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
         pci-dma.o
 
 ## windowspill.o
index 418268f497669add49f91aa35423f01a4356d849..fe3834bc1dbf627a6ecce45c587a2c06e5c77f15 100644 (file)
@@ -16,7 +16,7 @@
  *
  */
 #include <asm/uaccess.h>
-#include <asm/syscalls.h>
+#include <asm/syscall.h>
 #include <asm/unistd.h>
 #include <linux/linkage.h>
 #include <linux/stringify.h>
index 5934c4bfd52a3d9b71331785ac6fafc26ddef992..ef126277b4b334a551929ad27116290fc5b5d22f 100644 (file)
@@ -1462,20 +1462,7 @@ static struct elevator_type iosched_as = {
 
 static int __init as_init(void)
 {
-       int ret;
-
-       ret = elv_register(&iosched_as);
-       if (!ret) {
-               /*
-                * don't allow AS to get unregistered, since we would have
-                * to browse all tasks in the system and release their
-                * as_io_context first
-                */
-               __module_get(THIS_MODULE);
-               return 0;
-       }
-
-       return ret;
+       return elv_register(&iosched_as);
 }
 
 static void __exit as_exit(void)
index 78c6b312bd3030d3c86a9c35e3facc842b73e3eb..533a2938ffd6740f6f41f2c5bd52177e8dde8a0e 100644 (file)
@@ -219,9 +219,12 @@ static int cfq_queue_empty(request_queue_t *q)
        return !cfqd->busy_queues;
 }
 
-static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
+static inline pid_t cfq_queue_pid(struct task_struct *task, int rw, int is_sync)
 {
-       if (rw == READ || rw == WRITE_SYNC)
+       /*
+        * Use the per-process queue, for read requests and syncronous writes
+        */
+       if (!(rw & REQ_RW) || is_sync)
                return task->pid;
 
        return CFQ_KEY_ASYNC;
@@ -473,7 +476,7 @@ static struct request *
 cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio)
 {
        struct task_struct *tsk = current;
-       pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio));
+       pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio), bio_sync(bio));
        struct cfq_queue *cfqq;
 
        cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio);
@@ -1748,6 +1751,9 @@ static int cfq_may_queue(request_queue_t *q, int rw)
        struct cfq_data *cfqd = q->elevator->elevator_data;
        struct task_struct *tsk = current;
        struct cfq_queue *cfqq;
+       unsigned int key;
+
+       key = cfq_queue_pid(tsk, rw, rw & REQ_RW_SYNC);
 
        /*
         * don't force setup of a queue from here, as a call to may_queue
@@ -1755,7 +1761,7 @@ static int cfq_may_queue(request_queue_t *q, int rw)
         * so just lookup a possibly existing queue, or return 'may queue'
         * if that fails
         */
-       cfqq = cfq_find_cfq_hash(cfqd, cfq_queue_pid(tsk, rw), tsk->ioprio);
+       cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio);
        if (cfqq) {
                cfq_init_prio_data(cfqq);
                cfq_prio_boost(cfqq);
@@ -1798,10 +1804,10 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask)
        struct task_struct *tsk = current;
        struct cfq_io_context *cic;
        const int rw = rq_data_dir(rq);
-       pid_t key = cfq_queue_pid(tsk, rw);
+       const int is_sync = rq_is_sync(rq);
+       pid_t key = cfq_queue_pid(tsk, rw, is_sync);
        struct cfq_queue *cfqq;
        unsigned long flags;
-       int is_sync = key != CFQ_KEY_ASYNC;
 
        might_sleep_if(gfp_mask & __GFP_WAIT);
 
index a541b42c08e343f848d292a1ebfda4a0e82d5090..79807dbc306e58b063464a716c8ace72fb110f10 100644 (file)
@@ -2058,15 +2058,16 @@ static void freed_request(request_queue_t *q, int rw, int priv)
  * Returns NULL on failure, with queue_lock held.
  * Returns !NULL on success, with queue_lock *not held*.
  */
-static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
-                                  gfp_t gfp_mask)
+static struct request *get_request(request_queue_t *q, int rw_flags,
+                                  struct bio *bio, gfp_t gfp_mask)
 {
        struct request *rq = NULL;
        struct request_list *rl = &q->rq;
        struct io_context *ioc = NULL;
+       const int rw = rw_flags & 0x01;
        int may_queue, priv;
 
-       may_queue = elv_may_queue(q, rw);
+       may_queue = elv_may_queue(q, rw_flags);
        if (may_queue == ELV_MQUEUE_NO)
                goto rq_starved;
 
@@ -2114,7 +2115,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
 
        spin_unlock_irq(q->queue_lock);
 
-       rq = blk_alloc_request(q, rw, priv, gfp_mask);
+       rq = blk_alloc_request(q, rw_flags, priv, gfp_mask);
        if (unlikely(!rq)) {
                /*
                 * Allocation failed presumably due to memory. Undo anything
@@ -2162,12 +2163,13 @@ out:
  *
  * Called with q->queue_lock held, and returns with it unlocked.
  */
-static struct request *get_request_wait(request_queue_t *q, int rw,
+static struct request *get_request_wait(request_queue_t *q, int rw_flags,
                                        struct bio *bio)
 {
+       const int rw = rw_flags & 0x01;
        struct request *rq;
 
-       rq = get_request(q, rw, bio, GFP_NOIO);
+       rq = get_request(q, rw_flags, bio, GFP_NOIO);
        while (!rq) {
                DEFINE_WAIT(wait);
                struct request_list *rl = &q->rq;
@@ -2175,7 +2177,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw,
                prepare_to_wait_exclusive(&rl->wait[rw], &wait,
                                TASK_UNINTERRUPTIBLE);
 
-               rq = get_request(q, rw, bio, GFP_NOIO);
+               rq = get_request(q, rw_flags, bio, GFP_NOIO);
 
                if (!rq) {
                        struct io_context *ioc;
@@ -2910,6 +2912,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
        int el_ret, nr_sectors, barrier, err;
        const unsigned short prio = bio_prio(bio);
        const int sync = bio_sync(bio);
+       int rw_flags;
 
        nr_sectors = bio_sectors(bio);
 
@@ -2983,11 +2986,20 @@ static int __make_request(request_queue_t *q, struct bio *bio)
        }
 
 get_rq:
+       /*
+        * This sync check and mask will be re-done in init_request_from_bio(),
+        * but we need to set it earlier to expose the sync flag to the
+        * rq allocator and io schedulers.
+        */
+       rw_flags = bio_data_dir(bio);
+       if (sync)
+               rw_flags |= REQ_RW_SYNC;
+
        /*
         * Grab a free request. This is might sleep but can not fail.
         * Returns with the queue unlocked.
         */
-       req = get_request_wait(q, bio_data_dir(bio), bio);
+       req = get_request_wait(q, rw_flags, bio);
 
        /*
         * After dropping the lock and possibly sleeping here, our request
index 034c939bf91a2a26cabcbc836f508bbf283e911f..6e93004f2181ccb3f265994cf9806db528641796 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/crypto.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/seq_file.h>
index 048542341204e716bc24e721914a240cf781426e..674bf81c6e660040ab8d0136ecebd4e9f84aad66 100644 (file)
@@ -1549,12 +1549,12 @@ int fd1772_init(void)
 #ifdef TRACKBUFFER
        BufferDrive = BufferSide = BufferTrack = -1;
        /* Atari uses 512 - I want to eventually cope with 1K sectors */
-       DMABuffer = (char *)kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
+       DMABuffer = kmalloc((FD1772_MAX_SECTORS+1)*512,GFP_KERNEL);
        TrackBuffer = DMABuffer + 512;
 #else
        /* Allocate memory for the DMAbuffer - on the Atari this takes it
           out of some special memory... */
-       DMABuffer = (char *) kmalloc(2048);     /* Copes with pretty large sectors */
+       DMABuffer = kmalloc(2048);      /* Copes with pretty large sectors */
 #endif
        err = -ENOMEM;
        if (!DMAbuffer)
index 9021e34d20966f7b70a631408b9599556e3042c3..90786d7a20bbbfde234167b64ef86a4f0a8fa16b 100644 (file)
@@ -551,7 +551,7 @@ static int adma_port_start(struct ata_port *ap)
                return rc;
        adma_enter_reg_mode(ap);
        rc = -ENOMEM;
-       pp = kcalloc(1, sizeof(*pp), GFP_KERNEL);
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
        if (!pp)
                goto err_out;
        pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
@@ -672,7 +672,7 @@ static int adma_ata_init_one(struct pci_dev *pdev,
        if (rc)
                goto err_out_iounmap;
 
-       probe_ent = kcalloc(1, sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
        if (probe_ent == NULL) {
                rc = -ENOMEM;
                goto err_out_iounmap;
index bc1b13c8f5d717893661d12ee0fad2512175c91b..5aab7bd473ac9325d5e327597ec474d059199184 100644 (file)
@@ -1832,7 +1832,7 @@ static int __devinit eni_start(struct atm_dev *dev)
        /* initialize memory management */
        buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
        eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
-       eni_dev->free_list = (struct eni_free *) kmalloc(
+       eni_dev->free_list = kmalloc(
            sizeof(struct eni_free)*(eni_dev->free_list_size+1),GFP_KERNEL);
        if (!eni_dev->free_list) {
                printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
@@ -2232,7 +2232,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
                goto out0;
        }
 
-       eni_dev = (struct eni_dev *) kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
+       eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
        if (!eni_dev) goto out0;
        if (!cpu_zeroes) {
                cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
index 7d9b4e52f0bf4c985f1766fe2f88c35c78ea6c32..db33f6f4dd2a5517302e22fc5575c43c1a28413e 100644 (file)
@@ -2351,7 +2351,7 @@ he_open(struct atm_vcc *vcc)
 
        cid = he_mkcid(he_dev, vpi, vci);
 
-       he_vcc = (struct he_vcc *) kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
+       he_vcc = kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
        if (he_vcc == NULL) {
                hprintk("unable to allocate he_vcc during open\n");
                return -ENOMEM;
index 267825501dfe61570ed12300b45be52590bf5f89..09f477d4237a5f553d711748dab5ff953f3255b3 100644 (file)
@@ -2602,7 +2602,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
        struct atm_dev *atmdev;
        int result;
 
-       lanai = (struct lanai_dev *) kmalloc(sizeof(*lanai), GFP_KERNEL);
+       lanai = kmalloc(sizeof(*lanai), GFP_KERNEL);
        if (lanai == NULL) {
                printk(KERN_ERR DEV_LABEL
                       ": couldn't allocate dev_data structure!\n");
index bd09045948054ab836fe3b14f9f0384a85b08f86..aab9b3733d52197c5d9373dae1310fae01bd436f 100644 (file)
@@ -997,7 +997,7 @@ static scq_info *get_scq(int size, u32 scd)
    if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
       return NULL;
 
-   scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL);
+   scq = kmalloc(sizeof(scq_info), GFP_KERNEL);
    if (scq == NULL)
       return NULL;
    scq->org = kmalloc(2 * size, GFP_KERNEL);
@@ -1006,7 +1006,7 @@ static scq_info *get_scq(int size, u32 scd)
       kfree(scq);
       return NULL;
    }
-   scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) *
+   scq->skb = kmalloc(sizeof(struct sk_buff *) *
                                           (size / NS_SCQE_SIZE), GFP_KERNEL);
    if (scq->skb == NULL)
    {
index 7df0f373188eaad68253ff3d56a466752436e6b6..756d4f760da3b11f901ccbcedba6fc14d6bf18ad 100644 (file)
@@ -996,7 +996,7 @@ static int start_tx(struct atm_dev *dev)
 
        DPRINTK("start_tx\n");
        zatm_dev = ZATM_DEV(dev);
-       zatm_dev->tx_map = (struct atm_vcc **) kmalloc(sizeof(struct atm_vcc *)*
+       zatm_dev->tx_map = kmalloc(sizeof(struct atm_vcc *)*
            zatm_dev->chans,GFP_KERNEL);
        if (!zatm_dev->tx_map) return -ENOMEM;
        zatm_dev->tx_bw = ATM_OC3_PCR;
@@ -1591,7 +1591,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
        struct zatm_dev *zatm_dev;
        int ret = -ENOMEM;
 
-       zatm_dev = (struct zatm_dev *) kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
+       zatm_dev = kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
        if (!zatm_dev) {
                printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
                goto out;
index f098881f45b28129ec58aeae78e761fc4768e9bd..8bf2ca2e56b53ccb07a5ea8c32baec7fc1e51488 100644 (file)
@@ -163,6 +163,8 @@ int class_register(struct class * cls)
 void class_unregister(struct class * cls)
 {
        pr_debug("device class '%s': unregistering\n", cls->name);
+       if (cls->virtual_dir)
+               kobject_unregister(cls->virtual_dir);
        remove_class_attrs(cls);
        subsystem_unregister(&cls->subsys);
 }
index dbe0735f8c9e6bab0446ea0278cd749e3ea98630..f95d502772740d9fa653379f185e002742d9abf4 100644 (file)
@@ -173,7 +173,7 @@ pool_alloc_page (struct dma_pool *pool, gfp_t mem_flags)
        mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
        mapsize *= sizeof (long);
 
-       page = (struct dma_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+       page = kmalloc(mapsize + sizeof *page, mem_flags);
        if (!page)
                return NULL;
        page->vaddr = dma_alloc_coherent (pool->dev,
index d1df4a0879245d8dee8a91311fdf4ba7e4951a4a..f9c903ba9fcd1259e37120e2db74d55c6acdcbce 100644 (file)
@@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
  *     pointer.  The memory associated with the platform data will be freed
  *     when the platform device is released.
  */
-int platform_device_add_data(struct platform_device *pdev, void *data, size_t size)
+int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size)
 {
        void *d;
 
@@ -473,7 +473,7 @@ EXPORT_SYMBOL_GPL(platform_driver_unregister);
  * Returns zero if the driver registered and bound to a device, else returns
  * a negative error code and with the driver not registered.
  */
-int platform_driver_probe(struct platform_driver *drv,
+int __init_or_module platform_driver_probe(struct platform_driver *drv,
                int (*probe)(struct platform_device *))
 {
        int retval, code;
index ce9cfcb6071c5a7aa135ae92cdb56a2a0ab2da0e..58c1debf86f1c7271ed84bce7cf1ea097c878725 100644 (file)
@@ -28,13 +28,6 @@ config ATARI_FLOPPY
        tristate "Atari floppy support"
        depends on ATARI
 
-config BLK_DEV_SWIM_IOP
-       bool "Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)"
-       depends on MAC && EXPERIMENTAL && BROKEN
-       help
-         Say Y here to support the SWIM (Super Woz Integrated Machine) IOP
-         floppy controller on the Macintosh IIfx and Quadra 900/950.
-
 config MAC_FLOPPY
        tristate "Support for PowerMac floppy"
        depends on PPC_PMAC && !PPC_PMAC64
index 410f259a8031a651abbb13fb7f084d75da150450..dd88e33c1eb108ccd6d56a24dcb75eea8bca41f7 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_MAC_FLOPPY)        += swim3.o
 obj-$(CONFIG_BLK_DEV_FD)       += floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)     += amiflop.o
 obj-$(CONFIG_ATARI_FLOPPY)     += ataflop.o
-obj-$(CONFIG_BLK_DEV_SWIM_IOP) += swim_iop.o
 obj-$(CONFIG_ATARI_ACSI)       += acsi.o
 obj-$(CONFIG_ATARI_SLM)                += acsi_slm.o
 obj-$(CONFIG_AMIGA_Z2RAM)      += z2ram.o
index ee159edb6b88b92bc373d830eb285aa799558111..d719a5d8f4355e45905410f4a1c0b506702d5bb4 100644 (file)
@@ -1039,7 +1039,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                                status = -ENOMEM;
                                goto cleanup1;
                        }
-                       buff_size = (int *)kmalloc(MAXSGENTRIES * sizeof(int),
+                       buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
                                                   GFP_KERNEL);
                        if (!buff_size) {
                                status = -ENOMEM;
@@ -2837,7 +2837,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        if (err) {
                printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
                       "aborting\n");
-               goto err_out_disable_pdev;
+               return err;
        }
 
        subsystem_vendor_id = pdev->subsystem_vendor;
@@ -2865,7 +2865,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 #ifdef CCISS_DEBUG
        printk("address 0 = %x\n", c->paddr);
 #endif                         /* CCISS_DEBUG */
-       c->vaddr = remap_pci_mem(c->paddr, 200);
+       c->vaddr = remap_pci_mem(c->paddr, 0x250);
 
        /* Wait for the board to become ready.  (PCI hotplug needs this.)
         * We poll for up to 120 secs, once per 100ms. */
@@ -3004,11 +3004,12 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        }
        return 0;
 
-      err_out_free_res:
+err_out_free_res:
+       /*
+        * Deliberately omit pci_disable_device(): it does something nasty to
+        * Smart Array controllers that pci_enable_device does not undo
+        */
        pci_release_regions(pdev);
-
-      err_out_disable_pdev:
-       pci_disable_device(pdev);
        return err;
 }
 
@@ -3382,8 +3383,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
                if (drv->queue)
                        blk_cleanup_queue(drv->queue);
        }
+       /*
+        * Deliberately omit pci_disable_device(): it does something nasty to
+        * Smart Array controllers that pci_enable_device does not undo
+        */
        pci_release_regions(pdev);
-       pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        free_hba(i);
        return -1;
@@ -3452,8 +3456,11 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
 #ifdef CONFIG_CISS_SCSI_TAPE
        kfree(hba[i]->scsi_rejects.complete);
 #endif
+       /*
+        * Deliberately omit pci_disable_device(): it does something nasty to
+        * Smart Array controllers that pci_enable_device does not undo
+        */
        pci_release_regions(pdev);
-       pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
        free_hba(i);
 }
index d5f519ebbc0842d4b6eb194bc18a83f4ec8d020b..b94cd1c321313c17f8a068ef5144ce87102bf3e9 100644 (file)
@@ -1625,7 +1625,7 @@ static void start_fwbk(int ctlr)
                " processing\n");
        /* Command does not return anything, but idasend command needs a 
                buffer */
-       id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
+       id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
        if(id_ctlr_buf==NULL)
        {
                printk(KERN_WARNING "cpqarray: Out of memory. "
@@ -1660,14 +1660,14 @@ static void getgeometry(int ctlr)
 
        info_p->log_drv_map = 0;        
        
-       id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
+       id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
        if(id_ldrive == NULL)
        {
                printk( KERN_ERR "cpqarray:  out of memory.\n");
                return;
        }
 
-       id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
+       id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
        if(id_ctlr_buf == NULL)
        {
                kfree(id_ldrive);
@@ -1675,7 +1675,7 @@ static void getgeometry(int ctlr)
                return;
        }
 
-       id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
+       id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
        if(id_lstatus_buf == NULL)
        {
                kfree(id_ctlr_buf);
@@ -1684,7 +1684,7 @@ static void getgeometry(int ctlr)
                return;
        }
 
-       sense_config_buf = (config_t *)kmalloc(sizeof(config_t), GFP_KERNEL);
+       sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL);
        if(sense_config_buf == NULL)
        {
                kfree(id_lstatus_buf);
diff --git a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
deleted file mode 100644 (file)
index ed7b06c..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Driver for the SWIM (Super Woz Integrated Machine) IOP
- * floppy controller on the Macintosh IIfx and Quadra 900/950
- *
- * Written by Joshua M. Thompson (funaho@jurai.org)
- * based on the SWIM3 driver (c) 1996 by Paul Mackerras.
- *
- * 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.
- *
- * 1999-06-12 (jmt) - Initial implementation.
- */
-
-/*
- * -------------------
- * Theory of Operation
- * -------------------
- *
- * Since the SWIM IOP is message-driven we implement a simple request queue
- * system.  One outstanding request may be queued at any given time (this is
- * an IOP limitation); only when that request has completed can a new request
- * be sent.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/fd.h>
-#include <linux/ioctl.h>
-#include <linux/blkdev.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mac_iop.h>
-#include <asm/swim_iop.h>
-
-#define DRIVER_VERSION "Version 0.1 (1999-06-12)"
-
-#define MAX_FLOPPIES   4
-
-enum swim_state {
-       idle,
-       available,
-       revalidating,
-       transferring,
-       ejecting
-};
-
-struct floppy_state {
-       enum swim_state state;
-       int     drive_num;      /* device number */
-       int     secpercyl;      /* disk geometry information */
-       int     secpertrack;
-       int     total_secs;
-       int     write_prot;     /* 1 if write-protected, 0 if not, -1 dunno */
-       int     ref_count;
-       struct timer_list timeout;
-       int     ejected;
-       struct wait_queue *wait;
-       int     wanted;
-       int     timeout_pending;
-};
-
-struct swim_iop_req {
-       int     sent;
-       int     complete;
-       __u8    command[32];
-       struct floppy_state *fs;
-       void    (*done)(struct swim_iop_req *);
-};
-
-static struct swim_iop_req *current_req;
-static int floppy_count;
-
-static struct floppy_state floppy_states[MAX_FLOPPIES];
-static DEFINE_SPINLOCK(swim_iop_lock);
-
-#define CURRENT elv_next_request(swim_queue)
-
-static char *drive_names[7] = {
-       "not installed",        /* DRV_NONE    */
-       "unknown (1)",          /* DRV_UNKNOWN */
-       "a 400K drive",         /* DRV_400K    */
-       "an 800K drive"         /* DRV_800K    */
-       "unknown (4)",          /* ????        */
-       "an FDHD",              /* DRV_FDHD    */
-       "unknown (6)",          /* ????        */
-       "an Apple HD20"         /* DRV_HD20    */
-};
-
-int swimiop_init(void);
-static void swimiop_init_request(struct swim_iop_req *);
-static int swimiop_send_request(struct swim_iop_req *);
-static void swimiop_receive(struct iop_msg *);
-static void swimiop_status_update(int, struct swim_drvstatus *);
-static int swimiop_eject(struct floppy_state *fs);
-
-static int floppy_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long param);
-static int floppy_open(struct inode *inode, struct file *filp);
-static int floppy_release(struct inode *inode, struct file *filp);
-static int floppy_check_change(struct gendisk *disk);
-static int floppy_revalidate(struct gendisk *disk);
-static int grab_drive(struct floppy_state *fs, enum swim_state state,
-                     int interruptible);
-static void release_drive(struct floppy_state *fs);
-static void set_timeout(struct floppy_state *fs, int nticks,
-                       void (*proc)(unsigned long));
-static void fd_request_timeout(unsigned long);
-static void do_fd_request(request_queue_t * q);
-static void start_request(struct floppy_state *fs);
-
-static struct block_device_operations floppy_fops = {
-       .open           = floppy_open,
-       .release        = floppy_release,
-       .ioctl          = floppy_ioctl,
-       .media_changed  = floppy_check_change,
-       .revalidate_disk= floppy_revalidate,
-};
-
-static struct request_queue *swim_queue;
-/*
- * SWIM IOP initialization
- */
-
-int swimiop_init(void)
-{
-       volatile struct swim_iop_req req;
-       struct swimcmd_status *cmd = (struct swimcmd_status *) &req.command[0];
-       struct swim_drvstatus *ds = &cmd->status;
-       struct floppy_state *fs;
-       int i;
-
-       current_req = NULL;
-       floppy_count = 0;
-
-       if (!iop_ism_present)
-               return -ENODEV;
-
-       if (register_blkdev(FLOPPY_MAJOR, "fd"))
-               return -EBUSY;
-
-       swim_queue = blk_init_queue(do_fd_request, &swim_iop_lock);
-       if (!swim_queue) {
-               unregister_blkdev(FLOPPY_MAJOR, "fd");
-               return -ENOMEM;
-       }
-
-       printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n",
-               DRIVER_VERSION);
-
-       if (iop_listen(SWIM_IOP, SWIM_CHAN, swimiop_receive, "SWIM") != 0) {
-               printk(KERN_ERR "SWIM-IOP: IOP channel already in use; can't initialize.\n");
-               unregister_blkdev(FLOPPY_MAJOR, "fd");
-               blk_cleanup_queue(swim_queue);
-               return -EBUSY;
-       }
-
-       printk(KERN_ERR "SWIM_IOP: probing for installed drives.\n");
-
-       for (i = 0 ; i < MAX_FLOPPIES ; i++) {
-               memset(&floppy_states[i], 0, sizeof(struct floppy_state));
-               fs = &floppy_states[floppy_count];
-
-               swimiop_init_request(&req);
-               cmd->code = CMD_STATUS;
-               cmd->drive_num = i + 1;
-               if (swimiop_send_request(&req) != 0) continue;
-               while (!req.complete);
-               if (cmd->error != 0) {
-                       printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error);
-                       continue;
-               }
-               if (ds->installed != 0x01) continue;
-               printk("SWIM-IOP: drive %d is %s (%s, %s, %s, %s)\n", i,
-                       drive_names[ds->info.type],
-                       ds->info.external? "ext" : "int",
-                       ds->info.scsi? "scsi" : "floppy",
-                       ds->info.fixed? "fixed" : "removable",
-                       ds->info.secondary? "secondary" : "primary");
-               swimiop_status_update(floppy_count, ds);
-               fs->state = idle;
-
-               init_timer(&fs->timeout);
-               floppy_count++;
-       }
-       printk("SWIM-IOP: detected %d installed drives.\n", floppy_count);
-
-       for (i = 0; i < floppy_count; i++) {
-               struct gendisk *disk = alloc_disk(1);
-               if (!disk)
-                       continue;
-               disk->major = FLOPPY_MAJOR;
-               disk->first_minor = i;
-               disk->fops = &floppy_fops;
-               sprintf(disk->disk_name, "fd%d", i);
-               disk->private_data = &floppy_states[i];
-               disk->queue = swim_queue;
-               set_capacity(disk, 2880 * 2);
-               add_disk(disk);
-       }
-
-       return 0;
-}
-
-static void swimiop_init_request(struct swim_iop_req *req)
-{
-       req->sent = 0;
-       req->complete = 0;
-       req->done = NULL;
-}
-
-static int swimiop_send_request(struct swim_iop_req *req)
-{
-       unsigned long flags;
-       int err;
-
-       /* It's doubtful an interrupt routine would try to send */
-       /* a SWIM request, but I'd rather play it safe here.    */
-
-       local_irq_save(flags);
-
-       if (current_req != NULL) {
-               local_irq_restore(flags);
-               return -ENOMEM;
-       }
-
-       current_req = req;
-
-       /* Interrupts should be back on for iop_send_message() */
-
-       local_irq_restore(flags);
-
-       err = iop_send_message(SWIM_IOP, SWIM_CHAN, (void *) req,
-                               sizeof(req->command), (__u8 *) &req->command[0],
-                               swimiop_receive);
-
-       /* No race condition here; we own current_req at this point */
-
-       if (err) {
-               current_req = NULL;
-       } else {
-               req->sent = 1;
-       }
-       return err;
-}
-
-/*
- * Receive a SWIM message from the IOP.
- *
- * This will be called in two cases:
- *
- * 1. A message has been successfully sent to the IOP.
- * 2. An unsolicited message was received from the IOP.
- */
-
-void swimiop_receive(struct iop_msg *msg)
-{
-       struct swim_iop_req *req;
-       struct swimmsg_status *sm;
-       struct swim_drvstatus *ds;
-
-       req = current_req;
-
-       switch(msg->status) {
-               case IOP_MSGSTATUS_COMPLETE:
-                       memcpy(&req->command[0], &msg->reply[0], sizeof(req->command));
-                       req->complete = 1;
-                       if (req->done) (*req->done)(req);
-                       current_req = NULL;
-                       break;
-               case IOP_MSGSTATUS_UNSOL:
-                       sm = (struct swimmsg_status *) &msg->message[0];
-                       ds = &sm->status;
-                       swimiop_status_update(sm->drive_num, ds);
-                       iop_complete_message(msg);
-                       break;
-       }
-}
-
-static void swimiop_status_update(int drive_num, struct swim_drvstatus *ds)
-{
-       struct floppy_state *fs = &floppy_states[drive_num];
-
-       fs->write_prot = (ds->write_prot == 0x80);
-       if ((ds->disk_in_drive != 0x01) && (ds->disk_in_drive != 0x02)) {
-               fs->ejected = 1;
-       } else {
-               fs->ejected = 0;
-       }
-       switch(ds->info.type) {
-               case DRV_400K:
-                       fs->secpercyl = 10;
-                       fs->secpertrack = 10;
-                       fs->total_secs = 800;
-                       break;
-               case DRV_800K:
-                       fs->secpercyl = 20;
-                       fs->secpertrack = 10;
-                       fs->total_secs = 1600;
-                       break;
-               case DRV_FDHD:
-                       fs->secpercyl = 36;
-                       fs->secpertrack = 18;
-                       fs->total_secs = 2880;
-                       break;
-               default:
-                       fs->secpercyl = 0;
-                       fs->secpertrack = 0;
-                       fs->total_secs = 0;
-                       break;
-       }
-}
-
-static int swimiop_eject(struct floppy_state *fs)
-{
-       int err, n;
-       struct swim_iop_req req;
-       struct swimcmd_eject *cmd = (struct swimcmd_eject *) &req.command[0];
-
-       err = grab_drive(fs, ejecting, 1);
-       if (err) return err;
-
-       swimiop_init_request(&req);
-       cmd->code = CMD_EJECT;
-       cmd->drive_num = fs->drive_num;
-       err = swimiop_send_request(&req);
-       if (err) {
-               release_drive(fs);
-               return err;
-       }
-       for (n = 2*HZ; n > 0; --n) {
-               if (req.complete) break;
-               if (signal_pending(current)) {
-                       err = -EINTR;
-                       break;
-               }
-               schedule_timeout_interruptible(1);
-       }
-       release_drive(fs);
-       return cmd->error;
-}
-
-static struct floppy_struct floppy_type =
-       { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };    /*  7 1.44MB 3.5"   */
-
-static int floppy_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long param)
-{
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
-       int err;
-
-       if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       switch (cmd) {
-       case FDEJECT:
-               if (fs->ref_count != 1)
-                       return -EBUSY;
-               err = swimiop_eject(fs);
-               return err;
-       case FDGETPRM:
-               if (copy_to_user((void *) param, (void *) &floppy_type,
-                                sizeof(struct floppy_struct)))
-                       return -EFAULT;
-               return 0;
-       }
-       return -ENOTTY;
-}
-
-static int floppy_open(struct inode *inode, struct file *filp)
-{
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
-
-       if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
-               return -EBUSY;
-
-       if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
-               check_disk_change(inode->i_bdev);
-               if (fs->ejected)
-                       return -ENXIO;
-       }
-
-       if ((filp->f_mode & 2) && fs->write_prot)
-               return -EROFS;
-
-       if (filp->f_flags & O_EXCL)
-               fs->ref_count = -1;
-       else
-               ++fs->ref_count;
-
-       return 0;
-}
-
-static int floppy_release(struct inode *inode, struct file *filp)
-{
-       struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
-       if (fs->ref_count > 0)
-               fs->ref_count--;
-       return 0;
-}
-
-static int floppy_check_change(struct gendisk *disk)
-{
-       struct floppy_state *fs = disk->private_data;
-       return fs->ejected;
-}
-
-static int floppy_revalidate(struct gendisk *disk)
-{
-       struct floppy_state *fs = disk->private_data;
-       grab_drive(fs, revalidating, 0);
-       /* yadda, yadda */
-       release_drive(fs);
-       return 0;
-}
-
-static void floppy_off(unsigned int nr)
-{
-}
-
-static int grab_drive(struct floppy_state *fs, enum swim_state state,
-                     int interruptible)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       if (fs->state != idle) {
-               ++fs->wanted;
-               while (fs->state != available) {
-                       if (interruptible && signal_pending(current)) {
-                               --fs->wanted;
-                               local_irq_restore(flags);
-                               return -EINTR;
-                       }
-                       interruptible_sleep_on(&fs->wait);
-               }
-               --fs->wanted;
-       }
-       fs->state = state;
-       local_irq_restore(flags);
-       return 0;
-}
-
-static void release_drive(struct floppy_state *fs)
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       fs->state = idle;
-       start_request(fs);
-       local_irq_restore(flags);
-}
-
-static void set_timeout(struct floppy_state *fs, int nticks,
-                       void (*proc)(unsigned long))
-{
-       unsigned long flags;
-
-       local_irq_save(flags);
-       if (fs->timeout_pending)
-               del_timer(&fs->timeout);
-       init_timer(&fs->timeout);
-       fs->timeout.expires = jiffies + nticks;
-       fs->timeout.function = proc;
-       fs->timeout.data = (unsigned long) fs;
-       add_timer(&fs->timeout);
-       fs->timeout_pending = 1;
-       local_irq_restore(flags);
-}
-
-static void do_fd_request(request_queue_t * q)
-{
-       int i;
-
-       for (i = 0 ; i < floppy_count ; i++) {
-               start_request(&floppy_states[i]);
-       }
-}
-
-static void fd_request_complete(struct swim_iop_req *req)
-{
-       struct floppy_state *fs = req->fs;
-       struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req->command[0];
-
-       del_timer(&fs->timeout);
-       fs->timeout_pending = 0;
-       fs->state = idle;
-       if (cmd->error) {
-               printk(KERN_ERR "SWIM-IOP: error %d on read/write request.\n", cmd->error);
-               end_request(CURRENT, 0);
-       } else {
-               CURRENT->sector += cmd->num_blocks;
-               CURRENT->current_nr_sectors -= cmd->num_blocks;
-               if (CURRENT->current_nr_sectors <= 0) {
-                       end_request(CURRENT, 1);
-                       return;
-               }
-       }
-       start_request(fs);
-}
-
-static void fd_request_timeout(unsigned long data)
-{
-       struct floppy_state *fs = (struct floppy_state *) data;
-
-       fs->timeout_pending = 0;
-       end_request(CURRENT, 0);
-       fs->state = idle;
-}
-
-static void start_request(struct floppy_state *fs)
-{
-       volatile struct swim_iop_req req;
-       struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req.command[0];
-
-       if (fs->state == idle && fs->wanted) {
-               fs->state = available;
-               wake_up(&fs->wait);
-               return;
-       }
-       while (CURRENT && fs->state == idle) {
-               if (CURRENT->bh && !buffer_locked(CURRENT->bh))
-                       panic("floppy: block not locked");
-#if 0
-               printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
-                      CURRENT->rq_disk->disk_name, CURRENT->cmd,
-                      CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer);
-               printk("           errors=%d current_nr_sectors=%ld\n",
-                     CURRENT->errors, CURRENT->current_nr_sectors);
-#endif
-
-               if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
-                       end_request(CURRENT, 0);
-                       continue;
-               }
-               if (CURRENT->current_nr_sectors == 0) {
-                       end_request(CURRENT, 1);
-                       continue;
-               }
-               if (fs->ejected) {
-                       end_request(CURRENT, 0);
-                       continue;
-               }
-
-               swimiop_init_request(&req);
-               req.fs = fs;
-               req.done = fd_request_complete;
-
-               if (CURRENT->cmd == WRITE) {
-                       if (fs->write_prot) {
-                               end_request(CURRENT, 0);
-                               continue;
-                       }
-                       cmd->code = CMD_WRITE;
-               } else {
-                       cmd->code = CMD_READ;
-
-               }
-               cmd->drive_num = fs->drive_num;
-               cmd->buffer = CURRENT->buffer;
-               cmd->first_block = CURRENT->sector;
-               cmd->num_blocks = CURRENT->current_nr_sectors;
-
-               if (swimiop_send_request(&req)) {
-                       end_request(CURRENT, 0);
-                       continue;
-               }
-
-               set_timeout(fs, HZ*CURRENT->current_nr_sectors,
-                               fd_request_timeout);
-
-               fs->state = transferring;
-       }
-}
index 2df5cf4ec7432ee98d4daad48cc799c7b9657575..e4a2f8f3a1d764f909910dfd03c4b55e2e24f17c 100644 (file)
@@ -1810,7 +1810,7 @@ static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
 
        size = sizeof(s->disckey.value) + 4;
 
-       if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+       if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
                return -ENOMEM;
 
        init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
@@ -1861,7 +1861,7 @@ static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
 
        size = sizeof(s->manufact.value) + 4;
 
-       if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+       if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
                return -ENOMEM;
 
        init_cdrom_command(&cgc, buf, size, CGC_DATA_READ);
@@ -2849,7 +2849,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                /* FIXME: we need upper bound checking, too!! */
                if (lba < 0)
                        return -EINVAL;
-               cgc.buffer = (char *) kmalloc(blocksize, GFP_KERNEL);
+               cgc.buffer = kmalloc(blocksize, GFP_KERNEL);
                if (cgc.buffer == NULL)
                        return -ENOMEM;
                memset(&sense, 0, sizeof(sense));
@@ -3031,7 +3031,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                int size = sizeof(dvd_struct);
                if (!CDROM_CAN(CDC_DVD))
                        return -ENOSYS;
-               if ((s = (dvd_struct *) kmalloc(size, GFP_KERNEL)) == NULL)
+               if ((s = kmalloc(size, GFP_KERNEL)) == NULL)
                        return -ENOMEM;
                cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); 
                if (copy_from_user(s, (dvd_struct __user *)arg, size)) {
index e6d8e9ededeaeb57e562e84ad5987f89c8262f0c..b6c61bbb20e135adbba310b0d4f7cb5ea54d41d8 100644 (file)
@@ -1420,7 +1420,7 @@ int __init cm206_init(void)
                return -EIO;
        }
        printk(" adapter at 0x%x", cm206_base);
-       cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
+       cd = kmalloc(size, GFP_KERNEL);
        if (!cd)
                goto out_base;
        /* Now we have found the adaptor card, try to reset it. As we have
index 0a3aee29e067bcdd613ce917e96ba9c564435d55..9e43e39dc35c09dc25efafa0c56555bfeabf4dea 100644 (file)
@@ -97,7 +97,7 @@ config SERIAL_NONSTANDARD
 
 config COMPUTONE
        tristate "Computone IntelliPort Plus serial support"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
        ---help---
          This driver supports the entire family of Intelliport II/Plus
          controllers with the exception of the MicroChannel controllers and
@@ -203,7 +203,7 @@ config MOXA_SMARTIO
 
 config MOXA_SMARTIO_NEW
        tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
        help
          Say Y here if you have a Moxa SmartIO multiport serial card and/or
          want to help develop a new version of this driver.
@@ -218,7 +218,7 @@ config MOXA_SMARTIO_NEW
 
 config ISI
        tristate "Multi-Tech multiport card support (EXPERIMENTAL)"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && PCI
        select FW_LOADER
        help
          This is a driver for the Multi-Tech cards which provide several
@@ -312,7 +312,7 @@ config SPECIALIX_RTSCTS
 
 config SX
        tristate "Specialix SX (and SI) card support"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
        help
          This is a driver for the SX and SI multiport serial cards.
          Please read the file <file:Documentation/sx.txt> for details.
index 04a12027a740a57dea956fd3abbba1785739500e..b99b7561260dca1eeea4472bb95f3a087c9f688a 100644 (file)
@@ -443,7 +443,7 @@ int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
        p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
        if (p && p->readonly) return -EIO;
        if (!p || --p->refcount) {
-               q = (struct uni_pagedir *)kmalloc(sizeof(*p), GFP_KERNEL);
+               q = kmalloc(sizeof(*p), GFP_KERNEL);
                if (!q) {
                        if (p) p->refcount++;
                        return -ENOMEM;
index da601fd6c07ae24424350dc77541fb695c9ad15c..d649abbf08574595d2e270cd488ea478c2405ac9 100644 (file)
@@ -459,7 +459,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
                            (&display, (struct lcd_display *) arg,
                             sizeof(struct lcd_display)))
                                return -EFAULT;
-                       rom = (unsigned char *) kmalloc((128), GFP_ATOMIC);
+                       rom = kmalloc((128), GFP_ATOMIC);
                        if (rom == NULL) {
                                printk(KERN_ERR LCD "kmalloc() failed in %s\n",
                                                __FUNCTION__);
index b70b5388b5a81774b5050574cbd2383de0662455..b51d08be0bcfe5b908b6f4145823005657140e27 100644 (file)
@@ -525,7 +525,7 @@ static int lp_open(struct inode * inode, struct file * file)
                        return -EIO;
                }
        }
-       lp_table[minor].lp_buffer = (char *) kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
+       lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
        if (!lp_table[minor].lp_buffer) {
                LP_F(minor) &= ~LP_BUSY;
                return -ENOMEM;
index efa8076c33e047db432d4085713b2f586179ff26..cd989dce7c5387891ba8685fae2503fd62d0e78e 100644 (file)
@@ -315,6 +315,7 @@ static struct mxser_mon_ext mon_data_ext;
 static int mxser_set_baud_method[MXSER_PORTS + 1];
 static spinlock_t gm_lock;
 
+#ifdef CONFIG_PCI
 static int CheckIsMoxaMust(int io)
 {
        u8 oldmcr, hwid;
@@ -337,6 +338,7 @@ static int CheckIsMoxaMust(int io)
        }
        return MOXA_OTHER_UART;
 }
+#endif
 
 static void process_txrx_fifo(struct mxser_port *info)
 {
@@ -2380,9 +2382,11 @@ static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
        if (irq)
                free_irq(brd->irq, brd);
        if (pdev != NULL) {     /* PCI */
+#ifdef CONFIG_PCI
                pci_release_region(pdev, 2);
                pci_release_region(pdev, 3);
                pci_dev_put(pdev);
+#endif
        } else {
                release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
                release_region(brd->vector, 1);
@@ -2546,6 +2550,7 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
 static int __devinit mxser_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent)
 {
+#ifdef CONFIG_PCI
        struct mxser_board *brd;
        unsigned int i, j;
        unsigned long ioaddress;
@@ -2644,6 +2649,9 @@ err_relio:
        brd->info = NULL;
 err:
        return retval;
+#else
+       return -ENODEV;
+#endif
 }
 
 static void __devexit mxser_remove(struct pci_dev *pdev)
index 103d338f21e24483c36adc71f9433daf017de0f4..dc6d4184145769b403122715154aa7470886ea00 100644 (file)
@@ -125,8 +125,8 @@ static void transmit_block(struct r3964_info *pInfo);
 static void receive_char(struct r3964_info *pInfo, const unsigned char c);
 static void receive_error(struct r3964_info *pInfo, const char flag);
 static void on_timeout(unsigned long priv);
-static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg);
-static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf);
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf);
 static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
              int error_code, struct r3964_block_header *pBlock);
 static struct r3964_message* remove_msg(struct r3964_info *pInfo, 
@@ -829,7 +829,7 @@ static void on_timeout(unsigned long priv)
 }
 
 static struct r3964_client_info *findClient(
-  struct r3964_info *pInfo, pid_t pid)
+  struct r3964_info *pInfo, struct pid *pid)
 {
    struct r3964_client_info *pClient;
    
@@ -843,7 +843,7 @@ static struct r3964_client_info *findClient(
    return NULL;
 }
 
-static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
+static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
 {
    struct r3964_client_info *pClient;
    struct r3964_client_info **ppClient;
@@ -858,7 +858,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
          
          if(pClient->pid == pid)
          {
-            TRACE_PS("removing client %d from client list", pid);
+            TRACE_PS("removing client %d from client list", pid_nr(pid));
             *ppClient = pClient->next;
             while(pClient->msg_count)
             {
@@ -869,6 +869,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
                   TRACE_M("enable_signals - msg kfree %p",pMsg);
                }
             }
+           put_pid(pClient->pid);
             kfree(pClient);
             TRACE_M("enable_signals - kfree %p",pClient);
             return 0;
@@ -892,10 +893,10 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
          if(pClient==NULL)
             return -ENOMEM;
 
-         TRACE_PS("add client %d to client list", pid);
+         TRACE_PS("add client %d to client list", pid_nr(pid));
         spin_lock_init(&pClient->lock);
          pClient->sig_flags=arg;
-         pClient->pid = pid;
+         pClient->pid = get_pid(pid);
          pClient->next=pInfo->firstClient;
          pClient->first_msg = NULL;
          pClient->last_msg = NULL;
@@ -908,7 +909,7 @@ static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg)
    return 0;
 }
 
-static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf)
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf)
 {
     struct r3964_client_info *pClient;
     struct r3964_block_header *block;
@@ -1005,7 +1006,7 @@ queue_the_message:
    /* Send SIGIO signal to client process: */
    if(pClient->sig_flags & R3964_USE_SIGIO)
    {
-      kill_proc(pClient->pid, SIGIO, 1);
+      kill_pid(pClient->pid, SIGIO, 1);
    }
 }
 
@@ -1042,7 +1043,7 @@ static void remove_client_block(struct r3964_info *pInfo,
 {
     struct r3964_block_header *block;
 
-    TRACE_PS("remove_client_block PID %d", pClient->pid);
+    TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
 
     block=pClient->next_block_to_read;
     if(block)
@@ -1157,6 +1158,7 @@ static void r3964_close(struct tty_struct *tty)
              TRACE_M("r3964_close - msg kfree %p",pMsg);
           }
        }
+       put_pid(pClient->pid);
        kfree(pClient);
        TRACE_M("r3964_close - client kfree %p",pClient);
        pClient=pNext;
@@ -1193,12 +1195,11 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
    struct r3964_client_message theMsg;
    DECLARE_WAITQUEUE (wait, current);
    
-   int pid = current->pid;
    int count;
    
    TRACE_L("read()");
  
-   pClient=findClient(pInfo, pid);
+   pClient=findClient(pInfo, task_pid(current));
    if(pClient)
    {
       pMsg = remove_msg(pInfo, pClient);
@@ -1252,7 +1253,6 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
    struct r3964_block_header *pHeader;
    struct r3964_client_info *pClient;
    unsigned char *new_data;
-   int pid;
    
    TRACE_L("write request, %d characters", count);
 /* 
@@ -1295,9 +1295,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
    pHeader->locks = 0;
    pHeader->owner = NULL;
    
-   pid=current->pid;
-   
-   pClient=findClient(pInfo, pid);
+   pClient=findClient(pInfo, task_pid(current));
    if(pClient)
    {
       pHeader->owner = pClient;
@@ -1328,7 +1326,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file,
    switch(cmd)
    {
       case R3964_ENABLE_SIGNALS:
-         return enable_signals(pInfo, current->pid, arg);
+         return enable_signals(pInfo, task_pid(current), arg);
       case R3964_SETPRIORITY:
          if(arg<R3964_MASTER || arg>R3964_SLAVE)
             return -EINVAL;
@@ -1341,7 +1339,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file,
             pInfo->flags &= ~R3964_BCC;
          return 0;
       case R3964_READ_TELEGRAM:
-         return read_telegram(pInfo, current->pid, (unsigned char __user *)arg);
+         return read_telegram(pInfo, task_pid(current), (unsigned char __user *)arg);
       default:
          return -ENOIOCTLCMD;
    }
@@ -1357,7 +1355,6 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
                      struct poll_table_struct *wait)
 {
    struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
-   int pid=current->pid;
    struct r3964_client_info *pClient;
    struct r3964_message *pMsg=NULL;
    unsigned long flags;
@@ -1365,7 +1362,7 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
 
    TRACE_L("POLL");
 
-   pClient=findClient(pInfo,pid);
+   pClient=findClient(pInfo, task_pid(current));
    if(pClient)
      {
        poll_wait(file, &pInfo->read_wait, wait);
index e96a00fe13891b6f5f9fae1b2e1e6f1054d37956..2bdb0144a22e3f0b4d8675826bdd0ea353ac3079 100644 (file)
@@ -1151,7 +1151,6 @@ static int copy_from_read_buf(struct tty_struct *tty,
        n = min(*nr, n);
        spin_unlock_irqrestore(&tty->read_lock, flags);
        if (n) {
-               mb();
                retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
                n -= retval;
                spin_lock_irqsave(&tty->read_lock, flags);
index 5152cedd8878ff235bcbe2a0b0a2d593e7ed08dd..f108c136800a2ef3b2fcb990cc3d8aabf83b6ffe 100644 (file)
@@ -541,7 +541,7 @@ static int mgslpc_probe(struct pcmcia_device *link)
     if (debug_level >= DEBUG_LEVEL_INFO)
            printk("mgslpc_attach\n");
 
-    info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
+    info = kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
     if (!info) {
            printk("Error can't allocate device instance data\n");
            return -ENOMEM;
index 167ebc84e8d7361d35577ce59d4a74379437c0c4..245f03195b7c6da9ce7f664e974664617b4baf33 100644 (file)
@@ -556,7 +556,7 @@ struct CmdBlk *RIOGetCmdBlk(void)
 {
        struct CmdBlk *CmdBlkP;
 
-       CmdBlkP = (struct CmdBlk *)kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
+       CmdBlkP = kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
        if (CmdBlkP)
                memset(CmdBlkP, 0, sizeof(struct CmdBlk));
        return CmdBlkP;
index 66a7385bc34aebb96cbda088b2a0b74f23f31363..e1d70e8b626872f157f7c3731a349bcdc1abb9bf 100644 (file)
@@ -113,7 +113,7 @@ static int rtc_has_irq = 1;
 #define hpet_set_rtc_irq_bit(arg)              0
 #define hpet_rtc_timer_init()                  do { } while (0)
 #define hpet_rtc_dropped_irq()                         0
-static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;}
+static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;}
 #else
 extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
 #endif
@@ -165,7 +165,9 @@ static void mask_rtc_irq_bit(unsigned char bit)
 }
 #endif
 
+#ifdef CONFIG_PROC_FS
 static int rtc_proc_open(struct inode *inode, struct file *file);
+#endif
 
 /*
  *     Bits in rtc_status. (6 bits of room for future expansion)
@@ -906,6 +908,7 @@ static struct miscdevice rtc_dev = {
        .fops           = &rtc_fops,
 };
 
+#ifdef CONFIG_PROC_FS
 static const struct file_operations rtc_proc_fops = {
        .owner = THIS_MODULE,
        .open = rtc_proc_open,
@@ -913,14 +916,13 @@ static const struct file_operations rtc_proc_fops = {
        .llseek = seq_lseek,
        .release = single_release,
 };
-
-#if defined(RTC_IRQ) && !defined(__sparc__)
-static irq_handler_t rtc_int_handler_ptr;
 #endif
 
 static int __init rtc_init(void)
 {
+#ifdef CONFIG_PROC_FS
        struct proc_dir_entry *ent;
+#endif
 #if defined(__alpha__) || defined(__mips__)
        unsigned int year, ctrl;
        char *guess = NULL;
@@ -932,9 +934,11 @@ static int __init rtc_init(void)
        struct sparc_isa_bridge *isa_br;
        struct sparc_isa_device *isa_dev;
 #endif
-#endif
-#ifndef __sparc__
+#else
        void *r;
+#ifdef RTC_IRQ
+       irq_handler_t rtc_int_handler_ptr;
+#endif
 #endif
 
 #ifdef __sparc__
@@ -958,6 +962,7 @@ static int __init rtc_init(void)
                }
        }
 #endif
+       rtc_has_irq = 0;
        printk(KERN_ERR "rtc_init: no PC rtc found\n");
        return -EIO;
 
@@ -972,6 +977,7 @@ found:
         * PCI Slot 2 INTA# (and some INTx# in Slot 1).
         */
        if (request_irq(rtc_irq, rtc_interrupt, IRQF_SHARED, "rtc", (void *)&rtc_port)) {
+               rtc_has_irq = 0;
                printk(KERN_ERR "rtc: cannot register IRQ %d\n", rtc_irq);
                return -EIO;
        }
@@ -982,6 +988,9 @@ no_irq:
        else
                r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
        if (!r) {
+#ifdef RTC_IRQ
+               rtc_has_irq = 0;
+#endif
                printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
                       (long)(RTC_PORT(0)));
                return -EIO;
@@ -996,6 +1005,7 @@ no_irq:
 
        if(request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED, "rtc", NULL)) {
                /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
+               rtc_has_irq = 0;
                printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
                if (RTC_IOMAPPED)
                        release_region(RTC_PORT(0), RTC_IO_EXTENT);
@@ -1012,21 +1022,19 @@ no_irq:
        if (misc_register(&rtc_dev)) {
 #ifdef RTC_IRQ
                free_irq(RTC_IRQ, NULL);
+               rtc_has_irq = 0;
 #endif
                release_region(RTC_PORT(0), RTC_IO_EXTENT);
                return -ENODEV;
        }
 
+#ifdef CONFIG_PROC_FS
        ent = create_proc_entry("driver/rtc", 0, NULL);
-       if (!ent) {
-#ifdef RTC_IRQ
-               free_irq(RTC_IRQ, NULL);
+       if (ent)
+               ent->proc_fops = &rtc_proc_fops;
+       else
+               printk(KERN_WARNING "rtc: Failed to register with procfs.\n");
 #endif
-               release_region(RTC_PORT(0), RTC_IO_EXTENT);
-               misc_deregister(&rtc_dev);
-               return -ENOMEM;
-       }
-       ent->proc_fops = &rtc_proc_fops;
 
 #if defined(__alpha__) || defined(__mips__)
        rtc_freq = HZ;
@@ -1159,6 +1167,7 @@ static void rtc_dropped_irq(unsigned long data)
 }
 #endif
 
+#ifdef CONFIG_PROC_FS
 /*
  *     Info exported via "/proc/driver/rtc".
  */
@@ -1243,6 +1252,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
 {
        return single_open(file, rtc_proc_show, NULL);
 }
+#endif
 
 void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 {
index a3008ce13015496c5eb409429379e769f93f904c..1da92a689ae455f542533b1a980fa6c36d8aa75c 100644 (file)
@@ -2498,8 +2498,10 @@ static void __devexit sx_remove_card(struct sx_board *board,
                /* It is safe/allowed to del_timer a non-active timer */
                del_timer(&board->timer);
                if (pdev) {
+#ifdef CONFIG_PCI
                        pci_iounmap(pdev, board->base);
                        pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
+#endif
                } else {
                        iounmap(board->base);
                        release_region(board->hw_base, board->hw_len);
@@ -2601,6 +2603,7 @@ static struct eisa_driver sx_eisadriver = {
 
 #endif
 
+#ifdef CONFIG_PCI
  /******************************************************** 
  * Setting bit 17 in the CNTRL register of the PLX 9050  * 
  * chip forces a retry on writes while a read is pending.*
@@ -2632,10 +2635,12 @@ static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board)
        }
        iounmap(rebase);
 }
+#endif
 
 static int __devinit sx_pci_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
+#ifdef CONFIG_PCI
        struct sx_board *board;
        unsigned int i, reg;
        int retval = -EIO;
@@ -2700,6 +2705,9 @@ err_flag:
        board->flags &= ~SX_BOARD_PRESENT;
 err:
        return retval;
+#else
+       return -ENODEV;
+#endif
 }
 
 static void __devexit sx_pci_remove(struct pci_dev *pdev)
index acc6fab601ccaa6f592052595a3587810607c522..3fa625db9e4b133b6caf258ed442d2675dad18c5 100644 (file)
@@ -4332,7 +4332,7 @@ static struct mgsl_struct* mgsl_allocate_device(void)
 {
        struct mgsl_struct *info;
        
-       info = (struct mgsl_struct *)kmalloc(sizeof(struct mgsl_struct),
+       info = kmalloc(sizeof(struct mgsl_struct),
                 GFP_KERNEL);
                 
        if (!info) {
index 53e8ccf94fe33be05e76f7d3f1b6c7a6b8a2f394..8f4d67afe5bf99fe1daea30940640b2c1cbbbe72 100644 (file)
@@ -2730,7 +2730,7 @@ static int startup(SLMP_INFO * info)
                return 0;
 
        if (!info->tx_buf) {
-               info->tx_buf = (unsigned char *)kmalloc(info->max_frame_size, GFP_KERNEL);
+               info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
                if (!info->tx_buf) {
                        printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n",
                                __FILE__,__LINE__,info->device_name);
@@ -3798,7 +3798,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
 {
        SLMP_INFO *info;
 
-       info = (SLMP_INFO *)kmalloc(sizeof(SLMP_INFO),
+       info = kmalloc(sizeof(SLMP_INFO),
                 GFP_KERNEL);
 
        if (!info) {
index 05810c8d20bca7162794f399014153f1c9390add..13935235e0661b1b82eb6be10e298b8c5a63b0f2 100644 (file)
 #include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
-int sysrq_enabled = 1;
+int __read_mostly __sysrq_enabled = 1;
+
+static int __read_mostly sysrq_always_enabled;
+
+int sysrq_on(void)
+{
+       return __sysrq_enabled || sysrq_always_enabled;
+}
+
+/*
+ * A value of 1 means 'all', other nonzero values are an op mask:
+ */
+static inline int sysrq_on_mask(int mask)
+{
+       return sysrq_always_enabled || __sysrq_enabled == 1 ||
+                                               (__sysrq_enabled & mask);
+}
+
+static int __init sysrq_always_enabled_setup(char *str)
+{
+       sysrq_always_enabled = 1;
+       printk(KERN_INFO "debug: sysrq always enabled.\n");
+
+       return 1;
+}
+
+__setup("sysrq_always_enabled", sysrq_always_enabled_setup);
+
 
 static void sysrq_handle_loglevel(int key, struct tty_struct *tty)
 {
@@ -379,8 +406,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
                 * Should we check for enabled operations (/proc/sysrq-trigger
                 * should not) and is the invoked operation enabled?
                 */
-               if (!check_mask || sysrq_enabled == 1 ||
-                   (sysrq_enabled & op_p->enable_mask)) {
+               if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
                        printk("%s\n", op_p->action_msg);
                        console_loglevel = orig_log_level;
                        op_p->handler(key, tty);
@@ -414,9 +440,8 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
  */
 void handle_sysrq(int key, struct tty_struct *tty)
 {
-       if (!sysrq_enabled)
-               return;
-       __handle_sysrq(key, tty, 1);
+       if (sysrq_on())
+               __handle_sysrq(key, tty, 1);
 }
 EXPORT_SYMBOL(handle_sysrq);
 
index 4044c864fdd4da888c1d09126ebb2ce3af77637b..47a6eacb10bc4c0c49dc54357be1f7adf9e36fd7 100644 (file)
@@ -3335,18 +3335,13 @@ static void __do_SAK(struct work_struct *work)
        int session;
        int             i;
        struct file     *filp;
-       struct tty_ldisc *disc;
        struct fdtable *fdt;
        
        if (!tty)
                return;
        session = tty->session;
        
-       /* We don't want an ldisc switch during this */
-       disc = tty_ldisc_ref(tty);
-       if (disc && disc->flush_buffer)
-               disc->flush_buffer(tty);
-       tty_ldisc_deref(disc);
+       tty_ldisc_flush(tty);
 
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
@@ -3821,6 +3816,7 @@ struct tty_struct *get_current_tty(void)
        barrier();
        return tty;
 }
+EXPORT_SYMBOL_GPL(get_current_tty);
 
 /*
  * Initialize the console device. This is called *early*, so
index 6d2e314860df52f32314f66eb830c981af7dd1b8..0e0da443cbd57d545e2875a93dcecaee7d2c5639 100644 (file)
 static DEFINE_SPINLOCK(consolelock);
 static DEFINE_SPINLOCK(consoleloglock);
 
-#ifdef CONFIG_MAGIC_SYSRQ
 static int vio_sysrq_pressed;
-extern int sysrq_enabled;
-#endif
 
 #define VIOCHAR_NUM_BUF                16
 
@@ -936,8 +933,10 @@ static void vioHandleData(struct HvLpEvent *event)
         */
        num_pushed = 0;
        for (index = 0; index < cevent->len; index++) {
-#ifdef CONFIG_MAGIC_SYSRQ
-               if (sysrq_enabled) {
+               /*
+                * Will be optimized away if !CONFIG_MAGIC_SYSRQ:
+                */
+               if (sysrq_on()) {
                        /* 0x0f is the ascii character for ^O */
                        if (cevent->data[index] == '\x0f') {
                                vio_sysrq_pressed = 1;
@@ -956,7 +955,6 @@ static void vioHandleData(struct HvLpEvent *event)
                                continue;
                        }
                }
-#endif
                /*
                 * The sysrq sequence isn't included in this check if
                 * sysrq is enabled and compiled into the kernel because
index a8239dac994fee2264bf638bd3f5bff3176f446f..06c32a3e3ca42603df7470008711d9cc7b4fa5e1 100644 (file)
@@ -784,7 +784,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
        if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
                return 0;
 
-       newscreen = (unsigned short *) kmalloc(new_screen_size, GFP_USER);
+       newscreen = kmalloc(new_screen_size, GFP_USER);
        if (!newscreen)
                return -ENOMEM;
 
index ac5d60edbafaadda7d58dd13601fb70e9ac70a82..dc8368ebb1ac932c2a8b18427b7197bdab371d82 100644 (file)
@@ -129,7 +129,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
                            !capable(CAP_SYS_RESOURCE))
                                return -EPERM;
 
-                       key_map = (ushort *) kmalloc(sizeof(plain_map),
+                       key_map = kmalloc(sizeof(plain_map),
                                                     GFP_KERNEL);
                        if (!key_map)
                                return -ENOMEM;
@@ -259,7 +259,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
                    sz = 256;
                    while (sz < funcbufsize - funcbufleft + delta)
                      sz <<= 1;
-                   fnw = (char *) kmalloc(sz, GFP_KERNEL);
+                   fnw = kmalloc(sz, GFP_KERNEL);
                    if(!fnw) {
                      ret = -ENOMEM;
                      goto reterr;
@@ -1087,7 +1087,7 @@ static void complete_change_console(struct vc_data *vc)
        switch_screen(vc);
 
        /*
-        * This can't appear below a successful kill_proc().  If it did,
+        * This can't appear below a successful kill_pid().  If it did,
         * then the *blank_screen operation could occur while X, having
         * received acqsig, is waking up on another processor.  This
         * condition can lead to overlapping accesses to the VGA range
@@ -1110,7 +1110,7 @@ static void complete_change_console(struct vc_data *vc)
         */
        if (vc->vt_mode.mode == VT_PROCESS) {
                /*
-                * Send the signal as privileged - kill_proc() will
+                * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
                 * is awry
                 */
@@ -1170,7 +1170,7 @@ void change_console(struct vc_data *new_vc)
        vc = vc_cons[fg_console].d;
        if (vc->vt_mode.mode == VT_PROCESS) {
                /*
-                * Send the signal as privileged - kill_proc() will
+                * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
                 * is awry
                 */
index ca4e67a022d0eaa56edf97a1da2fbe63a1d70d3b..22b62b3cd14e5538f3b8e273c525c5586154b784 100644 (file)
@@ -266,7 +266,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
                        printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
                        fc->state = FC_STATE_OFFLINE;
                } else {
-                       fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
+                       fc->posmap = kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
                        if (!fc->posmap) {
                                printk("FC: Not enough memory, offlining channel\n");
                                fc->state = FC_STATE_OFFLINE;
@@ -355,7 +355,7 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
                        for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
                                set_bit (i, fc->scsi_bitmap);
                        fc->scsi_free = fc->can_queue;
-                       fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
+                       fc->cmd_slots = kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
                        fc->abort_count = 0;
                } else {
                        fc->scsi_name[0] = 0;
@@ -933,7 +933,7 @@ int fcp_scsi_dev_reset(struct scsi_cmnd *SCpnt)
         DECLARE_MUTEX_LOCKED(sem);
 
        if (!fc->rst_pkt) {
-               fc->rst_pkt = (struct scsi_cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
+               fc->rst_pkt = kmalloc(sizeof(SCpnt), GFP_KERNEL);
                if (!fc->rst_pkt) return FAILED;
                
                fcmd = FCP_CMND(fc->rst_pkt);
@@ -1107,7 +1107,7 @@ int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
        logi *l;
        int status;
 
-       l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
+       l = kzalloc(2 * sizeof(logi), GFP_KERNEL);
        if (!l) return -ENOMEM;
        l->code = LS_PLOGI;
        memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
@@ -1141,7 +1141,7 @@ int fc_do_prli(fc_channel *fc, unsigned char alpa)
        prli *p;
        int status;
 
-       p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
+       p = kzalloc(2 * sizeof(prli), GFP_KERNEL);
        if (!p) return -ENOMEM;
        p->code = LS_PRLI;
        p->params[0] = 0x08002000;
index e76d91906c99a3ab671dbb9e0736e3e197901efc..891ef6d0b1bf970d2a1fd2e6aad9fa43ba16df6d 100644 (file)
@@ -106,6 +106,31 @@ config SENSORS_K8TEMP
          This driver can also be built as a module.  If so, the module
          will be called k8temp.
 
+config SENSORS_AMS
+       tristate "Apple Motion Sensor driver"
+       depends on HWMON && PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+       help
+         Support for the motion sensor included in PowerBooks. Includes
+         implementations for PMU and I2C.
+
+         This driver can also be built as a module. If so, the module
+         will be called ams.
+
+config SENSORS_AMS_PMU
+       bool "PMU variant"
+       depends on SENSORS_AMS && ADB_PMU
+       default y
+       help
+         PMU variant of motion sensor, found in late 2005 PowerBooks.
+
+config SENSORS_AMS_I2C
+       bool "I2C variant"
+       depends on SENSORS_AMS && I2C
+       default y
+       help
+         I2C variant of motion sensor, found in early 2005 PowerBooks and
+         iBooks.
+
 config SENSORS_ASB100
        tristate "Asus ASB100 Bach"
        depends on HWMON && I2C && EXPERIMENTAL
@@ -142,11 +167,12 @@ config SENSORS_DS1621
          will be called ds1621.
 
 config SENSORS_F71805F
-       tristate "Fintek F71805F/FG"
+       tristate "Fintek F71805F/FG and F71872F/FG"
        depends on HWMON && EXPERIMENTAL
        help
          If you say yes here you get support for hardware monitoring
-         features of the Fintek F71805F/FG chips.
+         features of the Fintek F71805F/FG and F71872F/FG Super-I/O
+         chips.
 
          This driver can also be built as a module.  If so, the module
          will be called f71805f.
@@ -353,6 +379,19 @@ config SENSORS_PC87360
          This driver can also be built as a module.  If so, the module
          will be called pc87360.
 
+config SENSORS_PC87427
+       tristate "National Semiconductor PC87427"
+       depends on HWMON && EXPERIMENTAL
+       help
+         If you say yes here you get access to the hardware monitoring
+         functions of the National Semiconductor PC87427 Super-I/O chip.
+         The chip has two distinct logical devices, one for fan speed
+         monitoring and control, and one for voltage and temperature
+         monitoring. Only fan speed monitoring is supported right now.
+
+         This driver can also be built as a module.  If so, the module
+         will be called pc87427.
+
 config SENSORS_SIS5595
        tristate "Silicon Integrated Systems Corp. SiS5595"
        depends on HWMON && I2C && PCI && EXPERIMENTAL
@@ -474,6 +513,16 @@ config SENSORS_W83792D
          This driver can also be built as a module.  If so, the module
          will be called w83792d.
 
+config SENSORS_W83793
+       tristate "Winbond W83793"
+       depends on HWMON && I2C && EXPERIMENTAL
+       help
+         If you say yes here you get support for the Winbond W83793
+         hardware monitoring chip.
+
+         This driver can also be built as a module.  If so, the module
+         will be called w83793.
+
 config SENSORS_W83L785TS
        tristate "Winbond W83L785TS-S"
        depends on HWMON && I2C && EXPERIMENTAL
@@ -527,6 +576,9 @@ config SENSORS_HDAPS
          This driver also provides an absolute input class device, allowing
          the laptop to act as a pinball machine-esque joystick.
 
+         If your ThinkPad is not recognized by the driver, please update to latest
+         BIOS. This is especially the case for some R52 ThinkPads.
+
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of hdaps.
 
index af01cc64f7d265e31b7c9700f9c9eeefd596f43a..31661124271ee58d57adce2b33607669142feade 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_HWMON_VID)         += hwmon-vid.o
 obj-$(CONFIG_SENSORS_ASB100)   += asb100.o
 obj-$(CONFIG_SENSORS_W83627HF) += w83627hf.o
 obj-$(CONFIG_SENSORS_W83792D)  += w83792d.o
+obj-$(CONFIG_SENSORS_W83793)   += w83793.o
 obj-$(CONFIG_SENSORS_W83781D)  += w83781d.o
 obj-$(CONFIG_SENSORS_W83791D)  += w83791d.o
 
@@ -18,6 +19,7 @@ obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
 obj-$(CONFIG_SENSORS_ADM1026)  += adm1026.o
 obj-$(CONFIG_SENSORS_ADM1031)  += adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)  += adm9240.o
+obj-$(CONFIG_SENSORS_AMS)      += ams/
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_DS1621)   += ds1621.o
 obj-$(CONFIG_SENSORS_F71805F)  += f71805f.o
@@ -41,6 +43,7 @@ obj-$(CONFIG_SENSORS_LM90)    += lm90.o
 obj-$(CONFIG_SENSORS_LM92)     += lm92.o
 obj-$(CONFIG_SENSORS_MAX1619)  += max1619.o
 obj-$(CONFIG_SENSORS_PC87360)  += pc87360.o
+obj-$(CONFIG_SENSORS_PC87427)  += pc87427.o
 obj-$(CONFIG_SENSORS_SIS5595)  += sis5595.o
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/ams/Makefile b/drivers/hwmon/ams/Makefile
new file mode 100644 (file)
index 0000000..41c95b2
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for Apple Motion Sensor driver
+#
+
+ams-y                                  := ams-core.o ams-input.o
+ams-$(CONFIG_SENSORS_AMS_PMU)          += ams-pmu.o
+ams-$(CONFIG_SENSORS_AMS_I2C)          += ams-i2c.o
+obj-$(CONFIG_SENSORS_AMS)              += ams.o
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
new file mode 100644 (file)
index 0000000..f1f0f5d
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Apple Motion Sensor driver
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/pmac_pfunc.h>
+#include <asm/of_platform.h>
+
+#include "ams.h"
+
+/* There is only one motion sensor per machine */
+struct ams ams_info;
+
+static unsigned int verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
+
+/* Call with ams_info.lock held! */
+void ams_sensors(s8 *x, s8 *y, s8 *z)
+{
+       u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2;
+
+       if (orient & 0x80)
+               /* X and Y swapped */
+               ams_info.get_xyz(y, x, z);
+       else
+               ams_info.get_xyz(x, y, z);
+
+       if (orient & 0x04)
+               *z = ~(*z);
+       if (orient & 0x02)
+               *y = ~(*y);
+       if (orient & 0x01)
+               *x = ~(*x);
+}
+
+static ssize_t ams_show_current(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       s8 x, y, z;
+
+       mutex_lock(&ams_info.lock);
+       ams_sensors(&x, &y, &z);
+       mutex_unlock(&ams_info.lock);
+
+       return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z);
+}
+
+static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL);
+
+static void ams_handle_irq(void *data)
+{
+       enum ams_irq irq = *((enum ams_irq *)data);
+
+       spin_lock(&ams_info.irq_lock);
+
+       ams_info.worker_irqs |= irq;
+       schedule_work(&ams_info.worker);
+
+       spin_unlock(&ams_info.irq_lock);
+}
+
+static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL;
+static struct pmf_irq_client ams_freefall_client = {
+       .owner = THIS_MODULE,
+       .handler = ams_handle_irq,
+       .data = &ams_freefall_irq_data,
+};
+
+static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK;
+static struct pmf_irq_client ams_shock_client = {
+       .owner = THIS_MODULE,
+       .handler = ams_handle_irq,
+       .data = &ams_shock_irq_data,
+};
+
+/* Once hard disk parking is implemented in the kernel, this function can
+ * trigger it.
+ */
+static void ams_worker(struct work_struct *work)
+{
+       mutex_lock(&ams_info.lock);
+
+       if (ams_info.has_device) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&ams_info.irq_lock, flags);
+
+               if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
+                       if (verbose)
+                               printk(KERN_INFO "ams: freefall detected!\n");
+
+                       ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
+
+                       /* we must call this with interrupts enabled */
+                       spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+                       ams_info.clear_irq(AMS_IRQ_FREEFALL);
+                       spin_lock_irqsave(&ams_info.irq_lock, flags);
+               }
+
+               if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
+                       if (verbose)
+                               printk(KERN_INFO "ams: shock detected!\n");
+
+                       ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
+
+                       /* we must call this with interrupts enabled */
+                       spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+                       ams_info.clear_irq(AMS_IRQ_SHOCK);
+                       spin_lock_irqsave(&ams_info.irq_lock, flags);
+               }
+
+               spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+       }
+
+       mutex_unlock(&ams_info.lock);
+}
+
+/* Call with ams_info.lock held! */
+int ams_sensor_attach(void)
+{
+       int result;
+       u32 *prop;
+
+       /* Get orientation */
+       prop = (u32*)get_property(ams_info.of_node, "orientation", NULL);
+       if (!prop)
+               return -ENODEV;
+       ams_info.orient1 = *prop;
+       ams_info.orient2 = *(prop + 1);
+
+       /* Register freefall interrupt handler */
+       result = pmf_register_irq_client(ams_info.of_node,
+                       "accel-int-1",
+                       &ams_freefall_client);
+       if (result < 0)
+               return -ENODEV;
+
+       /* Reset saved irqs */
+       ams_info.worker_irqs = 0;
+
+       /* Register shock interrupt handler */
+       result = pmf_register_irq_client(ams_info.of_node,
+                       "accel-int-2",
+                       &ams_shock_client);
+       if (result < 0)
+               goto release_freefall;
+
+       /* Create device */
+       ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL);
+       if (!ams_info.of_dev) {
+               result = -ENODEV;
+               goto release_shock;
+       }
+
+       /* Create attributes */
+       result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current);
+       if (result)
+               goto release_of;
+
+       ams_info.vflag = !!(ams_info.get_vendor() & 0x10);
+
+       /* Init input device */
+       result = ams_input_init();
+       if (result)
+               goto release_device_file;
+
+       return result;
+release_device_file:
+       device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+release_of:
+       of_device_unregister(ams_info.of_dev);
+release_shock:
+       pmf_unregister_irq_client(&ams_shock_client);
+release_freefall:
+       pmf_unregister_irq_client(&ams_freefall_client);
+       return result;
+}
+
+int __init ams_init(void)
+{
+       struct device_node *np;
+
+       spin_lock_init(&ams_info.irq_lock);
+       mutex_init(&ams_info.lock);
+       INIT_WORK(&ams_info.worker, ams_worker);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+       np = of_find_node_by_name(NULL, "accelerometer");
+       if (np && device_is_compatible(np, "AAPL,accelerometer_1"))
+               /* Found I2C motion sensor */
+               return ams_i2c_init(np);
+#endif
+
+#ifdef CONFIG_SENSORS_AMS_PMU
+       np = of_find_node_by_name(NULL, "sms");
+       if (np && device_is_compatible(np, "sms"))
+               /* Found PMU motion sensor */
+               return ams_pmu_init(np);
+#endif
+
+       printk(KERN_ERR "ams: No motion sensor found.\n");
+
+       return -ENODEV;
+}
+
+void ams_exit(void)
+{
+       mutex_lock(&ams_info.lock);
+
+       if (ams_info.has_device) {
+               /* Remove input device */
+               ams_input_exit();
+
+               /* Shut down implementation */
+               ams_info.exit();
+
+               /* Flush interrupt worker
+                *
+                * We do this after ams_info.exit(), because an interrupt might
+                * have arrived before disabling them.
+                */
+               flush_scheduled_work();
+
+               /* Remove attributes */
+               device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+
+               /* Remove device */
+               of_device_unregister(ams_info.of_dev);
+
+               /* Remove handler */
+               pmf_unregister_irq_client(&ams_shock_client);
+               pmf_unregister_irq_client(&ams_freefall_client);
+       }
+
+       mutex_unlock(&ams_info.lock);
+}
+
+MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
+MODULE_DESCRIPTION("Apple Motion Sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(ams_init);
+module_exit(ams_exit);
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
new file mode 100644 (file)
index 0000000..0d24bdf
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Apple Motion Sensor driver (I2C variant)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * Clean room implementation based on the reverse engineered Mac OS X driver by
+ * Johannes Berg <johannes@sipsolutions.net>, documentation available at
+ * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+/* AMS registers */
+#define AMS_COMMAND    0x00    /* command register */
+#define AMS_STATUS     0x01    /* status register */
+#define AMS_CTRL1      0x02    /* read control 1 (number of values) */
+#define AMS_CTRL2      0x03    /* read control 2 (offset?) */
+#define AMS_CTRL3      0x04    /* read control 3 (size of each value?) */
+#define AMS_DATA1      0x05    /* read data 1 */
+#define AMS_DATA2      0x06    /* read data 2 */
+#define AMS_DATA3      0x07    /* read data 3 */
+#define AMS_DATA4      0x08    /* read data 4 */
+#define AMS_DATAX      0x20    /* data X */
+#define AMS_DATAY      0x21    /* data Y */
+#define AMS_DATAZ      0x22    /* data Z */
+#define AMS_FREEFALL   0x24    /* freefall int control */
+#define AMS_SHOCK      0x25    /* shock int control */
+#define AMS_SENSLOW    0x26    /* sensitivity low limit */
+#define AMS_SENSHIGH   0x27    /* sensitivity high limit */
+#define AMS_CTRLX      0x28    /* control X */
+#define AMS_CTRLY      0x29    /* control Y */
+#define AMS_CTRLZ      0x2A    /* control Z */
+#define AMS_UNKNOWN1   0x2B    /* unknown 1 */
+#define AMS_UNKNOWN2   0x2C    /* unknown 2 */
+#define AMS_UNKNOWN3   0x2D    /* unknown 3 */
+#define AMS_VENDOR     0x2E    /* vendor */
+
+/* AMS commands - use with the AMS_COMMAND register */
+enum ams_i2c_cmd {
+       AMS_CMD_NOOP = 0,
+       AMS_CMD_VERSION,
+       AMS_CMD_READMEM,
+       AMS_CMD_WRITEMEM,
+       AMS_CMD_ERASEMEM,
+       AMS_CMD_READEE,
+       AMS_CMD_WRITEEE,
+       AMS_CMD_RESET,
+       AMS_CMD_START,
+};
+
+static int ams_i2c_attach(struct i2c_adapter *adapter);
+static int ams_i2c_detach(struct i2c_adapter *adapter);
+
+static struct i2c_driver ams_i2c_driver = {
+       .driver = {
+               .name   = "ams",
+               .owner  = THIS_MODULE,
+       },
+       .attach_adapter = ams_i2c_attach,
+       .detach_adapter = ams_i2c_detach,
+};
+
+static s32 ams_i2c_read(u8 reg)
+{
+       return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg);
+}
+
+static int ams_i2c_write(u8 reg, u8 value)
+{
+       return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value);
+}
+
+static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
+{
+       s32 result;
+       int remaining = HZ / 20;
+
+       ams_i2c_write(AMS_COMMAND, cmd);
+       mdelay(5);
+
+       while (remaining) {
+               result = ams_i2c_read(AMS_COMMAND);
+               if (result == 0 || result & 0x80)
+                       return 0;
+
+               remaining = schedule_timeout(remaining);
+       }
+
+       return -1;
+}
+
+static void ams_i2c_set_irq(enum ams_irq reg, char enable)
+{
+       if (reg & AMS_IRQ_FREEFALL) {
+               u8 val = ams_i2c_read(AMS_CTRLX);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_i2c_write(AMS_CTRLX, val);
+       }
+
+       if (reg & AMS_IRQ_SHOCK) {
+               u8 val = ams_i2c_read(AMS_CTRLY);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_i2c_write(AMS_CTRLY, val);
+       }
+
+       if (reg & AMS_IRQ_GLOBAL) {
+               u8 val = ams_i2c_read(AMS_CTRLZ);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_i2c_write(AMS_CTRLZ, val);
+       }
+}
+
+static void ams_i2c_clear_irq(enum ams_irq reg)
+{
+       if (reg & AMS_IRQ_FREEFALL)
+               ams_i2c_write(AMS_FREEFALL, 0);
+
+       if (reg & AMS_IRQ_SHOCK)
+               ams_i2c_write(AMS_SHOCK, 0);
+}
+
+static u8 ams_i2c_get_vendor(void)
+{
+       return ams_i2c_read(AMS_VENDOR);
+}
+
+static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+       *x = ams_i2c_read(AMS_DATAX);
+       *y = ams_i2c_read(AMS_DATAY);
+       *z = ams_i2c_read(AMS_DATAZ);
+}
+
+static int ams_i2c_attach(struct i2c_adapter *adapter)
+{
+       unsigned long bus;
+       int vmaj, vmin;
+       int result;
+
+       /* There can be only one */
+       if (unlikely(ams_info.has_device))
+               return -ENODEV;
+
+       if (strncmp(adapter->name, "uni-n", 5))
+               return -ENODEV;
+
+       bus = simple_strtoul(adapter->name + 6, NULL, 10);
+       if (bus != ams_info.i2c_bus)
+               return -ENODEV;
+
+       ams_info.i2c_client.addr = ams_info.i2c_address;
+       ams_info.i2c_client.adapter = adapter;
+       ams_info.i2c_client.driver = &ams_i2c_driver;
+       strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");
+
+       if (ams_i2c_cmd(AMS_CMD_RESET)) {
+               printk(KERN_INFO "ams: Failed to reset the device\n");
+               return -ENODEV;
+       }
+
+       if (ams_i2c_cmd(AMS_CMD_START)) {
+               printk(KERN_INFO "ams: Failed to start the device\n");
+               return -ENODEV;
+       }
+
+       /* get version/vendor information */
+       ams_i2c_write(AMS_CTRL1, 0x02);
+       ams_i2c_write(AMS_CTRL2, 0x85);
+       ams_i2c_write(AMS_CTRL3, 0x01);
+
+       ams_i2c_cmd(AMS_CMD_READMEM);
+
+       vmaj = ams_i2c_read(AMS_DATA1);
+       vmin = ams_i2c_read(AMS_DATA2);
+       if (vmaj != 1 || vmin != 52) {
+               printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
+                       vmaj, vmin);
+               return -ENODEV;
+       }
+
+       ams_i2c_cmd(AMS_CMD_VERSION);
+
+       vmaj = ams_i2c_read(AMS_DATA1);
+       vmin = ams_i2c_read(AMS_DATA2);
+       if (vmaj != 0 || vmin != 1) {
+               printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
+                       vmaj, vmin);
+               return -ENODEV;
+       }
+
+       /* Disable interrupts */
+       ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+       result = ams_sensor_attach();
+       if (result < 0)
+               return result;
+
+       /* Set default values */
+       ams_i2c_write(AMS_SENSLOW, 0x15);
+       ams_i2c_write(AMS_SENSHIGH, 0x60);
+       ams_i2c_write(AMS_CTRLX, 0x08);
+       ams_i2c_write(AMS_CTRLY, 0x0F);
+       ams_i2c_write(AMS_CTRLZ, 0x4F);
+       ams_i2c_write(AMS_UNKNOWN1, 0x14);
+
+       /* Clear interrupts */
+       ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+       ams_info.has_device = 1;
+
+       /* Enable interrupts */
+       ams_i2c_set_irq(AMS_IRQ_ALL, 1);
+
+       printk(KERN_INFO "ams: Found I2C based motion sensor\n");
+
+       return 0;
+}
+
+static int ams_i2c_detach(struct i2c_adapter *adapter)
+{
+       if (ams_info.has_device) {
+               /* Disable interrupts */
+               ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+               /* Clear interrupts */
+               ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+               printk(KERN_INFO "ams: Unloading\n");
+
+               ams_info.has_device = 0;
+       }
+
+       return 0;
+}
+
+static void ams_i2c_exit(void)
+{
+       i2c_del_driver(&ams_i2c_driver);
+}
+
+int __init ams_i2c_init(struct device_node *np)
+{
+       char *tmp_bus;
+       int result;
+       u32 *prop;
+
+       mutex_lock(&ams_info.lock);
+
+       /* Set implementation stuff */
+       ams_info.of_node = np;
+       ams_info.exit = ams_i2c_exit;
+       ams_info.get_vendor = ams_i2c_get_vendor;
+       ams_info.get_xyz = ams_i2c_get_xyz;
+       ams_info.clear_irq = ams_i2c_clear_irq;
+       ams_info.bustype = BUS_I2C;
+
+       /* look for bus either using "reg" or by path */
+       prop = (u32*)get_property(ams_info.of_node, "reg", NULL);
+       if (!prop) {
+               result = -ENODEV;
+
+               goto exit;
+       }
+
+       tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
+       if (tmp_bus)
+               ams_info.i2c_bus = *(tmp_bus + 9) - '0';
+       else
+               ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
+       ams_info.i2c_address = ((*prop) & 0xff) >> 1;
+
+       result = i2c_add_driver(&ams_i2c_driver);
+
+exit:
+       mutex_unlock(&ams_info.lock);
+
+       return result;
+}
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c
new file mode 100644 (file)
index 0000000..f126aa4
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Apple Motion Sensor driver (joystick emulation)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+static unsigned int joystick;
+module_param(joystick, bool, 0644);
+MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
+
+static unsigned int invert;
+module_param(invert, bool, 0644);
+MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
+
+static int ams_input_kthread(void *data)
+{
+       s8 x, y, z;
+
+       while (!kthread_should_stop()) {
+               mutex_lock(&ams_info.lock);
+
+               ams_sensors(&x, &y, &z);
+
+               x -= ams_info.xcalib;
+               y -= ams_info.ycalib;
+               z -= ams_info.zcalib;
+
+               input_report_abs(ams_info.idev, ABS_X, invert ? -x : x);
+               input_report_abs(ams_info.idev, ABS_Y, invert ? -y : y);
+               input_report_abs(ams_info.idev, ABS_Z, z);
+
+               input_sync(ams_info.idev);
+
+               mutex_unlock(&ams_info.lock);
+
+               msleep(25);
+       }
+
+       return 0;
+}
+
+static int ams_input_open(struct input_dev *dev)
+{
+       ams_info.kthread = kthread_run(ams_input_kthread, NULL, "kams");
+       return IS_ERR(ams_info.kthread) ? PTR_ERR(ams_info.kthread) : 0;
+}
+
+static void ams_input_close(struct input_dev *dev)
+{
+       kthread_stop(ams_info.kthread);
+}
+
+/* Call with ams_info.lock held! */
+static void ams_input_enable(void)
+{
+       s8 x, y, z;
+
+       if (ams_info.idev)
+               return;
+
+       ams_sensors(&x, &y, &z);
+       ams_info.xcalib = x;
+       ams_info.ycalib = y;
+       ams_info.zcalib = z;
+
+       ams_info.idev = input_allocate_device();
+       if (!ams_info.idev)
+               return;
+
+       ams_info.idev->name = "Apple Motion Sensor";
+       ams_info.idev->id.bustype = ams_info.bustype;
+       ams_info.idev->id.vendor = 0;
+       ams_info.idev->open = ams_input_open;
+       ams_info.idev->close = ams_input_close;
+       ams_info.idev->cdev.dev = &ams_info.of_dev->dev;
+
+       input_set_abs_params(ams_info.idev, ABS_X, -50, 50, 3, 0);
+       input_set_abs_params(ams_info.idev, ABS_Y, -50, 50, 3, 0);
+       input_set_abs_params(ams_info.idev, ABS_Z, -50, 50, 3, 0);
+
+       set_bit(EV_ABS, ams_info.idev->evbit);
+       set_bit(EV_KEY, ams_info.idev->evbit);
+       set_bit(BTN_TOUCH, ams_info.idev->keybit);
+
+       if (input_register_device(ams_info.idev)) {
+               input_free_device(ams_info.idev);
+               ams_info.idev = NULL;
+               return;
+       }
+}
+
+/* Call with ams_info.lock held! */
+static void ams_input_disable(void)
+{
+       if (ams_info.idev) {
+               input_unregister_device(ams_info.idev);
+               ams_info.idev = NULL;
+       }
+}
+
+static ssize_t ams_input_show_joystick(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", joystick);
+}
+
+static ssize_t ams_input_store_joystick(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       if (sscanf(buf, "%d\n", &joystick) != 1)
+               return -EINVAL;
+
+       mutex_lock(&ams_info.lock);
+
+       if (joystick)
+               ams_input_enable();
+       else
+               ams_input_disable();
+
+       mutex_unlock(&ams_info.lock);
+
+       return count;
+}
+
+static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
+       ams_input_show_joystick, ams_input_store_joystick);
+
+/* Call with ams_info.lock held! */
+int ams_input_init(void)
+{
+       int result;
+
+       result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+
+       if (!result && joystick)
+               ams_input_enable();
+       return result;
+}
+
+/* Call with ams_info.lock held! */
+void ams_input_exit()
+{
+       ams_input_disable();
+       device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+}
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
new file mode 100644 (file)
index 0000000..4636ae0
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Apple Motion Sensor driver (PMU variant)
+ *
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+#include "ams.h"
+
+/* Attitude */
+#define AMS_X                  0x00
+#define AMS_Y                  0x01
+#define AMS_Z                  0x02
+
+/* Not exactly known, maybe chip vendor */
+#define AMS_VENDOR             0x03
+
+/* Freefall registers */
+#define AMS_FF_CLEAR           0x04
+#define AMS_FF_ENABLE          0x05
+#define AMS_FF_LOW_LIMIT       0x06
+#define AMS_FF_DEBOUNCE                0x07
+
+/* Shock registers */
+#define AMS_SHOCK_CLEAR                0x08
+#define AMS_SHOCK_ENABLE       0x09
+#define AMS_SHOCK_HIGH_LIMIT   0x0a
+#define AMS_SHOCK_DEBOUNCE     0x0b
+
+/* Global interrupt and power control register */
+#define AMS_CONTROL            0x0c
+
+static u8 ams_pmu_cmd;
+
+static void ams_pmu_req_complete(struct adb_request *req)
+{
+       complete((struct completion *)req->arg);
+}
+
+/* Only call this function from task context */
+static void ams_pmu_set_register(u8 reg, u8 value)
+{
+       static struct adb_request req;
+       DECLARE_COMPLETION(req_complete);
+
+       req.arg = &req_complete;
+       if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
+               return;
+
+       wait_for_completion(&req_complete);
+}
+
+/* Only call this function from task context */
+static u8 ams_pmu_get_register(u8 reg)
+{
+       static struct adb_request req;
+       DECLARE_COMPLETION(req_complete);
+
+       req.arg = &req_complete;
+       if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
+               return 0;
+
+       wait_for_completion(&req_complete);
+
+       if (req.reply_len > 0)
+               return req.reply[0];
+       else
+               return 0;
+}
+
+/* Enables or disables the specified interrupts */
+static void ams_pmu_set_irq(enum ams_irq reg, char enable)
+{
+       if (reg & AMS_IRQ_FREEFALL) {
+               u8 val = ams_pmu_get_register(AMS_FF_ENABLE);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_pmu_set_register(AMS_FF_ENABLE, val);
+       }
+
+       if (reg & AMS_IRQ_SHOCK) {
+               u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_pmu_set_register(AMS_SHOCK_ENABLE, val);
+       }
+
+       if (reg & AMS_IRQ_GLOBAL) {
+               u8 val = ams_pmu_get_register(AMS_CONTROL);
+               if (enable)
+                       val |= 0x80;
+               else
+                       val &= ~0x80;
+               ams_pmu_set_register(AMS_CONTROL, val);
+       }
+}
+
+static void ams_pmu_clear_irq(enum ams_irq reg)
+{
+       if (reg & AMS_IRQ_FREEFALL)
+               ams_pmu_set_register(AMS_FF_CLEAR, 0x00);
+
+       if (reg & AMS_IRQ_SHOCK)
+               ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00);
+}
+
+static u8 ams_pmu_get_vendor(void)
+{
+       return ams_pmu_get_register(AMS_VENDOR);
+}
+
+static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+       *x = ams_pmu_get_register(AMS_X);
+       *y = ams_pmu_get_register(AMS_Y);
+       *z = ams_pmu_get_register(AMS_Z);
+}
+
+static void ams_pmu_exit(void)
+{
+       /* Disable interrupts */
+       ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+       /* Clear interrupts */
+       ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+       ams_info.has_device = 0;
+
+       printk(KERN_INFO "ams: Unloading\n");
+}
+
+int __init ams_pmu_init(struct device_node *np)
+{
+       u32 *prop;
+       int result;
+
+       mutex_lock(&ams_info.lock);
+
+       /* Set implementation stuff */
+       ams_info.of_node = np;
+       ams_info.exit = ams_pmu_exit;
+       ams_info.get_vendor = ams_pmu_get_vendor;
+       ams_info.get_xyz = ams_pmu_get_xyz;
+       ams_info.clear_irq = ams_pmu_clear_irq;
+       ams_info.bustype = BUS_HOST;
+
+       /* Get PMU command, should be 0x4e, but we can never know */
+       prop = (u32*)get_property(ams_info.of_node, "reg", NULL);
+       if (!prop) {
+               result = -ENODEV;
+               goto exit;
+       }
+       ams_pmu_cmd = ((*prop) >> 8) & 0xff;
+
+       /* Disable interrupts */
+       ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+       /* Clear interrupts */
+       ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+       result = ams_sensor_attach();
+       if (result < 0)
+               goto exit;
+
+       /* Set default values */
+       ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
+       ams_pmu_set_register(AMS_FF_ENABLE, 0x08);
+       ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14);
+
+       ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60);
+       ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f);
+       ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14);
+
+       ams_pmu_set_register(AMS_CONTROL, 0x4f);
+
+       /* Clear interrupts */
+       ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+       ams_info.has_device = 1;
+
+       /* Enable interrupts */
+       ams_pmu_set_irq(AMS_IRQ_ALL, 1);
+
+       printk(KERN_INFO "ams: Found PMU based motion sensor\n");
+
+       result = 0;
+
+exit:
+       mutex_unlock(&ams_info.lock);
+
+       return result;
+}
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
new file mode 100644 (file)
index 0000000..240730e
--- /dev/null
@@ -0,0 +1,72 @@
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <asm/of_device.h>
+
+enum ams_irq {
+       AMS_IRQ_FREEFALL = 0x01,
+       AMS_IRQ_SHOCK = 0x02,
+       AMS_IRQ_GLOBAL = 0x04,
+       AMS_IRQ_ALL =
+               AMS_IRQ_FREEFALL |
+               AMS_IRQ_SHOCK |
+               AMS_IRQ_GLOBAL,
+};
+
+struct ams {
+       /* Locks */
+       spinlock_t irq_lock;
+       struct mutex lock;
+
+       /* General properties */
+       struct device_node *of_node;
+       struct of_device *of_dev;
+       char has_device;
+       char vflag;
+       u32 orient1;
+       u32 orient2;
+
+       /* Interrupt worker */
+       struct work_struct worker;
+       u8 worker_irqs;
+
+       /* Implementation
+        *
+        * Only call these functions with the main lock held.
+        */
+       void (*exit)(void);
+
+       void (*get_xyz)(s8 *x, s8 *y, s8 *z);
+       u8 (*get_vendor)(void);
+
+       void (*clear_irq)(enum ams_irq reg);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+       /* I2C properties */
+       int i2c_bus;
+       int i2c_address;
+       struct i2c_client i2c_client;
+#endif
+
+       /* Joystick emulation */
+       struct task_struct *kthread;
+       struct input_dev *idev;
+       __u16 bustype;
+
+       /* calibrated null values */
+       int xcalib, ycalib, zcalib;
+};
+
+extern struct ams ams_info;
+
+extern void ams_sensors(s8 *x, s8 *y, s8 *z);
+extern int ams_sensor_attach(void);
+
+extern int ams_pmu_init(struct device_node *np);
+extern int ams_i2c_init(struct device_node *np);
+
+extern int ams_input_init(void);
+extern void ams_input_exit(void);
index de17a72149d98ffb999b156b91a4942ee9cec2aa..a272cae8f60ef212d179a767daac10d7fa823593 100644 (file)
@@ -1,12 +1,15 @@
 /*
- * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated
- *             hardware monitoring features
+ * f71805f.c - driver for the Fintek F71805F/FG and F71872F/FG Super-I/O
+ *             chips integrated hardware monitoring features
  * Copyright (C) 2005-2006  Jean Delvare <khali@linux-fr.org>
  *
  * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
  * complete hardware monitoring features: voltage, fan and temperature
  * sensors, and manual and automatic fan speed control.
  *
+ * The F71872F/FG is almost the same, with two more voltages monitored,
+ * and 6 VID inputs.
+ *
  * 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
@@ -37,6 +40,7 @@
 static struct platform_device *pdev;
 
 #define DRVNAME "f71805f"
+enum kinds { f71805f, f71872f };
 
 /*
  * Super-I/O constants and functions
@@ -48,11 +52,13 @@ static struct platform_device *pdev;
 #define SIO_REG_DEVID          0x20    /* Device ID (2 bytes) */
 #define SIO_REG_DEVREV         0x22    /* Device revision */
 #define SIO_REG_MANID          0x23    /* Fintek ID (2 bytes) */
+#define SIO_REG_FNSEL1         0x29    /* Multi Function Select 1 (F71872F) */
 #define SIO_REG_ENABLE         0x30    /* Logical device enable */
 #define SIO_REG_ADDR           0x60    /* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID          0x1934
 #define SIO_F71805F_ID         0x0406
+#define SIO_F71872F_ID         0x0341
 
 static inline int
 superio_inb(int base, int reg)
@@ -96,22 +102,25 @@ superio_exit(int base)
  * ISA constants
  */
 
-#define REGION_LENGTH          2
-#define ADDR_REG_OFFSET                0
-#define DATA_REG_OFFSET                1
+#define REGION_LENGTH          8
+#define ADDR_REG_OFFSET                5
+#define DATA_REG_OFFSET                6
 
 /*
  * Registers
  */
 
-/* in nr from 0 to 8 (8-bit values) */
+/* in nr from 0 to 10 (8-bit values) */
 #define F71805F_REG_IN(nr)             (0x10 + (nr))
-#define F71805F_REG_IN_HIGH(nr)                (0x40 + 2 * (nr))
-#define F71805F_REG_IN_LOW(nr)         (0x41 + 2 * (nr))
+#define F71805F_REG_IN_HIGH(nr)                ((nr) < 10 ? 0x40 + 2 * (nr) : 0x2E)
+#define F71805F_REG_IN_LOW(nr)         ((nr) < 10 ? 0x41 + 2 * (nr) : 0x2F)
 /* fan nr from 0 to 2 (12-bit values, two registers) */
 #define F71805F_REG_FAN(nr)            (0x20 + 2 * (nr))
 #define F71805F_REG_FAN_LOW(nr)                (0x28 + 2 * (nr))
+#define F71805F_REG_FAN_TARGET(nr)     (0x69 + 16 * (nr))
 #define F71805F_REG_FAN_CTRL(nr)       (0x60 + 16 * (nr))
+#define F71805F_REG_PWM_FREQ(nr)       (0x63 + 16 * (nr))
+#define F71805F_REG_PWM_DUTY(nr)       (0x6B + 16 * (nr))
 /* temp nr from 0 to 2 (8-bit values) */
 #define F71805F_REG_TEMP(nr)           (0x1B + (nr))
 #define F71805F_REG_TEMP_HIGH(nr)      (0x54 + 2 * (nr))
@@ -122,6 +131,14 @@ superio_exit(int base)
 /* status nr from 0 to 2 */
 #define F71805F_REG_STATUS(nr)         (0x36 + (nr))
 
+/* individual register bits */
+#define FAN_CTRL_DC_MODE               0x10
+#define FAN_CTRL_LATCH_FULL            0x08
+#define FAN_CTRL_MODE_MASK             0x03
+#define FAN_CTRL_MODE_SPEED            0x00
+#define FAN_CTRL_MODE_TEMPERATURE      0x01
+#define FAN_CTRL_MODE_MANUAL           0x02
+
 /*
  * Data structures and manipulation thereof
  */
@@ -138,12 +155,16 @@ struct f71805f_data {
        unsigned long last_limits;      /* In jiffies */
 
        /* Register values */
-       u8 in[9];
-       u8 in_high[9];
-       u8 in_low[9];
+       u8 in[11];
+       u8 in_high[11];
+       u8 in_low[11];
+       u16 has_in;
        u16 fan[3];
        u16 fan_low[3];
-       u8 fan_enabled;         /* Read once at init time */
+       u16 fan_target[3];
+       u8 fan_ctrl[3];
+       u8 pwm[3];
+       u8 pwm_freq[3];
        u8 temp[3];
        u8 temp_high[3];
        u8 temp_hyst[3];
@@ -151,6 +172,11 @@ struct f71805f_data {
        unsigned long alarms;
 };
 
+struct f71805f_sio_data {
+       enum kinds kind;
+       u8 fnsel1;
+};
+
 static inline long in_from_reg(u8 reg)
 {
        return (reg * 8);
@@ -200,6 +226,33 @@ static inline u16 fan_to_reg(long rpm)
        return (1500000 / rpm);
 }
 
+static inline unsigned long pwm_freq_from_reg(u8 reg)
+{
+       unsigned long clock = (reg & 0x80) ? 48000000UL : 1000000UL;
+
+       reg &= 0x7f;
+       if (reg == 0)
+               reg++;
+       return clock / (reg << 8);
+}
+
+static inline u8 pwm_freq_to_reg(unsigned long val)
+{
+       if (val >= 187500)      /* The highest we can do */
+               return 0x80;
+       if (val >= 1475)        /* Use 48 MHz clock */
+               return 0x80 | (48000000UL / (val << 8));
+       if (val < 31)           /* The lowest we can do */
+               return 0x7f;
+       else                    /* Use 1 MHz clock */
+               return 1000000UL / (val << 8);
+}
+
+static inline int pwm_mode_from_reg(u8 reg)
+{
+       return !(reg & FAN_CTRL_DC_MODE);
+}
+
 static inline long temp_from_reg(u8 reg)
 {
        return (reg * 1000);
@@ -274,16 +327,21 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
        /* Limit registers cache is refreshed after 60 seconds */
        if (time_after(jiffies, data->last_updated + 60 * HZ)
         || !data->valid) {
-               for (nr = 0; nr < 9; nr++) {
+               for (nr = 0; nr < 11; nr++) {
+                       if (!(data->has_in & (1 << nr)))
+                               continue;
                        data->in_high[nr] = f71805f_read8(data,
                                            F71805F_REG_IN_HIGH(nr));
                        data->in_low[nr] = f71805f_read8(data,
                                           F71805F_REG_IN_LOW(nr));
                }
                for (nr = 0; nr < 3; nr++) {
-                       if (data->fan_enabled & (1 << nr))
-                               data->fan_low[nr] = f71805f_read16(data,
-                                                   F71805F_REG_FAN_LOW(nr));
+                       data->fan_low[nr] = f71805f_read16(data,
+                                           F71805F_REG_FAN_LOW(nr));
+                       data->fan_target[nr] = f71805f_read16(data,
+                                              F71805F_REG_FAN_TARGET(nr));
+                       data->pwm_freq[nr] = f71805f_read8(data,
+                                            F71805F_REG_PWM_FREQ(nr));
                }
                for (nr = 0; nr < 3; nr++) {
                        data->temp_high[nr] = f71805f_read8(data,
@@ -299,14 +357,19 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
        /* Measurement registers cache is refreshed after 1 second */
        if (time_after(jiffies, data->last_updated + HZ)
         || !data->valid) {
-               for (nr = 0; nr < 9; nr++) {
+               for (nr = 0; nr < 11; nr++) {
+                       if (!(data->has_in & (1 << nr)))
+                               continue;
                        data->in[nr] = f71805f_read8(data,
                                       F71805F_REG_IN(nr));
                }
                for (nr = 0; nr < 3; nr++) {
-                       if (data->fan_enabled & (1 << nr))
-                               data->fan[nr] = f71805f_read16(data,
-                                               F71805F_REG_FAN(nr));
+                       data->fan[nr] = f71805f_read16(data,
+                                       F71805F_REG_FAN(nr));
+                       data->fan_ctrl[nr] = f71805f_read8(data,
+                                            F71805F_REG_FAN_CTRL(nr));
+                       data->pwm[nr] = f71805f_read8(data,
+                                       F71805F_REG_PWM_DUTY(nr));
                }
                for (nr = 0; nr < 3; nr++) {
                        data->temp[nr] = f71805f_read8(data,
@@ -333,35 +396,43 @@ static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
                        char *buf)
 {
        struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
 
-       return sprintf(buf, "%ld\n", in0_from_reg(data->in[0]));
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in[nr]));
 }
 
 static ssize_t show_in0_max(struct device *dev, struct device_attribute
                            *devattr, char *buf)
 {
        struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
 
-       return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0]));
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[nr]));
 }
 
 static ssize_t show_in0_min(struct device *dev, struct device_attribute
                            *devattr, char *buf)
 {
        struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
 
-       return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0]));
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[nr]));
 }
 
 static ssize_t set_in0_max(struct device *dev, struct device_attribute
                           *devattr, const char *buf, size_t count)
 {
        struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
        long val = simple_strtol(buf, NULL, 10);
 
        mutex_lock(&data->update_lock);
-       data->in_high[0] = in0_to_reg(val);
-       f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
+       data->in_high[nr] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
        mutex_unlock(&data->update_lock);
 
        return count;
@@ -371,11 +442,13 @@ static ssize_t set_in0_min(struct device *dev, struct device_attribute
                           *devattr, const char *buf, size_t count)
 {
        struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
        long val = simple_strtol(buf, NULL, 10);
 
        mutex_lock(&data->update_lock);
-       data->in_low[0] = in0_to_reg(val);
-       f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
+       data->in_low[nr] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
        mutex_unlock(&data->update_lock);
 
        return count;
@@ -463,6 +536,16 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute
        return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
 }
 
+static ssize_t show_fan_target(struct device *dev, struct device_attribute
+                              *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", fan_from_reg(data->fan_target[nr]));
+}
+
 static ssize_t set_fan_min(struct device *dev, struct device_attribute
                           *devattr, const char *buf, size_t count)
 {
@@ -479,6 +562,157 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
        return count;
 }
 
+static ssize_t set_fan_target(struct device *dev, struct device_attribute
+                             *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       data->fan_target[nr] = fan_to_reg(val);
+       f71805f_write16(data, F71805F_REG_FAN_TARGET(nr),
+                       data->fan_target[nr]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
+                       char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%d\n", (int)data->pwm[nr]);
+}
+
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute
+                              *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       int mode;
+
+       switch (data->fan_ctrl[nr] & FAN_CTRL_MODE_MASK) {
+       case FAN_CTRL_MODE_SPEED:
+               mode = 3;
+               break;
+       case FAN_CTRL_MODE_TEMPERATURE:
+               mode = 2;
+               break;
+       default: /* MANUAL */
+               mode = 1;
+       }
+
+       return sprintf(buf, "%d\n", mode);
+}
+
+static ssize_t show_pwm_freq(struct device *dev, struct device_attribute
+                            *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%lu\n", pwm_freq_from_reg(data->pwm_freq[nr]));
+}
+
+static ssize_t show_pwm_mode(struct device *dev, struct device_attribute
+                            *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%d\n", pwm_mode_from_reg(data->fan_ctrl[nr]));
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
+                      const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+
+       if (val > 255)
+               return -EINVAL;
+
+       mutex_lock(&data->update_lock);
+       data->pwm[nr] = val;
+       f71805f_write8(data, F71805F_REG_PWM_DUTY(nr), data->pwm[nr]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+static struct attribute *f71805f_attr_pwm[];
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
+                             *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       u8 reg;
+
+       if (val < 1 || val > 3)
+               return -EINVAL;
+
+       if (val > 1) { /* Automatic mode, user can't set PWM value */
+               if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
+                                    S_IRUGO))
+                       dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1);
+       }
+
+       mutex_lock(&data->update_lock);
+       reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr))
+           & ~FAN_CTRL_MODE_MASK;
+       switch (val) {
+       case 1:
+               reg |= FAN_CTRL_MODE_MANUAL;
+               break;
+       case 2:
+               reg |= FAN_CTRL_MODE_TEMPERATURE;
+               break;
+       case 3:
+               reg |= FAN_CTRL_MODE_SPEED;
+               break;
+       }
+       data->fan_ctrl[nr] = reg;
+       f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg);
+       mutex_unlock(&data->update_lock);
+
+       if (val == 1) { /* Manual mode, user can set PWM value */
+               if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr],
+                                    S_IRUGO | S_IWUSR))
+                       dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1);
+       }
+
+       return count;
+}
+
+static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
+                           *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       data->pwm_freq[nr] = pwm_freq_to_reg(val);
+       f71805f_write8(data, F71805F_REG_PWM_FREQ(nr), data->pwm_freq[nr]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
                         char *buf)
 {
@@ -557,7 +791,7 @@ static ssize_t show_alarms_in(struct device *dev, struct device_attribute
 {
        struct f71805f_data *data = f71805f_update_device(dev);
 
-       return sprintf(buf, "%lu\n", data->alarms & 0x1ff);
+       return sprintf(buf, "%lu\n", data->alarms & 0x7ff);
 }
 
 static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
@@ -594,9 +828,11 @@ static ssize_t show_name(struct device *dev, struct device_attribute
        return sprintf(buf, "%s\n", data->name);
 }
 
-static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
-static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
-static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0);
+static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR,
+                         show_in0_max, set_in0_max, 0);
+static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR,
+                         show_in0_min, set_in0_min, 0);
 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
 static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
                          show_in_max, set_in_max, 1);
@@ -637,16 +873,32 @@ static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR,
                          show_in_max, set_in_max, 8);
 static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR,
                          show_in_min, set_in_min, 8);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in0, NULL, 9);
+static SENSOR_DEVICE_ATTR(in9_max, S_IRUGO | S_IWUSR,
+                         show_in0_max, set_in0_max, 9);
+static SENSOR_DEVICE_ATTR(in9_min, S_IRUGO | S_IWUSR,
+                         show_in0_min, set_in0_min, 9);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in0, NULL, 10);
+static SENSOR_DEVICE_ATTR(in10_max, S_IRUGO | S_IWUSR,
+                         show_in0_max, set_in0_max, 10);
+static SENSOR_DEVICE_ATTR(in10_min, S_IRUGO | S_IWUSR,
+                         show_in0_min, set_in0_min, 10);
 
 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
 static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
                          show_fan_min, set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR,
+                         show_fan_target, set_fan_target, 0);
 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
 static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
                          show_fan_min, set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan2_target, S_IRUGO | S_IWUSR,
+                         show_fan_target, set_fan_target, 1);
 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
 static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
                          show_fan_min, set_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan3_target, S_IRUGO | S_IWUSR,
+                         show_fan_target, set_fan_target, 2);
 
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
@@ -667,6 +919,27 @@ static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
                    show_temp_hyst, set_temp_hyst, 2);
 static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
 
+/* pwm (value) files are created read-only, write permission is
+   then added or removed dynamically as needed */
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 0);
+static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR,
+                         show_pwm_freq, set_pwm_freq, 0);
+static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO, show_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 1);
+static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO | S_IWUSR,
+                         show_pwm_freq, set_pwm_freq, 1);
+static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, show_pwm_mode, NULL, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO, show_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
+                         show_pwm_enable, set_pwm_enable, 2);
+static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR,
+                         show_pwm_freq, set_pwm_freq, 2);
+static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
+
 static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
 static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
 static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
@@ -676,6 +949,8 @@ static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5);
 static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6);
 static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7);
 static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 9);
+static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 10);
 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11);
 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12);
 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13);
@@ -689,9 +964,9 @@ static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
 static struct attribute *f71805f_attributes[] = {
-       &dev_attr_in0_input.attr,
-       &dev_attr_in0_max.attr,
-       &dev_attr_in0_min.attr,
+       &sensor_dev_attr_in0_input.dev_attr.attr,
+       &sensor_dev_attr_in0_max.dev_attr.attr,
+       &sensor_dev_attr_in0_min.dev_attr.attr,
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_max.dev_attr.attr,
        &sensor_dev_attr_in1_min.dev_attr.attr,
@@ -701,9 +976,6 @@ static struct attribute *f71805f_attributes[] = {
        &sensor_dev_attr_in3_input.dev_attr.attr,
        &sensor_dev_attr_in3_max.dev_attr.attr,
        &sensor_dev_attr_in3_min.dev_attr.attr,
-       &sensor_dev_attr_in4_input.dev_attr.attr,
-       &sensor_dev_attr_in4_max.dev_attr.attr,
-       &sensor_dev_attr_in4_min.dev_attr.attr,
        &sensor_dev_attr_in5_input.dev_attr.attr,
        &sensor_dev_attr_in5_max.dev_attr.attr,
        &sensor_dev_attr_in5_min.dev_attr.attr,
@@ -713,9 +985,29 @@ static struct attribute *f71805f_attributes[] = {
        &sensor_dev_attr_in7_input.dev_attr.attr,
        &sensor_dev_attr_in7_max.dev_attr.attr,
        &sensor_dev_attr_in7_min.dev_attr.attr,
-       &sensor_dev_attr_in8_input.dev_attr.attr,
-       &sensor_dev_attr_in8_max.dev_attr.attr,
-       &sensor_dev_attr_in8_min.dev_attr.attr,
+
+       &sensor_dev_attr_fan1_input.dev_attr.attr,
+       &sensor_dev_attr_fan1_min.dev_attr.attr,
+       &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+       &sensor_dev_attr_fan1_target.dev_attr.attr,
+       &sensor_dev_attr_fan2_input.dev_attr.attr,
+       &sensor_dev_attr_fan2_min.dev_attr.attr,
+       &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+       &sensor_dev_attr_fan2_target.dev_attr.attr,
+       &sensor_dev_attr_fan3_input.dev_attr.attr,
+       &sensor_dev_attr_fan3_min.dev_attr.attr,
+       &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+       &sensor_dev_attr_fan3_target.dev_attr.attr,
+
+       &sensor_dev_attr_pwm1.dev_attr.attr,
+       &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm1_mode.dev_attr.attr,
+       &sensor_dev_attr_pwm2.dev_attr.attr,
+       &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm2_mode.dev_attr.attr,
+       &sensor_dev_attr_pwm3.dev_attr.attr,
+       &sensor_dev_attr_pwm3_enable.dev_attr.attr,
+       &sensor_dev_attr_pwm3_mode.dev_attr.attr,
 
        &sensor_dev_attr_temp1_input.dev_attr.attr,
        &sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -734,11 +1026,9 @@ static struct attribute *f71805f_attributes[] = {
        &sensor_dev_attr_in1_alarm.dev_attr.attr,
        &sensor_dev_attr_in2_alarm.dev_attr.attr,
        &sensor_dev_attr_in3_alarm.dev_attr.attr,
-       &sensor_dev_attr_in4_alarm.dev_attr.attr,
        &sensor_dev_attr_in5_alarm.dev_attr.attr,
        &sensor_dev_attr_in6_alarm.dev_attr.attr,
        &sensor_dev_attr_in7_alarm.dev_attr.attr,
-       &sensor_dev_attr_in8_alarm.dev_attr.attr,
        &dev_attr_alarms_in.attr,
        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
        &sensor_dev_attr_temp2_alarm.dev_attr.attr,
@@ -754,29 +1044,59 @@ static const struct attribute_group f71805f_group = {
        .attrs = f71805f_attributes,
 };
 
-static struct attribute *f71805f_attributes_fan[3][4] = {
+static struct attribute *f71805f_attributes_optin[4][5] = {
        {
-               &sensor_dev_attr_fan1_input.dev_attr.attr,
-               &sensor_dev_attr_fan1_min.dev_attr.attr,
-               &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+               &sensor_dev_attr_in4_input.dev_attr.attr,
+               &sensor_dev_attr_in4_max.dev_attr.attr,
+               &sensor_dev_attr_in4_min.dev_attr.attr,
+               &sensor_dev_attr_in4_alarm.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_in8_input.dev_attr.attr,
+               &sensor_dev_attr_in8_max.dev_attr.attr,
+               &sensor_dev_attr_in8_min.dev_attr.attr,
+               &sensor_dev_attr_in8_alarm.dev_attr.attr,
                NULL
        }, {
-               &sensor_dev_attr_fan2_input.dev_attr.attr,
-               &sensor_dev_attr_fan2_min.dev_attr.attr,
-               &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+               &sensor_dev_attr_in9_input.dev_attr.attr,
+               &sensor_dev_attr_in9_max.dev_attr.attr,
+               &sensor_dev_attr_in9_min.dev_attr.attr,
+               &sensor_dev_attr_in9_alarm.dev_attr.attr,
                NULL
        }, {
-               &sensor_dev_attr_fan3_input.dev_attr.attr,
-               &sensor_dev_attr_fan3_min.dev_attr.attr,
-               &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+               &sensor_dev_attr_in10_input.dev_attr.attr,
+               &sensor_dev_attr_in10_max.dev_attr.attr,
+               &sensor_dev_attr_in10_min.dev_attr.attr,
+               &sensor_dev_attr_in10_alarm.dev_attr.attr,
                NULL
        }
 };
 
-static const struct attribute_group f71805f_group_fan[3] = {
-       { .attrs = f71805f_attributes_fan[0] },
-       { .attrs = f71805f_attributes_fan[1] },
-       { .attrs = f71805f_attributes_fan[2] },
+static const struct attribute_group f71805f_group_optin[4] = {
+       { .attrs = f71805f_attributes_optin[0] },
+       { .attrs = f71805f_attributes_optin[1] },
+       { .attrs = f71805f_attributes_optin[2] },
+       { .attrs = f71805f_attributes_optin[3] },
+};
+
+/* We don't include pwm_freq files in the arrays above, because they must be
+   created conditionally (only if pwm_mode is 1 == PWM) */
+static struct attribute *f71805f_attributes_pwm_freq[] = {
+       &sensor_dev_attr_pwm1_freq.dev_attr.attr,
+       &sensor_dev_attr_pwm2_freq.dev_attr.attr,
+       &sensor_dev_attr_pwm3_freq.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group f71805f_group_pwm_freq = {
+       .attrs = f71805f_attributes_pwm_freq,
+};
+
+/* We also need an indexed access to pwmN files to toggle writability */
+static struct attribute *f71805f_attr_pwm[] = {
+       &sensor_dev_attr_pwm1.dev_attr.attr,
+       &sensor_dev_attr_pwm2.dev_attr.attr,
+       &sensor_dev_attr_pwm3.dev_attr.attr,
 };
 
 /*
@@ -798,18 +1118,30 @@ static void __devinit f71805f_init_device(struct f71805f_data *data)
        /* Fan monitoring can be disabled. If it is, we won't be polling
           the register values, and won't create the related sysfs files. */
        for (i = 0; i < 3; i++) {
-               reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i));
-               if (!(reg & 0x80))
-                       data->fan_enabled |= (1 << i);
+               data->fan_ctrl[i] = f71805f_read8(data,
+                                                 F71805F_REG_FAN_CTRL(i));
+               /* Clear latch full bit, else "speed mode" fan speed control
+                  doesn't work */
+               if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) {
+                       data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL;
+                       f71805f_write8(data, F71805F_REG_FAN_CTRL(i),
+                                      data->fan_ctrl[i]);
+               }
        }
 }
 
 static int __devinit f71805f_probe(struct platform_device *pdev)
 {
+       struct f71805f_sio_data *sio_data = pdev->dev.platform_data;
        struct f71805f_data *data;
        struct resource *res;
        int i, err;
 
+       static const char *names[] = {
+               "f71805f",
+               "f71872f",
+       };
+
        if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
                err = -ENOMEM;
                printk(KERN_ERR DRVNAME ": Out of memory\n");
@@ -819,24 +1151,69 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
        data->addr = res->start;
        mutex_init(&data->lock);
-       data->name = "f71805f";
+       data->name = names[sio_data->kind];
        mutex_init(&data->update_lock);
 
        platform_set_drvdata(pdev, data);
 
+       /* Some voltage inputs depend on chip model and configuration */
+       switch (sio_data->kind) {
+       case f71805f:
+               data->has_in = 0x1ff;
+               break;
+       case f71872f:
+               data->has_in = 0x6ef;
+               if (sio_data->fnsel1 & 0x01)
+                       data->has_in |= (1 << 4); /* in4 */
+               if (sio_data->fnsel1 & 0x02)
+                       data->has_in |= (1 << 8); /* in8 */
+               break;
+       }
+
        /* Initialize the F71805F chip */
        f71805f_init_device(data);
 
        /* Register sysfs interface files */
        if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
                goto exit_free;
-       for (i = 0; i < 3; i++) {
-               if (!(data->fan_enabled & (1 << i)))
-                       continue;
+       if (data->has_in & (1 << 4)) { /* in4 */
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &f71805f_group_optin[0])))
+                       goto exit_remove_files;
+       }
+       if (data->has_in & (1 << 8)) { /* in8 */
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &f71805f_group_optin[1])))
+                       goto exit_remove_files;
+       }
+       if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */
                if ((err = sysfs_create_group(&pdev->dev.kobj,
-                                             &f71805f_group_fan[i])))
+                                             &f71805f_group_optin[2])))
                        goto exit_remove_files;
        }
+       if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &f71805f_group_optin[3])))
+                       goto exit_remove_files;
+       }
+       for (i = 0; i < 3; i++) {
+               /* If control mode is PWM, create pwm_freq file */
+               if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) {
+                       if ((err = sysfs_create_file(&pdev->dev.kobj,
+                                       f71805f_attributes_pwm_freq[i])))
+                               goto exit_remove_files;
+               }
+               /* If PWM is in manual mode, add write permission */
+               if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) {
+                       if ((err = sysfs_chmod_file(&pdev->dev.kobj,
+                                                   f71805f_attr_pwm[i],
+                                                   S_IRUGO | S_IWUSR))) {
+                               dev_err(&pdev->dev, "chmod +w pwm%d failed\n",
+                                       i + 1);
+                               goto exit_remove_files;
+                       }
+               }
+       }
 
        data->class_dev = hwmon_device_register(&pdev->dev);
        if (IS_ERR(data->class_dev)) {
@@ -849,8 +1226,9 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
 
 exit_remove_files:
        sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
-       for (i = 0; i < 3; i++)
-               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
+       for (i = 0; i < 4; i++)
+               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
+       sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
 exit_free:
        platform_set_drvdata(pdev, NULL);
        kfree(data);
@@ -866,8 +1244,9 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
        hwmon_device_unregister(data->class_dev);
        sysfs_remove_group(&pdev->dev.kobj, &f71805f_group);
-       for (i = 0; i < 3; i++)
-               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]);
+       for (i = 0; i < 4; i++)
+               sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
+       sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
        kfree(data);
 
        return 0;
@@ -882,7 +1261,8 @@ static struct platform_driver f71805f_driver = {
        .remove         = __devexit_p(f71805f_remove),
 };
 
-static int __init f71805f_device_add(unsigned short address)
+static int __init f71805f_device_add(unsigned short address,
+                                    const struct f71805f_sio_data *sio_data)
 {
        struct resource res = {
                .start  = address,
@@ -906,26 +1286,45 @@ static int __init f71805f_device_add(unsigned short address)
                goto exit_device_put;
        }
 
+       pdev->dev.platform_data = kmalloc(sizeof(struct f71805f_sio_data),
+                                         GFP_KERNEL);
+       if (!pdev->dev.platform_data) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+               goto exit_device_put;
+       }
+       memcpy(pdev->dev.platform_data, sio_data,
+              sizeof(struct f71805f_sio_data));
+
        err = platform_device_add(pdev);
        if (err) {
                printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
                       err);
-               goto exit_device_put;
+               goto exit_kfree_data;
        }
 
        return 0;
 
+exit_kfree_data:
+       kfree(pdev->dev.platform_data);
+       pdev->dev.platform_data = NULL;
 exit_device_put:
        platform_device_put(pdev);
 exit:
        return err;
 }
 
-static int __init f71805f_find(int sioaddr, unsigned short *address)
+static int __init f71805f_find(int sioaddr, unsigned short *address,
+                              struct f71805f_sio_data *sio_data)
 {
        int err = -ENODEV;
        u16 devid;
 
+       static const char *names[] = {
+               "F71805F/FG",
+               "F71872F/FG",
+       };
+
        superio_enter(sioaddr);
 
        devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -933,7 +1332,15 @@ static int __init f71805f_find(int sioaddr, unsigned short *address)
                goto exit;
 
        devid = superio_inw(sioaddr, SIO_REG_DEVID);
-       if (devid != SIO_F71805F_ID) {
+       switch (devid) {
+       case SIO_F71805F_ID:
+               sio_data->kind = f71805f;
+               break;
+       case SIO_F71872F_ID:
+               sio_data->kind = f71872f;
+               sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
+               break;
+       default:
                printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
                       "skipping\n");
                goto exit;
@@ -952,10 +1359,12 @@ static int __init f71805f_find(int sioaddr, unsigned short *address)
                       "skipping\n");
                goto exit;
        }
+       *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
 
        err = 0;
-       printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n",
-              *address, superio_inb(sioaddr, SIO_REG_DEVREV));
+       printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n",
+              names[sio_data->kind], *address,
+              superio_inb(sioaddr, SIO_REG_DEVREV));
 
 exit:
        superio_exit(sioaddr);
@@ -966,9 +1375,10 @@ static int __init f71805f_init(void)
 {
        int err;
        unsigned short address;
+       struct f71805f_sio_data sio_data;
 
-       if (f71805f_find(0x2e, &address)
-        && f71805f_find(0x4e, &address))
+       if (f71805f_find(0x2e, &address, &sio_data)
+        && f71805f_find(0x4e, &address, &sio_data))
                return -ENODEV;
 
        err = platform_driver_register(&f71805f_driver);
@@ -976,7 +1386,7 @@ static int __init f71805f_init(void)
                goto exit;
 
        /* Sets global pdev as a side effect */
-       err = f71805f_device_add(address);
+       err = f71805f_device_add(address, &sio_data);
        if (err)
                goto exit_driver;
 
@@ -990,13 +1400,16 @@ exit:
 
 static void __exit f71805f_exit(void)
 {
+       kfree(pdev->dev.platform_data);
+       pdev->dev.platform_data = NULL;
        platform_device_unregister(pdev);
+
        platform_driver_unregister(&f71805f_driver);
 }
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("F71805F hardware monitoring driver");
+MODULE_DESCRIPTION("F71805F/F71872F hardware monitoring driver");
 
 module_init(f71805f_init);
 module_exit(f71805f_exit);
index e8ef62b83d6bf578dfb765cecf847c55cf38f6a4..bf759ea545ac593e319fe1d89f12e48b5caba0b9 100644 (file)
@@ -478,74 +478,64 @@ static struct attribute_group hdaps_attribute_group = {
 /* Module stuff */
 
 /* hdaps_dmi_match - found a match.  return one, short-circuiting the hunt. */
-static int hdaps_dmi_match(struct dmi_system_id *id)
+static int __init hdaps_dmi_match(struct dmi_system_id *id)
 {
        printk(KERN_INFO "hdaps: %s detected.\n", id->ident);
        return 1;
 }
 
 /* hdaps_dmi_match_invert - found an inverted match. */
-static int hdaps_dmi_match_invert(struct dmi_system_id *id)
+static int __init hdaps_dmi_match_invert(struct dmi_system_id *id)
 {
        hdaps_invert = 1;
        printk(KERN_INFO "hdaps: inverting axis readings.\n");
        return hdaps_dmi_match(id);
 }
 
-#define HDAPS_DMI_MATCH_NORMAL(model)  {               \
-       .ident = "IBM " model,                          \
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model) {                \
+       .ident = vendor " " model,                      \
        .callback = hdaps_dmi_match,                    \
        .matches = {                                    \
-               DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),     \
+               DMI_MATCH(DMI_BOARD_VENDOR, vendor),    \
                DMI_MATCH(DMI_PRODUCT_VERSION, model)   \
        }                                               \
 }
 
-#define HDAPS_DMI_MATCH_INVERT(model)  {               \
-       .ident = "IBM " model,                          \
+#define HDAPS_DMI_MATCH_INVERT(vendor, model) {                \
+       .ident = vendor " " model,                      \
        .callback = hdaps_dmi_match_invert,             \
        .matches = {                                    \
-               DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),     \
+               DMI_MATCH(DMI_BOARD_VENDOR, vendor),    \
                DMI_MATCH(DMI_PRODUCT_VERSION, model)   \
        }                                               \
 }
 
-#define HDAPS_DMI_MATCH_LENOVO(model)   {               \
-        .ident = "Lenovo " model,                       \
-        .callback = hdaps_dmi_match_invert,             \
-        .matches = {                                    \
-                DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  \
-                DMI_MATCH(DMI_PRODUCT_VERSION, model)   \
-        }                                               \
-}
+/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
+   "ThinkPad T42p", so the order of the entries matters.
+   If your ThinkPad is not recognized, please update to latest
+   BIOS. This is especially the case for some R52 ThinkPads. */
+static struct dmi_system_id __initdata hdaps_whitelist[] = {
+       HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
+       HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
+       HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
+       HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
+       HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
+       HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
+       { .ident = NULL }
+};
 
 static int __init hdaps_init(void)
 {
        int ret;
 
-       /* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
-         "ThinkPad T42p", so the order of the entries matters */
-       struct dmi_system_id hdaps_whitelist[] = {
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad H"),
-               HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad H"),    /* R52 (1846AQG) */
-               HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),
-               HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad T42"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),
-               HDAPS_DMI_MATCH_LENOVO("ThinkPad T60p"),
-               HDAPS_DMI_MATCH_LENOVO("ThinkPad T60"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),
-               HDAPS_DMI_MATCH_LENOVO("ThinkPad X60"),
-               HDAPS_DMI_MATCH_NORMAL("ThinkPad Z60m"),
-               { .ident = NULL }
-       };
-
        if (!dmi_check_system(hdaps_whitelist)) {
                printk(KERN_WARNING "hdaps: supported laptop not found!\n");
                ret = -ENODEV;
index 9d67320e6840161c7f8c5dcf068abf3fe69367e7..31c42002708f9ee050235778e7147be234acdf22 100644 (file)
@@ -1,7 +1,7 @@
 /*
     hwmon-vid.c - VID/VRM/VRD voltage conversions
 
-    Copyright (c) 2004 Rudolf Marek <r.marek@sh.cvut.cz>
+    Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz>
 
     Partly imported from i2c-vid.h of the lm_sensors project
     Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -232,7 +232,7 @@ u8 vid_which_vrm(void)
 EXPORT_SYMBOL(vid_from_reg);
 EXPORT_SYMBOL(vid_which_vrm);
 
-MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
+MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
 
 MODULE_DESCRIPTION("hwmon-vid driver");
 MODULE_LICENSE("GPL");
index 323ef06719c160537942a002b5495a79159c2b28..1ed8b7e2c35df01e57dfab60aab6c0dc8825c37e 100644 (file)
@@ -3,7 +3,7 @@
              monitoring.
 
     Supports: IT8705F  Super I/O chip w/LPC interface
-              IT8712F  Super I/O chip w/LPC interface & SMBus
+              IT8712F  Super I/O chip w/LPC interface
               IT8716F  Super I/O chip w/LPC interface
               IT8718F  Super I/O chip w/LPC interface
               Sis950   A clone of the IT8705F
 #include <asm/io.h>
 
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 static unsigned short isa_address;
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718);
+enum chips { it87, it8712, it8716, it8718 };
 
 #define        REG     0x2e    /* The register to read/write */
 #define        DEV     0x07    /* Register: Logical device select */
@@ -162,8 +158,6 @@ static u8 vid_value;
 #define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
 #define IT87_REG_TEMP_LOW(nr)  (0x41 + (nr) * 2)
 
-#define IT87_REG_I2C_ADDR      0x48
-
 #define IT87_REG_VIN_ENABLE    0x50
 #define IT87_REG_TEMP_ENABLE   0x51
 
@@ -242,33 +236,22 @@ struct it87_data {
 };
 
 
-static int it87_attach_adapter(struct i2c_adapter *adapter);
-static int it87_isa_attach_adapter(struct i2c_adapter *adapter);
-static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
+static int it87_detect(struct i2c_adapter *adapter);
 static int it87_detach_client(struct i2c_client *client);
 
 static int it87_read_value(struct i2c_client *client, u8 reg);
-static int it87_write_value(struct i2c_client *client, u8 reg, u8 value);
+static void it87_write_value(struct i2c_client *client, u8 reg, u8 value);
 static struct it87_data *it87_update_device(struct device *dev);
 static int it87_check_pwm(struct i2c_client *client);
 static void it87_init_client(struct i2c_client *client, struct it87_data *data);
 
 
-static struct i2c_driver it87_driver = {
-       .driver = {
-               .name   = "it87",
-       },
-       .id             = I2C_DRIVERID_IT87,
-       .attach_adapter = it87_attach_adapter,
-       .detach_client  = it87_detach_client,
-};
-
 static struct i2c_driver it87_isa_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = "it87-isa",
        },
-       .attach_adapter = it87_isa_attach_adapter,
+       .attach_adapter = it87_detect,
        .detach_client  = it87_detach_client,
 };
 
@@ -850,22 +833,6 @@ static const struct attribute_group it87_group_opt = {
        .attrs = it87_attributes_opt,
 };
 
-/* This function is called when:
-     * it87_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and it87_driver is still present) */
-static int it87_attach_adapter(struct i2c_adapter *adapter)
-{
-       if (!(adapter->class & I2C_CLASS_HWMON))
-               return 0;
-       return i2c_probe(adapter, &addr_data, it87_detect);
-}
-
-static int it87_isa_attach_adapter(struct i2c_adapter *adapter)
-{
-       return it87_detect(adapter, isa_address, -1);
-}
-
 /* SuperIO detection - will change isa_address if a chip is found */
 static int __init it87_find(unsigned short *address)
 {
@@ -916,29 +883,20 @@ exit:
 }
 
 /* This function is called by i2c_probe */
-static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
+static int it87_detect(struct i2c_adapter *adapter)
 {
-       int i;
        struct i2c_client *new_client;
        struct it87_data *data;
        int err = 0;
-       const char *name = "";
-       int is_isa = i2c_is_isa_adapter(adapter);
+       const char *name;
        int enable_pwm_interface;
 
-       if (!is_isa && 
-           !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-               goto ERROR0;
-
        /* Reserve the ISA region */
-       if (is_isa)
-               if (!request_region(address, IT87_EXTENT,
-                                   it87_isa_driver.driver.name))
-                       goto ERROR0;
-
-       /* For now, we presume we have a valid client. We create the
-          client structure, even though we cannot fill it completely yet.
-          But it allows us to access it87_{read,write}_value. */
+       if (!request_region(isa_address, IT87_EXTENT,
+                           it87_isa_driver.driver.name)){
+               err = -EBUSY;
+               goto ERROR0;
+       }
 
        if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) {
                err = -ENOMEM;
@@ -946,80 +904,46 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        new_client = &data->client;
-       if (is_isa)
-               mutex_init(&data->lock);
+       mutex_init(&data->lock);
        i2c_set_clientdata(new_client, data);
-       new_client->addr = address;
+       new_client->addr = isa_address;
        new_client->adapter = adapter;
-       new_client->driver = is_isa ? &it87_isa_driver : &it87_driver;
-       new_client->flags = 0;
+       new_client->driver = &it87_isa_driver;
 
        /* Now, we do the remaining detection. */
-
-       if (kind < 0) {
-               if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
-                 || (!is_isa
-                  && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) {
-                       err = -ENODEV;
-                       goto ERROR2;
-               }
+       if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
+        || it87_read_value(new_client, IT87_REG_CHIPID) != 0x90) {
+               err = -ENODEV;
+               goto ERROR2;
        }
 
        /* Determine the chip type. */
-       if (kind <= 0) {
-               i = it87_read_value(new_client, IT87_REG_CHIPID);
-               if (i == 0x90) {
-                       kind = it87;
-                       if (is_isa) {
-                               switch (chip_type) {
-                               case IT8712F_DEVID:
-                                       kind = it8712;
-                                       break;
-                               case IT8716F_DEVID:
-                                       kind = it8716;
-                                       break;
-                               case IT8718F_DEVID:
-                                       kind = it8718;
-                                       break;
-                               }
-                       }
-               }
-               else {
-                       if (kind == 0)
-                               dev_info(&adapter->dev, 
-                                       "Ignoring 'force' parameter for unknown chip at "
-                                       "adapter %d, address 0x%02x\n",
-                                       i2c_adapter_id(adapter), address);
-                       err = -ENODEV;
-                       goto ERROR2;
-               }
-       }
-
-       if (kind == it87) {
-               name = "it87";
-       } else if (kind == it8712) {
+       switch (chip_type) {
+       case IT8712F_DEVID:
+               data->type = it8712;
                name = "it8712";
-       } else if (kind == it8716) {
+               break;
+       case IT8716F_DEVID:
+               data->type = it8716;
                name = "it8716";
-       } else if (kind == it8718) {
+               break;
+       case IT8718F_DEVID:
+               data->type = it8718;
                name = "it8718";
+               break;
+       default:
+               data->type = it87;
+               name = "it87";
        }
 
        /* Fill in the remaining client fields and put it into the global list */
        strlcpy(new_client->name, name, I2C_NAME_SIZE);
-       data->type = kind;
-       data->valid = 0;
        mutex_init(&data->update_lock);
 
        /* Tell the I2C layer a new client has arrived */
        if ((err = i2c_attach_client(new_client)))
                goto ERROR2;
 
-       if (!is_isa)
-               dev_info(&new_client->dev, "The I2C interface to IT87xxF "
-                        "hardware monitoring chips is deprecated. Please "
-                        "report if you still rely on it.\n");
-
        /* Check PWM configuration */
        enable_pwm_interface = it87_check_pwm(new_client);
 
@@ -1129,8 +1053,7 @@ ERROR3:
 ERROR2:
        kfree(data);
 ERROR1:
-       if (is_isa)
-               release_region(address, IT87_EXTENT);
+       release_region(isa_address, IT87_EXTENT);
 ERROR0:
        return err;
 }
@@ -1147,50 +1070,39 @@ static int it87_detach_client(struct i2c_client *client)
        if ((err = i2c_detach_client(client)))
                return err;
 
-       if(i2c_is_isa_client(client))
-               release_region(client->addr, IT87_EXTENT);
+       release_region(client->addr, IT87_EXTENT);
        kfree(data);
 
        return 0;
 }
 
-/* The SMBus locks itself, but ISA access must be locked explicitly! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
+/* ISA access must be locked explicitly!
    We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
    would slow down the IT87 access and should not be necessary. */
 static int it87_read_value(struct i2c_client *client, u8 reg)
 {
        struct it87_data *data = i2c_get_clientdata(client);
-
        int res;
-       if (i2c_is_isa_client(client)) {
-               mutex_lock(&data->lock);
-               outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
-               res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
-               mutex_unlock(&data->lock);
-               return res;
-       } else
-               return i2c_smbus_read_byte_data(client, reg);
+
+       mutex_lock(&data->lock);
+       outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+       res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
+       mutex_unlock(&data->lock);
+
+       return res;
 }
 
-/* The SMBus locks itself, but ISA access muse be locked explicitly! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
+/* ISA access must be locked explicitly!
    We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
    would slow down the IT87 access and should not be necessary. */
-static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
+static void it87_write_value(struct i2c_client *client, u8 reg, u8 value)
 {
        struct it87_data *data = i2c_get_clientdata(client);
 
-       if (i2c_is_isa_client(client)) {
-               mutex_lock(&data->lock);
-               outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
-               outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
-               mutex_unlock(&data->lock);
-               return 0;
-       } else
-               return i2c_smbus_write_byte_data(client, reg, value);
+       mutex_lock(&data->lock);
+       outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+       outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
+       mutex_unlock(&data->lock);
 }
 
 /* Return 1 if and only if the PWM interface is safe to use */
@@ -1426,26 +1338,14 @@ static int __init sm_it87_init(void)
 {
        int res;
 
-       res = i2c_add_driver(&it87_driver);
-       if (res)
+       if ((res = it87_find(&isa_address)))
                return res;
-
-       if (!it87_find(&isa_address)) {
-               res = i2c_isa_add_driver(&it87_isa_driver);
-               if (res) {
-                       i2c_del_driver(&it87_driver);
-                       return res;
-               }
-       }
-
-       return 0;
+       return i2c_isa_add_driver(&it87_isa_driver);
 }
 
 static void __exit sm_it87_exit(void)
 {
-       if (isa_address)
-               i2c_isa_del_driver(&it87_isa_driver);
-       i2c_del_driver(&it87_driver);
+       i2c_isa_del_driver(&it87_isa_driver);
 }
 
 
index f58b64ed09e3fa06eaa512aaa90d4a1bf04b9c80..5d8d0ca08fa9a344f58f7e3d8f8984fa5ae78a87 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * k8temp.c - Linux kernel module for hardware monitoring
  *
- * Copyright (C) 2006 Rudolf Marek <r.marek@sh.cvut.cz>
+ * Copyright (C) 2006 Rudolf Marek <r.marek@assembler.cz>
  *
  * Inspired from the w83785 and amd756 drivers.
  *
@@ -286,7 +286,7 @@ static void __exit k8temp_exit(void)
        pci_unregister_driver(&k8temp_driver);
 }
 
-MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>");
+MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
 MODULE_DESCRIPTION("AMD K8 core temperature monitor");
 MODULE_LICENSE("GPL");
 
index 3b8b81984ad4cf04ab3c0fdb91079654cbda519e..c8a21be09d8756cc612de0ebab23e7691ce973a8 100644 (file)
@@ -1000,7 +1000,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
                        (i&0x02) ? "external" : "internal");
 
                data->vid_conf = confreg[3];
-               data->vrm = 90;
+               data->vrm = vid_which_vrm();
        }
 
        /* Fan clock dividers may be needed before any data is read */
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
new file mode 100644 (file)
index 0000000..affa21a
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+ *  pc87427.c - hardware monitoring driver for the
+ *              National Semiconductor PC87427 Super-I/O chip
+ *  Copyright (C) 2006 Jean Delvare <khali@linux-fr.org>
+ *
+ *  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.
+ *
+ *  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.
+ *
+ *  Supports the following chips:
+ *
+ *  Chip        #vin    #fan    #pwm    #temp   devid
+ *  PC87427     -       8       -       -       0xF2
+ *
+ *  This driver assumes that no more than one chip is present.
+ *  Only fan inputs are supported so far, although the chip can do much more.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+#include <asm/io.h>
+
+static struct platform_device *pdev;
+
+#define DRVNAME "pc87427"
+
+/* The lock mutex protects both the I/O accesses (needed because the
+   device is using banked registers) and the register cache (needed to keep
+   the data in the registers and the cache in sync at any time). */
+struct pc87427_data {
+       struct class_device *class_dev;
+       struct mutex lock;
+       int address[2];
+       const char *name;
+
+       unsigned long last_updated;     /* in jiffies */
+       u8 fan_enabled;                 /* bit vector */
+       u16 fan[8];                     /* register values */
+       u16 fan_min[8];                 /* register values */
+       u8 fan_status[8];               /* register values */
+};
+
+/*
+ * Super-I/O registers and operations
+ */
+
+#define SIOREG_LDSEL   0x07    /* Logical device select */
+#define SIOREG_DEVID   0x20    /* Device ID */
+#define SIOREG_ACT     0x30    /* Device activation */
+#define SIOREG_MAP     0x50    /* I/O or memory mapping */
+#define SIOREG_IOBASE  0x60    /* I/O base address */
+
+static const u8 logdev[2] = { 0x09, 0x14 };
+static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
+#define LD_FAN         0
+#define LD_IN          1
+#define LD_TEMP                1
+
+static inline void superio_outb(int sioaddr, int reg, int val)
+{
+       outb(reg, sioaddr);
+       outb(val, sioaddr + 1);
+}
+
+static inline int superio_inb(int sioaddr, int reg)
+{
+       outb(reg, sioaddr);
+       return inb(sioaddr + 1);
+}
+
+static inline void superio_exit(int sioaddr)
+{
+       outb(0x02, sioaddr);
+       outb(0x02, sioaddr + 1);
+}
+
+/*
+ * Logical devices
+ */
+
+#define REGION_LENGTH          32
+#define PC87427_REG_BANK       0x0f
+#define BANK_FM(nr)            (nr)
+#define BANK_FT(nr)            (0x08 + (nr))
+#define BANK_FC(nr)            (0x10 + (nr) * 2)
+
+/*
+ * I/O access functions
+ */
+
+/* ldi is the logical device index */
+static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
+{
+       return inb(data->address[ldi] + reg);
+}
+
+/* Must be called with data->lock held, except during init */
+static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
+                                    u8 bank, u8 reg)
+{
+       outb(bank, data->address[ldi] + PC87427_REG_BANK);
+       return inb(data->address[ldi] + reg);
+}
+
+/* Must be called with data->lock held, except during init */
+static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
+                                      u8 bank, u8 reg, u8 value)
+{
+       outb(bank, data->address[ldi] + PC87427_REG_BANK);
+       outb(value, data->address[ldi] + reg);
+}
+
+/*
+ * Fan registers and conversions
+ */
+
+/* fan data registers are 16-bit wide */
+#define PC87427_REG_FAN                        0x12
+#define PC87427_REG_FAN_MIN            0x14
+#define PC87427_REG_FAN_STATUS         0x10
+
+#define FAN_STATUS_STALL               (1 << 3)
+#define FAN_STATUS_LOSPD               (1 << 1)
+#define FAN_STATUS_MONEN               (1 << 0)
+
+/* Dedicated function to read all registers related to a given fan input.
+   This saves us quite a few locks and bank selections.
+   Must be called with data->lock held.
+   nr is from 0 to 7 */
+static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
+{
+       int iobase = data->address[LD_FAN];
+
+       outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
+       data->fan[nr] = inw(iobase + PC87427_REG_FAN);
+       data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
+       data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
+       /* Clear fan alarm bits */
+       outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
+}
+
+/* The 2 LSB of fan speed registers are used for something different.
+   The actual 2 LSB of the measurements are not available. */
+static inline unsigned long fan_from_reg(u16 reg)
+{
+       reg &= 0xfffc;
+       if (reg == 0x0000 || reg == 0xfffc)
+               return 0;
+       return 5400000UL / reg;
+}
+
+/* The 2 LSB of the fan speed limit registers are not significant. */
+static inline u16 fan_to_reg(unsigned long val)
+{
+       if (val < 83UL)
+               return 0xffff;
+       if (val >= 1350000UL)
+               return 0x0004;
+       return ((1350000UL + val / 2) / val) << 2;
+}
+
+/*
+ * Data interface
+ */
+
+static struct pc87427_data *pc87427_update_device(struct device *dev)
+{
+       struct pc87427_data *data = dev_get_drvdata(dev);
+       int i;
+
+       mutex_lock(&data->lock);
+       if (!time_after(jiffies, data->last_updated + HZ)
+        && data->last_updated)
+               goto done;
+
+       /* Fans */
+       for (i = 0; i < 8; i++) {
+               if (!(data->fan_enabled & (1 << i)))
+                       continue;
+               pc87427_readall_fan(data, i);
+       }
+       data->last_updated = jiffies;
+
+done:
+       mutex_unlock(&data->lock);
+       return data;
+}
+
+static ssize_t show_fan_input(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pc87427_data *data = pc87427_update_device(dev);
+       int nr = attr->index;
+
+       return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
+}
+
+static ssize_t show_fan_min(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pc87427_data *data = pc87427_update_device(dev);
+       int nr = attr->index;
+
+       return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
+}
+
+static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pc87427_data *data = pc87427_update_device(dev);
+       int nr = attr->index;
+
+       return sprintf(buf, "%d\n", !!(data->fan_status[nr]
+                                      & FAN_STATUS_LOSPD));
+}
+
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct pc87427_data *data = pc87427_update_device(dev);
+       int nr = attr->index;
+
+       return sprintf(buf, "%d\n", !!(data->fan_status[nr]
+                                      & FAN_STATUS_STALL));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct pc87427_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       unsigned long val = simple_strtoul(buf, NULL, 10);
+       int iobase = data->address[LD_FAN];
+
+       mutex_lock(&data->lock);
+       outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
+       /* The low speed limit registers are read-only while monitoring
+          is enabled, so we have to disable monitoring, then change the
+          limit, and finally enable monitoring again. */
+       outb(0, iobase + PC87427_REG_FAN_STATUS);
+       data->fan_min[nr] = fan_to_reg(val);
+       outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
+       outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 2);
+static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 3);
+static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 4);
+static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 5);
+static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 6);
+static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
+                         show_fan_min, set_fan_min, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
+
+static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
+static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
+static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
+
+static struct attribute *pc87427_attributes_fan[8][5] = {
+       {
+               &sensor_dev_attr_fan1_input.dev_attr.attr,
+               &sensor_dev_attr_fan1_min.dev_attr.attr,
+               &sensor_dev_attr_fan1_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan1_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan2_input.dev_attr.attr,
+               &sensor_dev_attr_fan2_min.dev_attr.attr,
+               &sensor_dev_attr_fan2_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan2_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan3_input.dev_attr.attr,
+               &sensor_dev_attr_fan3_min.dev_attr.attr,
+               &sensor_dev_attr_fan3_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan3_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan4_input.dev_attr.attr,
+               &sensor_dev_attr_fan4_min.dev_attr.attr,
+               &sensor_dev_attr_fan4_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan4_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan5_input.dev_attr.attr,
+               &sensor_dev_attr_fan5_min.dev_attr.attr,
+               &sensor_dev_attr_fan5_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan5_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan6_input.dev_attr.attr,
+               &sensor_dev_attr_fan6_min.dev_attr.attr,
+               &sensor_dev_attr_fan6_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan6_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan7_input.dev_attr.attr,
+               &sensor_dev_attr_fan7_min.dev_attr.attr,
+               &sensor_dev_attr_fan7_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan7_fault.dev_attr.attr,
+               NULL
+       }, {
+               &sensor_dev_attr_fan8_input.dev_attr.attr,
+               &sensor_dev_attr_fan8_min.dev_attr.attr,
+               &sensor_dev_attr_fan8_alarm.dev_attr.attr,
+               &sensor_dev_attr_fan8_fault.dev_attr.attr,
+               NULL
+       }
+};
+
+static const struct attribute_group pc87427_group_fan[8] = {
+       { .attrs = pc87427_attributes_fan[0] },
+       { .attrs = pc87427_attributes_fan[1] },
+       { .attrs = pc87427_attributes_fan[2] },
+       { .attrs = pc87427_attributes_fan[3] },
+       { .attrs = pc87427_attributes_fan[4] },
+       { .attrs = pc87427_attributes_fan[5] },
+       { .attrs = pc87427_attributes_fan[6] },
+       { .attrs = pc87427_attributes_fan[7] },
+};
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+                        *devattr, char *buf)
+{
+       struct pc87427_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+
+/*
+ * Device detection, attach and detach
+ */
+
+static void __devinit pc87427_init_device(struct device *dev)
+{
+       struct pc87427_data *data = dev_get_drvdata(dev);
+       int i;
+       u8 reg;
+
+       /* The FMC module should be ready */
+       reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
+       if (!(reg & 0x80))
+               dev_warn(dev, "FMC module not ready!\n");
+
+       /* Check which fans are enabled */
+       for (i = 0; i < 8; i++) {
+               reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
+                                        PC87427_REG_FAN_STATUS);
+               if (reg & FAN_STATUS_MONEN)
+                       data->fan_enabled |= (1 << i);
+       }
+
+       if (!data->fan_enabled) {
+               dev_dbg(dev, "Enabling all fan inputs\n");
+               for (i = 0; i < 8; i++)
+                       pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
+                                           PC87427_REG_FAN_STATUS,
+                                           FAN_STATUS_MONEN);
+               data->fan_enabled = 0xff;
+       }
+}
+
+static int __devinit pc87427_probe(struct platform_device *pdev)
+{
+       struct pc87427_data *data;
+       struct resource *res;
+       int i, err;
+
+       if (!(data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Out of memory\n");
+               goto exit;
+       }
+
+       /* This will need to be revisited when we add support for
+          temperature and voltage monitoring. */
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       data->address[0] = res->start;
+
+       mutex_init(&data->lock);
+       data->name = "pc87427";
+       platform_set_drvdata(pdev, data);
+       pc87427_init_device(&pdev->dev);
+
+       /* Register sysfs hooks */
+       if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
+               goto exit_kfree;
+       for (i = 0; i < 8; i++) {
+               if (!(data->fan_enabled & (1 << i)))
+                       continue;
+               if ((err = sysfs_create_group(&pdev->dev.kobj,
+                                             &pc87427_group_fan[i])))
+                       goto exit_remove_files;
+       }
+
+       data->class_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+               goto exit_remove_files;
+       }
+
+       return 0;
+
+exit_remove_files:
+       for (i = 0; i < 8; i++) {
+               if (!(data->fan_enabled & (1 << i)))
+                       continue;
+               sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
+       }
+exit_kfree:
+       platform_set_drvdata(pdev, NULL);
+       kfree(data);
+exit:
+       return err;
+}
+
+static int __devexit pc87427_remove(struct platform_device *pdev)
+{
+       struct pc87427_data *data = platform_get_drvdata(pdev);
+       int i;
+
+       platform_set_drvdata(pdev, NULL);
+       hwmon_device_unregister(data->class_dev);
+       device_remove_file(&pdev->dev, &dev_attr_name);
+       for (i = 0; i < 8; i++) {
+               if (!(data->fan_enabled & (1 << i)))
+                       continue;
+               sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
+       }
+       kfree(data);
+
+       return 0;
+}
+
+
+static struct platform_driver pc87427_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = DRVNAME,
+       },
+       .probe          = pc87427_probe,
+       .remove         = __devexit_p(pc87427_remove),
+};
+
+static int __init pc87427_device_add(unsigned short address)
+{
+       struct resource res = {
+               .start  = address,
+               .end    = address + REGION_LENGTH - 1,
+               .name   = logdev_str[0],
+               .flags  = IORESOURCE_IO,
+       };
+       int err;
+
+       pdev = platform_device_alloc(DRVNAME, address);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+               goto exit;
+       }
+
+       err = platform_device_add_resources(pdev, &res, 1);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device resource addition failed "
+                      "(%d)\n", err);
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto exit_device_put;
+       }
+
+       return 0;
+
+exit_device_put:
+       platform_device_put(pdev);
+exit:
+       return err;
+}
+
+static int __init pc87427_find(int sioaddr, unsigned short *address)
+{
+       u16 val;
+       int i, err = 0;
+
+       /* Identify device */
+       val = superio_inb(sioaddr, SIOREG_DEVID);
+       if (val != 0xf2) {      /* PC87427 */
+               err = -ENODEV;
+               goto exit;
+       }
+
+       for (i = 0; i < 2; i++) {
+               address[i] = 0;
+               /* Select logical device */
+               superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
+
+               val = superio_inb(sioaddr, SIOREG_ACT);
+               if (!(val & 0x01)) {
+                       printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
+                              "not activated\n", logdev[i]);
+                       continue;
+               }
+
+               val = superio_inb(sioaddr, SIOREG_MAP);
+               if (val & 0x01) {
+                       printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
+                              "is memory-mapped, can't use\n", logdev[i]);
+                       continue;
+               }
+
+               val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
+                   | superio_inb(sioaddr, SIOREG_IOBASE + 1);
+               if (!val) {
+                       printk(KERN_INFO DRVNAME ": I/O base address not set "
+                              "for logical device 0x%02x\n", logdev[i]);
+                       continue;
+               }
+               address[i] = val;
+       }
+
+exit:
+       superio_exit(sioaddr);
+       return err;
+}
+
+static int __init pc87427_init(void)
+{
+       int err;
+       unsigned short address[2];
+
+       if (pc87427_find(0x2e, address)
+        && pc87427_find(0x4e, address))
+               return -ENODEV;
+
+       /* For now the driver only handles fans so we only care about the
+          first address. */
+       if (!address[0])
+               return -ENODEV;
+
+       err = platform_driver_register(&pc87427_driver);
+       if (err)
+               goto exit;
+
+       /* Sets global pdev as a side effect */
+       err = pc87427_device_add(address[0]);
+       if (err)
+               goto exit_driver;
+
+       return 0;
+
+exit_driver:
+       platform_driver_unregister(&pc87427_driver);
+exit:
+       return err;
+}
+
+static void __exit pc87427_exit(void)
+{
+       platform_device_unregister(pdev);
+       platform_driver_unregister(&pc87427_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
+MODULE_LICENSE("GPL");
+
+module_init(pc87427_init);
+module_exit(pc87427_exit);
index 2257806d0102b203bff43aa3e3c73530c7ef49dc..212a1558c63b62a0556f469f1370341e9c14b039 100644 (file)
@@ -3,7 +3,7 @@
                 the Winbond W83627EHF Super-I/O chip
     Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
     Copyright (C) 2006  Yuan Mu (Winbond),
-                        Rudolf Marek <r.marek@sh.cvut.cz>
+                        Rudolf Marek <r.marek@assembler.cz>
                         David Hubbard <david.c.hubbard@gmail.com>
 
     Shamelessly ripped from the w83627hf driver
index 4e108262576fa9bcf7887b94a21225d14d013d50..b0fa296740d1897ce6770f5b136914da1142d501 100644 (file)
@@ -3,7 +3,7 @@
                 monitoring
     Copyright (C) 2004, 2005 Winbond Electronics Corp.
                         Chunhao Huang <DZShen@Winbond.com.tw>,
-                        Rudolf Marek <r.marek@sh.cvut.cz>
+                        Rudolf Marek <r.marek@assembler.cz>
 
     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
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
new file mode 100644 (file)
index 0000000..c12ac5a
--- /dev/null
@@ -0,0 +1,1609 @@
+/*
+    w83793.c - Linux kernel driver for hardware monitoring
+    Copyright (C) 2006 Winbond Electronics Corp.
+                  Yuan Mu
+                  Rudolf Marek <r.marek@assembler.cz>
+
+    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 - version 2.
+
+    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., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301 USA.
+*/
+
+/*
+    Supports following chips:
+
+    Chip       #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
+    w83793     10      12      8       6       0x7b    0x5ca3  yes     no
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(w83793);
+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
+                      "{bus, clientaddr, subclientaddr1, subclientaddr2}");
+
+static int reset;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
+
+/*
+   Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
+   as ID, Bank Select registers
+*/
+#define W83793_REG_BANKSEL             0x00
+#define W83793_REG_VENDORID            0x0d
+#define W83793_REG_CHIPID              0x0e
+#define W83793_REG_DEVICEID            0x0f
+
+#define W83793_REG_CONFIG              0x40
+#define W83793_REG_MFC                 0x58
+#define W83793_REG_FANIN_CTRL          0x5c
+#define W83793_REG_FANIN_SEL           0x5d
+#define W83793_REG_I2C_ADDR            0x0b
+#define W83793_REG_I2C_SUBADDR         0x0c
+#define W83793_REG_VID_INA             0x05
+#define W83793_REG_VID_INB             0x06
+#define W83793_REG_VID_LATCHA          0x07
+#define W83793_REG_VID_LATCHB          0x08
+#define W83793_REG_VID_CTRL            0x59
+
+static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
+
+#define TEMP_READ      0
+#define TEMP_CRIT      1
+#define TEMP_CRIT_HYST 2
+#define TEMP_WARN      3
+#define TEMP_WARN_HYST 4
+/* only crit and crit_hyst affect real-time alarm status
+   current crit crit_hyst warn warn_hyst */
+static u16 W83793_REG_TEMP[][5] = {
+       {0x1c, 0x78, 0x79, 0x7a, 0x7b},
+       {0x1d, 0x7c, 0x7d, 0x7e, 0x7f},
+       {0x1e, 0x80, 0x81, 0x82, 0x83},
+       {0x1f, 0x84, 0x85, 0x86, 0x87},
+       {0x20, 0x88, 0x89, 0x8a, 0x8b},
+       {0x21, 0x8c, 0x8d, 0x8e, 0x8f},
+};
+
+#define W83793_REG_TEMP_LOW_BITS       0x22
+
+#define W83793_REG_BEEP(index)         (0x53 + (index))
+#define W83793_REG_ALARM(index)                (0x4b + (index))
+
+#define W83793_REG_CLR_CHASSIS         0x4a    /* SMI MASK4 */
+#define W83793_REG_IRQ_CTRL            0x50
+#define W83793_REG_OVT_CTRL            0x51
+#define W83793_REG_OVT_BEEP            0x52
+
+#define IN_READ                                0
+#define IN_MAX                         1
+#define IN_LOW                         2
+static const u16 W83793_REG_IN[][3] = {
+       /* Current, High, Low */
+       {0x10, 0x60, 0x61},     /* Vcore A      */
+       {0x11, 0x62, 0x63},     /* Vcore B      */
+       {0x12, 0x64, 0x65},     /* Vtt          */
+       {0x14, 0x6a, 0x6b},     /* VSEN1        */
+       {0x15, 0x6c, 0x6d},     /* VSEN2        */
+       {0x16, 0x6e, 0x6f},     /* +3VSEN       */
+       {0x17, 0x70, 0x71},     /* +12VSEN      */
+       {0x18, 0x72, 0x73},     /* 5VDD         */
+       {0x19, 0x74, 0x75},     /* 5VSB         */
+       {0x1a, 0x76, 0x77},     /* VBAT         */
+};
+
+/* Low Bits of Vcore A/B Vtt Read/High/Low */
+static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 };
+static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 };
+
+#define W83793_REG_FAN(index)          (0x23 + 2 * (index))    /* High byte */
+#define W83793_REG_FAN_MIN(index)      (0x90 + 2 * (index))    /* High byte */
+
+#define W83793_REG_PWM_DEFAULT         0xb2
+#define W83793_REG_PWM_ENABLE          0x207
+#define W83793_REG_PWM_UPTIME          0xc3    /* Unit in 0.1 second */
+#define W83793_REG_PWM_DOWNTIME                0xc4    /* Unit in 0.1 second */
+#define W83793_REG_TEMP_CRITICAL       0xc5
+
+#define PWM_DUTY                       0
+#define PWM_START                      1
+#define PWM_NONSTOP                    2
+#define W83793_REG_PWM(index, nr)      (((nr) == 0 ? 0xb3 : \
+                                        (nr) == 1 ? 0x220 : 0x218) + (index))
+
+/* bit field, fan1 is bit0, fan2 is bit1 ... */
+#define W83793_REG_TEMP_FAN_MAP(index) (0x201 + (index))
+#define W83793_REG_TEMP_TOL(index)     (0x208 + (index))
+#define W83793_REG_TEMP_CRUISE(index)  (0x210 + (index))
+#define W83793_REG_PWM_STOP_TIME(index)        (0x228 + (index))
+#define W83793_REG_SF2_TEMP(index, nr) (0x230 + ((index) << 4) + (nr))
+#define W83793_REG_SF2_PWM(index, nr)  (0x238 + ((index) << 4) + (nr))
+
+static inline unsigned long FAN_FROM_REG(u16 val)
+{
+       if ((val >= 0xfff) || (val == 0))
+               return  0;
+       return (1350000UL / val);
+}
+
+static inline u16 FAN_TO_REG(long rpm)
+{
+       if (rpm <= 0)
+               return 0x0fff;
+       return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe);
+}
+
+static inline unsigned long TIME_FROM_REG(u8 reg)
+{
+       return (reg * 100);
+}
+
+static inline u8 TIME_TO_REG(unsigned long val)
+{
+       return SENSORS_LIMIT((val + 50) / 100, 0, 0xff);
+}
+
+static inline long TEMP_FROM_REG(s8 reg)
+{
+       return (reg * 1000);
+}
+
+static inline s8 TEMP_TO_REG(long val, s8 min, s8 max)
+{
+       return SENSORS_LIMIT((val + (val < 0 ? -500 : 500)) / 1000, min, max);
+}
+
+struct w83793_data {
+       struct i2c_client client;
+       struct i2c_client *lm75[2];
+       struct class_device *class_dev;
+       struct mutex update_lock;
+       char valid;                     /* !=0 if following fields are valid */
+       unsigned long last_updated;     /* In jiffies */
+       unsigned long last_nonvolatile; /* In jiffies, last time we update the
+                                          nonvolatile registers */
+
+       u8 bank;
+       u8 vrm;
+       u8 vid[2];
+       u8 in[10][3];           /* Register value, read/high/low */
+       u8 in_low_bits[3];      /* Additional resolution for VCore A/B Vtt */
+
+       u16 has_fan;            /* Only fan1- fan5 has own pins */
+       u16 fan[12];            /* Register value combine */
+       u16 fan_min[12];        /* Register value combine */
+
+       s8 temp[6][5];          /* current, crit, crit_hyst,warn, warn_hyst */
+       u8 temp_low_bits;       /* Additional resolution TD1-TD4 */
+       u8 temp_mode[2];        /* byte 0: Temp D1-D4 mode each has 2 bits
+                                  byte 1: Temp R1,R2 mode, each has 1 bit */
+       u8 temp_critical;       /* If reached all fan will be at full speed */
+       u8 temp_fan_map[6];     /* Temp controls which pwm fan, bit field */
+
+       u8 has_pwm;
+       u8 pwm_enable;          /* Register value, each Temp has 1 bit */
+       u8 pwm_uptime;          /* Register value */
+       u8 pwm_downtime;        /* Register value */
+       u8 pwm_default;         /* All fan default pwm, next poweron valid */
+       u8 pwm[8][3];           /* Register value */
+       u8 pwm_stop_time[8];
+       u8 temp_cruise[6];
+
+       u8 alarms[5];           /* realtime status registers */
+       u8 beeps[5];
+       u8 beep_enable;
+       u8 tolerance[3];        /* Temp tolerance(Smart Fan I/II) */
+       u8 sf2_pwm[6][7];       /* Smart FanII: Fan duty cycle */
+       u8 sf2_temp[6][7];      /* Smart FanII: Temp level point */
+};
+
+static u8 w83793_read_value(struct i2c_client *client, u16 reg);
+static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
+static int w83793_attach_adapter(struct i2c_adapter *adapter);
+static int w83793_detect(struct i2c_adapter *adapter, int address, int kind);
+static int w83793_detach_client(struct i2c_client *client);
+static void w83793_init_client(struct i2c_client *client);
+static void w83793_update_nonvolatile(struct device *dev);
+static struct w83793_data *w83793_update_device(struct device *dev);
+
+static struct i2c_driver w83793_driver = {
+       .driver = {
+                  .name = "w83793",
+       },
+       .attach_adapter = w83793_attach_adapter,
+       .detach_client = w83793_detach_client,
+};
+
+static ssize_t
+show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+
+       return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t
+show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83793_data *data = w83793_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int index = sensor_attr->index;
+
+       return sprintf(buf, "%d\n", vid_from_reg(data->vid[index], data->vrm));
+}
+
+static ssize_t
+store_vrm(struct device *dev, struct device_attribute *attr,
+         const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+
+       data->vrm = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+
+#define ALARM_STATUS                   0
+#define BEEP_ENABLE                    1
+static ssize_t
+show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83793_data *data = w83793_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index >> 3;
+       int bit = sensor_attr->index & 0x07;
+       u8 val;
+
+       if (ALARM_STATUS == nr) {
+               val = (data->alarms[index] >> (bit)) & 1;
+       } else {                /* BEEP_ENABLE */
+               val = (data->beeps[index] >> (bit)) & 1;
+       }
+
+       return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t
+store_beep(struct device *dev, struct device_attribute *attr,
+          const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int index = sensor_attr->index >> 3;
+       int shift = sensor_attr->index & 0x07;
+       u8 beep_bit = 1 << shift;
+       u8 val;
+
+       val = simple_strtoul(buf, NULL, 10);
+       if (val != 0 && val != 1)
+               return -EINVAL;
+
+       mutex_lock(&data->update_lock);
+       data->beeps[index] = w83793_read_value(client, W83793_REG_BEEP(index));
+       data->beeps[index] &= ~beep_bit;
+       data->beeps[index] |= val << shift;
+       w83793_write_value(client, W83793_REG_BEEP(index), data->beeps[index]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t
+show_beep_enable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83793_data *data = w83793_update_device(dev);
+       return sprintf(buf, "%u\n", (data->beep_enable >> 1) & 0x01);
+}
+
+static ssize_t
+store_beep_enable(struct device *dev, struct device_attribute *attr,
+                 const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u8 val = simple_strtoul(buf, NULL, 10);
+
+       if (val != 0 && val != 1)
+               return -EINVAL;
+
+       mutex_lock(&data->update_lock);
+       data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP)
+                           & 0xfd;
+       data->beep_enable |= val << 1;
+       w83793_write_value(client, W83793_REG_OVT_BEEP, data->beep_enable);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+/* Write any value to clear chassis alarm */
+static ssize_t
+store_chassis_clear(struct device *dev,
+                   struct device_attribute *attr, const char *buf,
+                   size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u8 val;
+
+       mutex_lock(&data->update_lock);
+       val = w83793_read_value(client, W83793_REG_CLR_CHASSIS);
+       val |= 0x80;
+       w83793_write_value(client, W83793_REG_CLR_CHASSIS, val);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+#define FAN_INPUT                      0
+#define FAN_MIN                                1
+static ssize_t
+show_fan(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+       u16 val;
+
+       if (FAN_INPUT == nr) {
+               val = data->fan[index] & 0x0fff;
+       } else {
+               val = data->fan_min[index] & 0x0fff;
+       }
+
+       return sprintf(buf, "%lu\n", FAN_FROM_REG(val));
+}
+
+static ssize_t
+store_fan_min(struct device *dev, struct device_attribute *attr,
+             const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int index = sensor_attr->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10));
+
+       mutex_lock(&data->update_lock);
+       data->fan_min[index] = val;
+       w83793_write_value(client, W83793_REG_FAN_MIN(index),
+                          (val >> 8) & 0xff);
+       w83793_write_value(client, W83793_REG_FAN_MIN(index) + 1, val & 0xff);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+#define PWM_DUTY                       0
+#define PWM_START                      1
+#define PWM_NONSTOP                    2
+#define PWM_STOP_TIME                  3
+static ssize_t
+show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       struct w83793_data *data = w83793_update_device(dev);
+       u16 val;
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+
+       if (PWM_STOP_TIME == nr)
+               val = TIME_FROM_REG(data->pwm_stop_time[index]);
+       else
+               val = (data->pwm[index][nr] & 0x3f) << 2;
+
+       return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_pwm(struct device *dev, struct device_attribute *attr,
+         const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       u8 val;
+
+       mutex_lock(&data->update_lock);
+       if (PWM_STOP_TIME == nr) {
+               val = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+               data->pwm_stop_time[index] = val;
+               w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index),
+                                  val);
+       } else {
+               val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff)
+                     >> 2;
+               data->pwm[index][nr] =
+                   w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0;
+               data->pwm[index][nr] |= val;
+               w83793_write_value(client, W83793_REG_PWM(index, nr),
+                                                       data->pwm[index][nr]);
+       }
+
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+       long temp = TEMP_FROM_REG(data->temp[index][nr]);
+
+       if (TEMP_READ == nr && index < 4) {     /* Only TD1-TD4 have low bits */
+               int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250;
+               temp += temp > 0 ? low : -low;
+       }
+       return sprintf(buf, "%ld\n", temp);
+}
+
+static ssize_t
+store_temp(struct device *dev, struct device_attribute *attr,
+          const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       long tmp = simple_strtol(buf, NULL, 10);
+
+       mutex_lock(&data->update_lock);
+       data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127);
+       w83793_write_value(client, W83793_REG_TEMP[index][nr],
+                          data->temp[index][nr]);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/*
+       TD1-TD4
+       each has 4 mode:(2 bits)
+       0:      Stop monitor
+       1:      Use internal temp sensor(default)
+       2:      Use sensor in AMD CPU and get result by AMDSI
+       3:      Use sensor in Intel CPU and get result by PECI
+
+       TR1-TR2
+       each has 2 mode:(1 bit)
+       0:      Disable temp sensor monitor
+       1:      To enable temp sensors monitor
+*/
+
+/* 0 disable, 5 AMDSI, 6 PECI */
+static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 };
+
+static ssize_t
+show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct w83793_data *data = w83793_update_device(dev);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int index = sensor_attr->index;
+       u8 mask = (index < 4) ? 0x03 : 0x01;
+       u8 shift = (index < 4) ? (2 * index) : (index - 4);
+       u8 tmp;
+       index = (index < 4) ? 0 : 1;
+
+       tmp = (data->temp_mode[index] >> shift) & mask;
+
+       /* for the internal sensor, found out if diode or thermistor */
+       if (tmp == 1) {
+               tmp = index == 0 ? 3 : 4;
+       } else {
+               tmp = TO_TEMP_MODE[tmp];
+       }
+
+       return sprintf(buf, "%d\n", tmp);
+}
+
+static ssize_t
+store_temp_mode(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int index = sensor_attr->index;
+       u8 mask = (index < 4) ? 0x03 : 0x01;
+       u8 shift = (index < 4) ? (2 * index) : (index - 4);
+       u8 val = simple_strtoul(buf, NULL, 10);
+
+       /* transform the sysfs interface values into table above */
+       if ((val == 5 || val == 6) && (index < 4)) {
+               val -= 3;
+       } else if ((val == 3 && index < 4)
+               || (val == 4 && index >= 4)
+               || val == 0) {
+               /* transform diode or thermistor into internal enable */
+               val = !!val;
+       } else {
+               return -EINVAL;
+       }
+
+       index = (index < 4) ? 0 : 1;
+       mutex_lock(&data->update_lock);
+       data->temp_mode[index] =
+           w83793_read_value(client, W83793_REG_TEMP_MODE[index]);
+       data->temp_mode[index] &= ~(mask << shift);
+       data->temp_mode[index] |= val << shift;
+       w83793_write_value(client, W83793_REG_TEMP_MODE[index],
+                                                       data->temp_mode[index]);
+       mutex_unlock(&data->update_lock);
+
+       return count;
+}
+
+#define SETUP_PWM_DEFAULT              0
+#define SETUP_PWM_UPTIME               1       /* Unit in 0.1s */
+#define SETUP_PWM_DOWNTIME             2       /* Unit in 0.1s */
+#define SETUP_TEMP_CRITICAL            3
+static ssize_t
+show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       struct w83793_data *data = w83793_update_device(dev);
+       u32 val = 0;
+
+       if (SETUP_PWM_DEFAULT == nr) {
+               val = (data->pwm_default & 0x3f) << 2;
+       } else if (SETUP_PWM_UPTIME == nr) {
+               val = TIME_FROM_REG(data->pwm_uptime);
+       } else if (SETUP_PWM_DOWNTIME == nr) {
+               val = TIME_FROM_REG(data->pwm_downtime);
+       } else if (SETUP_TEMP_CRITICAL == nr) {
+               val = TEMP_FROM_REG(data->temp_critical & 0x7f);
+       }
+
+       return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_sf_setup(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+
+       mutex_lock(&data->update_lock);
+       if (SETUP_PWM_DEFAULT == nr) {
+               data->pwm_default =
+                   w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0;
+               data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL,
+                                                                 10),
+                                                  0, 0xff) >> 2;
+               w83793_write_value(client, W83793_REG_PWM_DEFAULT,
+                                                       data->pwm_default);
+       } else if (SETUP_PWM_UPTIME == nr) {
+               data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+               data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0;
+               w83793_write_value(client, W83793_REG_PWM_UPTIME,
+                                                       data->pwm_uptime);
+       } else if (SETUP_PWM_DOWNTIME == nr) {
+               data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+               data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0;
+               w83793_write_value(client, W83793_REG_PWM_DOWNTIME,
+                                                       data->pwm_downtime);
+       } else {                /* SETUP_TEMP_CRITICAL */
+               data->temp_critical =
+                   w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80;
+               data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10),
+                                                  0, 0x7f);
+               w83793_write_value(client, W83793_REG_TEMP_CRITICAL,
+                                                       data->temp_critical);
+       }
+
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/*
+       Temp SmartFan control
+       TEMP_FAN_MAP
+       Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1...
+       It's possible two or more temp channels control the same fan, w83793
+       always prefers to pick the most critical request and applies it to
+       the related Fan.
+       It's possible one fan is not in any mapping of 6 temp channels, this
+       means the fan is manual mode
+
+       TEMP_PWM_ENABLE
+       Each temp channel has its own SmartFan mode, and temp channel
+       control fans that are set by TEMP_FAN_MAP
+       0:      SmartFanII mode
+       1:      Thermal Cruise Mode
+
+       TEMP_CRUISE
+       Target temperature in thermal cruise mode, w83793 will try to turn
+       fan speed to keep the temperature of target device around this
+       temperature.
+
+       TEMP_TOLERANCE
+       If Temp higher or lower than target with this tolerance, w83793
+       will take actions to speed up or slow down the fan to keep the
+       temperature within the tolerance range.
+*/
+
+#define TEMP_FAN_MAP                   0
+#define TEMP_PWM_ENABLE                        1
+#define TEMP_CRUISE                    2
+#define TEMP_TOLERANCE                 3
+static ssize_t
+show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+       u32 val;
+
+       if (TEMP_FAN_MAP == nr) {
+               val = data->temp_fan_map[index];
+       } else if (TEMP_PWM_ENABLE == nr) {
+               /* +2 to transfrom into 2 and 3 to conform with sysfs intf */
+               val = ((data->pwm_enable >> index) & 0x01) + 2;
+       } else if (TEMP_CRUISE == nr) {
+               val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f);
+       } else {                /* TEMP_TOLERANCE */
+               val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0);
+               val = TEMP_FROM_REG(val & 0x0f);
+       }
+       return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t
+store_sf_ctrl(struct device *dev, struct device_attribute *attr,
+             const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u32 val;
+
+       mutex_lock(&data->update_lock);
+       if (TEMP_FAN_MAP == nr) {
+               val = simple_strtoul(buf, NULL, 10) & 0xff;
+               w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val);
+               data->temp_fan_map[index] = val;
+       } else if (TEMP_PWM_ENABLE == nr) {
+               val = simple_strtoul(buf, NULL, 10);
+               if (2 == val || 3 == val) {
+                       data->pwm_enable =
+                           w83793_read_value(client, W83793_REG_PWM_ENABLE);
+                       if (val - 2)
+                               data->pwm_enable |= 1 << index;
+                       else
+                               data->pwm_enable &= ~(1 << index);
+                       w83793_write_value(client, W83793_REG_PWM_ENABLE,
+                                                       data->pwm_enable);
+               } else {
+                       mutex_unlock(&data->update_lock);
+                       return -EINVAL;
+               }
+       } else if (TEMP_CRUISE == nr) {
+               data->temp_cruise[index] =
+                   w83793_read_value(client, W83793_REG_TEMP_CRUISE(index));
+               val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
+               data->temp_cruise[index] &= 0x80;
+               data->temp_cruise[index] |= val;
+
+               w83793_write_value(client, W83793_REG_TEMP_CRUISE(index),
+                                               data->temp_cruise[index]);
+       } else {                /* TEMP_TOLERANCE */
+               int i = index >> 1;
+               u8 shift = (index & 0x01) ? 4 : 0;
+               data->tolerance[i] =
+                   w83793_read_value(client, W83793_REG_TEMP_TOL(i));
+
+               val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f);
+               data->tolerance[i] &= ~(0x0f << shift);
+               data->tolerance[i] |= val << shift;
+               w83793_write_value(client, W83793_REG_TEMP_TOL(i),
+                                                       data->tolerance[i]);
+       }
+
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+show_sf2_pwm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+
+       return sprintf(buf, "%d\n", (data->sf2_pwm[index][nr] & 0x3f) << 2);
+}
+
+static ssize_t
+store_sf2_pwm(struct device *dev, struct device_attribute *attr,
+             const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2;
+
+       mutex_lock(&data->update_lock);
+       data->sf2_pwm[index][nr] =
+           w83793_read_value(client, W83793_REG_SF2_PWM(index, nr)) & 0xc0;
+       data->sf2_pwm[index][nr] |= val;
+       w83793_write_value(client, W83793_REG_SF2_PWM(index, nr),
+                                               data->sf2_pwm[index][nr]);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t
+show_sf2_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+
+       return sprintf(buf, "%ld\n",
+                      TEMP_FROM_REG(data->sf2_temp[index][nr] & 0x7f));
+}
+
+static ssize_t
+store_sf2_temp(struct device *dev, struct device_attribute *attr,
+              const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
+
+       mutex_lock(&data->update_lock);
+       data->sf2_temp[index][nr] =
+           w83793_read_value(client, W83793_REG_SF2_TEMP(index, nr)) & 0x80;
+       data->sf2_temp[index][nr] |= val;
+       w83793_write_value(client, W83793_REG_SF2_TEMP(index, nr),
+                                            data->sf2_temp[index][nr]);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+/* only Vcore A/B and Vtt have additional 2 bits precision */
+static ssize_t
+show_in(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct w83793_data *data = w83793_update_device(dev);
+       u16 val = data->in[index][nr];
+
+       if (index < 3) {
+               val <<= 2;
+               val += (data->in_low_bits[nr] >> (index * 2)) & 0x3;
+       }
+       return sprintf(buf, "%d\n", val * scale_in[index]);
+}
+
+static ssize_t
+store_in(struct device *dev, struct device_attribute *attr,
+        const char *buf, size_t count)
+{
+       struct sensor_device_attribute_2 *sensor_attr =
+           to_sensor_dev_attr_2(attr);
+       int nr = sensor_attr->nr;
+       int index = sensor_attr->index;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u32 val;
+
+       val =
+           (simple_strtoul(buf, NULL, 10) +
+            scale_in[index] / 2) / scale_in[index];
+       mutex_lock(&data->update_lock);
+       if (index > 2) {
+               val = SENSORS_LIMIT(val, 0, 255);
+       } else {
+               val = SENSORS_LIMIT(val, 0, 0x3FF);
+               data->in_low_bits[nr] =
+                   w83793_read_value(client, W83793_REG_IN_LOW_BITS[nr]);
+               data->in_low_bits[nr] &= ~(0x03 << (2 * index));
+               data->in_low_bits[nr] |= (val & 0x03) << (2 * index);
+               w83793_write_value(client, W83793_REG_IN_LOW_BITS[nr],
+                                                    data->in_low_bits[nr]);
+               val >>= 2;
+       }
+       data->in[index][nr] = val;
+       w83793_write_value(client, W83793_REG_IN[index][nr],
+                                                       data->in[index][nr]);
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+#define NOT_USED                       -1
+
+#define SENSOR_ATTR_IN(index)                                          \
+       SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL,        \
+               IN_READ, index),                                        \
+       SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in,      \
+               store_in, IN_MAX, index),                               \
+       SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in,      \
+               store_in, IN_LOW, index),                               \
+       SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep,      \
+               NULL, ALARM_STATUS, index + ((index > 2) ? 1 : 0)),     \
+       SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO,              \
+               show_alarm_beep, store_beep, BEEP_ENABLE,               \
+               index + ((index > 2) ? 1 : 0))
+
+#define SENSOR_ATTR_FAN(index)                                         \
+       SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep,     \
+               NULL, ALARM_STATUS, index + 17),                        \
+       SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO,             \
+               show_alarm_beep, store_beep, BEEP_ENABLE, index + 17),  \
+       SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan,            \
+               NULL, FAN_INPUT, index - 1),                            \
+       SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO,              \
+               show_fan, store_fan_min, FAN_MIN, index - 1)
+
+#define SENSOR_ATTR_PWM(index)                                         \
+       SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm,          \
+               store_pwm, PWM_DUTY, index - 1),                        \
+       SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO,          \
+               show_pwm, store_pwm, PWM_NONSTOP, index - 1),           \
+       SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO,            \
+               show_pwm, store_pwm, PWM_START, index - 1),             \
+       SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO,        \
+               show_pwm, store_pwm, PWM_STOP_TIME, index - 1)
+
+#define SENSOR_ATTR_TEMP(index)                                                \
+       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | S_IWUSR,            \
+               show_temp_mode, store_temp_mode, NOT_USED, index - 1),  \
+       SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp,          \
+               NULL, TEMP_READ, index - 1),                            \
+       SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp,  \
+               store_temp, TEMP_CRIT, index - 1),                      \
+       SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR,        \
+               show_temp, store_temp, TEMP_CRIT_HYST, index - 1),      \
+       SENSOR_ATTR_2(temp##index##_warn, S_IRUGO | S_IWUSR, show_temp, \
+               store_temp, TEMP_WARN, index - 1),                      \
+       SENSOR_ATTR_2(temp##index##_warn_hyst, S_IRUGO | S_IWUSR,       \
+               show_temp, store_temp, TEMP_WARN_HYST, index - 1),      \
+       SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO,                     \
+               show_alarm_beep, NULL, ALARM_STATUS, index + 11),       \
+       SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,            \
+               show_alarm_beep, store_beep, BEEP_ENABLE, index + 11),  \
+       SENSOR_ATTR_2(temp##index##_auto_channels_pwm,                  \
+               S_IRUGO | S_IWUSR, show_sf_ctrl, store_sf_ctrl,         \
+               TEMP_FAN_MAP, index - 1),                               \
+       SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO,      \
+               show_sf_ctrl, store_sf_ctrl, TEMP_PWM_ENABLE,           \
+               index - 1),                                             \
+       SENSOR_ATTR_2(thermal_cruise##index, S_IRUGO | S_IWUSR,         \
+               show_sf_ctrl, store_sf_ctrl, TEMP_CRUISE, index - 1),   \
+       SENSOR_ATTR_2(tolerance##index, S_IRUGO | S_IWUSR, show_sf_ctrl,\
+               store_sf_ctrl, TEMP_TOLERANCE, index - 1),              \
+       SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 0, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 1, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 2, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 3, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 4, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 5, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \
+               show_sf2_pwm, store_sf2_pwm, 6, index - 1),             \
+       SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 0, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 1, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 2, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 3, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 4, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 5, index - 1),           \
+       SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\
+               show_sf2_temp, store_sf2_temp, 6, index - 1)
+
+static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = {
+       SENSOR_ATTR_IN(0),
+       SENSOR_ATTR_IN(1),
+       SENSOR_ATTR_IN(2),
+       SENSOR_ATTR_IN(3),
+       SENSOR_ATTR_IN(4),
+       SENSOR_ATTR_IN(5),
+       SENSOR_ATTR_IN(6),
+       SENSOR_ATTR_IN(7),
+       SENSOR_ATTR_IN(8),
+       SENSOR_ATTR_IN(9),
+       SENSOR_ATTR_TEMP(1),
+       SENSOR_ATTR_TEMP(2),
+       SENSOR_ATTR_TEMP(3),
+       SENSOR_ATTR_TEMP(4),
+       SENSOR_ATTR_TEMP(5),
+       SENSOR_ATTR_TEMP(6),
+       SENSOR_ATTR_FAN(1),
+       SENSOR_ATTR_FAN(2),
+       SENSOR_ATTR_FAN(3),
+       SENSOR_ATTR_FAN(4),
+       SENSOR_ATTR_FAN(5),
+       SENSOR_ATTR_PWM(1),
+       SENSOR_ATTR_PWM(2),
+       SENSOR_ATTR_PWM(3),
+};
+
+/* Fan6-Fan12 */
+static struct sensor_device_attribute_2 w83793_left_fan[] = {
+       SENSOR_ATTR_FAN(6),
+       SENSOR_ATTR_FAN(7),
+       SENSOR_ATTR_FAN(8),
+       SENSOR_ATTR_FAN(9),
+       SENSOR_ATTR_FAN(10),
+       SENSOR_ATTR_FAN(11),
+       SENSOR_ATTR_FAN(12),
+};
+
+/* Pwm4-Pwm8 */
+static struct sensor_device_attribute_2 w83793_left_pwm[] = {
+       SENSOR_ATTR_PWM(4),
+       SENSOR_ATTR_PWM(5),
+       SENSOR_ATTR_PWM(6),
+       SENSOR_ATTR_PWM(7),
+       SENSOR_ATTR_PWM(8),
+};
+
+static struct sensor_device_attribute_2 sda_single_files[] = {
+       SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0),
+       SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1),
+       SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm,
+                     NOT_USED, NOT_USED),
+       SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
+                     store_chassis_clear, ALARM_STATUS, 30),
+       SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
+                     store_beep_enable, NOT_USED, NOT_USED),
+       SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup,
+                     store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED),
+       SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup,
+                     store_sf_setup, SETUP_PWM_UPTIME, NOT_USED),
+       SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup,
+                     store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED),
+       SENSOR_ATTR_2(temp_critical, S_IWUSR | S_IRUGO, show_sf_setup,
+                     store_sf_setup, SETUP_TEMP_CRITICAL, NOT_USED),
+};
+
+static void w83793_init_client(struct i2c_client *client)
+{
+       if (reset) {
+               w83793_write_value(client, W83793_REG_CONFIG, 0x80);
+       }
+
+       /* Start monitoring */
+       w83793_write_value(client, W83793_REG_CONFIG,
+                          w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
+
+}
+
+static int w83793_attach_adapter(struct i2c_adapter *adapter)
+{
+       if (!(adapter->class & I2C_CLASS_HWMON))
+               return 0;
+       return i2c_probe(adapter, &addr_data, w83793_detect);
+}
+
+static int w83793_detach_client(struct i2c_client *client)
+{
+       struct w83793_data *data = i2c_get_clientdata(client);
+       struct device *dev = &client->dev;
+       int err, i;
+
+       /* main client */
+       if (data) {
+               hwmon_device_unregister(data->class_dev);
+
+               for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
+                       device_remove_file(dev,
+                                          &w83793_sensor_attr_2[i].dev_attr);
+
+               for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
+                       device_remove_file(dev, &sda_single_files[i].dev_attr);
+
+               for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
+                       device_remove_file(dev, &w83793_left_fan[i].dev_attr);
+
+               for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
+                       device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
+       }
+
+       if ((err = i2c_detach_client(client)))
+               return err;
+
+       /* main client */
+       if (data)
+               kfree(data);
+       /* subclient */
+       else
+               kfree(client);
+
+       return 0;
+}
+
+static int
+w83793_create_subclient(struct i2c_adapter *adapter,
+                       struct i2c_client *client, int addr,
+                       struct i2c_client **sub_cli)
+{
+       int err = 0;
+       struct i2c_client *sub_client;
+
+       (*sub_cli) = sub_client =
+           kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+       if (!(sub_client)) {
+               return -ENOMEM;
+       }
+       sub_client->addr = 0x48 + addr;
+       i2c_set_clientdata(sub_client, NULL);
+       sub_client->adapter = adapter;
+       sub_client->driver = &w83793_driver;
+       strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE);
+       if ((err = i2c_attach_client(sub_client))) {
+               dev_err(&client->dev, "subclient registration "
+                       "at address 0x%x failed\n", sub_client->addr);
+               kfree(sub_client);
+       }
+       return err;
+}
+
+static int
+w83793_detect_subclients(struct i2c_adapter *adapter, int address,
+                        int kind, struct i2c_client *client)
+{
+       int i, id, err;
+       u8 tmp;
+       struct w83793_data *data = i2c_get_clientdata(client);
+
+       id = i2c_adapter_id(adapter);
+       if (force_subclients[0] == id && force_subclients[1] == address) {
+               for (i = 2; i <= 3; i++) {
+                       if (force_subclients[i] < 0x48
+                           || force_subclients[i] > 0x4f) {
+                               dev_err(&client->dev,
+                                       "invalid subclient "
+                                       "address %d; must be 0x48-0x4f\n",
+                                       force_subclients[i]);
+                               err = -EINVAL;
+                               goto ERROR_SC_0;
+                       }
+               }
+               w83793_write_value(client, W83793_REG_I2C_SUBADDR,
+                                  (force_subclients[2] & 0x07) |
+                                  ((force_subclients[3] & 0x07) << 4));
+       }
+
+       tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR);
+       if (!(tmp & 0x08)) {
+               err =
+                   w83793_create_subclient(adapter, client, tmp & 0x7,
+                                           &data->lm75[0]);
+               if (err < 0)
+                       goto ERROR_SC_0;
+       }
+       if (!(tmp & 0x80)) {
+               if ((data->lm75[0] != NULL)
+                   && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) {
+                       dev_err(&client->dev,
+                               "duplicate addresses 0x%x, "
+                               "use force_subclients\n", data->lm75[0]->addr);
+                       err = -ENODEV;
+                       goto ERROR_SC_1;
+               }
+               err = w83793_create_subclient(adapter, client,
+                                             (tmp >> 4) & 0x7, &data->lm75[1]);
+               if (err < 0)
+                       goto ERROR_SC_1;
+       }
+
+       return 0;
+
+       /* Undo inits in case of errors */
+
+ERROR_SC_1:
+       if (data->lm75[0] != NULL) {
+               i2c_detach_client(data->lm75[0]);
+               kfree(data->lm75[0]);
+       }
+ERROR_SC_0:
+       return err;
+}
+
+static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+       int i;
+       u8 tmp, val;
+       struct i2c_client *client;
+       struct device *dev;
+       struct w83793_data *data;
+       int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
+       int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5;
+       int err = 0;
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+               goto exit;
+       }
+
+       /* OK. For now, we presume we have a valid client. We now create the
+          client structure, even though we cannot fill it completely yet.
+          But it allows us to access w83793_{read,write}_value. */
+
+       if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       client = &data->client;
+       dev = &client->dev;
+       i2c_set_clientdata(client, data);
+       client->addr = address;
+       client->adapter = adapter;
+       client->driver = &w83793_driver;
+
+       data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
+
+       /* Now, we do the remaining detection. */
+       if (kind < 0) {
+               tmp = data->bank & 0x80 ? 0x5c : 0xa3;
+               /* Check Winbond vendor ID */
+               if (tmp != i2c_smbus_read_byte_data(client,
+                                                       W83793_REG_VENDORID)) {
+                       pr_debug("w83793: Detection failed at check "
+                                "vendor id\n");
+                       err = -ENODEV;
+                       goto free_mem;
+               }
+
+               /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
+                  should match */
+               if ((data->bank & 0x07) == 0
+                && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
+                   (address << 1)) {
+                       pr_debug("w83793: Detection failed at check "
+                                "i2c addr\n");
+                       err = -ENODEV;
+                       goto free_mem;
+               }
+
+       }
+
+       /* We have either had a force parameter, or we have already detected the
+          Winbond. Determine the chip type now */
+
+       if (kind <= 0) {
+               if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) {
+                       kind = w83793;
+               } else {
+                       if (kind == 0)
+                               dev_warn(&adapter->dev, "w83793: Ignoring "
+                                        "'force' parameter for unknown chip "
+                                        "at address 0x%02x\n", address);
+                       err = -ENODEV;
+                       goto free_mem;
+               }
+       }
+
+       /* Fill in the remaining client fields and put into the global list */
+       strlcpy(client->name, "w83793", I2C_NAME_SIZE);
+
+       mutex_init(&data->update_lock);
+
+       /* Tell the I2C layer a new client has arrived */
+       if ((err = i2c_attach_client(client)))
+               goto free_mem;
+
+       if ((err = w83793_detect_subclients(adapter, address, kind, client)))
+               goto detach_client;
+
+       /* Initialize the chip */
+       w83793_init_client(client);
+
+       data->vrm = vid_which_vrm();
+       /*
+          Only fan 1-5 has their own input pins,
+          Pwm 1-3 has their own pins
+        */
+       data->has_fan = 0x1f;
+       data->has_pwm = 0x07;
+       tmp = w83793_read_value(client, W83793_REG_MFC);
+       val = w83793_read_value(client, W83793_REG_FANIN_CTRL);
+
+       /* check the function of pins 49-56 */
+       if (!(tmp & 0x80)) {
+               data->has_pwm |= 0x18;  /* pwm 4,5 */
+               if (val & 0x01) {       /* fan 6 */
+                       data->has_fan |= 0x20;
+                       data->has_pwm |= 0x20;
+               }
+               if (val & 0x02) {       /* fan 7 */
+                       data->has_fan |= 0x40;
+                       data->has_pwm |= 0x40;
+               }
+               if (!(tmp & 0x40) && (val & 0x04)) {    /* fan 8 */
+                       data->has_fan |= 0x80;
+                       data->has_pwm |= 0x80;
+               }
+       }
+
+       if (0x08 == (tmp & 0x0c)) {
+               if (val & 0x08) /* fan 9 */
+                       data->has_fan |= 0x100;
+               if (val & 0x10) /* fan 10 */
+                       data->has_fan |= 0x200;
+       }
+
+       if (0x20 == (tmp & 0x30)) {
+               if (val & 0x20) /* fan 11 */
+                       data->has_fan |= 0x400;
+               if (val & 0x40) /* fan 12 */
+                       data->has_fan |= 0x800;
+       }
+
+       if ((tmp & 0x01) && (val & 0x04)) {     /* fan 8, second location */
+               data->has_fan |= 0x80;
+               data->has_pwm |= 0x80;
+       }
+
+       /* Register sysfs hooks */
+       for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) {
+               err = device_create_file(dev,
+                                        &w83793_sensor_attr_2[i].dev_attr);
+               if (err)
+                       goto exit_remove;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
+               err = device_create_file(dev, &sda_single_files[i].dev_attr);
+               if (err)
+                       goto exit_remove;
+
+       }
+
+       for (i = 5; i < 12; i++) {
+               int j;
+               if (!(data->has_fan & (1 << i)))
+                       continue;
+               for (j = 0; j < files_fan; j++) {
+                       err = device_create_file(dev,
+                                          &w83793_left_fan[(i - 5) * files_fan
+                                                               + j].dev_attr);
+                       if (err)
+                               goto exit_remove;
+               }
+       }
+
+       for (i = 3; i < 8; i++) {
+               int j;
+               if (!(data->has_pwm & (1 << i)))
+                       continue;
+               for (j = 0; j < files_pwm; j++) {
+                       err = device_create_file(dev,
+                                          &w83793_left_pwm[(i - 3) * files_pwm
+                                                               + j].dev_attr);
+                       if (err)
+                               goto exit_remove;
+               }
+       }
+
+       data->class_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto exit_remove;
+       }
+
+       return 0;
+
+       /* Unregister sysfs hooks */
+
+exit_remove:
+       for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
+               device_remove_file(dev, &w83793_sensor_attr_2[i].dev_attr);
+
+       for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
+               device_remove_file(dev, &sda_single_files[i].dev_attr);
+
+       for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
+               device_remove_file(dev, &w83793_left_fan[i].dev_attr);
+
+       for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
+               device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
+
+       if (data->lm75[0] != NULL) {
+               i2c_detach_client(data->lm75[0]);
+               kfree(data->lm75[0]);
+       }
+       if (data->lm75[1] != NULL) {
+               i2c_detach_client(data->lm75[1]);
+               kfree(data->lm75[1]);
+       }
+detach_client:
+       i2c_detach_client(client);
+free_mem:
+       kfree(data);
+exit:
+       return err;
+}
+
+static void w83793_update_nonvolatile(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       int i, j;
+       /*
+          They are somewhat "stable" registers, and to update them everytime
+          takes so much time, it's just not worthy. Update them in a long
+          interval to avoid exception.
+        */
+       if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300)
+             || !data->valid))
+               return;
+       /* update voltage limits */
+       for (i = 1; i < 3; i++) {
+               for (j = 0; j < ARRAY_SIZE(data->in); j++) {
+                       data->in[j][i] =
+                           w83793_read_value(client, W83793_REG_IN[j][i]);
+               }
+               data->in_low_bits[i] =
+                   w83793_read_value(client, W83793_REG_IN_LOW_BITS[i]);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
+               /* Update the Fan measured value and limits */
+               if (!(data->has_fan & (1 << i))) {
+                       continue;
+               }
+               data->fan_min[i] =
+                   w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8;
+               data->fan_min[i] |=
+                   w83793_read_value(client, W83793_REG_FAN_MIN(i) + 1);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) {
+               data->temp_fan_map[i] =
+                   w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i));
+               for (j = 1; j < 5; j++) {
+                       data->temp[i][j] =
+                           w83793_read_value(client, W83793_REG_TEMP[i][j]);
+               }
+               data->temp_cruise[i] =
+                   w83793_read_value(client, W83793_REG_TEMP_CRUISE(i));
+               for (j = 0; j < 7; j++) {
+                       data->sf2_pwm[i][j] =
+                           w83793_read_value(client, W83793_REG_SF2_PWM(i, j));
+                       data->sf2_temp[i][j] =
+                           w83793_read_value(client,
+                                             W83793_REG_SF2_TEMP(i, j));
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->temp_mode); i++)
+               data->temp_mode[i] =
+                   w83793_read_value(client, W83793_REG_TEMP_MODE[i]);
+
+       for (i = 0; i < ARRAY_SIZE(data->tolerance); i++) {
+               data->tolerance[i] =
+                   w83793_read_value(client, W83793_REG_TEMP_TOL(i));
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->pwm); i++) {
+               if (!(data->has_pwm & (1 << i)))
+                       continue;
+               data->pwm[i][PWM_NONSTOP] =
+                   w83793_read_value(client, W83793_REG_PWM(i, PWM_NONSTOP));
+               data->pwm[i][PWM_START] =
+                   w83793_read_value(client, W83793_REG_PWM(i, PWM_START));
+               data->pwm_stop_time[i] =
+                   w83793_read_value(client, W83793_REG_PWM_STOP_TIME(i));
+       }
+
+       data->pwm_default = w83793_read_value(client, W83793_REG_PWM_DEFAULT);
+       data->pwm_enable = w83793_read_value(client, W83793_REG_PWM_ENABLE);
+       data->pwm_uptime = w83793_read_value(client, W83793_REG_PWM_UPTIME);
+       data->pwm_downtime = w83793_read_value(client, W83793_REG_PWM_DOWNTIME);
+       data->temp_critical =
+           w83793_read_value(client, W83793_REG_TEMP_CRITICAL);
+       data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP);
+
+       for (i = 0; i < ARRAY_SIZE(data->beeps); i++) {
+               data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i));
+       }
+
+       data->last_nonvolatile = jiffies;
+}
+
+static struct w83793_data *w83793_update_device(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct w83793_data *data = i2c_get_clientdata(client);
+       int i;
+
+       mutex_lock(&data->update_lock);
+
+       if (!(time_after(jiffies, data->last_updated + HZ * 2)
+             || !data->valid))
+               goto END;
+
+       /* Update the voltages measured value and limits */
+       for (i = 0; i < ARRAY_SIZE(data->in); i++)
+               data->in[i][IN_READ] =
+                   w83793_read_value(client, W83793_REG_IN[i][IN_READ]);
+
+       data->in_low_bits[IN_READ] =
+           w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]);
+
+       for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
+               if (!(data->has_fan & (1 << i))) {
+                       continue;
+               }
+               data->fan[i] =
+                   w83793_read_value(client, W83793_REG_FAN(i)) << 8;
+               data->fan[i] |=
+                   w83793_read_value(client, W83793_REG_FAN(i) + 1);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+               data->temp[i][TEMP_READ] =
+                   w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]);
+
+       data->temp_low_bits =
+           w83793_read_value(client, W83793_REG_TEMP_LOW_BITS);
+
+       for (i = 0; i < ARRAY_SIZE(data->pwm); i++) {
+               if (data->has_pwm & (1 << i))
+                       data->pwm[i][PWM_DUTY] =
+                           w83793_read_value(client,
+                                             W83793_REG_PWM(i, PWM_DUTY));
+       }
+
+       for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
+               data->alarms[i] =
+                   w83793_read_value(client, W83793_REG_ALARM(i));
+       data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
+       data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
+       w83793_update_nonvolatile(dev);
+       data->last_updated = jiffies;
+       data->valid = 1;
+
+END:
+       mutex_unlock(&data->update_lock);
+       return data;
+}
+
+/* Ignore the possibility that somebody change bank outside the driver
+   Must be called with data->update_lock held, except during initialization */
+static u8 w83793_read_value(struct i2c_client *client, u16 reg)
+{
+       struct w83793_data *data = i2c_get_clientdata(client);
+       u8 res = 0xff;
+       u8 new_bank = reg >> 8;
+
+       new_bank |= data->bank & 0xfc;
+       if (data->bank != new_bank) {
+               if (i2c_smbus_write_byte_data
+                   (client, W83793_REG_BANKSEL, new_bank) >= 0)
+                       data->bank = new_bank;
+               else {
+                       dev_err(&client->dev,
+                               "set bank to %d failed, fall back "
+                               "to bank %d, read reg 0x%x error\n",
+                               new_bank, data->bank, reg);
+                       res = 0x0;      /* read 0x0 from the chip */
+                       goto END;
+               }
+       }
+       res = i2c_smbus_read_byte_data(client, reg & 0xff);
+END:
+       return res;
+}
+
+/* Must be called with data->update_lock held, except during initialization */
+static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value)
+{
+       struct w83793_data *data = i2c_get_clientdata(client);
+       int res;
+       u8 new_bank = reg >> 8;
+
+       new_bank |= data->bank & 0xfc;
+       if (data->bank != new_bank) {
+               if ((res = i2c_smbus_write_byte_data
+                   (client, W83793_REG_BANKSEL, new_bank)) >= 0)
+                       data->bank = new_bank;
+               else {
+                       dev_err(&client->dev,
+                               "set bank to %d failed, fall back "
+                               "to bank %d, write reg 0x%x error\n",
+                               new_bank, data->bank, reg);
+                       goto END;
+               }
+       }
+
+       res = i2c_smbus_write_byte_data(client, reg & 0xff, value);
+END:
+       return res;
+}
+
+static int __init sensors_w83793_init(void)
+{
+       return i2c_add_driver(&w83793_driver);
+}
+
+static void __exit sensors_w83793_exit(void)
+{
+       i2c_del_driver(&w83793_driver);
+}
+
+MODULE_AUTHOR("Yuan Mu");
+MODULE_DESCRIPTION("w83793 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83793_init);
+module_exit(sensors_w83793_exit);
index 33fbb47100a36d02a45492cc8233301d66c4b7c1..8e1e3f8e40a41faff644d63072271edf409dba25 100644 (file)
@@ -2,7 +2,7 @@
  *     i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge
  *
  *     Copyright (C) 2004 Patrick Mochel
- *                   2005 Rudolf Marek <r.marek@sh.cvut.cz>
+ *                   2005 Rudolf Marek <r.marek@assembler.cz>
  *
  *     The 1563 southbridge is deceptively similar to the 1533, with a
  *     few notable exceptions. One of those happens to be the fact they
index 60bef94cd25f795892f0392f6d3493f86a3fa257..4ee56def61f277cd019001dd9ffb434053f59f38 100644 (file)
@@ -82,7 +82,7 @@ struct tps65010 {
        struct i2c_client       client;
        struct mutex            lock;
        int                     irq;
-       struct work_struct      work;
+       struct delayed_work     work;
        struct dentry           *file;
        unsigned                charging:1;
        unsigned                por:1;
@@ -328,7 +328,7 @@ static void tps65010_interrupt(struct tps65010 *tps)
 {
        u8 tmp = 0, mask, poll;
 
-       /* IRQs won't trigger irqs for certain events, but we can get
+       /* IRQs won't trigger for certain events, but we can get
         * others by polling (normally, with external power applied).
         */
        poll = 0;
@@ -411,10 +411,11 @@ static void tps65010_interrupt(struct tps65010 *tps)
 }
 
 /* handle IRQs and polling using keventd for now */
-static void tps65010_work(void *_tps)
+static void tps65010_work(struct work_struct *work)
 {
-       struct tps65010         *tps = _tps;
+       struct tps65010         *tps;
 
+       tps = container_of(work, struct tps65010, work.work);
        mutex_lock(&tps->lock);
 
        tps65010_interrupt(tps);
@@ -452,7 +453,7 @@ static irqreturn_t tps65010_irq(int irq, void *_tps)
 
        disable_irq_nosync(irq);
        set_bit(FLAG_IRQ_ENABLE, &tps->flags);
-       (void) schedule_work(&tps->work);
+       (void) schedule_work(&tps->work.work);
        return IRQ_HANDLED;
 }
 
@@ -465,13 +466,15 @@ static int __exit tps65010_detach_client(struct i2c_client *client)
        struct tps65010         *tps;
 
        tps = container_of(client, struct tps65010, client);
+       free_irq(tps->irq, tps);
 #ifdef CONFIG_ARM
        if (machine_is_omap_h2())
                omap_free_gpio(58);
        if (machine_is_omap_osk())
                omap_free_gpio(OMAP_MPUIO(1));
 #endif
-       free_irq(tps->irq, tps);
+       cancel_delayed_work(&tps->work);
+       flush_scheduled_work();
        debugfs_remove(tps->file);
        if (i2c_detach_client(client) == 0)
                kfree(tps);
@@ -505,7 +508,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
                return 0;
 
        mutex_init(&tps->lock);
-       INIT_WORK(&tps->work, tps65010_work, tps);
+       INIT_DELAYED_WORK(&tps->work, tps65010_work);
        tps->irq = -1;
        tps->client.addr = address;
        tps->client.adapter = bus;
@@ -620,7 +623,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
        (void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK3, 0x0f
                | i2c_smbus_read_byte_data(&tps->client, TPS_MASK3));
 
-       tps65010_work(tps);
+       tps65010_work(&tps->work.work);
 
        tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
                                tps, DEBUG_FOPS);
@@ -672,7 +675,7 @@ int tps65010_set_vbus_draw(unsigned mA)
                        && test_and_set_bit(
                                FLAG_VBUS_CHANGED, &the_tps->flags)) {
                /* gadget drivers call this in_irq() */
-               (void) schedule_work(&the_tps->work);
+               (void) schedule_work(&the_tps->work.work);
        }
        local_irq_restore(flags);
 
index e3a267622bb6073fdcb5911dfca2c4178bdf670f..d33717c8afd466731855e4a42f01d65c9ee85b2e 100644 (file)
@@ -2147,7 +2147,7 @@ static int ide_floppy_probe(ide_drive_t *drive)
                printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
                goto failed;
        }
-       if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+       if ((floppy = kzalloc(sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
                printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
                goto failed;
        }
index e2f4bb5490638de5c1326dc863c322417c99002b..b3bcd1d7315e8780e6d74885a0d1f39862270162 100644 (file)
@@ -2573,11 +2573,11 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
        int pages = tape->pages_per_stage;
        char *b_data = NULL;
 
-       if ((stage = (idetape_stage_t *) kmalloc (sizeof (idetape_stage_t),GFP_KERNEL)) == NULL)
+       if ((stage = kmalloc(sizeof (idetape_stage_t),GFP_KERNEL)) == NULL)
                return NULL;
        stage->next = NULL;
 
-       bh = stage->bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
+       bh = stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
        if (bh == NULL)
                goto abort;
        bh->b_reqnext = NULL;
@@ -2607,7 +2607,7 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full,
                        continue;
                }
                prev_bh = bh;
-               if ((bh = (struct idetape_bh *)kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) {
+               if ((bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) {
                        free_page((unsigned long) b_data);
                        goto abort;
                }
@@ -4860,7 +4860,7 @@ static int ide_tape_probe(ide_drive_t *drive)
                printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
                printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
        }
-       tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+       tape = kzalloc(sizeof (idetape_tape_t), GFP_KERNEL);
        if (tape == NULL) {
                printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
                goto failed;
index e993a51f250e5fa026c718d5f66091cd2952a5d2..08119da06d54d0dec32b038f1dc5ad23c385a448 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
+ * Portions Copyright (C) 2005-2006    MontaVista Software, Inc.
  *
  * Thanks to HighPoint Technologies for their assistance, and hardware.
  * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
  * development and support.
  *
  *
- * Highpoint have their own driver (source except for the raid part)
- * available from http://www.highpoint-tech.com/hpt3xx-opensource-v131.tgz
- * This may be useful to anyone wanting to work on the mainstream hpt IDE.
+ * HighPoint has its own drivers (open source except for the RAID part)
+ * available from http://www.highpoint-tech.com/BIOS%20+%20Driver/.
+ * This may be useful to anyone wanting to work on this driver, however  do not
+ * trust  them too much since the code tends to become less and less meaningful
+ * as the time passes... :-/
  *
  * Note that final HPT370 support was done by force extraction of GPL.
  *
  * keeping me sane. 
  *             Alan Cox <alan@redhat.com>
  *
+ * - fix the clock turnaround code: it was writing to the wrong ports when
+ *   called for the secondary channel, caching the current clock mode per-
+ *   channel caused the cached register value to get out of sync with the
+ *   actual one, the channels weren't serialized, the turnaround shouldn't
+ *   be done on 66 MHz PCI bus
+ * - avoid calibrating PLL twice as the second time results in a wrong PCI
+ *   frequency and thus in the wrong timings for the secondary channel
+ * - disable UltraATA/133 for HPT372 by default (50 MHz DPLL clock do not
+ *   allow for this speed anyway)
+ * - add support for HPT302N and HPT371N clocking (the same as for HPT372N)
+ * - HPT371/N are single channel chips, so avoid touching the primary channel
+ *   which exists only virtually (there's no pins for it)
+ * - fix/remove bad/unused timing tables and use one set of tables for the whole
+ *   HPT37x chip family; save space by introducing the separate transfer mode
+ *   table in which the mode lookup is done
+ * - use f_CNT value saved by  the HighPoint BIOS as reading it directly gives
+ *   the wrong PCI frequency since DPLL has already been calibrated by BIOS
+ * - fix the hotswap code:  it caused RESET- to glitch when tristating the bus,
+ *   and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
+ * - pass to init_chipset() handlers a copy of the IDE PCI device structure as
+ *   they tamper with its fields
+ *             <source@mvista.com>
+ *
  */
 
 
 
 /* various tuning parameters */
 #define HPT_RESET_STATE_ENGINE
-#undef HPT_DELAY_INTERRUPT
-#undef HPT_SERIALIZE_IO
+#undef HPT_DELAY_INTERRUPT
+#define HPT_SERIALIZE_IO       0
 
 static const char *quirk_drives[] = {
        "QUANTUM FIREBALLlct08 08",
@@ -141,305 +167,175 @@ static const char *bad_ata33[] = {
        NULL
 };
 
-struct chipset_bus_clock_list_entry {
-       u8              xfer_speed;
-       unsigned int    chipset_settings;
+static u8 xfer_speeds[] = {
+       XFER_UDMA_6,
+       XFER_UDMA_5,
+       XFER_UDMA_4,
+       XFER_UDMA_3,
+       XFER_UDMA_2,
+       XFER_UDMA_1,
+       XFER_UDMA_0,
+
+       XFER_MW_DMA_2,
+       XFER_MW_DMA_1,
+       XFER_MW_DMA_0,
+
+       XFER_PIO_4,
+       XFER_PIO_3,
+       XFER_PIO_2,
+       XFER_PIO_1,
+       XFER_PIO_0
 };
 
-/* key for bus clock timings
- * bit
- * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
- *        DMA. cycles = value + 1
- * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
- *        register access.
- * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
- *        register access.
- * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
- *        during task file register access.
- * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
- *        xfer.
- * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
- *        register access.
- * 28     UDMA enable
- * 29     DMA enable
- * 30     PIO_MST enable. if set, the chip is in bus master mode during
- *        PIO.
- * 31     FIFO enable.
+/* Key for bus clock timings
+ * 36x   37x
+ * bits  bits
+ * 0:3  0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
+ *             cycles = value + 1
+ * 4:7  4:8    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
+ *             cycles = value + 1
+ * 8:11  9:12  cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
+ *             register access.
+ * 12:15 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file
+ *             register access.
+ * 16:18 18:20 udma_cycle_time. Clock cycles for UDMA xfer.
+ * -    21     CLK frequency: 0=ATA clock, 1=dual ATA clock.
+ * 19:21 22:24 pre_high_time. Time to initialize the 1st cycle for PIO and
+ *             MW DMA xfer.
+ * 22:24 25:27 cmd_pre_high_time. Time to initialize the 1st PIO cycle for
+ *             task file register access.
+ * 28   28     UDMA enable.
+ * 29   29     DMA  enable.
+ * 30   30     PIO MST enable. If set, the chip is in bus master mode during
+ *             PIO xfer.
+ * 31   31     FIFO enable.
  */
-static struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
-       {       XFER_UDMA_4,    0x900fd943      },
-       {       XFER_UDMA_3,    0x900ad943      },
-       {       XFER_UDMA_2,    0x900bd943      },
-       {       XFER_UDMA_1,    0x9008d943      },
-       {       XFER_UDMA_0,    0x9008d943      },
-
-       {       XFER_MW_DMA_2,  0xa008d943      },
-       {       XFER_MW_DMA_1,  0xa010d955      },
-       {       XFER_MW_DMA_0,  0xa010d9fc      },
-
-       {       XFER_PIO_4,     0xc008d963      },
-       {       XFER_PIO_3,     0xc010d974      },
-       {       XFER_PIO_2,     0xc010d997      },
-       {       XFER_PIO_1,     0xc010d9c7      },
-       {       XFER_PIO_0,     0xc018d9d9      },
-       {       0,              0x0120d9d9      }
-};
-
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
-       {       XFER_UDMA_4,    0x90c9a731      },
-       {       XFER_UDMA_3,    0x90cfa731      },
-       {       XFER_UDMA_2,    0x90caa731      },
-       {       XFER_UDMA_1,    0x90cba731      },
-       {       XFER_UDMA_0,    0x90c8a731      },
-
-       {       XFER_MW_DMA_2,  0xa0c8a731      },
-       {       XFER_MW_DMA_1,  0xa0c8a732      },      /* 0xa0c8a733 */
-       {       XFER_MW_DMA_0,  0xa0c8a797      },
-
-       {       XFER_PIO_4,     0xc0c8a731      },
-       {       XFER_PIO_3,     0xc0c8a742      },
-       {       XFER_PIO_2,     0xc0d0a753      },
-       {       XFER_PIO_1,     0xc0d0a7a3      },      /* 0xc0d0a793 */
-       {       XFER_PIO_0,     0xc0d0a7aa      },      /* 0xc0d0a7a7 */
-       {       0,              0x0120a7a7      }
-};
-
-static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
-       {       XFER_UDMA_4,    0x90c98521      },
-       {       XFER_UDMA_3,    0x90cf8521      },
-       {       XFER_UDMA_2,    0x90cf8521      },
-       {       XFER_UDMA_1,    0x90cb8521      },
-       {       XFER_UDMA_0,    0x90cb8521      },
-
-       {       XFER_MW_DMA_2,  0xa0ca8521      },
-       {       XFER_MW_DMA_1,  0xa0ca8532      },
-       {       XFER_MW_DMA_0,  0xa0ca8575      },
-
-       {       XFER_PIO_4,     0xc0ca8521      },
-       {       XFER_PIO_3,     0xc0ca8532      },
-       {       XFER_PIO_2,     0xc0ca8542      },
-       {       XFER_PIO_1,     0xc0d08572      },
-       {       XFER_PIO_0,     0xc0d08585      },
-       {       0,              0x01208585      }
-};
-
-/* from highpoint documentation. these are old values */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
-/*     {       XFER_UDMA_5,    0x1A85F442,     0x16454e31      }, */
-       {       XFER_UDMA_5,    0x16454e31      },
-       {       XFER_UDMA_4,    0x16454e31      },
-       {       XFER_UDMA_3,    0x166d4e31      },
-       {       XFER_UDMA_2,    0x16494e31      },
-       {       XFER_UDMA_1,    0x164d4e31      },
-       {       XFER_UDMA_0,    0x16514e31      },
-
-       {       XFER_MW_DMA_2,  0x26514e21      },
-       {       XFER_MW_DMA_1,  0x26514e33      },
-       {       XFER_MW_DMA_0,  0x26514e97      },
-
-       {       XFER_PIO_4,     0x06514e21      },
-       {       XFER_PIO_3,     0x06514e22      },
-       {       XFER_PIO_2,     0x06514e33      },
-       {       XFER_PIO_1,     0x06914e43      },
-       {       XFER_PIO_0,     0x06914e57      },
-       {       0,              0x06514e57      }
-};
-
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
-       {       XFER_UDMA_5,    0x14846231      },
-       {       XFER_UDMA_4,    0x14886231      },
-       {       XFER_UDMA_3,    0x148c6231      },
-       {       XFER_UDMA_2,    0x148c6231      },
-       {       XFER_UDMA_1,    0x14906231      },
-       {       XFER_UDMA_0,    0x14986231      },
-
-       {       XFER_MW_DMA_2,  0x26514e21      },
-       {       XFER_MW_DMA_1,  0x26514e33      },
-       {       XFER_MW_DMA_0,  0x26514e97      },
-
-       {       XFER_PIO_4,     0x06514e21      },
-       {       XFER_PIO_3,     0x06514e22      },
-       {       XFER_PIO_2,     0x06514e33      },
-       {       XFER_PIO_1,     0x06914e43      },
-       {       XFER_PIO_0,     0x06914e57      },
-       {       0,              0x06514e57      }
-};
-
-/* these are the current (4 sep 2001) timings from highpoint */
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = {
-       {       XFER_UDMA_5,    0x12446231      },
-       {       XFER_UDMA_4,    0x12446231      },
-       {       XFER_UDMA_3,    0x126c6231      },
-       {       XFER_UDMA_2,    0x12486231      },
-       {       XFER_UDMA_1,    0x124c6233      },
-       {       XFER_UDMA_0,    0x12506297      },
-
-       {       XFER_MW_DMA_2,  0x22406c31      },
-       {       XFER_MW_DMA_1,  0x22406c33      },
-       {       XFER_MW_DMA_0,  0x22406c97      },
-
-       {       XFER_PIO_4,     0x06414e31      },
-       {       XFER_PIO_3,     0x06414e42      },
-       {       XFER_PIO_2,     0x06414e53      },
-       {       XFER_PIO_1,     0x06814e93      },
-       {       XFER_PIO_0,     0x06814ea7      },
-       {       0,              0x06814ea7      }
-};
-
-/* 2x 33MHz timings */
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = {
-       {       XFER_UDMA_5,    0x1488e673      },
-       {       XFER_UDMA_4,    0x1488e673      },
-       {       XFER_UDMA_3,    0x1498e673      },
-       {       XFER_UDMA_2,    0x1490e673      },
-       {       XFER_UDMA_1,    0x1498e677      },
-       {       XFER_UDMA_0,    0x14a0e73f      },
-
-       {       XFER_MW_DMA_2,  0x2480fa73      },
-       {       XFER_MW_DMA_1,  0x2480fa77      }, 
-       {       XFER_MW_DMA_0,  0x2480fb3f      },
-
-       {       XFER_PIO_4,     0x0c82be73      },
-       {       XFER_PIO_3,     0x0c82be95      },
-       {       XFER_PIO_2,     0x0c82beb7      },
-       {       XFER_PIO_1,     0x0d02bf37      },
-       {       XFER_PIO_0,     0x0d02bf5f      },
-       {       0,              0x0d02bf5f      }
-};
 
-static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = {
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x0ac1f48a      }
+static u32 forty_base_hpt36x[] = {
+       /* XFER_UDMA_6 */       0x900fd943,
+       /* XFER_UDMA_5 */       0x900fd943,
+       /* XFER_UDMA_4 */       0x900fd943,
+       /* XFER_UDMA_3 */       0x900ad943,
+       /* XFER_UDMA_2 */       0x900bd943,
+       /* XFER_UDMA_1 */       0x9008d943,
+       /* XFER_UDMA_0 */       0x9008d943,
+
+       /* XFER_MW_DMA_2 */     0xa008d943,
+       /* XFER_MW_DMA_1 */     0xa010d955,
+       /* XFER_MW_DMA_0 */     0xa010d9fc,
+
+       /* XFER_PIO_4 */        0xc008d963,
+       /* XFER_PIO_3 */        0xc010d974,
+       /* XFER_PIO_2 */        0xc010d997,
+       /* XFER_PIO_1 */        0xc010d9c7,
+       /* XFER_PIO_0 */        0xc018d9d9
 };
 
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
-       {       XFER_UDMA_6,    0x1c81dc62      },
-       {       XFER_UDMA_5,    0x1c6ddc62      },
-       {       XFER_UDMA_4,    0x1c8ddc62      },
-       {       XFER_UDMA_3,    0x1c8edc62      },      /* checkme */
-       {       XFER_UDMA_2,    0x1c91dc62      },
-       {       XFER_UDMA_1,    0x1c9adc62      },      /* checkme */
-       {       XFER_UDMA_0,    0x1c82dc62      },      /* checkme */
-
-       {       XFER_MW_DMA_2,  0x2c829262      },
-       {       XFER_MW_DMA_1,  0x2c829266      },      /* checkme */
-       {       XFER_MW_DMA_0,  0x2c82922e      },      /* checkme */
-
-       {       XFER_PIO_4,     0x0c829c62      },
-       {       XFER_PIO_3,     0x0c829c84      },
-       {       XFER_PIO_2,     0x0c829ca6      },
-       {       XFER_PIO_1,     0x0d029d26      },
-       {       XFER_PIO_0,     0x0d029d5e      },
-       {       0,              0x0d029d5e      }
+static u32 thirty_three_base_hpt36x[] = {
+       /* XFER_UDMA_6 */       0x90c9a731,
+       /* XFER_UDMA_5 */       0x90c9a731,
+       /* XFER_UDMA_4 */       0x90c9a731,
+       /* XFER_UDMA_3 */       0x90cfa731,
+       /* XFER_UDMA_2 */       0x90caa731,
+       /* XFER_UDMA_1 */       0x90cba731,
+       /* XFER_UDMA_0 */       0x90c8a731,
+
+       /* XFER_MW_DMA_2 */     0xa0c8a731,
+       /* XFER_MW_DMA_1 */     0xa0c8a732,     /* 0xa0c8a733 */
+       /* XFER_MW_DMA_0 */     0xa0c8a797,
+
+       /* XFER_PIO_4 */        0xc0c8a731,
+       /* XFER_PIO_3 */        0xc0c8a742,
+       /* XFER_PIO_2 */        0xc0d0a753,
+       /* XFER_PIO_1 */        0xc0d0a7a3,     /* 0xc0d0a793 */
+       /* XFER_PIO_0 */        0xc0d0a7aa      /* 0xc0d0a7a7 */
 };
 
-static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x0a81f443      }
+static u32 twenty_five_base_hpt36x[] = {
+       /* XFER_UDMA_6 */       0x90c98521,
+       /* XFER_UDMA_5 */       0x90c98521,
+       /* XFER_UDMA_4 */       0x90c98521,
+       /* XFER_UDMA_3 */       0x90cf8521,
+       /* XFER_UDMA_2 */       0x90cf8521,
+       /* XFER_UDMA_1 */       0x90cb8521,
+       /* XFER_UDMA_0 */       0x90cb8521,
+
+       /* XFER_MW_DMA_2 */     0xa0ca8521,
+       /* XFER_MW_DMA_1 */     0xa0ca8532,
+       /* XFER_MW_DMA_0 */     0xa0ca8575,
+
+       /* XFER_PIO_4 */        0xc0ca8521,
+       /* XFER_PIO_3 */        0xc0ca8532,
+       /* XFER_PIO_2 */        0xc0ca8542,
+       /* XFER_PIO_1 */        0xc0d08572,
+       /* XFER_PIO_0 */        0xc0d08585
 };
 
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
-       {       XFER_UDMA_6,    0x1c869c62      },
-       {       XFER_UDMA_5,    0x1cae9c62      },
-       {       XFER_UDMA_4,    0x1c8a9c62      },
-       {       XFER_UDMA_3,    0x1c8e9c62      },
-       {       XFER_UDMA_2,    0x1c929c62      },
-       {       XFER_UDMA_1,    0x1c9a9c62      },
-       {       XFER_UDMA_0,    0x1c829c62      },
-
-       {       XFER_MW_DMA_2,  0x2c829c62      },
-       {       XFER_MW_DMA_1,  0x2c829c66      },
-       {       XFER_MW_DMA_0,  0x2c829d2e      },
-
-       {       XFER_PIO_4,     0x0c829c62      },
-       {       XFER_PIO_3,     0x0c829c84      },
-       {       XFER_PIO_2,     0x0c829ca6      },
-       {       XFER_PIO_1,     0x0d029d26      },
-       {       XFER_PIO_0,     0x0d029d5e      },
-       {       0,              0x0d029d26      }
+static u32 thirty_three_base_hpt37x[] = {
+       /* XFER_UDMA_6 */       0x12446231,     /* 0x12646231 ?? */
+       /* XFER_UDMA_5 */       0x12446231,
+       /* XFER_UDMA_4 */       0x12446231,
+       /* XFER_UDMA_3 */       0x126c6231,
+       /* XFER_UDMA_2 */       0x12486231,
+       /* XFER_UDMA_1 */       0x124c6233,
+       /* XFER_UDMA_0 */       0x12506297,
+
+       /* XFER_MW_DMA_2 */     0x22406c31,
+       /* XFER_MW_DMA_1 */     0x22406c33,
+       /* XFER_MW_DMA_0 */     0x22406c97,
+
+       /* XFER_PIO_4 */        0x06414e31,
+       /* XFER_PIO_3 */        0x06414e42,
+       /* XFER_PIO_2 */        0x06414e53,
+       /* XFER_PIO_1 */        0x06814e93,
+       /* XFER_PIO_0 */        0x06814ea7
 };
 
-static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
-       {       XFER_UDMA_6,    0x12808242      },
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x06814e93      }
+static u32 fifty_base_hpt37x[] = {
+       /* XFER_UDMA_6 */       0x12848242,
+       /* XFER_UDMA_5 */       0x12848242,
+       /* XFER_UDMA_4 */       0x12ac8242,
+       /* XFER_UDMA_3 */       0x128c8242,
+       /* XFER_UDMA_2 */       0x120c8242,
+       /* XFER_UDMA_1 */       0x12148254,
+       /* XFER_UDMA_0 */       0x121882ea,
+
+       /* XFER_MW_DMA_2 */     0x22808242,
+       /* XFER_MW_DMA_1 */     0x22808254,
+       /* XFER_MW_DMA_0 */     0x228082ea,
+
+       /* XFER_PIO_4 */        0x0a81f442,
+       /* XFER_PIO_3 */        0x0a81f443,
+       /* XFER_PIO_2 */        0x0a81f454,
+       /* XFER_PIO_1 */        0x0ac1f465,
+       /* XFER_PIO_0 */        0x0ac1f48a
 };
 
-/* FIXME: 50MHz timings for HPT374 */
-
-#if 0
-static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
-       {       XFER_UDMA_6,    0x12406231      },      /* checkme */
-       {       XFER_UDMA_5,    0x12446231      },      /* 0x14846231 */
-       {       XFER_UDMA_4,    0x16814ea7      },      /* 0x14886231 */
-       {       XFER_UDMA_3,    0x16814ea7      },      /* 0x148c6231 */
-       {       XFER_UDMA_2,    0x16814ea7      },      /* 0x148c6231 */
-       {       XFER_UDMA_1,    0x16814ea7      },      /* 0x14906231 */
-       {       XFER_UDMA_0,    0x16814ea7      },      /* 0x14986231 */
-       {       XFER_MW_DMA_2,  0x16814ea7      },      /* 0x26514e21 */
-       {       XFER_MW_DMA_1,  0x16814ea7      },      /* 0x26514e97 */
-       {       XFER_MW_DMA_0,  0x16814ea7      },      /* 0x26514e97 */
-       {       XFER_PIO_4,     0x06814ea7      },      /* 0x06514e21 */
-       {       XFER_PIO_3,     0x06814ea7      },      /* 0x06514e22 */
-       {       XFER_PIO_2,     0x06814ea7      },      /* 0x06514e33 */
-       {       XFER_PIO_1,     0x06814ea7      },      /* 0x06914e43 */
-       {       XFER_PIO_0,     0x06814ea7      },      /* 0x06914e57 */
-       {       0,              0x06814ea7      }
+static u32 sixty_six_base_hpt37x[] = {
+       /* XFER_UDMA_6 */       0x1c869c62,
+       /* XFER_UDMA_5 */       0x1cae9c62,     /* 0x1c8a9c62 */
+       /* XFER_UDMA_4 */       0x1c8a9c62,
+       /* XFER_UDMA_3 */       0x1c8e9c62,
+       /* XFER_UDMA_2 */       0x1c929c62,
+       /* XFER_UDMA_1 */       0x1c9a9c62,
+       /* XFER_UDMA_0 */       0x1c829c62,
+
+       /* XFER_MW_DMA_2 */     0x2c829c62,
+       /* XFER_MW_DMA_1 */     0x2c829c66,
+       /* XFER_MW_DMA_0 */     0x2c829d2e,
+
+       /* XFER_PIO_4 */        0x0c829c62,
+       /* XFER_PIO_3 */        0x0c829c84,
+       /* XFER_PIO_2 */        0x0c829ca6,
+       /* XFER_PIO_1 */        0x0d029d26,
+       /* XFER_PIO_0 */        0x0d029d5e
 };
-#endif
 
 #define HPT366_DEBUG_DRIVE_INFO                0
 #define HPT374_ALLOW_ATA133_6          0
 #define HPT371_ALLOW_ATA133_6          0
 #define HPT302_ALLOW_ATA133_6          0
-#define HPT372_ALLOW_ATA133_6          1
+#define HPT372_ALLOW_ATA133_6          0
 #define HPT370_ALLOW_ATA100_5          1
 #define HPT366_ALLOW_ATA66_4           1
 #define HPT366_ALLOW_ATA66_3           1
@@ -461,9 +357,10 @@ struct hpt_info
        int revision;           /* Chipset revision */
        int flags;              /* Chipset properties */
 #define PLL_MODE       1
-#define IS_372N                2
+#define IS_3xxN        2
+#define PCI_66MHZ      4
                                /* Speed table */
-       struct chipset_bus_clock_list_entry *speed;
+       u32 *speed;
 };
 
 /*
@@ -600,12 +497,20 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
        return 0;
 }
 
-static unsigned int pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table)
+static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table)
 {
-       for ( ; chipset_table->xfer_speed ; chipset_table++)
-               if (chipset_table->xfer_speed == speed)
-                       return chipset_table->chipset_settings;
-       return chipset_table->chipset_settings;
+       int i;
+
+       /*
+        * Lookup the transfer mode table to get the index into
+        * the timing table.
+        *
+        * NOTE: For XFER_PIO_SLOW, PIO mode 0 timings will be used.
+        */
+       for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++)
+               if (xfer_speeds[i] == speed)
+                       break;
+       return chipset_table[i];
 }
 
 static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
@@ -956,156 +861,127 @@ static int hpt374_ide_dma_end (ide_drive_t *drive)
 }
 
 /**
- *     hpt372n_set_clock       -       perform clock switching dance
- *     @drive: Drive to switch
- *     @mode: Switching mode (0x21 for write, 0x23 otherwise)
+ *     hpt3xxn_set_clock       -       perform clock switching dance
+ *     @hwif: hwif to switch
+ *     @mode: clocking mode (0x21 for write, 0x23 otherwise)
  *
- *     Switch the DPLL clock on the HPT372N devices. This is a
- *     right mess.
+ *     Switch the DPLL clock on the HPT3xxN devices. This is a right mess.
+ *     NOTE: avoid touching the disabled primary channel on HPT371N -- it
+ *     doesn't physically exist anyway...
  */
-static void hpt372n_set_clock(ide_drive_t *drive, int mode)
+
+static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
 {
-       ide_hwif_t *hwif        = HWIF(drive);
-       
-       /* FIXME: should we check for DMA active and BUG() */
+       u8 mcr1, scr2 = hwif->INB(hwif->dma_master + 0x7b);
+
+       if ((scr2 & 0x7f) == mode)
+               return;
+
+       /* MISC. control register 1 has the channel enable bit... */
+       mcr1 = hwif->INB(hwif->dma_master + 0x70);
+
        /* Tristate the bus */
-       outb(0x80, hwif->dma_base+0x73);
-       outb(0x80, hwif->dma_base+0x77);
-       
+       if (mcr1 & 0x04)
+               hwif->OUTB(0x80, hwif->dma_master + 0x73);
+       hwif->OUTB(0x80, hwif->dma_master + 0x77);
+
        /* Switch clock and reset channels */
-       outb(mode, hwif->dma_base+0x7B);
-       outb(0xC0, hwif->dma_base+0x79);
-       
+       hwif->OUTB(mode, hwif->dma_master + 0x7b);
+       hwif->OUTB(0xc0, hwif->dma_master + 0x79);
+
        /* Reset state machines */
-       outb(0x37, hwif->dma_base+0x70);
-       outb(0x37, hwif->dma_base+0x74);
-       
+       if (mcr1 & 0x04)
+               hwif->OUTB(0x37, hwif->dma_master + 0x70);
+       hwif->OUTB(0x37, hwif->dma_master + 0x74);
+
        /* Complete reset */
-       outb(0x00, hwif->dma_base+0x79);
-       
+       hwif->OUTB(0x00, hwif->dma_master + 0x79);
+
        /* Reconnect channels to bus */
-       outb(0x00, hwif->dma_base+0x73);
-       outb(0x00, hwif->dma_base+0x77);
+       if (mcr1 & 0x04)
+               hwif->OUTB(0x00, hwif->dma_master + 0x73);
+       hwif->OUTB(0x00, hwif->dma_master + 0x77);
 }
 
 /**
- *     hpt372n_rw_disk         -       prepare for I/O
+ *     hpt3xxn_rw_disk         -       prepare for I/O
  *     @drive: drive for command
  *     @rq: block request structure
  *
- *     This is called when a disk I/O is issued to the 372N.
+ *     This is called when a disk I/O is issued to HPT3xxN.
  *     We need it because of the clock switching.
  */
 
-static void hpt372n_rw_disk(ide_drive_t *drive, struct request *rq)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       int wantclock;
-
-       wantclock = rq_data_dir(rq) ? 0x23 : 0x21;
-
-       if (hwif->config_data != wantclock) {
-               hpt372n_set_clock(drive, wantclock);
-               hwif->config_data = wantclock;
-       }
-}
-
-/*
- * Since SUN Cobalt is attempting to do this operation, I should disclose
- * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date
- * HOTSWAP ATA Infrastructure.
- */
-
-static void hpt3xx_reset (ide_drive_t *drive)
-{
-}
-
-static int hpt3xx_tristate (ide_drive_t * drive, int state)
+static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = hwif->pci_dev;
-       u8 reg59h = 0, reset    = (hwif->channel) ? 0x80 : 0x40;
-       u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;
-
-       pci_read_config_byte(dev, 0x59, &reg59h);
-       pci_read_config_byte(dev, state_reg, &regXXh);
+       u8 wantclock            = rq_data_dir(rq) ? 0x23 : 0x21;
 
-       if (state) {
-               (void) ide_do_reset(drive);
-               pci_write_config_byte(dev, state_reg, regXXh|0x80);
-               pci_write_config_byte(dev, 0x59, reg59h|reset);
-       } else {
-               pci_write_config_byte(dev, 0x59, reg59h & ~(reset));
-               pci_write_config_byte(dev, state_reg, regXXh & ~(0x80));
-               (void) ide_do_reset(drive);
-       }
-       return 0;
+       hpt3xxn_set_clock(hwif, wantclock);
 }
 
 /* 
- * set/get power state for a drive.
- * turning the power off does the following things:
- *   1) soft-reset the drive
- *   2) tri-states the ide bus
+ * Set/get power state for a drive.
  *
- * when we turn things back on, we need to re-initialize things.
+ * When we turn the power back on, we need to re-initialize things.
  */
 #define TRISTATE_BIT  0x8000
-static int hpt370_busproc(ide_drive_t * drive, int state)
+
+static int hpt3xx_busproc(ide_drive_t *drive, int state)
 {
        ide_hwif_t *hwif        = drive->hwif;
        struct pci_dev *dev     = hwif->pci_dev;
-       u8 tristate = 0, resetmask = 0, bus_reg = 0;
-       u16 tri_reg;
+       u8  tristate, resetmask, bus_reg = 0;
+       u16 tri_reg = 0;
 
        hwif->bus_state = state;
 
        if (hwif->channel) { 
                /* secondary channel */
-               tristate = 0x56;
-               resetmask = 0x80; 
+               tristate  = 0x56;
+               resetmask = 0x80;
        } else { 
                /* primary channel */
-               tristate = 0x52;
+               tristate  = 0x52;
                resetmask = 0x40;
        }
 
-       /* grab status */
+       /* Grab the status. */
        pci_read_config_word(dev, tristate, &tri_reg);
        pci_read_config_byte(dev, 0x59, &bus_reg);
 
-       /* set the state. we don't set it if we don't need to do so.
-        * make sure that the drive knows that it has failed if it's off */
+       /*
+        * Set the state. We don't set it if we don't need to do so.
+        * Make sure that the drive knows that it has failed if it's off.
+        */
        switch (state) {
        case BUSSTATE_ON:
-               hwif->drives[0].failures = 0;
-               hwif->drives[1].failures = 0;
-               if ((bus_reg & resetmask) == 0)
+               if (!(bus_reg & resetmask))
                        return 0;
-               tri_reg &= ~TRISTATE_BIT;
-               bus_reg &= ~resetmask;
-               break;
+               hwif->drives[0].failures = hwif->drives[1].failures = 0;
+
+               pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask);
+               pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT);
+               return 0;
        case BUSSTATE_OFF:
-               hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-               hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
-               if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask))
+               if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT))
                        return 0;
                tri_reg &= ~TRISTATE_BIT;
-               bus_reg |= resetmask;
                break;
        case BUSSTATE_TRISTATE:
-               hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-               hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
-               if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask))
+               if ((bus_reg & resetmask) &&  (tri_reg & TRISTATE_BIT))
                        return 0;
                tri_reg |= TRISTATE_BIT;
-               bus_reg |= resetmask;
                break;
+       default:
+               return -EINVAL;
        }
-       pci_write_config_byte(dev, 0x59, bus_reg);
-       pci_write_config_word(dev, tristate, tri_reg);
 
+       hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
+       hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+
+       pci_write_config_word(dev, tristate, tri_reg);
+       pci_write_config_byte(dev, 0x59, bus_reg | resetmask);
        return 0;
 }
 
@@ -1119,14 +995,14 @@ static void __devinit hpt366_clocking(ide_hwif_t *hwif)
        /* detect bus speed by looking at control reg timing: */
        switch((reg1 >> 8) & 7) {
                case 5:
-                       info->speed = forty_base_hpt366;
+                       info->speed = forty_base_hpt36x;
                        break;
                case 9:
-                       info->speed = twenty_five_base_hpt366;
+                       info->speed = twenty_five_base_hpt36x;
                        break;
                case 7:
                default:
-                       info->speed = thirty_three_base_hpt366;
+                       info->speed = thirty_three_base_hpt36x;
                        break;
        }
 }
@@ -1136,9 +1012,9 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
        struct hpt_info *info = ide_get_hwifdata(hwif);
        struct pci_dev *dev = hwif->pci_dev;
        int adjust, i;
-       u16 freq;
-       u32 pll;
-       u8 reg5bh;
+       u16 freq = 0;
+       u32 pll, temp = 0;
+       u8 reg5bh = 0, mcr1 = 0;
        
        /*
         * default to pci clock. make sure MA15/16 are set to output
@@ -1151,27 +1027,40 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
        pci_write_config_byte(dev, 0x5b, 0x23);
 
        /*
-        * set up the PLL. we need to adjust it so that it's stable. 
-        * freq = Tpll * 192 / Tpci
+        * We'll have to read f_CNT value in order to determine
+        * the PCI clock frequency according to the following ratio:
+        *
+        * f_CNT = Fpci * 192 / Fdpll
+        *
+        * First try reading the register in which the HighPoint BIOS
+        * saves f_CNT value before  reprogramming the DPLL from its
+        * default setting (which differs for the various chips).
+        * NOTE: This register is only accessible via I/O space.
         *
-        * Todo. For non x86 should probably check the dword is
-        * set to 0xABCDExxx indicating the BIOS saved f_CNT
+        * In case the signature check fails, we'll have to resort to
+        * reading the f_CNT register itself in hopes that nobody has
+        * touched the DPLL yet...
         */
-       pci_read_config_word(dev, 0x78, &freq);
-       freq &= 0x1FF;
-       
+       temp = inl(pci_resource_start(dev, 4) + 0x90);
+       if ((temp & 0xFFFFF000) != 0xABCDE000) {
+               printk(KERN_WARNING "HPT37X: no clock data saved by BIOS\n");
+
+               /* Calculate the average value of f_CNT */
+               for (temp = i = 0; i < 128; i++) {
+                       pci_read_config_word(dev, 0x78, &freq);
+                       temp += freq & 0x1ff;
+                       mdelay(1);
+               }
+               freq = temp / 128;
+       } else
+               freq = temp & 0x1ff;
+
        /*
-        * The 372N uses different PCI clock information and has
-        * some other complications
-        *      On PCI33 timing we must clock switch
-        *      On PCI66 timing we must NOT use the PCI clock
-        *
-        * Currently we always set up the PLL for the 372N
+        * HPT3xxN chips use different PCI clock information.
+        * Currently we always set up the PLL for them.
         */
-        
-       if(info->flags & IS_372N)
-       {
-               printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");
+
+       if (info->flags & IS_3xxN) {
                if(freq < 0x55)
                        pll = F_LOW_PCI_33;
                else if(freq < 0x70)
@@ -1180,10 +1069,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
                        pll = F_LOW_PCI_50;
                else
                        pll = F_LOW_PCI_66;
-                       
-               printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll);
-                       
-               /* We always use the pll not the PCI clock on 372N */
+
+               printk(KERN_INFO "HPT3xxN detected, FREQ: %d, PLL: %d\n", freq, pll);
        }
        else
        {
@@ -1197,41 +1084,22 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
                        pll = F_LOW_PCI_66;
        
                if (pll == F_LOW_PCI_33) {
-                       if (info->revision >= 8)
-                               info->speed = thirty_three_base_hpt374;
-                       else if (info->revision >= 5)
-                               info->speed = thirty_three_base_hpt372;
-                       else if (info->revision >= 4)
-                               info->speed = thirty_three_base_hpt370a;
-                       else
-                               info->speed = thirty_three_base_hpt370;
+                       info->speed = thirty_three_base_hpt37x;
                        printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n");
                } else if (pll == F_LOW_PCI_40) {
                        /* Unsupported */
                } else if (pll == F_LOW_PCI_50) {
-                       if (info->revision >= 8)
-                               info->speed = fifty_base_hpt370a;
-                       else if (info->revision >= 5)
-                               info->speed = fifty_base_hpt372;
-                       else if (info->revision >= 4)
-                               info->speed = fifty_base_hpt370a;
-                       else
-                               info->speed = fifty_base_hpt370a;
+                       info->speed = fifty_base_hpt37x;
                        printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n");
                } else {
-                       if (info->revision >= 8) {
-                               printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");
-                       }
-                       else if (info->revision >= 5)
-                               info->speed = sixty_six_base_hpt372;
-                       else if (info->revision >= 4)
-                               info->speed = sixty_six_base_hpt370a;
-                       else
-                               info->speed = sixty_six_base_hpt370;
+                       info->speed = sixty_six_base_hpt37x;
                        printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n");
                }
        }
-       
+
+       if (pll == F_LOW_PCI_66)
+               info->flags |= PCI_66MHZ;
+
        /*
         * only try the pll if we don't have a table for the clock
         * speed that we're running at. NOTE: the internal PLL will
@@ -1248,11 +1116,8 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
        info->flags |= PLL_MODE;
        
        /*
-        * FIXME: make this work correctly, esp with 372N as per
-        * reference driver code.
-        *
-        * adjust PLL based upon PCI clock, enable it, and wait for
-        * stabilization.
+        * Adjust the PLL based upon the PCI clock, enable it, and
+        * wait for stabilization...
         */
        adjust = 0;
        freq = (pll < F_LOW_PCI_50) ? 2 : 4;
@@ -1275,22 +1140,12 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
                                pci_write_config_dword(dev, 0x5c, 
                                                       pll & ~0x100);
                                pci_write_config_byte(dev, 0x5b, 0x21);
-                               if (info->revision >= 8)
-                                       info->speed = fifty_base_hpt370a;
-                               else if (info->revision >= 5)
-                                       info->speed = fifty_base_hpt372;
-                               else if (info->revision >= 4)
-                                       info->speed = fifty_base_hpt370a;
-                               else
-                                       info->speed = fifty_base_hpt370a;
+
+                               info->speed = fifty_base_hpt37x;
                                printk("HPT37X: using 50MHz internal PLL\n");
                                goto init_hpt37X_done;
                        }
                }
-               if (!pci_get_drvdata(dev)) {
-                       printk("No Clock Stabilization!!!\n");
-                       return;
-               }
 pll_recal:
                if (adjust & 1)
                        pll -= (adjust >> 1);
@@ -1300,11 +1155,16 @@ pll_recal:
 
 init_hpt37X_done:
        if (!info->speed)
-               printk(KERN_ERR "HPT37X%s: unknown bus timing [%d %d].\n",
-                       (info->flags & IS_372N)?"N":"", pll, freq);
-       /* reset state engine */
-       pci_write_config_byte(dev, 0x50, 0x37); 
-       pci_write_config_byte(dev, 0x54, 0x37); 
+               printk(KERN_ERR "HPT37x%s: unknown bus timing [%d %d].\n",
+                      (info->flags & IS_3xxN) ? "N" : "", pll, freq);
+       /*
+        * Reset the state engines.
+        * NOTE: avoid accidentally enabling the primary channel on HPT371N.
+        */
+       pci_read_config_byte(dev, 0x50, &mcr1);
+       if (mcr1 & 0x04)
+               pci_write_config_byte(dev, 0x50, 0x37);
+       pci_write_config_byte(dev, 0x54, 0x37);
        udelay(100);
 }
 
@@ -1367,6 +1227,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        struct pci_dev *dev             = hwif->pci_dev;
        struct hpt_info *info           = ide_get_hwifdata(hwif);
        u8 ata66 = 0, regmask           = (hwif->channel) ? 0x01 : 0x02;
+       int serialize                   = HPT_SERIALIZE_IO;
        
        hwif->tuneproc                  = &hpt3xx_tune_drive;
        hwif->speedproc                 = &hpt3xx_tune_chipset;
@@ -1374,8 +1235,20 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
        hwif->intrproc                  = &hpt3xx_intrproc;
        hwif->maskproc                  = &hpt3xx_maskproc;
        
-       if(info->flags & IS_372N)
-               hwif->rw_disk = &hpt372n_rw_disk;
+       /*
+        * HPT3xxN chips have some complications:
+        *
+        * - on 33 MHz PCI we must clock switch
+        * - on 66 MHz PCI we must NOT use the PCI clock
+        */
+       if ((info->flags & (IS_3xxN | PCI_66MHZ)) == IS_3xxN) {
+               /*
+                * Clock is shared between the channels,
+                * so we'll have to serialize them... :-(
+                */
+               serialize = 1;
+               hwif->rw_disk = &hpt3xxn_rw_disk;
+       }
 
        /*
         * The HPT37x uses the CBLID pins as outputs for MA15/MA16
@@ -1418,29 +1291,15 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
                PCI_FUNC(hwif->pci_dev->devfn));
 #endif /* DEBUG */
 
-#ifdef HPT_SERIALIZE_IO
-       /* serialize access to this device */
-       if (hwif->mate)
+       /* Serialize access to this device */
+       if (serialize && hwif->mate)
                hwif->serialized = hwif->mate->serialized = 1;
-#endif
 
-       if (info->revision >= 3) {
-               u8 reg5ah = 0;
-                       pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
-               /*
-                * set up ioctl for power status.
-                * note: power affects both
-                * drives on each channel
-                */
-               hwif->resetproc = &hpt3xx_reset;
-               hwif->busproc   = &hpt370_busproc;
-       } else if (info->revision >= 2) {
-               hwif->resetproc = &hpt3xx_reset;
-               hwif->busproc   = &hpt3xx_tristate;
-       } else {
-               hwif->resetproc = &hpt3xx_reset;
-               hwif->busproc   = &hpt3xx_tristate;
-       }
+       /*
+        * Set up ioctl for power status.
+        * NOTE:  power affects both drives on each channel.
+        */
+       hwif->busproc = &hpt3xx_busproc;
 
        if (!hwif->dma_base) {
                hwif->drives[0].autotune = 1;
@@ -1490,7 +1349,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
                return;
                
        if(info->speed == NULL) {
-               printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n");
+               printk(KERN_WARNING "hpt366: no known IDE timings, disabling DMA.\n");
                return;
        }
 
@@ -1519,9 +1378,10 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
 
 static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
 {
-       struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
-       unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
-       u8 did, rid;
+       struct hpt_info *info   = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
+       struct pci_dev  *dev    = hwif->pci_dev;
+       u16 did                 = dev->device;
+       u8  rid                 = 0;
 
        if(info == NULL) {
                printk(KERN_WARNING "hpt366: out of memory.\n");
@@ -1529,15 +1389,22 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
        }
        ide_set_hwifdata(hwif, info);
 
-       if(dmabase) {
-               did = inb(dmabase + 0x22);
-               rid = inb(dmabase + 0x28);
-
-               if((did == 4 && rid == 6) || (did == 5 && rid > 1))
-                       info->flags |= IS_372N;
+       /* Avoid doing the same thing twice. */
+       if (hwif->channel && hwif->mate) {
+               memcpy(info, ide_get_hwifdata(hwif->mate), sizeof(struct hpt_info));
+               return;
        }
 
-       info->revision = hpt_revision(hwif->pci_dev);
+       pci_read_config_byte(dev, PCI_CLASS_REVISION, &rid);
+
+       if (( did == PCI_DEVICE_ID_TTI_HPT366  && rid == 6) ||
+           ((did == PCI_DEVICE_ID_TTI_HPT372  ||
+             did == PCI_DEVICE_ID_TTI_HPT302  ||
+             did == PCI_DEVICE_ID_TTI_HPT371) && rid > 1) ||
+             did == PCI_DEVICE_ID_TTI_HPT372N)
+               info->flags |= IS_3xxN;
+
+       info->revision = hpt_revision(dev);
 
        if (info->revision >= 3)
                hpt37x_clocking(hwif);
@@ -1574,6 +1441,23 @@ static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
        return ide_setup_pci_device(dev, d);
 }
 
+static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
+{
+       u8 mcr1 = 0;
+
+       /*
+        * HPT371 chips physically have only one channel, the secondary one,
+        * but the primary channel registers do exist!  Go figure...
+        * So,  we manually disable the non-existing channel here
+        * (if the BIOS hasn't done this already).
+        */
+       pci_read_config_byte(dev, 0x50, &mcr1);
+       if (mcr1 & 0x04)
+               pci_write_config_byte(dev, 0x50, (mcr1 & ~0x04));
+
+       return ide_setup_pci_device(dev, d);
+}
+
 static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
 {
        struct pci_dev *findev = NULL;
@@ -1661,13 +1545,14 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
                .bootable       = OFF_BOARD,
        },{     /* 3 */
                .name           = "HPT371",
-               .init_setup     = init_setup_hpt37x,
+               .init_setup     = init_setup_hpt371,
                .init_chipset   = init_chipset_hpt366,
                .init_iops      = init_iops_hpt366,
                .init_hwif      = init_hwif_hpt366,
                .init_dma       = init_dma_hpt366,
                .channels       = 2,
                .autodma        = AUTODMA,
+               .enablebits     = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
                .bootable       = OFF_BOARD,
        },{     /* 4 */
                .name           = "HPT374",
@@ -1699,13 +1584,16 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
  *
  *     Called when the PCI registration layer (or the IDE initialization)
  *     finds a device matching our IDE device tables.
+ *
+ *     NOTE: since we'll have to modify some fields of the ide_pci_device_t
+ *     structure depending on the chip's revision, we'd better pass a local
+ *     copy down the call chain...
  */
 static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &hpt366_chipsets[id->driver_data];
+       ide_pci_device_t d = hpt366_chipsets[id->driver_data];
 
-       return d->init_setup(dev, d);
+       return d.init_setup(dev, &d);
 }
 
 static struct pci_device_id hpt366_pci_tbl[] = {
index 54bc569db4b014e999068a57c5ae11b1f41f6a69..35461eab2fafc3f88d454120637562abdff84a85 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/hil.h>
+#include <linux/io.h>
 #include <linux/spinlock.h>
+#include <asm/irq.h>
+#ifdef CONFIG_HP300
+#include <asm/hwtest.h>
+#endif
 
 
 MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
index 3cac23739344cbae32ecf27b50c6b6f4da987535..09ea50dd3459d536a6a4f9414f6a56a8be3f2758 100644 (file)
@@ -408,7 +408,7 @@ act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
         p = cblock.buffer;
         if (!access_ok(VERIFY_READ, p, length))
                 return -EFAULT;
-        buf = (u_char *) kmalloc(1024, GFP_KERNEL);
+        buf = kmalloc(1024, GFP_KERNEL);
         if (!buf)
                 return -ENOMEM;
         timeout = 0;
index 097bfa7bc323ad1738893ea00adfab252a4abd19..c4d438c17dabf0cd1a1bbb06a1fda9953cce25e2 100644 (file)
@@ -2013,7 +2013,7 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
        strcpy(card->name, id);
        card->contrnr = contr;
        card->nbchan = profp->nbchannel;
-       card->bchans = (capidrv_bchan *) kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
+       card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
        if (!card->bchans) {
                printk(KERN_WARNING
                "capidrv: (%s) Could not allocate bchan-structs.\n", id);
index 399b316111f72db4a292e71f4b52470a0fe1ec05..06967da7c4a8fd0ee13ce94a8d46cfda8797051d 100644 (file)
@@ -45,7 +45,7 @@ put_info_buffer(char *cp)
                return;
        if (!*cp)
                return;
-       if (!(ib = (struct divert_info *) kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
+       if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
                 return;        /* no memory */
        strcpy(ib->info_start, cp);     /* set output string */
        ib->next = NULL;
index 03319ea5aa0cdf8e6445f29909746bbfe7d53454..7d97d54588d9425501c4805e3157c07158d6b67b 100644 (file)
@@ -153,7 +153,7 @@ int cf_command(int drvid, int mode,
   *ielenp = p - ielenp - 1; /* set total IE length */ 
 
   /* allocate mem for information struct */  
-  if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC))) 
+  if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
              return(-ENOMEM); /* no memory */
   init_timer(&cs->timer);
   cs->info[0] = '\0';
@@ -276,7 +276,7 @@ int insertrule(int idx, divert_rule *newrule)
 { struct deflect_struc *ds,*ds1=NULL;
   unsigned long flags;
 
-  if (!(ds = (struct deflect_struc *) kmalloc(sizeof(struct deflect_struc), 
+  if (!(ds = kmalloc(sizeof(struct deflect_struc),
                                               GFP_KERNEL))) 
     return(-ENOMEM); /* no memory */
 
@@ -451,7 +451,7 @@ static int isdn_divert_icall(isdn_ctrl *ic)
            if (dv->rule.action == DEFLECT_PROCEED)
            if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime))) 
               return(0); /* no external deflection needed */  
-           if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC))) 
+           if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
              return(0); /* no memory */
            init_timer(&cs->timer);
            cs->info[0] = '\0';
index 63b629b1cdb2be0c1e79ac5d7d56f100914a5c11..b5e7f9c7d74e6bd5bac9c0e1126259fa1700038e 100644 (file)
@@ -1853,20 +1853,24 @@ static int gigaset_write_cmd(struct cardstate *cs,
 {
        struct cmdbuf_t *cb;
        unsigned long flags;
-       int status;
+       int rc;
 
        gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
                             DEBUG_TRANSCMD : DEBUG_LOCKCMD,
                           "CMD Transmit", len, buf);
 
-       if (len <= 0)
-               return 0;                       /* nothing to do */
+       if (len <= 0) {
+               /* nothing to do */
+               rc = 0;
+               goto notqueued;
+       }
 
        if (len > IF_WRITEBUF)
                len = IF_WRITEBUF;
        if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
                dev_err(cs->dev, "%s: out of memory\n", __func__);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto notqueued;
        }
 
        memcpy(cb->buf, buf, len);
@@ -1891,11 +1895,21 @@ static int gigaset_write_cmd(struct cardstate *cs,
        if (unlikely(!cs->connected)) {
                spin_unlock_irqrestore(&cs->lock, flags);
                gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
+               /* flush command queue */
+               spin_lock_irqsave(&cs->cmdlock, flags);
+               while (cs->cmdbuf != NULL)
+                       complete_cb(cs);
+               spin_unlock_irqrestore(&cs->cmdlock, flags);
                return -ENODEV;
        }
-       status = start_cbsend(cs);
+       rc = start_cbsend(cs);
        spin_unlock_irqrestore(&cs->lock, flags);
-       return status < 0 ? status : len;
+       return rc < 0 ? rc : len;
+
+notqueued:                     /* request handled without queuing */
+       if (wake_tasklet)
+               tasklet_schedule(wake_tasklet);
+       return rc;
 }
 
 /* gigaset_write_room
@@ -1964,20 +1978,15 @@ static int gigaset_freebcshw(struct bc_state *bcs)
 
        /* kill URBs and tasklets before freeing - better safe than sorry */
        atomic_set(&ubc->running, 0);
-       for (i = 0; i < BAS_OUTURBS; ++i)
-               if (ubc->isoouturbs[i].urb) {
-                       gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d",
-                               __func__, i);
-                       usb_kill_urb(ubc->isoouturbs[i].urb);
-                       usb_free_urb(ubc->isoouturbs[i].urb);
-               }
-       for (i = 0; i < BAS_INURBS; ++i)
-               if (ubc->isoinurbs[i]) {
-                       gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d",
-                               __func__, i);
-                       usb_kill_urb(ubc->isoinurbs[i]);
-                       usb_free_urb(ubc->isoinurbs[i]);
-               }
+       gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__);
+       for (i = 0; i < BAS_OUTURBS; ++i) {
+               usb_kill_urb(ubc->isoouturbs[i].urb);
+               usb_free_urb(ubc->isoouturbs[i].urb);
+       }
+       for (i = 0; i < BAS_INURBS; ++i) {
+               usb_kill_urb(ubc->isoinurbs[i]);
+               usb_free_urb(ubc->isoinurbs[i]);
+       }
        tasklet_kill(&ubc->sent_tasklet);
        tasklet_kill(&ubc->rcvd_tasklet);
        kfree(ubc->isooutbuf);
@@ -2099,55 +2108,32 @@ static void freeurbs(struct cardstate *cs)
        struct bas_bc_state *ubc;
        int i, j;
 
+       gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__);
        for (j = 0; j < 2; ++j) {
                ubc = cs->bcs[j].hw.bas;
-               for (i = 0; i < BAS_OUTURBS; ++i)
-                       if (ubc->isoouturbs[i].urb) {
-                               usb_kill_urb(ubc->isoouturbs[i].urb);
-                               gig_dbg(DEBUG_INIT,
-                                       "%s: isoc output URB %d/%d unlinked",
-                                       __func__, j, i);
-                               usb_free_urb(ubc->isoouturbs[i].urb);
-                               ubc->isoouturbs[i].urb = NULL;
-                       }
-               for (i = 0; i < BAS_INURBS; ++i)
-                       if (ubc->isoinurbs[i]) {
-                               usb_kill_urb(ubc->isoinurbs[i]);
-                               gig_dbg(DEBUG_INIT,
-                                       "%s: isoc input URB %d/%d unlinked",
-                                       __func__, j, i);
-                               usb_free_urb(ubc->isoinurbs[i]);
-                               ubc->isoinurbs[i] = NULL;
-                       }
-       }
-       if (ucs->urb_int_in) {
-               usb_kill_urb(ucs->urb_int_in);
-               gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked",
-                       __func__);
-               usb_free_urb(ucs->urb_int_in);
-               ucs->urb_int_in = NULL;
-       }
-       if (ucs->urb_cmd_out) {
-               usb_kill_urb(ucs->urb_cmd_out);
-               gig_dbg(DEBUG_INIT, "%s: command output URB unlinked",
-                       __func__);
-               usb_free_urb(ucs->urb_cmd_out);
-               ucs->urb_cmd_out = NULL;
-       }
-       if (ucs->urb_cmd_in) {
-               usb_kill_urb(ucs->urb_cmd_in);
-               gig_dbg(DEBUG_INIT, "%s: command input URB unlinked",
-                       __func__);
-               usb_free_urb(ucs->urb_cmd_in);
-               ucs->urb_cmd_in = NULL;
-       }
-       if (ucs->urb_ctrl) {
-               usb_kill_urb(ucs->urb_ctrl);
-               gig_dbg(DEBUG_INIT, "%s: control output URB unlinked",
-                       __func__);
-               usb_free_urb(ucs->urb_ctrl);
-               ucs->urb_ctrl = NULL;
+               for (i = 0; i < BAS_OUTURBS; ++i) {
+                       usb_kill_urb(ubc->isoouturbs[i].urb);
+                       usb_free_urb(ubc->isoouturbs[i].urb);
+                       ubc->isoouturbs[i].urb = NULL;
+               }
+               for (i = 0; i < BAS_INURBS; ++i) {
+                       usb_kill_urb(ubc->isoinurbs[i]);
+                       usb_free_urb(ubc->isoinurbs[i]);
+                       ubc->isoinurbs[i] = NULL;
+               }
        }
+       usb_kill_urb(ucs->urb_int_in);
+       usb_free_urb(ucs->urb_int_in);
+       ucs->urb_int_in = NULL;
+       usb_kill_urb(ucs->urb_cmd_out);
+       usb_free_urb(ucs->urb_cmd_out);
+       ucs->urb_cmd_out = NULL;
+       usb_kill_urb(ucs->urb_cmd_in);
+       usb_free_urb(ucs->urb_cmd_in);
+       ucs->urb_cmd_in = NULL;
+       usb_kill_urb(ucs->urb_ctrl);
+       usb_free_urb(ucs->urb_ctrl);
+       ucs->urb_ctrl = NULL;
 }
 
 /* gigaset_probe
index 8e2b03889f3cb0a6b6a8174eac5d7ef0ee34fe5f..94a935089119b48d1d5f14e51ed195caeda1fc2a 100644 (file)
@@ -275,7 +275,7 @@ hysdn_conf_open(struct inode *ino, struct file *filep)
        } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
                /* read access -> output card info data */
 
-               if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
+               if (!(tmp = kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
                        unlock_kernel();
                        return (-EFAULT);       /* out of memory */
                }
index f241f5e551cbf9a803d70fea08beac008b7b99d9..375d956884d73faa0c6168c56fa37748a0610dd9 100644 (file)
@@ -111,7 +111,7 @@ put_log_buffer(hysdn_card * card, char *cp)
        if (pd->if_used <= 0)
                return;         /* no open file for read */
 
-       if (!(ib = (struct log_data *) kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
+       if (!(ib = kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
                 return;        /* no memory */
        strcpy(ib->log_start, cp);      /* set output string */
        ib->next = NULL;
index 2cc56d6a9fae76758e5a2e5f71a84bd4a25dffcf..fb350c567c6ba01c768c87845ed37c70db6a79b2 100644 (file)
@@ -328,7 +328,7 @@ adpcm_state *
 isdn_audio_adpcm_init(adpcm_state * s, int nbits)
 {
        if (!s)
-               s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
+               s = kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
        if (s) {
                s->a = 0;
                s->d = 5;
@@ -343,7 +343,7 @@ dtmf_state *
 isdn_audio_dtmf_init(dtmf_state * s)
 {
        if (!s)
-               s = (dtmf_state *) kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
+               s = kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
        if (s) {
                s->idx = 0;
                s->last = ' ';
@@ -621,7 +621,7 @@ silence_state *
 isdn_audio_silence_init(silence_state * s)
 {
        if (!s)
-               s = (silence_state *) kmalloc(sizeof(silence_state), GFP_ATOMIC);
+               s = kmalloc(sizeof(silence_state), GFP_ATOMIC);
        if (s) {
                s->idx = 0;
                s->state = 0;
index c36c817578cbe65608b745da7b48c1338c6814f5..838b3734e2b6d82cf2bda00072399167077da68a 100644 (file)
@@ -2948,7 +2948,7 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
        isdn_net_phone *n;
 
        if (p) {
-               if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
+               if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
                        return -ENOMEM;
                strcpy(n->num, phone->phone);
                n->next = p->local->phone[phone->outgoing & 1];
index 43811795b46bfb31bdd947e7998e73a487588234..1726131b20be1ed00e2161515582abc89c4de0b2 100644 (file)
@@ -717,7 +717,7 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
                printk(KERN_DEBUG "ippp: device not activated.\n");
                return 0;
        }
-       nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
+       nbuf = kmalloc(len + 4, GFP_ATOMIC);
        if (!nbuf) {
                printk(KERN_WARNING "ippp: Can't alloc buf\n");
                return 0;
index 6ff85574e941ff5ee6b27549a43f45248cd6319f..eafcce5e656a7a796bba72c222ea33ab3ba413ad 100644 (file)
@@ -100,7 +100,7 @@ pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
                dev_kfree_skb(skb);
                return -1;
        }
-       if ((frame = (struct frame_buf *) kmalloc(sizeof(struct frame_buf),
+       if ((frame = kmalloc(sizeof(struct frame_buf),
                                                  GFP_ATOMIC)) == NULL) {
                printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
                dev_kfree_skb(skb);
index 36412e90f09b95be706461504fed6eb823b2d7a0..703cc88d1ef974bcf8d0b27f7625f23d079aec4c 100644 (file)
@@ -1,6 +1,8 @@
 #
 # KVM configuration
 #
+menu "Virtualization"
+
 config KVM
        tristate "Kernel-based Virtual Machine (KVM) support"
        depends on X86 && EXPERIMENTAL
@@ -31,3 +33,5 @@ config KVM_AMD
        ---help---
          Provides support for KVM on AMD processors equipped with the AMD-V
          (SVM) extensions.
+
+endmenu
index 5785d0870ab6ebfc4c45e596a91b21c5999755f3..930e04ce1af63944203017b94957d4fc4a21436f 100644 (file)
@@ -140,7 +140,7 @@ enum {
        VCPU_REGS_RBP = 5,
        VCPU_REGS_RSI = 6,
        VCPU_REGS_RDI = 7,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        VCPU_REGS_R8 = 8,
        VCPU_REGS_R9 = 9,
        VCPU_REGS_R10 = 10,
@@ -375,7 +375,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
 void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
 void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 void set_efer(struct kvm_vcpu *vcpu, u64 efer);
 #endif
 
@@ -485,7 +485,7 @@ static inline unsigned long read_tr_base(void)
        return segment_base(tr);
 }
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 static inline unsigned long read_msr(unsigned long msr)
 {
        u64 value;
@@ -533,7 +533,7 @@ static inline u32 get_rdx_init_val(void)
 #define TSS_REDIRECTION_SIZE (256 / 8)
 #define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1)
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 
 /*
  * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.  Therefore
index b6b8a41b5ec80b9a56bf39355ea3add4893d991b..fd1bb870545c28adc3fa8c4bb7927046504e67e8 100644 (file)
@@ -72,18 +72,7 @@ static struct dentry *debugfs_dir;
 #define CR8_RESEVED_BITS (~0x0fULL)
 #define EFER_RESERVED_BITS 0xfffffffffffff2fe
 
-struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
-{
-       int i;
-
-       for (i = 0; i < vcpu->nmsrs; ++i)
-               if (vcpu->guest_msrs[i].index == msr)
-                       return &vcpu->guest_msrs[i];
-       return 0;
-}
-EXPORT_SYMBOL_GPL(find_msr_entry);
-
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 // LDT or TSS descriptor in the GDT. 16 bytes.
 struct segment_descriptor_64 {
        struct segment_descriptor s;
@@ -115,7 +104,7 @@ unsigned long segment_base(u16 selector)
        }
        d = (struct segment_descriptor *)(table_base + (selector & ~7));
        v = d->base_low | ((ul)d->base_mid << 16) | ((ul)d->base_high << 24);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        if (d->system == 0
            && (d->type == 2 || d->type == 9 || d->type == 11))
                v |= ((ul)((struct segment_descriptor_64 *)d)->base_higher) << 32;
@@ -216,7 +205,6 @@ static struct kvm_vcpu *vcpu_load(struct kvm *kvm, int vcpu_slot)
 static void vcpu_put(struct kvm_vcpu *vcpu)
 {
        kvm_arch_ops->vcpu_put(vcpu);
-       put_cpu();
        mutex_unlock(&vcpu->mutex);
 }
 
@@ -351,7 +339,7 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        }
 
        if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                if ((vcpu->shadow_efer & EFER_LME)) {
                        int cs_db, cs_l;
 
@@ -1120,12 +1108,10 @@ static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
        return kvm_arch_ops->get_msr(vcpu, msr_index, pdata);
 }
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 
 void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
-       struct vmx_msr_entry *msr;
-
        if (efer & EFER_RESERVED_BITS) {
                printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
                       efer);
@@ -1140,16 +1126,12 @@ void set_efer(struct kvm_vcpu *vcpu, u64 efer)
                return;
        }
 
+       kvm_arch_ops->set_efer(vcpu, efer);
+
        efer &= ~EFER_LMA;
        efer |= vcpu->shadow_efer & EFER_LMA;
 
        vcpu->shadow_efer = efer;
-
-       msr = find_msr_entry(vcpu, MSR_EFER);
-
-       if (!(efer & EFER_LMA))
-           efer &= ~EFER_LME;
-       msr->data = efer;
 }
 EXPORT_SYMBOL_GPL(set_efer);
 
@@ -1243,7 +1225,7 @@ static int kvm_dev_ioctl_get_regs(struct kvm *kvm, struct kvm_regs *regs)
        regs->rdi = vcpu->regs[VCPU_REGS_RDI];
        regs->rsp = vcpu->regs[VCPU_REGS_RSP];
        regs->rbp = vcpu->regs[VCPU_REGS_RBP];
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        regs->r8 = vcpu->regs[VCPU_REGS_R8];
        regs->r9 = vcpu->regs[VCPU_REGS_R9];
        regs->r10 = vcpu->regs[VCPU_REGS_R10];
@@ -1287,7 +1269,7 @@ static int kvm_dev_ioctl_set_regs(struct kvm *kvm, struct kvm_regs *regs)
        vcpu->regs[VCPU_REGS_RDI] = regs->rdi;
        vcpu->regs[VCPU_REGS_RSP] = regs->rsp;
        vcpu->regs[VCPU_REGS_RBP] = regs->rbp;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        vcpu->regs[VCPU_REGS_R8] = regs->r8;
        vcpu->regs[VCPU_REGS_R9] = regs->r9;
        vcpu->regs[VCPU_REGS_R10] = regs->r10;
@@ -1401,7 +1383,7 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
        vcpu->cr8 = sregs->cr8;
 
        mmu_reset_needed |= vcpu->shadow_efer != sregs->efer;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        kvm_arch_ops->set_efer(vcpu, sregs->efer);
 #endif
        vcpu->apic_base = sregs->apic_base;
@@ -1434,7 +1416,7 @@ static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
 static u32 msrs_to_save[] = {
        MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
        MSR_K6_STAR,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
        MSR_IA32_TIME_STAMP_COUNTER,
index 7d7f2aa10960db84647d1717ada89b2b574411ec..74cc862f4935ea9bf9a18aecf3daa9ad114cce38 100644 (file)
@@ -9,7 +9,7 @@
 #include "kvm.h"
 
 static const u32 host_save_msrs[] = {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
        MSR_FS_BASE, MSR_GS_BASE,
 #endif
index 87e12d2bfa1676a78700182464d22cd12abe83ed..d139f73fb6e1f280ec5dfe9f10480522df80a645 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __KVM_VMX_H
 #define __KVM_VMX_H
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 /*
  * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
  * mechanism (cpu bug AA24)
index 4e29d9b7211cfd536b80f848d72b6ccfb348b3fd..3d367cbfe1f93ca9ac09a452b0baa9c8cfe262d9 100644 (file)
 
 
 #define PT32_PTE_COPY_MASK \
-       (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
-       PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_PAT_MASK | \
-       PT_GLOBAL_MASK )
-
-#define PT32_NON_PTE_COPY_MASK \
-       (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
-       PT_ACCESSED_MASK | PT_DIRTY_MASK)
-
-
-#define PT64_PTE_COPY_MASK \
-       (PT64_NX_MASK | PT32_PTE_COPY_MASK)
-
-#define PT64_NON_PTE_COPY_MASK \
-       (PT64_NX_MASK | PT32_NON_PTE_COPY_MASK)
-
+       (PT_PRESENT_MASK | PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_GLOBAL_MASK)
 
+#define PT64_PTE_COPY_MASK (PT64_NX_MASK | PT32_PTE_COPY_MASK)
 
 #define PT_FIRST_AVAIL_BITS_SHIFT 9
 #define PT64_SECOND_AVAIL_BITS_SHIFT 52
index 765c2e1a048e100c69d15e0e0ccfbeaace56b5fe..a9771b4c5bb8ff350d647bc14d40c9d97ea61571 100644 (file)
@@ -32,7 +32,6 @@
        #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
        #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
        #define PT_PTE_COPY_MASK PT64_PTE_COPY_MASK
-       #define PT_NON_PTE_COPY_MASK PT64_NON_PTE_COPY_MASK
 #elif PTTYPE == 32
        #define pt_element_t u32
        #define guest_walker guest_walker32
@@ -43,7 +42,6 @@
        #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
        #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
        #define PT_PTE_COPY_MASK PT32_PTE_COPY_MASK
-       #define PT_NON_PTE_COPY_MASK PT32_NON_PTE_COPY_MASK
 #else
        #error Invalid PTTYPE value
 #endif
@@ -105,9 +103,7 @@ static void FNAME(set_pde)(struct kvm_vcpu *vcpu, u64 guest_pde,
        if (PTTYPE == 32 && is_cpuid_PSE36())
                gaddr |= (guest_pde & PT32_DIR_PSE36_MASK) <<
                        (32 - PT32_DIR_PSE36_SHIFT);
-       *shadow_pte = (guest_pde & (PT_NON_PTE_COPY_MASK | PT_GLOBAL_MASK)) |
-                         ((guest_pde & PT_DIR_PAT_MASK) >>
-                                   (PT_DIR_PAT_SHIFT - PT_PAT_SHIFT));
+       *shadow_pte = guest_pde & PT_PTE_COPY_MASK;
        set_pte_common(vcpu, shadow_pte, gaddr,
                       guest_pde & PT_DIRTY_MASK, access_bits);
 }
@@ -162,6 +158,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
                u32 index = SHADOW_PT_INDEX(addr, level);
                u64 *shadow_ent = ((u64 *)__va(shadow_addr)) + index;
                pt_element_t *guest_ent;
+               u64 shadow_pte;
 
                if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) {
                        if (level == PT_PAGE_TABLE_LEVEL)
@@ -204,14 +201,11 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
                shadow_addr = kvm_mmu_alloc_page(vcpu, shadow_ent);
                if (!VALID_PAGE(shadow_addr))
                        return ERR_PTR(-ENOMEM);
-               if (!kvm_arch_ops->is_long_mode(vcpu) && level == 3)
-                       *shadow_ent = shadow_addr |
-                               (*guest_ent & (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK));
-               else {
-                       *shadow_ent = shadow_addr |
-                               (*guest_ent & PT_NON_PTE_COPY_MASK);
-                       *shadow_ent |= (PT_WRITABLE_MASK | PT_USER_MASK);
-               }
+               shadow_pte = shadow_addr | PT_PRESENT_MASK;
+               if (vcpu->mmu.root_level > 3 || level != 3)
+                       shadow_pte |= PT_ACCESSED_MASK
+                               | PT_WRITABLE_MASK | PT_USER_MASK;
+               *shadow_ent = shadow_pte;
                prev_shadow_ent = shadow_ent;
        }
 }
index a33a89c68138a20308089aae0105c25c31da703f..0e6bc8c649ce9ada43835a155be4c40fd439365d 100644 (file)
@@ -287,7 +287,7 @@ static void svm_hardware_enable(void *garbage)
 
        struct svm_cpu_data *svm_data;
        uint64_t efer;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        struct desc_ptr gdt_descr;
 #else
        struct Xgt_desc_struct gdt_descr;
@@ -377,6 +377,7 @@ static __init int svm_hardware_setup(void)
        void *msrpm_va;
        int r;
 
+       kvm_emulator_want_group7_invlpg();
 
        iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER);
 
@@ -397,7 +398,7 @@ static __init int svm_hardware_setup(void)
        memset(msrpm_va, 0xff, PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER));
        msrpm_base = page_to_pfn(msrpm_pages) << PAGE_SHIFT;
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1);
        set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1);
        set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1);
@@ -704,7 +705,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
 
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        if (vcpu->shadow_efer & KVM_EFER_LME) {
                if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK)) {
                        vcpu->shadow_efer |= KVM_EFER_LMA;
@@ -1097,7 +1098,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
        case MSR_IA32_APICBASE:
                *data = vcpu->apic_base;
                break;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case MSR_STAR:
                *data = vcpu->svm->vmcb->save.star;
                break;
@@ -1149,7 +1150,7 @@ static int rdmsr_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 {
        switch (ecx) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case MSR_EFER:
                set_efer(vcpu, data);
                break;
@@ -1172,7 +1173,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
        case MSR_IA32_APICBASE:
                vcpu->apic_base = data;
                break;
-#ifdef __x86_64___
+#ifdef CONFIG_X86_64_
        case MSR_STAR:
                vcpu->svm->vmcb->save.star = data;
                break;
@@ -1345,53 +1346,18 @@ static void kvm_reput_irq(struct kvm_vcpu *vcpu)
 
 static void save_db_regs(unsigned long *db_regs)
 {
-#ifdef __x86_64__
-       asm ("mov %%dr0, %%rax \n\t"
-            "mov %%rax, %[dr0] \n\t"
-            "mov %%dr1, %%rax \n\t"
-            "mov %%rax, %[dr1] \n\t"
-            "mov %%dr2, %%rax \n\t"
-            "mov %%rax, %[dr2] \n\t"
-            "mov %%dr3, %%rax \n\t"
-            "mov %%rax, %[dr3] \n\t"
-            : [dr0] "=m"(db_regs[0]),
-              [dr1] "=m"(db_regs[1]),
-              [dr2] "=m"(db_regs[2]),
-              [dr3] "=m"(db_regs[3])
-            : : "rax");
-#else
-       asm ("mov %%dr0, %%eax \n\t"
-            "mov %%eax, %[dr0] \n\t"
-            "mov %%dr1, %%eax \n\t"
-            "mov %%eax, %[dr1] \n\t"
-            "mov %%dr2, %%eax \n\t"
-            "mov %%eax, %[dr2] \n\t"
-            "mov %%dr3, %%eax \n\t"
-            "mov %%eax, %[dr3] \n\t"
-            : [dr0] "=m"(db_regs[0]),
-              [dr1] "=m"(db_regs[1]),
-              [dr2] "=m"(db_regs[2]),
-              [dr3] "=m"(db_regs[3])
-            : : "eax");
-#endif
+       asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
+       asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
+       asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
+       asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
 }
 
 static void load_db_regs(unsigned long *db_regs)
 {
-       asm volatile ("mov %[dr0], %%dr0 \n\t"
-            "mov %[dr1], %%dr1 \n\t"
-            "mov %[dr2], %%dr2 \n\t"
-            "mov %[dr3], %%dr3 \n\t"
-            :
-            : [dr0] "r"(db_regs[0]),
-              [dr1] "r"(db_regs[1]),
-              [dr2] "r"(db_regs[2]),
-              [dr3] "r"(db_regs[3])
-#ifdef __x86_64__
-            : "rax");
-#else
-            : "eax");
-#endif
+       asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
+       asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
+       asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
+       asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
 }
 
 static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1422,7 +1388,7 @@ again:
                load_db_regs(vcpu->svm->db_regs);
        }
        asm volatile (
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "push %%rbx; push %%rcx; push %%rdx;"
                "push %%rsi; push %%rdi; push %%rbp;"
                "push %%r8;  push %%r9;  push %%r10; push %%r11;"
@@ -1432,7 +1398,7 @@ again:
                "push %%esi; push %%edi; push %%ebp;"
 #endif
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "mov %c[rbx](%[vcpu]), %%rbx \n\t"
                "mov %c[rcx](%[vcpu]), %%rcx \n\t"
                "mov %c[rdx](%[vcpu]), %%rdx \n\t"
@@ -1456,7 +1422,7 @@ again:
                "mov %c[rbp](%[vcpu]), %%ebp \n\t"
 #endif
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                /* Enter guest mode */
                "push %%rax \n\t"
                "mov %c[svm](%[vcpu]), %%rax \n\t"
@@ -1477,7 +1443,7 @@ again:
 #endif
 
                /* Save guest registers, load host registers */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "mov %%rbx, %c[rbx](%[vcpu]) \n\t"
                "mov %%rcx, %c[rcx](%[vcpu]) \n\t"
                "mov %%rdx, %c[rdx](%[vcpu]) \n\t"
@@ -1518,7 +1484,7 @@ again:
                  [rsi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RSI])),
                  [rdi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RDI])),
                  [rbp]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBP]))
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                  ,[r8 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R8 ])),
                  [r9 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R9 ])),
                  [r10]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R10])),
@@ -1663,9 +1629,7 @@ static struct kvm_arch_ops svm_arch_ops = {
 
 static int __init svm_init(void)
 {
-       kvm_emulator_want_group7_invlpg();
-       kvm_init_arch(&svm_arch_ops, THIS_MODULE);
-       return 0;
+       return kvm_init_arch(&svm_arch_ops, THIS_MODULE);
 }
 
 static void __exit svm_exit(void)
index bda7a7ae216769f0c5681e2933696cdf24311857..f0f0b1a781f8191304da44ed396ac8e89cd086ba 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <asm/io.h>
+#include <asm/desc.h>
 
 #include "segment_descriptor.h"
 
@@ -33,7 +34,7 @@ MODULE_LICENSE("GPL");
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
 static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 #define HOST_IS_64 1
 #else
 #define HOST_IS_64 0
@@ -70,15 +71,13 @@ static struct kvm_vmx_segment_field {
 };
 
 static const u32 vmx_msr_index[] = {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
 #endif
        MSR_EFER, MSR_K6_STAR,
 };
 #define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index))
 
-struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr);
-
 static inline int is_page_fault(u32 intr_info)
 {
        return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
@@ -92,6 +91,16 @@ static inline int is_external_interrupt(u32 intr_info)
                == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
 }
 
+static struct vmx_msr_entry *find_msr_entry(struct kvm_vcpu *vcpu, u32 msr)
+{
+       int i;
+
+       for (i = 0; i < vcpu->nmsrs; ++i)
+               if (vcpu->guest_msrs[i].index == msr)
+                       return &vcpu->guest_msrs[i];
+       return 0;
+}
+
 static void vmcs_clear(struct vmcs *vmcs)
 {
        u64 phys_addr = __pa(vmcs);
@@ -137,7 +146,7 @@ static u32 vmcs_read32(unsigned long field)
 
 static u64 vmcs_read64(unsigned long field)
 {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        return vmcs_readl(field);
 #else
        return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32);
@@ -167,7 +176,7 @@ static void vmcs_write32(unsigned long field, u32 value)
 
 static void vmcs_write64(unsigned long field, u64 value)
 {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        vmcs_writel(field, value);
 #else
        vmcs_writel(field, value);
@@ -296,7 +305,7 @@ static void guest_write_tsc(u64 guest_tsc)
 
 static void reload_tss(void)
 {
-#ifndef __x86_64__
+#ifndef CONFIG_X86_64
 
        /*
         * VT restores TR but not its size.  Useless.
@@ -327,7 +336,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
        }
 
        switch (msr_index) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case MSR_FS_BASE:
                data = vmcs_readl(GUEST_FS_BASE);
                break;
@@ -390,7 +399,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
 {
        struct vmx_msr_entry *msr;
        switch (msr_index) {
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case MSR_FS_BASE:
                vmcs_writel(GUEST_FS_BASE, data);
                break;
@@ -525,7 +534,7 @@ static __init void hardware_enable(void *garbage)
        u64 old;
 
        rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
-       if ((old & 5) == 0)
+       if ((old & 5) != 5)
                /* enable and lock */
                wrmsrl(MSR_IA32_FEATURE_CONTROL, old | 5);
        write_cr4(read_cr4() | CR4_VMXE); /* FIXME: not cpu hotplug safe */
@@ -725,7 +734,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
 }
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 
 static void enter_lmode(struct kvm_vcpu *vcpu)
 {
@@ -767,7 +776,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
                enter_rmode(vcpu);
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        if (vcpu->shadow_efer & EFER_LME) {
                if (!is_paging(vcpu) && (cr0 & CR0_PG_MASK))
                        enter_lmode(vcpu);
@@ -808,7 +817,7 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
        vcpu->cr4 = cr4;
 }
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
 
 static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
@@ -883,6 +892,8 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
                ar |= (var->db & 1) << 14;
                ar |= (var->g & 1) << 15;
        }
+       if (ar == 0) /* a 0 value means unusable */
+               ar = AR_UNUSABLE_MASK;
        vmcs_write32(sf->ar_bytes, ar);
 }
 
@@ -1095,7 +1106,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
        vmcs_write16(HOST_FS_SELECTOR, read_fs());    /* 22.2.4 */
        vmcs_write16(HOST_GS_SELECTOR, read_gs());    /* 22.2.4 */
        vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS);  /* 22.2.4 */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        rdmsrl(MSR_FS_BASE, a);
        vmcs_writel(HOST_FS_BASE, a); /* 22.2.4 */
        rdmsrl(MSR_GS_BASE, a);
@@ -1164,8 +1175,10 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
                                VM_ENTRY_CONTROLS, 0);
        vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);  /* 22.2.1 */
 
+#ifdef CONFIG_X86_64
        vmcs_writel(VIRTUAL_APIC_PAGE_ADDR, 0);
        vmcs_writel(TPR_THRESHOLD, 0);
+#endif
 
        vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK);
        vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
@@ -1173,7 +1186,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
        vcpu->cr0 = 0x60000010;
        vmx_set_cr0(vcpu, vcpu->cr0); // enter rmode
        vmx_set_cr4(vcpu, 0);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        vmx_set_efer(vcpu, 0);
 #endif
 
@@ -1689,7 +1702,7 @@ again:
                vmcs_write16(HOST_GS_SELECTOR, 0);
        }
 
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
        vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
 #else
@@ -1713,7 +1726,7 @@ again:
        asm (
                /* Store host registers */
                "pushf \n\t"
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "push %%rax; push %%rbx; push %%rdx;"
                "push %%rsi; push %%rdi; push %%rbp;"
                "push %%r8;  push %%r9;  push %%r10; push %%r11;"
@@ -1727,7 +1740,7 @@ again:
                /* Check if vmlaunch of vmresume is needed */
                "cmp $0, %1 \n\t"
                /* Load guest registers.  Don't clobber flags. */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "mov %c[cr2](%3), %%rax \n\t"
                "mov %%rax, %%cr2 \n\t"
                "mov %c[rax](%3), %%rax \n\t"
@@ -1764,7 +1777,7 @@ again:
                ".globl kvm_vmx_return \n\t"
                "kvm_vmx_return: "
                /* Save guest registers, load host registers, keep flags */
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                "xchg %3,     0(%%rsp) \n\t"
                "mov %%rax, %c[rax](%3) \n\t"
                "mov %%rbx, %c[rbx](%3) \n\t"
@@ -1816,7 +1829,7 @@ again:
                [rsi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RSI])),
                [rdi]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RDI])),
                [rbp]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RBP])),
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                [r8 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R8 ])),
                [r9 ]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R9 ])),
                [r10]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_R10])),
@@ -1837,7 +1850,7 @@ again:
        fx_save(vcpu->guest_fx_image);
        fx_restore(vcpu->host_fx_image);
 
-#ifndef __x86_64__
+#ifndef CONFIG_X86_64
        asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
 #endif
 
@@ -1855,7 +1868,7 @@ again:
                         */
                        local_irq_disable();
                        load_gs(gs_sel);
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
                        wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
 #endif
                        local_irq_enable();
@@ -1965,7 +1978,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
        .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch,
        .set_cr3 = vmx_set_cr3,
        .set_cr4 = vmx_set_cr4,
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        .set_efer = vmx_set_efer,
 #endif
        .get_idt = vmx_get_idt,
@@ -1989,8 +2002,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
 
 static int __init vmx_init(void)
 {
-       kvm_init_arch(&vmx_arch_ops, THIS_MODULE);
-       return 0;
+       return kvm_init_arch(&vmx_arch_ops, THIS_MODULE);
 }
 
 static void __exit vmx_exit(void)
index 7e838bf0592dfd29788ac33e004e8fee33c49a70..1bff3e925fda5686e0bb0042a2189a5593ec8188 100644 (file)
@@ -238,7 +238,7 @@ struct operand {
  * any modified flags.
  */
 
-#if defined(__x86_64__)
+#if defined(CONFIG_X86_64)
 #define _LO32 "k"              /* force 32-bit operand */
 #define _STK  "%%rsp"          /* stack pointer */
 #elif defined(__i386__)
@@ -385,7 +385,7 @@ struct operand {
        } while (0)
 
 /* Emulate an instruction with quadword operands (x86/64 only). */
-#if defined(__x86_64__)
+#if defined(CONFIG_X86_64)
 #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)           \
        do {                                                              \
                __asm__ __volatile__ (                                    \
@@ -495,7 +495,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        case X86EMUL_MODE_PROT32:
                op_bytes = ad_bytes = 4;
                break;
-#ifdef __x86_64__
+#ifdef CONFIG_X86_64
        case X86EMUL_MODE_PROT64:
                op_bytes = 4;
                ad_bytes = 8;
@@ -1341,7 +1341,7 @@ twobyte_special_insn:
                        }
                        break;
                }
-#elif defined(__x86_64__)
+#elif defined(CONFIG_X86_64)
                {
                        unsigned long old, new;
                        if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
index 658b58de30fc83f8f2d7675798055867ce942e22..5d41bd55125e91c53f4461f53c7d6ecfaf2350af 100644 (file)
@@ -162,7 +162,7 @@ struct x86_emulate_ctxt {
 /* Host execution mode. */
 #if defined(__i386__)
 #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
-#elif defined(__x86_64__)
+#elif defined(CONFIG_X86_64)
 #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
 #endif
 
index d43ea81d6df9bcae26441a61edba92349d5308a1..7cec6de5e2b0704b1a74cfa0d4851d7dda72f983 100644 (file)
@@ -828,7 +828,7 @@ static ssize_t adb_write(struct file *file, const char __user *buf,
        if (!access_ok(VERIFY_READ, buf, count))
                return -EFAULT;
 
-       req = (struct adb_request *) kmalloc(sizeof(struct adb_request),
+       req = kmalloc(sizeof(struct adb_request),
                                             GFP_KERNEL);
        if (req == NULL)
                return -ENOMEM;
index 8862a83b8d8480451453fc7e6625350ce7f46cb2..4300c628f8af813d58113273f1402baba69bd87c 100644 (file)
@@ -321,7 +321,7 @@ static int do_open(struct inode * inode, struct file * filp)
 {
        struct apm_user *       as;
 
-       as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
+       as = kmalloc(sizeof(*as), GFP_KERNEL);
        if (as == NULL) {
                printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
                       sizeof(*as));
index 6dde27ab79a817a1c9899eac5a319754e8d8f534..6f30459b9385361d0fae5c61f399bafbaa3d67af 100644 (file)
@@ -945,7 +945,7 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id)
         */
        tlen = sizeof(struct property) + len + 18;
 
-       prop = kcalloc(tlen, 1, GFP_KERNEL);
+       prop = kzalloc(tlen, GFP_KERNEL);
        if (prop == NULL)
                return NULL;
        hdr = (struct smu_sdbp_header *)(prop + 1);
index d9986f3a3fbf37c29b815e51ab9c44b015d43a7b..93e6ef9233f9ec6bdb9632c06db15e301e666c9c 100644 (file)
@@ -847,7 +847,7 @@ pbook_pci_save(void)
        n_pbook_pci_saves = npci;
        if (npci == 0)
                return;
-       ps = (struct pci_save *) kmalloc(npci * sizeof(*ps), GFP_KERNEL);
+       ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL);
        pbook_pci_saves = ps;
        if (ps == NULL)
                return;
index a7a5ab5543389b5171ca770dc4dad7f8fed526d0..4ebd0f2a75ecee907c06b76c659ddc1e9e700841 100644 (file)
@@ -173,7 +173,7 @@ static int make_request(request_queue_t *q, struct bio *bio)
        conf_t *conf = (conf_t*)mddev->private;
        int failit = 0;
 
-       if (bio->bi_rw & 1) {
+       if (bio_data_dir(bio) == WRITE) {
                /* write request */
                if (atomic_read(&conf->counters[WriteAll])) {
                        /* special case - don't decrement, don't generic_make_request,
index b3c5e12f081d7482cfa3d204204e40a5e2424cf4..b30f74be3982ce8fbfad91a5204cc7e49799479d 100644 (file)
@@ -1736,7 +1736,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                /* take from bio_init */
                bio->bi_next = NULL;
                bio->bi_flags |= 1 << BIO_UPTODATE;
-               bio->bi_rw = 0;
+               bio->bi_rw = READ;
                bio->bi_vcnt = 0;
                bio->bi_idx = 0;
                bio->bi_phys_segments = 0;
index 7492d6033ac634250c74f84e9e66273f83ff06b6..f0141910bb8d8a0166df17903c977c404057514c 100644 (file)
@@ -1785,7 +1785,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                                biolist = bio;
                                                bio->bi_private = r10_bio;
                                                bio->bi_end_io = end_sync_read;
-                                               bio->bi_rw = 0;
+                                               bio->bi_rw = READ;
                                                bio->bi_sector = r10_bio->devs[j].addr +
                                                        conf->mirrors[d].rdev->data_offset;
                                                bio->bi_bdev = conf->mirrors[d].rdev->bdev;
@@ -1801,7 +1801,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                                biolist = bio;
                                                bio->bi_private = r10_bio;
                                                bio->bi_end_io = end_sync_write;
-                                               bio->bi_rw = 1;
+                                               bio->bi_rw = WRITE;
                                                bio->bi_sector = r10_bio->devs[k].addr +
                                                        conf->mirrors[i].rdev->data_offset;
                                                bio->bi_bdev = conf->mirrors[i].rdev->bdev;
@@ -1870,7 +1870,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                        biolist = bio;
                        bio->bi_private = r10_bio;
                        bio->bi_end_io = end_sync_read;
-                       bio->bi_rw = 0;
+                       bio->bi_rw = READ;
                        bio->bi_sector = r10_bio->devs[i].addr +
                                conf->mirrors[d].rdev->data_offset;
                        bio->bi_bdev = conf->mirrors[d].rdev->bdev;
index 377f8bc9b78bea8a54b302716a3572fca3cc7202..be008f034ada5e222c18043cf0b766426c86f03c 100644 (file)
@@ -1827,16 +1827,16 @@ static void handle_stripe5(struct stripe_head *sh)
                struct bio *bi;
                mdk_rdev_t *rdev;
                if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
-                       rw = 1;
+                       rw = WRITE;
                else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
-                       rw = 0;
+                       rw = READ;
                else
                        continue;
  
                bi = &sh->dev[i].req;
  
                bi->bi_rw = rw;
-               if (rw)
+               if (rw == WRITE)
                        bi->bi_end_io = raid5_end_write_request;
                else
                        bi->bi_end_io = raid5_end_read_request;
@@ -1872,7 +1872,7 @@ static void handle_stripe5(struct stripe_head *sh)
                                atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
                        generic_make_request(bi);
                } else {
-                       if (rw == 1)
+                       if (rw == WRITE)
                                set_bit(STRIPE_DEGRADED, &sh->state);
                        PRINTK("skip op %ld on disc %d for sector %llu\n",
                                bi->bi_rw, i, (unsigned long long)sh->sector);
@@ -2370,16 +2370,16 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                struct bio *bi;
                mdk_rdev_t *rdev;
                if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags))
-                       rw = 1;
+                       rw = WRITE;
                else if (test_and_clear_bit(R5_Wantread, &sh->dev[i].flags))
-                       rw = 0;
+                       rw = READ;
                else
                        continue;
 
                bi = &sh->dev[i].req;
 
                bi->bi_rw = rw;
-               if (rw)
+               if (rw == WRITE)
                        bi->bi_end_io = raid5_end_write_request;
                else
                        bi->bi_end_io = raid5_end_read_request;
@@ -2415,7 +2415,7 @@ static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
                                atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
                        generic_make_request(bi);
                } else {
-                       if (rw == 1)
+                       if (rw == WRITE)
                                set_bit(STRIPE_DEGRADED, &sh->state);
                        PRINTK("skip op %ld on disc %d for sector %llu\n",
                                bi->bi_rw, i, (unsigned long long)sh->sector);
@@ -2567,7 +2567,7 @@ static int raid5_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_
        unsigned int chunk_sectors = mddev->chunk_size >> 9;
        unsigned int bio_sectors = bio->bi_size >> 9;
 
-       if (bio_data_dir(bio))
+       if (bio_data_dir(bio) == WRITE)
                return biovec->bv_len; /* always allow writes to be mergeable */
 
        max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
@@ -2751,7 +2751,7 @@ static int make_request(request_queue_t *q, struct bio * bi)
        disk_stat_inc(mddev->gendisk, ios[rw]);
        disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi));
 
-       if (bio_data_dir(bi) == READ &&
+       if (rw == READ &&
             mddev->reshape_position == MaxSector &&
             chunk_aligned_read(q,bi))
                return 0;
index 240ad084fa787ae4f5dc07b0acf47f25d2554b5c..50bc32a8bd5533921a9af2923cf618728a18db8b 100644 (file)
@@ -480,7 +480,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
        struct ca_msg *hw_buffer;
        int result = 0;
 
-       if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
+       if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
                dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
                return -ENOMEM;
        }
index 80a85cb4975fb6d28e95f9a9cefc0d1223dc2140..3e35931af35d13cd70d14f04eb5ec9fe26cd7db1 100644 (file)
@@ -657,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
 
        case BTTV_BOARD_TWINHAN_DST:
                /*      DST is not a frontend driver !!!                */
-               state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
+               state = kmalloc(sizeof (struct dst_state), GFP_KERNEL);
                if (!state) {
                        printk("dvb_bt8xx: No memory\n");
                        break;
index 42f39a89bc4d7a05c039e68515394e9b2c59fedc..a6fb1d6a7b5dd168394933b9abb609ae3c7f6c19 100644 (file)
@@ -195,7 +195,7 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
        struct ttusbdecfe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
@@ -215,7 +215,7 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
        struct ttusbdecfe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
+       state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index b1012e92ee04e4b2e524ab44f1f883ad83b21342..917021fc29933ab373ba7641c03d1923bee56026 100644 (file)
@@ -218,7 +218,7 @@ static int dabusb_alloc_buffers (pdabusb_t s)
                 pipesize, packets, transfer_buffer_length);
 
        while (buffers < (s->total_buffer_size << 10)) {
-               b = (pbuff_t) kzalloc (sizeof (buff_t), GFP_KERNEL);
+               b = kzalloc(sizeof (buff_t), GFP_KERNEL);
                if (!b) {
                        err("kzalloc(sizeof(buff_t))==NULL");
                        goto err;
@@ -659,7 +659,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
        switch (cmd) {
 
        case IOCTL_DAB_BULK:
-               pbulk = (pbulk_transfer_t) kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
+               pbulk = kmalloc(sizeof (bulk_transfer_t), GFP_KERNEL);
 
                if (!pbulk) {
                        ret = -ENOMEM;
index 368d6e219fa43b767e2072c1c01a5169ad9f3e6e..86d2884e16c688a5af9c43717f6f7b0a4f379b9b 100644 (file)
@@ -138,7 +138,7 @@ static int grabbuf_alloc(struct planb *pb)
                + MAX_LNUM
 #endif /* PLANB_GSCANLINE */
                );
-       if ((pb->rawbuf = (unsigned char**) kmalloc (npage
+       if ((pb->rawbuf = kmalloc(npage
                                * sizeof(unsigned long), GFP_KERNEL)) == 0)
                return -ENOMEM;
        for (i = 0; i < npage; i++) {
index d8b88024bc2fa4ad93015b70078704e41ab78ffb..b560c9d7c5168f492809ddab1308d64fab75e297 100644 (file)
@@ -690,7 +690,7 @@ int usbvideo_register(
        }
 
        base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
-       cams = (struct usbvideo *) kzalloc(base_size, GFP_KERNEL);
+       cams = kzalloc(base_size, GFP_KERNEL);
        if (cams == NULL) {
                err("Failed to allocate %d. bytes for usbvideo struct", base_size);
                return -ENOMEM;
index 2ae3fb250630be9dd7f51dfa82e6b61e36375ae1..290e641356502fd8c87a95bc2649831d669c4b76 100644 (file)
@@ -346,7 +346,7 @@ videocodec_build_table (void)
                size);
 
        kfree(videocodec_buf);
-       videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
+       videocodec_buf = kmalloc(size, GFP_KERNEL);
 
        i = 0;
        i += scnprintf(videocodec_buf + i, size - 1,
index dc388a3ff5e0f34752789c4e8e56325344ebea77..cbe384fb848c97078d609a751d34a8d0f627cfa7 100644 (file)
@@ -18,7 +18,7 @@ extern struct i2o_driver i2o_exec_driver;
 extern int i2o_exec_lct_get(struct i2o_controller *);
 
 extern int __init i2o_exec_init(void);
-extern void __exit i2o_exec_exit(void);
+extern void i2o_exec_exit(void);
 
 /* driver */
 extern struct bus_type i2o_bus_type;
@@ -26,7 +26,7 @@ extern struct bus_type i2o_bus_type;
 extern int i2o_driver_dispatch(struct i2o_controller *, u32);
 
 extern int __init i2o_driver_init(void);
-extern void __exit i2o_driver_exit(void);
+extern void i2o_driver_exit(void);
 
 /* PCI */
 extern int __init i2o_pci_init(void);
index 9104b65ff70f0e85de7522deddd017313159edf6..d3235f213c8933fe72bf77d464e64a69b8789b09 100644 (file)
@@ -362,7 +362,7 @@ int __init i2o_driver_init(void)
  *
  *     Unregisters the I2O bus and frees driver array.
  */
-void __exit i2o_driver_exit(void)
+void i2o_driver_exit(void)
 {
        bus_unregister(&i2o_bus_type);
        kfree(i2o_drivers);
index 902753b2c66101858fe295e7bc97c24cff674389..a539d3b61e7680ee739b830a6f2319e7f2ade102 100644 (file)
@@ -595,7 +595,7 @@ int __init i2o_exec_init(void)
  *
  *     Unregisters the Exec OSM from the I2O core.
  */
-void __exit i2o_exec_exit(void)
+void i2o_exec_exit(void)
 {
        i2o_driver_unregister(&i2o_exec_driver);
 };
index 1de30d711671ce91ae354027fe36f9b2e2e508fb..e33d446e74939df3875e619e59fde8ae638c13d0 100644 (file)
@@ -186,7 +186,7 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type)
        if (!dev)
                return -ENXIO;
 
-       ops = (u8 *) kmalloc(kcmd.oplen, GFP_KERNEL);
+       ops = kmalloc(kcmd.oplen, GFP_KERNEL);
        if (!ops)
                return -ENOMEM;
 
@@ -199,7 +199,7 @@ static int i2o_cfg_parms(unsigned long arg, unsigned int type)
         * It's possible to have a _very_ large table
         * and that the user asks for all of it at once...
         */
-       res = (u8 *) kmalloc(65536, GFP_KERNEL);
+       res = kmalloc(65536, GFP_KERNEL);
        if (!res) {
                kfree(ops);
                return -ENOMEM;
index 5db71604592789492a5718150d9659d1d0455b77..0a7e86859bf10677de7d3bc4227d84ed098303ba 100644 (file)
@@ -459,7 +459,7 @@ add_dataflash(struct spi_device *spi, char *name,
        struct mtd_info                 *device;
        struct flash_platform_data      *pdata = spi->dev.platform_data;
 
-       priv = (struct dataflash *) kzalloc(sizeof *priv, GFP_KERNEL);
+       priv = kzalloc(sizeof *priv, GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
index fa4362fb4dd8a2b7260b75ae66c0866dcb472233..0f3baa5d9c2a08a147639518f4703251e595b7ad 100644 (file)
@@ -768,7 +768,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        if (mtd->type != MTD_NORFLASH)
                return;
 
-       part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
+       part = kzalloc(sizeof(struct partition), GFP_KERNEL);
        if (!part)
                return;
 
index b98592a8bac8034fb899c6b7f6c452be1b1bb68e..f22e46dfd770681c2772b1b9d904811e55e33475 100644 (file)
@@ -186,7 +186,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
  */
 static int ipddp_create(struct ipddp_route *new_rt)
 {
-        struct ipddp_route *rt =(struct ipddp_route*) kmalloc(sizeof(*rt), GFP_KERNEL);
+        struct ipddp_route *rt = kmalloc(sizeof(*rt), GFP_KERNEL);
 
         if (rt == NULL)
                 return -ENOMEM;
index bae1de1e78025ff05dbe12e8827ce49a0f38c9ca..7845eaf6f29f9f38a4d2b6ad9b5aa56496c82568 100644 (file)
@@ -395,7 +395,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
  * Allocate the main control structure for this instance.
  */
     maxmaxcode = MAXCODE(bits);
-    db         = (struct bsd_db *) kmalloc (sizeof (struct bsd_db),
+    db         = kmalloc(sizeof (struct bsd_db),
                                            GFP_KERNEL);
     if (!db)
       {
index 16620bd97fbf71c60738762927fb1a2c4ebd0f25..11af0ae7510e0823d033629a3bdf15f1a6175f2c 100644 (file)
@@ -1603,7 +1603,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
   irda_qos_bits_to_value (&self->qos);
 
   /* Allocate twice the size to guarantee alignment */
-  self->ringbuf = (void *) kmalloc (OBOE_RING_LEN << 1, GFP_KERNEL);
+  self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
   if (!self->ringbuf)
     {
       printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
index 6e95645e72459b7aee4d06c39a532026f6565662..3ca1082ec7764b9b831e51c55745c2f43ef7b37c 100644 (file)
@@ -1747,7 +1747,7 @@ static int irda_usb_probe(struct usb_interface *intf,
        /* Don't change this buffer size and allocation without doing
         * some heavy and complete testing. Don't ask why :-(
         * Jean II */
-       self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
+       self->speed_buff = kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
        if (self->speed_buff == NULL) 
                goto err_out_3;
 
index 654a68b490ae6011f7810e968c8426e382b69872..3098960dc2a134ce97df39c125a0ba2492c01b75 100644 (file)
@@ -164,7 +164,7 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
        
        /* Allocate memory if needed */
        if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+               self->tx_buff.head = kmalloc(self->tx_buff.truesize,
                                                      GFP_KERNEL);
                if (self->tx_buff.head == NULL) {
                        IRDA_ERROR("%s(), can't allocate memory for "
index b833016f1825fecf5b5008d4cb626ae15241be46..177c502f73857d38ef4a52ada04d0f56065b93ba 100644 (file)
@@ -884,7 +884,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
 
        dev->trans_start = jiffies;
 
-       tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
+       tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
        if (tx_cmd == NULL) {
                printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
                lp->stats.tx_dropped++;
@@ -1266,7 +1266,7 @@ static void set_multicast_list(struct net_device *dev) {
        if (dev->mc_count > 0) {
                struct dev_mc_list *dmi;
                char *cp;
-               cmd = (struct i596_cmd *)kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
+               cmd = kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
                if (cmd == NULL) {
                        printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name);
                        return;
index b01fc70a57db63a20e06ff58108621965a5b31a2..a4d7529ef41515d464282c883fe6c191b8b4366d 100644 (file)
@@ -50,7 +50,7 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
        struct phy_device *dev;
        /* We allocate the device, and initialize the
         * default values */
-       dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 
        if (NULL == dev)
                return (struct phy_device*) PTR_ERR((void*)-ENOMEM);
index f54c55242f4a26922c8c1414b6c4308209b99e9f..72c8d6628f583a041023dfab6a90d7922e101cf8 100644 (file)
@@ -121,7 +121,7 @@ static void *z_comp_alloc(unsigned char *options, int opt_len)
        if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
                return NULL;
 
-       state = (struct ppp_deflate_state *) kmalloc(sizeof(*state),
+       state = kmalloc(sizeof(*state),
                                                     GFP_KERNEL);
        if (state == NULL)
                return NULL;
@@ -341,7 +341,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len)
        if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
                return NULL;
 
-       state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+       state = kmalloc(sizeof(*state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index f3655fd772f5b765c7f0e33fb693480a255135ae..d5bdd25746591a8b0bb47b2dca226b3fbca34fcf 100644 (file)
@@ -200,7 +200,7 @@ static void *mppe_alloc(unsigned char *options, int optlen)
            || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
                goto out;
 
-       state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+       state = kmalloc(sizeof(*state), GFP_KERNEL);
        if (state == NULL)
                goto out;
 
index b60f0451f6cdaddff325b599ae5f37e85a6e5c4e..8a39376f87dc27bf5431bbd596eae58429fc7671 100644 (file)
@@ -749,7 +749,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
        struct skge_element *e;
        int i;
 
-       ring->start = kcalloc(sizeof(*e), ring->count, GFP_KERNEL);
+       ring->start = kcalloc(ring->count, sizeof(*e), GFP_KERNEL);
        if (!ring->start)
                return -ENOMEM;
 
index 39c2152a07f426a9676263f6391a742c5d41ef89..a0806d262fc6530c1e72c2c75b14a999cc74e529 100644 (file)
@@ -229,10 +229,10 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
        if (len < 576 * 2)
                len = 576 * 2;
 
-       xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
-       rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+       xbuff = kmalloc(len + 4, GFP_ATOMIC);
+       rbuff = kmalloc(len + 4, GFP_ATOMIC);
 #ifdef SL_INCLUDE_CSLIP
-       cbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+       cbuff = kmalloc(len + 4, GFP_ATOMIC);
 #endif
 
 
index a4f735723c4100ad2a7df897f8868f4e1a4b2b93..a02c5fb40567eb59b73daabd5f93b8d063720e60 100644 (file)
@@ -231,7 +231,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
                return NULL;
        }
        
-       sv=(struct sv11_device *)kmalloc(sizeof(struct sv11_device), GFP_KERNEL);
+       sv = kmalloc(sizeof(struct sv11_device), GFP_KERNEL);
        if(!sv)
                goto fail3;
                        
index 36d1c3ff7078d28c91827e5af3d99644df09c0e0..62184dee377c5961c33b30179ba8784ea45185c1 100644 (file)
@@ -3455,7 +3455,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if ((err = pci_enable_device(pdev)) < 0)
                return err;
 
-       card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL);
+       card = kmalloc(sizeof(pc300_t), GFP_KERNEL);
        if (card == NULL) {
                printk("PC300 found at RAM 0x%016llx, "
                       "but could not allocate card structure.\n",
index b2a23aed4428576b5dc55adfc60db4588f6e001f..5873c346e7e9ee25ee53f3679982407c6b99d0eb 100644 (file)
@@ -784,7 +784,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        continue;
                } 
                
-               new = (st_cpc_rx_buf *)kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+               new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
                if (new == 0) {
                        cpc_tty_rx_disc_frame(pc300chan);
                        continue;
index 9c3ccc6691435b7b5ac96a266566fa8d6f93e8bb..1c9edd97accd679a816a66aa6e2a8cbb422c6d30 100644 (file)
@@ -123,8 +123,8 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
        unsigned char *xbuff, *rbuff;
        int len = 2* newmtu;
 
-       xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
-       rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
+       xbuff = kmalloc(len + 4, GFP_ATOMIC);
+       rbuff = kmalloc(len + 4, GFP_ATOMIC);
 
        if (xbuff == NULL || rbuff == NULL)  
        {
@@ -465,11 +465,11 @@ static int x25_asy_open(struct net_device *dev)
 
        len = dev->mtu * 2;
 
-       sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+       sl->rbuff = kmalloc(len + 4, GFP_KERNEL);
        if (sl->rbuff == NULL)   {
                goto norbuff;
        }
-       sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
+       sl->xbuff = kmalloc(len + 4, GFP_KERNEL);
        if (sl->xbuff == NULL)   {
                goto noxbuff;
        }
index 974a8e5bec8b493b6061a6433fa02fabdf5d1094..efb8cf3bd8ad6c0eaebc789fd2b8caf787d48d88 100644 (file)
@@ -1253,7 +1253,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
                        return NULL;
        }
 
-       tmpbuf = (char *) kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
+       tmpbuf = kmalloc(WLAN_AUTH_CHALLENGE_LEN, GFP_ATOMIC);
        if (tmpbuf == NULL) {
                PDEBUG(DEBUG_AP, "AP: kmalloc failed for challenge\n");
                return NULL;
index 24fc387bba6753255caee927c78352a6bcc2a2fc..c7678e67697dc435ebf721f13b253058aafb1bf0 100644 (file)
@@ -201,7 +201,7 @@ static u8 * prism2_read_pda(struct net_device *dev)
                0x7f0002 /* Intel PRO/Wireless 2011B (PCI) */,
        };
 
-       buf = (u8 *) kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
+       buf = kmalloc(PRISM2_PDA_SIZE, GFP_KERNEL);
        if (buf == NULL)
                return NULL;
 
index a394a23b9a20090ae54922a774725d2848cdd332..3079378fb8cd284effe9f0285a3a81c5f8af1392 100644 (file)
@@ -2252,7 +2252,7 @@ static int hostap_tx_compl_read(local_info_t *local, int error,
        if (txdesc->sw_support) {
                len = le16_to_cpu(txdesc->data_len);
                if (len < PRISM2_DATA_MAXLEN) {
-                       *payload = (char *) kmalloc(len, GFP_ATOMIC);
+                       *payload = kmalloc(len, GFP_ATOMIC);
                        if (*payload == NULL ||
                            hfa384x_from_bap(dev, BAP0, *payload, len)) {
                                PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
index 3b7b8063ff1c7803eb18fb3ba48039ee5c65077f..cb08bc5db2bd52b3b14b11fd6e3408d27c72b963 100644 (file)
@@ -3829,7 +3829,7 @@ static int prism2_ioctl_priv_hostapd(local_info_t *local, struct iw_point *p)
            p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+       param = kmalloc(p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
index 0796be9d9e77b2644901285a75db9250dc6e732b..04c19cefa1da4dad3f1e4da8d9d241199e622af2 100644 (file)
@@ -250,7 +250,7 @@ u16 hostap_tx_callback_register(local_info_t *local,
        unsigned long flags;
        struct hostap_tx_callback_info *entry;
 
-       entry = (struct hostap_tx_callback_info *) kmalloc(sizeof(*entry),
+       entry = kmalloc(sizeof(*entry),
                                                           GFP_ATOMIC);
        if (entry == NULL)
                return 0;
index dd9ba4aad7bb402b080518351f87db32da015f83..0e94fbbf7a941801eb1bbf2051323fe15f793eb4 100644 (file)
@@ -2246,7 +2246,7 @@ static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
        if (priv->snapshot[0])
                return 1;
        for (i = 0; i < 0x30; i++) {
-               priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
+               priv->snapshot[i] = kmalloc(0x1000, GFP_ATOMIC);
                if (!priv->snapshot[i]) {
                        IPW_DEBUG_INFO("%s: Error allocating snapshot "
                                       "buffer %d\n", priv->net_dev->name, i);
index 96606ed100761bca80fc5a04524f2b5fc0868959..838d510213c60ef74b3e6c1e04d24b156e27db01 100644 (file)
@@ -2775,7 +2775,7 @@ prism54_hostapd(struct net_device *ndev, struct iw_point *p)
            p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+       param = kmalloc(p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
index 233d906c08f0eed014e14a3395fe31ff562cd7b4..5eb81638e8467a1ff7b516a33aa9888941839f31 100644 (file)
@@ -603,7 +603,7 @@ static wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char se
   if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
     return NULL;
   
-  new_wavepoint=(wavepoint_history *) kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
+  new_wavepoint = kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
   if(new_wavepoint==NULL)
     return NULL;
   
index 77e11ddad836d135f444d53f567262686d408c96..78ea72fb8f0ce9a3de74d6fd594442d90527ee4d 100644 (file)
@@ -101,7 +101,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
 
        /* Allocate a single memory block for values and addresses. */
        count16 = 2*count;
-       a16 = (zd_addr_t *)kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+       a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
                                   GFP_NOFS);
        if (!a16) {
                dev_dbg_f(zd_chip_dev(chip),
index 12bab64a62a15da1d1f853a0fa203cc268c6d311..6fb3f7979f21b89043bb3cc90d16240d110c590d 100644 (file)
@@ -874,7 +874,7 @@ void *iosapic_register(unsigned long hpa)
                return NULL;
        }
 
-       isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
+       isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
        if (!isi) {
                BUG();
                return NULL;
index 298a6cfd84069fce3845a9ad9c14989449a9450d..ae5e974c45a794aa0a16c968ac1eb21b69c84b8e 100644 (file)
@@ -520,7 +520,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                        return 2;
 
                while (nummem--) {
-                       mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+                       mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
                        if (!mem_node)
                                break;
@@ -548,7 +548,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                }
 
                while (numpmem--) {
-                       p_mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+                       p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
                        if (!p_mem_node)
                                break;
@@ -576,7 +576,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                }
 
                while (numio--) {
-                       io_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+                       io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
                        if (!io_node)
                                break;
@@ -604,7 +604,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
                }
 
                while (numbus--) {
-                       bus_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+                       bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
 
                        if (!bus_node)
                                break;
index 6d3f580f2666a07135ac6e5a6a0050df62062e31..25d3aadfddbf8c13b2e642c37cbd8641d34213a0 100644 (file)
@@ -1320,7 +1320,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
        DBG_ENTER_ROUTINE
        
        spin_lock_init(&list_lock);     
-       php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
+       php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
 
        if (!php_ctlr) {        /* allocate controller state data */
                err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
index 55866b6b26fac755d6ba194fedf875965d71b060..6f5fabbd14e58f77453c112e9c77850af1d38b52 100644 (file)
@@ -148,7 +148,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
 {
        struct aer_rpc *rpc;
 
-       if (!(rpc = (struct aer_rpc *)kmalloc(sizeof(struct aer_rpc),
+       if (!(rpc = kmalloc(sizeof(struct aer_rpc),
                GFP_KERNEL)))
                return NULL;
 
index 52d4a38b366735714e8f3c90c9fca4022dcd6a70..3334f22a86c0617f3a16471db8ffb064fadecbf9 100644 (file)
@@ -230,7 +230,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        if (!io)
                return -ENODEV;
 
-       cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+       cf = kzalloc(sizeof *cf, GFP_KERNEL);
        if (!cf)
                return -ENOMEM;
 
index 06bf7f48836ea9edcf0c1e503041a90f393e3ece..e65a6b8188f6c896d715f56b71f09b05618a7a3c 100644 (file)
@@ -220,7 +220,7 @@ static int __devinit omap_cf_probe(struct device *dev)
        if (irq < 0)
                return -EINVAL;
 
-       cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
+       cf = kzalloc(sizeof *cf, GFP_KERNEL);
        if (!cf)
                return -ENOMEM;
        init_timer(&cf->timer);
index 3ac5b123215a09f17551531d106324e1e8ac9554..a0b158704ca1f8f5eb5982f55477c96586d5692f 100644 (file)
@@ -395,7 +395,7 @@ static void isapnp_parse_id(struct pnp_dev * dev, unsigned short vendor, unsigne
        struct pnp_id * id;
        if (!dev)
                return;
-       id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+       id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
        if (!id)
                return;
        sprintf(id->id, "%c%c%c%x%x%x%x",
@@ -419,7 +419,7 @@ static struct pnp_dev * __init isapnp_parse_device(struct pnp_card *card, int si
        struct pnp_dev *dev;
 
        isapnp_peek(tmp, size);
-       dev = kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
        if (!dev)
                return NULL;
        dev->number = number;
@@ -450,7 +450,7 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
        unsigned long bits;
 
        isapnp_peek(tmp, size);
-       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
        bits = (tmp[1] << 8) | tmp[0];
@@ -474,7 +474,7 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
        struct pnp_dma *dma;
 
        isapnp_peek(tmp, size);
-       dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+       dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
        if (!dma)
                return;
        dma->map = tmp[0];
@@ -494,7 +494,7 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
        struct pnp_port *port;
 
        isapnp_peek(tmp, size);
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = (tmp[2] << 8) | tmp[1];
@@ -517,7 +517,7 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
        struct pnp_port *port;
 
        isapnp_peek(tmp, size);
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = port->max = (tmp[1] << 8) | tmp[0];
@@ -539,7 +539,7 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
        struct pnp_mem *mem;
 
        isapnp_peek(tmp, size);
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
@@ -562,7 +562,7 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
        struct pnp_mem *mem;
 
        isapnp_peek(tmp, size);
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
@@ -584,7 +584,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
        struct pnp_mem *mem;
 
        isapnp_peek(tmp, size);
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = mem->max = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
@@ -829,7 +829,7 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
 
 static void isapnp_parse_card_id(struct pnp_card * card, unsigned short vendor, unsigned short device)
 {
-       struct pnp_id * id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+       struct pnp_id * id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
        if (!id)
                return;
        sprintf(id->id, "%c%c%c%x%x%x%x",
@@ -865,7 +865,7 @@ static int __init isapnp_build_device_list(void)
                        header[4], header[5], header[6], header[7], header[8]);
                printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
 #endif
-               if ((card = kcalloc(1, sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
+               if ((card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
                        continue;
 
                card->number = csn;
index 6cf34a63c79044f39f122633b07d836fb75eb4ef..62eda5d5902413136a2006e8ba2242c1c76ad641 100644 (file)
@@ -139,7 +139,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
                return 0;
 
        pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));
-       dev =  kcalloc(1, sizeof(struct pnp_dev), GFP_KERNEL);
+       dev =  kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
        if (!dev) {
                pnp_err("Out of memory");
                return -ENOMEM;
@@ -169,7 +169,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
        dev->number = num;
        
        /* set the initial values for the PnP device */
-       dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+       dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
        if (!dev_id)
                goto err;
        pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
@@ -201,7 +201,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
                for (i = 0; i < cid_list->count; i++) {
                        if (!ispnpidacpi(cid_list->id[i].value))
                                continue;
-                       dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+                       dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
                        if (!dev_id)
                                continue;
 
index 379048fdf05dccf01575a5727219529ac7d39fac..7a535542fe9204a0bb5336f0e0c7894c38726f3e 100644 (file)
@@ -298,7 +298,7 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso
 
        if (p->channel_count == 0)
                return;
-       dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+       dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
        if (!dma)
                return;
 
@@ -354,7 +354,7 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option,
 
        if (p->interrupt_count == 0)
                return;
-       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
 
@@ -375,7 +375,7 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
 
        if (p->interrupt_count == 0)
                return;
-       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
 
@@ -396,7 +396,7 @@ pnpacpi_parse_port_option(struct pnp_option *option,
 
        if (io->address_length == 0)
                return;
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = io->minimum;
@@ -417,7 +417,7 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option,
 
        if (io->address_length == 0)
                return;
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = port->max = io->address;
@@ -436,7 +436,7 @@ pnpacpi_parse_mem24_option(struct pnp_option *option,
 
        if (p->address_length == 0)
                return;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = p->minimum;
@@ -459,7 +459,7 @@ pnpacpi_parse_mem32_option(struct pnp_option *option,
 
        if (p->address_length == 0)
                return;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = p->minimum;
@@ -482,7 +482,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
 
        if (p->address_length == 0)
                return;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = mem->max = p->address;
@@ -514,7 +514,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
                return;
 
        if (p->resource_type == ACPI_MEMORY_RANGE) {
-               mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+               mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
                if (!mem)
                        return;
                mem->min = mem->max = p->minimum;
@@ -524,7 +524,7 @@ pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
                    ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0;
                pnp_register_mem_resource(option, mem);
        } else if (p->resource_type == ACPI_IO_RANGE) {
-               port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+               port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
                if (!port)
                        return;
                port->min = port->max = p->minimum;
@@ -721,7 +721,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
        if (!res_cnt)
                return -EINVAL;
        buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
-       buffer->pointer = kcalloc(1, buffer->length - 1, GFP_KERNEL);
+       buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
        if (!buffer->pointer)
                return -ENOMEM;
        pnp_dbg("Res cnt %d", res_cnt);
index 33adeba1a31f1c87930e1266989a44b36b9f775e..95738dbd5d4555cec6428595b06ce72cd32aa8be 100644 (file)
@@ -109,10 +109,10 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
        if (!current->fs->root) {
                return -EAGAIN;
        }
-       if (!(envp = (char **) kcalloc (20, sizeof (char *), GFP_KERNEL))) {
+       if (!(envp = kcalloc(20, sizeof (char *), GFP_KERNEL))) {
                return -ENOMEM;
        }
-       if (!(buf = kcalloc (1, 256, GFP_KERNEL))) {
+       if (!(buf = kzalloc(256, GFP_KERNEL))) {
                kfree (envp);
                return -ENOMEM;
        }
@@ -220,7 +220,7 @@ static int pnpbios_get_resources(struct pnp_dev * dev, struct pnp_resource_table
        if(!pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -1;
        if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
@@ -243,7 +243,7 @@ static int pnpbios_set_resources(struct pnp_dev * dev, struct pnp_resource_table
        if (!pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -1;
        if (pnp_bios_get_dev_node(&nodenum, (char )PNPMODE_DYNAMIC, node)) {
@@ -294,7 +294,7 @@ static int pnpbios_disable_resources(struct pnp_dev *dev)
        if(dev->flags & PNPBIOS_NO_DISABLE || !pnpbios_is_dynamic(dev))
                return -EPERM;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -ENOMEM;
 
@@ -336,7 +336,7 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node)
        }
 
        /* set the initial values for the PnP device */
-       dev_id = kcalloc(1, sizeof(struct pnp_id), GFP_KERNEL);
+       dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
        if (!dev_id)
                return -1;
        pnpid32_to_pnpid(node->eisa_id,id);
@@ -374,7 +374,7 @@ static void __init build_devlist(void)
        struct pnp_bios_node *node;
        struct pnp_dev *dev;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return;
 
@@ -391,7 +391,7 @@ static void __init build_devlist(void)
                                break;
                }
                nodes_got++;
-               dev =  kcalloc(1, sizeof (struct pnp_dev), GFP_KERNEL);
+               dev =  kzalloc(sizeof (struct pnp_dev), GFP_KERNEL);
                if (!dev)
                        break;
                if(insert_device(dev,node)<0)
index 5a3dfc97f5e90ef655aac0ce5a7c6576a6274a70..8027073f7919b78f7071edb7db11fabece4d314e 100644 (file)
@@ -87,7 +87,7 @@ static int proc_read_escd(char *buf, char **start, off_t pos,
                return -EFBIG;
        }
 
-       tmpbuf = kcalloc(1, escd.escd_size, GFP_KERNEL);
+       tmpbuf = kzalloc(escd.escd_size, GFP_KERNEL);
        if (!tmpbuf) return -ENOMEM;
 
        if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base)) {
@@ -133,7 +133,7 @@ static int proc_read_devices(char *buf, char **start, off_t pos,
        if (pos >= 0xff)
                return 0;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node) return -ENOMEM;
 
        for (nodenum=pos; nodenum<0xff; ) {
@@ -168,7 +168,7 @@ static int proc_read_node(char *buf, char **start, off_t pos,
        u8 nodenum = (long)data;
        int len;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node) return -ENOMEM;
        if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
                kfree(node);
@@ -188,7 +188,7 @@ static int proc_write_node(struct file *file, const char __user *buf,
        u8 nodenum = (long)data;
        int ret = count;
 
-       node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
+       node = kzalloc(node_info.max_node_size, GFP_KERNEL);
        if (!node)
                return -ENOMEM;
        if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
index ef508a4de557fd23ca4816f9313b3e4a66846dea..95b79685a9d1e1f72dbe6b36f68748c60c7bd034 100644 (file)
@@ -248,7 +248,7 @@ static void
 pnpbios_parse_mem_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_mem * mem;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = ((p[5] << 8) | p[4]) << 8;
@@ -264,7 +264,7 @@ static void
 pnpbios_parse_mem32_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_mem * mem;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
@@ -280,7 +280,7 @@ static void
 pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_mem * mem;
-       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
@@ -297,7 +297,7 @@ pnpbios_parse_irq_option(unsigned char *p, int size, struct pnp_option *option)
        struct pnp_irq * irq;
        unsigned long bits;
 
-       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
        bits = (p[2] << 8) | p[1];
@@ -314,7 +314,7 @@ static void
 pnpbios_parse_dma_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_dma * dma;
-       dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
+       dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
        if (!dma)
                return;
        dma->map = p[1];
@@ -327,7 +327,7 @@ static void
 pnpbios_parse_port_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_port * port;
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = (p[3] << 8) | p[2];
@@ -343,7 +343,7 @@ static void
 pnpbios_parse_fixed_port_option(unsigned char *p, int size, struct pnp_option *option)
 {
        struct pnp_port * port;
-       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
+       port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = port->max = (p[2] << 8) | p[1];
@@ -527,7 +527,7 @@ pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_de
                case SMALL_TAG_COMPATDEVID: /* compatible ID */
                        if (len != 4)
                                goto len_err;
-                       dev_id =  kcalloc(1, sizeof (struct pnp_id), GFP_KERNEL);
+                       dev_id =  kzalloc(sizeof (struct pnp_id), GFP_KERNEL);
                        if (!dev_id)
                                return NULL;
                        memset(dev_id, 0, sizeof(struct pnp_id));
index 5c8addcaf1fbd8a0a49078155a81be129b040800..4f654c901c64d8c37278970576d13cdd829de904 100644 (file)
@@ -137,6 +137,9 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
        tm->tm_year = at91_alarm_year - 1900;
 
+       alrm->enabled = (at91_sys_read(AT91_RTC_IMR) & AT91_RTC_ALARM)
+                       ? 1 : 0;
+
        pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
                1900 + tm->tm_year, tm->tm_mon, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -223,8 +226,6 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 {
        unsigned long imr = at91_sys_read(AT91_RTC_IMR);
 
-       seq_printf(seq, "alarm_IRQ\t: %s\n",
-                       (imr & AT91_RTC_ALARM) ? "yes" : "no");
        seq_printf(seq, "update_IRQ\t: %s\n",
                        (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
        seq_printf(seq, "periodic_IRQ\t: %s\n",
index 828b329e08e0ca62a23617863825a325ca3511d7..94d3df62a5fa85834d440839bba21f6c3054958b 100644 (file)
@@ -435,7 +435,7 @@ static int rtc_dev_add_device(struct class_device *class_dev,
                goto err_cdev_del;
        }
 
-       dev_info(class_dev->dev, "rtc intf: dev (%d:%d)\n",
+       dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n",
                MAJOR(rtc->rtc_dev->devt),
                MINOR(rtc->rtc_dev->devt));
 
index eac5fb1fc02f4c9a66ff4d8e4bffacea3cee9715..d59880d44fba26e3555c46d000c13a65e12d3ec4 100644 (file)
@@ -279,9 +279,8 @@ static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
        local_irq_enable();
 
        bcd2tm(&alm->time);
-       alm->pending = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
+       alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
                        & OMAP_RTC_INTERRUPTS_IT_ALARM);
-       alm->enabled = alm->pending && device_may_wakeup(dev);
 
        return 0;
 }
index d51d8f20e634e020428b834febb6852731303310..c272afd62173245b3d6d503fd9703a8102891329 100644 (file)
@@ -65,7 +65,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
                        seq_printf(seq, "%02d\n", alrm.time.tm_mday);
                else
                        seq_printf(seq, "**\n");
-               seq_printf(seq, "alrm_wakeup\t: %s\n",
+               seq_printf(seq, "alarm_IRQ\t: %s\n",
                                alrm.enabled ? "yes" : "no");
                seq_printf(seq, "alrm_pending\t: %s\n",
                                alrm.pending ? "yes" : "no");
@@ -120,7 +120,7 @@ static int rtc_proc_add_device(struct class_device *class_dev,
                        ent->owner = rtc->owner;
                        ent->data = class_dev;
 
-                       dev_info(class_dev->dev, "rtc intf: proc\n");
+                       dev_dbg(class_dev->dev, "rtc intf: proc\n");
                }
                else
                        rtc_dev = NULL;
index e301dea57bb37fff0918791a2f6e74117c079b88..f406a2b55aea829b48e05b53180e40e8b1a48a04 100644 (file)
@@ -191,6 +191,8 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        alm_en = readb(base + S3C2410_RTCALM);
 
+       alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0;
+
        pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
                 alm_en,
                 alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
@@ -331,12 +333,8 @@ static int s3c_rtc_ioctl(struct device *dev,
 
 static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       unsigned int rtcalm = readb(s3c_rtc_base + S3C2410_RTCALM);
        unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
 
-       seq_printf(seq, "alarm_IRQ\t: %s\n",
-                  (rtcalm & S3C2410_RTCALM_ALMEN) ? "yes" : "no" );
-
        seq_printf(seq, "periodic_IRQ\t: %s\n",
                     (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
 
index bd4d7d174ef4a01a7d58d5835cea904d910e50dc..9c8ead43a59c38561c1393ea32a1b66b187e0578 100644 (file)
@@ -289,9 +289,7 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
 {
-       seq_printf(seq, "trim/divider\t: 0x%08lx\n", RTTR);
-       seq_printf(seq, "alarm_IRQ\t: %s\n",
-                       (RTSR & RTSR_ALE) ? "yes" : "no" );
+       seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR);
        seq_printf(seq, "update_IRQ\t: %s\n",
                        (RTSR & RTSR_HZE) ? "yes" : "no");
        seq_printf(seq, "periodic_IRQ\t: %s\n",
index 625637b84d33424be18af05530db5293b11fd3ea..9418a59fb368a3729d02fd68c579179c0571f5f9 100644 (file)
@@ -83,7 +83,7 @@ static int __devinit rtc_sysfs_add_device(struct class_device *class_dev,
 {
        int err;
 
-       dev_info(class_dev->dev, "rtc intf: sysfs\n");
+       dev_dbg(class_dev->dev, "rtc intf: sysfs\n");
 
        err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
        if (err)
index c9321b920e904d3bf0b1fb006d78381898c718b3..25b5d7a6641796fc272b41428917146a2dcd3215 100644 (file)
@@ -688,7 +688,7 @@ raw3215_probe (struct ccw_device *cdev)
        raw->cdev = cdev;
        raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
        memset(raw, 0, sizeof(struct raw3215_info));
-       raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
+       raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
                                       GFP_KERNEL|GFP_DMA);
        if (raw->buffer == NULL) {
                spin_lock(&raw3215_device_lock);
index e3491a5f52196eeedbad1d7ee3a16f35cd3c2184..3e86fd1756e5dc5b43df29fb6c7fd480fd2160b4 100644 (file)
@@ -377,7 +377,7 @@ do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
                if (!(key_map = kbd->key_maps[tmp.kb_table])) {
                        int j;
 
-                       key_map = (ushort *) kmalloc(sizeof(plain_map),
+                       key_map = kmalloc(sizeof(plain_map),
                                                     GFP_KERNEL);
                        if (!key_map)
                                return -ENOMEM;
index 732dfbdb85c45860c575e7c6667fbdfc3d35c0b8..f7c10d954ec604219069d540900959e522b0352c 100644 (file)
@@ -127,7 +127,7 @@ cpi_prepare_req(void)
        struct cpi_sccb *sccb;
        struct cpi_evbuf *evb;
 
-       req = (struct sclp_req *) kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
+       req = kmalloc(sizeof(struct sclp_req), GFP_KERNEL);
        if (req == NULL)
                return ERR_PTR(-ENOMEM);
        sccb = (struct cpi_sccb *) __get_free_page(GFP_KERNEL | GFP_DMA);
index a62b00083d0cb04df308241d61de289f86666eb7..5bb13a9d08989b0544b1fc2bb23af1b296c45f44 100644 (file)
@@ -295,7 +295,7 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev,
        struct completion work;
        int rc;
 
-       ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+       ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
        if (!ap_msg.message)
                return -ENOMEM;
        ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -337,7 +337,7 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev,
        struct completion work;
        int rc;
 
-       ap_msg.message = (void *) kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
+       ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL);
        if (!ap_msg.message)
                return -ENOMEM;
        ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
index b6a4ecdc80257152a1244d46eb5a2fc0365fe5cd..32e37014345c60fb02e803d2d25866aeac815fd7 100644 (file)
@@ -279,7 +279,7 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev,
        struct completion work;
        int rc;
 
-       ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
+       ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
        if (!ap_msg.message)
                return -ENOMEM;
        ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
@@ -321,7 +321,7 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev,
        struct completion work;
        int rc;
 
-       ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
+       ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL);
        if (!ap_msg.message)
                return -ENOMEM;
        ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
index 2da8b9381407eee5e1c56425835e7b8f18353f3f..b7153c1e15cdea786c2fb7c9d453213aaddda39d 100644 (file)
@@ -717,7 +717,7 @@ long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, struct ica_xcRB *xcRB)
        };
        int rc;
 
-       ap_msg.message = (void *) kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
+       ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
        if (!ap_msg.message)
                return -ENOMEM;
        ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
index 3257c22dd79cc014f2787567addb0aec31c2a787..03cc263fe0daf6d1e835a6617bbadc69fa297258 100644 (file)
@@ -1646,7 +1646,7 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
                return -1;
        }
        memset(ch, 0, sizeof (struct channel));
-       if ((ch->ccw = (struct ccw1 *) kmalloc(8*sizeof(struct ccw1),
+       if ((ch->ccw = kmalloc(8*sizeof(struct ccw1),
                                               GFP_KERNEL | GFP_DMA)) == NULL) {
                kfree(ch);
                ctc_pr_warn("ctc: Out of memory in add_channel\n");
@@ -1693,7 +1693,7 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
                return -1;
        }
        fsm_newstate(ch->fsm, CH_STATE_IDLE);
-       if ((ch->irb = (struct irb *) kmalloc(sizeof (struct irb),
+       if ((ch->irb = kmalloc(sizeof (struct irb),
                                              GFP_KERNEL)) == NULL) {
                ctc_pr_warn("ctc: Out of memory in add_channel\n");
                kfree_fsm(ch->fsm);
@@ -2535,7 +2535,7 @@ ctc_print_statistics(struct ctc_priv *priv)
        DBF_TEXT(trace, 4, __FUNCTION__);
        if (!priv)
                return;
-       sbuf = (char *)kmalloc(2048, GFP_KERNEL);
+       sbuf = kmalloc(2048, GFP_KERNEL);
        if (sbuf == NULL)
                return;
        p = sbuf;
index 1476ce2b437cb498f7e47b680767b71cdd80f99e..229aeb5fc399b79cf34bd4c5a68f174e16c58b68 100644 (file)
@@ -772,7 +772,7 @@ iucv_register_program (__u8 pgmname[16],
        }
 
        /* Allocate handler entry */
-       new_handler = (handler *)kmalloc(sizeof(handler), GFP_ATOMIC);
+       new_handler = kmalloc(sizeof(handler), GFP_ATOMIC);
        if (new_handler == NULL) {
                printk(KERN_WARNING "%s: storage allocation for new handler "
                       "failed.\n", __FUNCTION__);
index 5d39b2df0cc43fdcb49417641bdbb606f3e18ff0..85093b71f9fa52ebc9f0f95716c16f840111a926 100644 (file)
@@ -237,7 +237,7 @@ zfcp_device_setup(char *devstr)
                return 0;
 
        len = strlen(devstr) + 1;
-       str = (char *) kmalloc(len, GFP_KERNEL);
+       str = kmalloc(len, GFP_KERNEL);
        if (!str)
                goto err_out;
        memcpy(str, devstr, len);
index 2722af5d340428402e9085ba5421d4eee115e1cf..386e7de0b7e3c47a38efdda9ed01def8fc6839d6 100644 (file)
@@ -659,7 +659,7 @@ static int vfc_probe(void)
        if (!cards)
                return -ENODEV;
 
-       vfc_dev_lst = (struct vfc_dev **)kmalloc(sizeof(struct vfc_dev *) *
+       vfc_dev_lst = kmalloc(sizeof(struct vfc_dev *) *
                                                 (cards+1),
                                                 GFP_KERNEL);
        if (vfc_dev_lst == NULL)
index ac108f9e26741c544daa6c8756ff8a512a1b6fd2..426cd6f49f5db6ad1ddcd01de7bbd2e7850d3b47 100644 (file)
@@ -288,7 +288,7 @@ int aac_get_containers(struct aac_dev *dev)
 
        if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
                maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
-       fsa_dev_ptr = (struct fsa_dev_info *) kmalloc(
+       fsa_dev_ptr = kmalloc(
          sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL);
        if (!fsa_dev_ptr) {
                aac_fib_free(fibptr);
index d5cf8b91a0e7ad4ccc93e77d8b5ec45d8cad2292..6d305b2f854e2fad06e869ac05c996351cb21c7e 100644 (file)
@@ -386,7 +386,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
         *      Ok now init the communication subsystem
         */
 
-       dev->queues = (struct aac_queue_block *) kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
+       dev->queues = kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
        if (dev->queues == NULL) {
                printk(KERN_ERR "Error could not allocate comm region.\n");
                return NULL;
index d7a61a6bdaae0720362b306d33fc489a790841f5..1d239f6c01030e4450df42918fd313f362e1da5c 100644 (file)
@@ -699,7 +699,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 #endif
                int i;
                ccb[mbo].op = 2;        /* SCSI Initiator Command  w/scatter-gather */
-               SCpnt->host_scribble = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+               SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA);
                sgpnt = (struct scatterlist *) SCpnt->request_buffer;
                cptr = (struct chain *) SCpnt->host_scribble;
                if (cptr == NULL) {
index 46eed10b25d95db126f5bbe38be66c52d8791407..7d1fec620948bd11f1c90c043fbb88b450a5b6e1 100644 (file)
@@ -2565,7 +2565,7 @@ aic7xxx_allocate_scb(struct aic7xxx_host *p)
       }
     }
     scb_count = min( (i-1), p->scb_data->maxscbs - p->scb_data->numscbs);
-    scb_ap = (struct aic7xxx_scb *)kmalloc(sizeof (struct aic7xxx_scb) * scb_count
+    scb_ap = kmalloc(sizeof (struct aic7xxx_scb) * scb_count
                                           + sizeof(struct aic7xxx_scb_dma), GFP_ATOMIC);
     if (scb_ap == NULL)
       return(0);
index e95b367d09edd739af8e1739a8d9ed2a1b8d20aa..a965ed3548d5583fd2ac56d343b0e8d5a0f64d08 100644 (file)
@@ -4319,7 +4319,7 @@ static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
 
        dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
        while (pages--) {
-               ptr = (struct SGentry *)kmalloc(PAGE_SIZE, GFP_KERNEL);
+               ptr = kmalloc(PAGE_SIZE, GFP_KERNEL);
                if (!ptr) {
                        adapter_sg_tables_free(acb);
                        return 1;
index 60b1b434eba75adac8707f014da4d2c95868ceaf..365db537a28da81ddee1d7a1403a50ddc02a0383 100644 (file)
@@ -297,7 +297,7 @@ static void adpt_inquiry(adpt_hba* pHba)
        s32 rcode;
 
        memset(msg, 0, sizeof(msg));
-       buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+       buf = kmalloc(80,GFP_KERNEL|ADDR32);
        if(!buf){
                printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
                return;
@@ -1311,7 +1311,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                schedule_timeout_uninterruptible(1);
        } while (m == EMPTY_QUEUE);
 
-       status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+       status = kmalloc(4, GFP_KERNEL|ADDR32);
        if(status == NULL) {
                adpt_send_nop(pHba, m);
                printk(KERN_ERR"IOP reset failed - no free memory.\n");
@@ -1444,7 +1444,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
                        }
                        continue;
                }
-               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+               d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
                if(d==NULL)
                {
                        printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
@@ -2425,7 +2425,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
                                pDev = pDev->next_lun;
                        }
                        if(!pDev ) { // Something new add it
-                               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+                               d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
                                if(d==NULL)
                                {
                                        printk(KERN_CRIT "Out of memory for I2O device data.\n");
@@ -2728,7 +2728,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 
        kfree(pHba->reply_pool);
 
-       pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+       pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
        if(!pHba->reply_pool){
                printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
                return -1;
index f160357e37a6f065b18f68cc1df2cc463455bbd4..d561663fb4e41cfcce5716a9be8adf362a10f7a6 100644 (file)
@@ -2828,7 +2828,7 @@ static int i91u_detect(struct scsi_host_template * tpnt)
 
        for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
                i = tul_num_ch * tul_num_scb * sizeof(SCB);
-               if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
+               if ((tul_scb = kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
                        break;
        }
        if (tul_scb == NULL) {
index 824fe080d1dc2b9d0b2e1a35b2e1a64464e615b9..7d231106790308999b22b5276718cec47f369cb2 100644 (file)
@@ -5777,7 +5777,7 @@ static int osst_probe(struct device *dev)
        dev_num = i;
 
        /* allocate a struct osst_tape for this device */
-       tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
+       tpnt = kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
        if (tpnt == NULL) {
                write_unlock(&os_scsi_tapes_lock);
                printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
index aa60a5f1fbc3b5b639cf0123900b0ba862a36518..3b2e1a53e6e2df3e63dbf153e42ae516e33be652 100644 (file)
@@ -117,7 +117,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
 #endif
                        return 0;
        }
-       fcs = (struct ctrl_inquiry *) kmalloc (sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
+       fcs = kmalloc(sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
        if (!fcs) {
                printk ("PLUTO: Not enough memory to probe\n");
                return 0;
index d1268cb46837b258cd721f992546c7f1084d6345..0578ba42718b125ead70d8a9d599934d18f5e1fe 100644 (file)
@@ -546,7 +546,7 @@ int sr_is_xa(Scsi_CD *cd)
        if (!xa_test)
                return 0;
 
-       raw_sector = (unsigned char *) kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
+       raw_sector = kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd));
        if (!raw_sector)
                return -ENOMEM;
        if (0 == sr_read_sector(cd, cd->ms_offset + 16,
index a3e9d0f2eb5ba2da67f6431e68888487ac93158d..4eb3da996b369518edb0a1efa924f5c97657a614 100644 (file)
@@ -117,7 +117,7 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength)
                density = (blocklength > 2048) ? 0x81 : 0x83;
 #endif
 
-       buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+       buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
        if (!buffer)
                return -ENOMEM;
 
@@ -164,7 +164,7 @@ int sr_cd_check(struct cdrom_device_info *cdi)
        if (cd->cdi.mask & CDC_MULTI_SESSION)
                return 0;
 
-       buffer = (unsigned char *) kmalloc(512, GFP_KERNEL | GFP_DMA);
+       buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
        if (!buffer)
                return -ENOMEM;
 
index 940fa1e6f9941d1ec81d0e92c69bec9e3f66af56..21cd4c7f528997477f73458c90dda916ec8ffa9a 100644 (file)
@@ -5545,7 +5545,7 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram
        /*
         *  Allocate the array of lists of CCBs hashed by DSA.
         */
-       np->ccbh = kcalloc(sizeof(struct sym_ccb **), CCB_HASH_SIZE, GFP_KERNEL);
+       np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(struct sym_ccb **), GFP_KERNEL);
        if (!np->ccbh)
                goto attach_failed;
 
index 4d0ff8f4a01b14024fed710507a1fd0013396780..52e2e64c6649dc25379994f6b1b119bc2d3b768f 100644 (file)
@@ -2238,6 +2238,30 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b0_bt_1_460800 },
 
+       /*
+        * Korenix Jetcard F0/F1 cards (JC1204, JC1208, JC1404, JC1408).
+        * Cards are identified by their subsystem vendor IDs, which
+        * (in hex) match the model number.
+        *
+        * Note that JC140x are RS422/485 cards which require ox950
+        * ACR = 0x10, and as such are not currently fully supported.
+        */
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1204, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1402, 0x0002, 0, 0,
+               pbn_b0_2_921600 }, */
+/*     {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+               0x1404, 0x0004, 0, 0,
+               pbn_b0_4_921600 }, */
+       {       PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
+               0x1208, 0x0004, 0, 0,
+               pbn_b0_4_921600 },
+
        /*
         * Dell Remote Access Card 4 - Tim_T_Murphy@Dell.com
         */
index 72f3db99ff940f40978de7764953920c7e18093d..3e0abbb49fe134e4721037ffdbeedb242dd6e062 100644 (file)
@@ -598,7 +598,7 @@ at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
 {
        struct at91_request *req;
 
-       req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
+       req = kzalloc(sizeof (struct at91_request), gfp_flags);
        if (!req)
                return NULL;
 
index 5516c59ed5ec28d6ea1dc864fd8a9ebd504bdd56..2d12bf9f19d64efecc95b991c94697dc921f7295 100644 (file)
@@ -2195,7 +2195,7 @@ static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags)
        if (size == 0)
                return NULL;
 
-       gb = (struct gs_buf *)kmalloc(sizeof(struct gs_buf), kmalloc_flags);
+       gb = kmalloc(sizeof(struct gs_buf), kmalloc_flags);
        if (gb == NULL)
                return NULL;
 
index 9325e46a68c03d847386a5d3884d8cc163039828..282d82efc0b0a0e8280884ad7a041e3561b7bf80 100644 (file)
@@ -365,7 +365,7 @@ static inline struct urb *urb_list_first(int epid)
 /* Adds an urb_entry last in the list for this epid. */
 static inline void urb_list_add(struct urb *urb, int epid)
 {
-       urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
+       urb_entry_t *urb_entry = kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
        assert(urb_entry);
 
        urb_entry->urb = urb;
index c703f73e16550211652c86fc1d37be2e30bead47..6c7f3efb1d40d71a74e8e8296c81f187e1264860 100644 (file)
@@ -766,7 +766,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned
                 bep->bufp = kmalloc (bufsize, GFP_KERNEL);
                 if (!bep->bufp)
                        goto bl_fail;
-                bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
+                bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL);
                 if (!bep->dr)
                        goto bl_fail;
                 bep->urbp = usb_alloc_urb (0, GFP_KERNEL);
@@ -1969,7 +1969,7 @@ static int auerswald_probe (struct usb_interface *intf,
        info("device is a %s", cp->dev_desc);
 
         /* get the maximum allowed control transfer length */
-        pbuf = (__le16 *) kmalloc (2, GFP_KERNEL);    /* use an allocated buffer because of urb target */
+        pbuf = kmalloc(2, GFP_KERNEL);    /* use an allocated buffer because of urb target */
         if (!pbuf) {
                err( "out of memory");
                goto pfail;
index 7e8a0acd52eea2a6b77c66ac6aff9f19883ef2b5..70250252ae2ae404d30f5583d4396a6e70f590fa 100644 (file)
@@ -705,7 +705,7 @@ static int uss720_probe(struct usb_interface *intf,
        /*
         * Allocate parport interface 
         */
-       if (!(priv = kcalloc(sizeof(struct parport_uss720_private), 1, GFP_KERNEL))) {
+       if (!(priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) {
                usb_put_dev(usbdev);
                return -ENOMEM;
        }
index 99f26b3e502f39dcd017c5854c635dabb435a16d..ea5f44de3de2e6aa3edbc157b394925fcb685515 100644 (file)
@@ -469,7 +469,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
        struct rndis_halt       *halt;
 
        /* try to clear any rndis state/activity (no i/o from stack!) */
-       halt = kcalloc(1, sizeof *halt, GFP_KERNEL);
+       halt = kzalloc(sizeof *halt, GFP_KERNEL);
        if (halt) {
                halt->msg_type = RNDIS_MSG_HALT;
                halt->msg_len = ccpu2(sizeof *halt);
index a1fdb85b8c0ae91225c447f5cb79b6c19792e991..45cdf9bc43b2bd01ae9daa5bb10f8949386a1cce 100644 (file)
@@ -1493,7 +1493,7 @@ static struct cypress_buf *cypress_buf_alloc(unsigned int size)
        if (size == 0)
                return NULL;
 
-       cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
+       cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
        if (cb == NULL)
                return NULL;
 
index 9d9ea874639ce047bc3ac855d4b94abd020fa254..efd9ce3f931f48430787149fbbc0a329f7118ccd 100644 (file)
@@ -1681,7 +1681,7 @@ dbg( "digi_startup: TOP" );
        for( i=0; i<serial->type->num_ports+1; i++ ) {
 
                /* allocate port private structure */
-               priv = (struct digi_port *)kmalloc( sizeof(struct digi_port),
+               priv = kmalloc( sizeof(struct digi_port),
                        GFP_KERNEL );
                if( priv == (struct digi_port *)0 ) {
                        while( --i >= 0 )
@@ -1714,7 +1714,7 @@ dbg( "digi_startup: TOP" );
        }
 
        /* allocate serial private structure */
-       serial_priv = (struct digi_serial *)kmalloc( sizeof(struct digi_serial),
+       serial_priv = kmalloc( sizeof(struct digi_serial),
                GFP_KERNEL );
        if( serial_priv == (struct digi_serial *)0 ) {
                for( i=0; i<serial->type->num_ports+1; i++ )
index 2da2684e080982a4f72c91ee3c26b9c79a85568b..980285c0233a049cfca9d1acc01a4ecff6e858c2 100644 (file)
@@ -2811,7 +2811,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size)
        if (size == 0)
                return NULL;
 
-       eb = (struct edge_buf *)kmalloc(sizeof(struct edge_buf), GFP_KERNEL);
+       eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL);
        if (eb == NULL)
                return NULL;
 
index d72cf8bc7f76be74678eccdc4df280aabfff57c5..42f757a5b876e621da94472c53506bf9401a37fc 100644 (file)
@@ -595,7 +595,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
 
        bytes_in = 0;
        bytes_out = 0;
-       priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
+       priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
        if (priv == NULL) {
                err("%s - Out of memory", __FUNCTION__);
                return -ENOMEM;
index e284d6c0fd35b03f5f42c97ff6af5358463bd1a3..62bea0c923bd25e52a5a8ef956971eefea07ec91 100644 (file)
@@ -269,7 +269,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp)
        }
 
        // allocate memory for write_urb transfer buffer
-       port->write_urb->transfer_buffer = (unsigned char *) kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
+       port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
        if (! port->write_urb->transfer_buffer) {
                kfree(transfer_buffer);
                usb_free_urb(port->write_urb);
@@ -696,7 +696,7 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
                return 0;
 
        case TCFLSH:   // 0x540B
-               transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL);
+               transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
                if (! transfer_buffer) {
                        return -ENOBUFS;
                }
index d124d780e42e27703216908337f011094d181c4c..5dc2ac9afa90b01a210d1993c05b3dea47323309 100644 (file)
@@ -159,7 +159,7 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size)
        if (size == 0)
                return NULL;
 
-       pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
+       pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL);
        if (pb == NULL)
                return NULL;
 
index f42eb9ea64052a1a9d6dc90ee59966fc392a9c90..83189005c6fbb400e353167b2d16b3b64db7fdba 100644 (file)
@@ -1710,7 +1710,7 @@ static struct circ_buf *ti_buf_alloc(void)
 {
        struct circ_buf *cb;
 
-       cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
+       cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL);
        if (cb == NULL)
                return NULL;
 
index dc45e58e2b8c88892e92bcecacc5fdba32a839ee..5483d8564c1b9b42015e39ffc264366fdac95d24 100644 (file)
@@ -416,7 +416,7 @@ static int whiteheat_attach (struct usb_serial *serial)
        for (i = 0; i < serial->num_ports; i++) {
                port = serial->port[i];
 
-               info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
+               info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
                if (info == NULL) {
                        err("%s: Out of memory for port structures\n", serial->type->description);
                        goto no_private;
@@ -487,7 +487,7 @@ static int whiteheat_attach (struct usb_serial *serial)
                usb_set_serial_port_data(port, info);
        }
 
-       command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
+       command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
        if (command_info == NULL) {
                err("%s: Out of memory for port structures\n", serial->type->description);
                goto no_command_private;
index fb8bacaae27cbcb5eaaf6f845fc5e10dc8ddaa7f..e3528eca29a54d7ddb67866cc66261db95d18b20 100644 (file)
@@ -646,7 +646,7 @@ sddr09_read_sg_test_only(struct us_data *us) {
                return result;
        }
 
-       buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO);
+       buf = kmalloc(bulklen, GFP_NOIO);
        if (!buf)
                return -ENOMEM;
 
index 6761b68c35e97182046e1774d1755ef810423bb7..6c9dc2e69c82f69d5a24a7e590fab50070451b9c 100644 (file)
@@ -447,7 +447,7 @@ static int clcdfb_probe(struct amba_device *dev, void *id)
                goto out;
        }
 
-       fb = (struct clcd_fb *) kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
+       fb = kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
        if (!fb) {
                printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n");
                ret = -ENOMEM;
index 88a47845c4f7db713a9960948ffbbf9fa29155dd..1a849b870bcc8986a25eae263f053cfd516961e0 100644 (file)
@@ -2906,14 +2906,6 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
        par->crsr.spot_x = par->crsr.spot_y = 0;
        par->crsr.height = par->crsr.width = 0;
 
-#if 0  /* fbmon not done.  uncomment for 2.5.x -brad */
-       if (!fbmon_valid_timings(pixclock[clk_shift], htotal, vtotal,
-                                &fb_info)) {
-               DPRINTK("mode doesn't fit for monitor\n");
-               return -EINVAL;
-       }
-#endif
-
        return 0;
 }
 
index 176f9b85cdbebbc3f3d32dafc450c8d54adf1952..09684d7a7ce942c8458d23fcad35f3cfa161958c 100644 (file)
@@ -1488,10 +1488,6 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        else
                info->var.accel_flags = 0;
 
-#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
-       if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
-               return -EINVAL;
-#endif
        aty_crtc_to_var(&crtc, var);
        var->pixclock = par->pll_ops->pll_to_var(info, &pll);
        return 0;
index 797b42305b0ff4f2e4485799e5e2ed0e9470acdb..fe28848e7b52e201f128d58b56f1a50c23a23526 100644 (file)
@@ -146,7 +146,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
        unsigned long flags;
        struct matroxfb_dh_maven_info* m2info;
 
-       m2info = (struct matroxfb_dh_maven_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+       m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
        if (!m2info)
                return NULL;
 
index e9b4115fcad0208891bfe672159453e40f3db1ea..cb2aa402ddfd93eb0b180f9a05c74909c2be859a 100644 (file)
@@ -2028,7 +2028,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
        }
 
 #ifdef CONFIG_FB_MATROX_MULTIHEAD
-       minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL);
+       minfo = kmalloc(sizeof(*minfo), GFP_KERNEL);
        if (!minfo)
                return -1;
 #else
index 27eb4bb4f89fe2000aa2dbeda19a3c1a40a3387c..2c9801090faeaa89e95b0c9d2a1ad3822052cc61 100644 (file)
@@ -694,7 +694,7 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
        /* hardware is CRTC2 incapable... */
        if (!ACCESS_FBINFO(devflags.crtc2))
                return NULL;
-       m2info = (struct matroxfb_dh_fb_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);
+       m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
        if (!m2info) {
                printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
                return NULL;
index 711cb11d6eb34e6223d2eb67463de2073492d909..59cd1e750f30dc595f96271277587ae151eab31c 100644 (file)
  *     Remove never finished and bogus 24/32bit support
  *     Clean up macro abuse
  *     Minor tidying for format.
+ * 12/2006 Helge Deller    <deller@gmx.de>
+ *     add /sys/class/graphics/fbX/vgapass sysfs-interface
+ *     add module option "mode_option" to set initial screen mode
+ *     use fbdev default videomode database
+ *     remove debug functions from ioctl
  */
 
 /*
  *
  * sstfb specific ioctls:
  *             toggle vga (0x46db) : toggle vga_pass_through
- *             fill fb    (0x46dc) : fills fb
- *             test disp  (0x46de) : draws a test image
  */
 
 #undef SST_DEBUG
 
-/*
-  Default video mode .
-  0 800x600@60  took from glide
-  1 640x480@75  took from glide
-  2 1024x768@76 std fb.mode
-  3 640x480@60  glide default */
-#define DEFAULT_MODE 3 
 
 /*
  * Includes
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <asm/io.h>
-#include <asm/ioctl.h>
 #include <asm/uaccess.h>
 #include <video/sstfb.h>
 
 
 /* initialized by setup */
 
-static int vgapass;            /* enable Vga passthrough cable */
+static int vgapass;            /* enable VGA passthrough cable */
 static int mem;                        /* mem size in MB, 0 = autodetect */
 static int clipping = 1;       /* use clipping (slower, safer) */
 static int gfxclk;             /* force FBI freq in Mhz . Dangerous */
 static int slowpci;            /* slow PCI settings */
 
-static char *mode_option __devinitdata;
+/*
+  Possible default video modes: 800x600@60, 640x480@75, 1024x768@76, 640x480@60
+*/
+#define DEFAULT_VIDEO_MODE "640x480@60"
+
+static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE;
 
 enum {
        ID_VOODOO1 = 0,
@@ -119,48 +119,11 @@ static struct sst_spec voodoo_spec[] __devinitdata = {
  { .name = "Voodoo2",        .default_gfx_clock = 75000, .max_gfxclk = 85 },
 };
 
-static struct fb_var_screeninfo        sstfb_default =
-#if ( DEFAULT_MODE == 0 )
-    { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
-    800, 600, 800, 600, 0, 0, 16, 0,
-    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0,
-    25000, 86, 41, 23, 1, 127, 4,
-    0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 1 )
-    {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
-    640, 480, 640, 480, 0, 0, 16, 0,
-    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0,
-    31746, 118, 17, 16, 1, 63, 3,
-    0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 2 )
-    { /* 1024x768@76 took from my /etc/fb.modes */
-    1024, 768, 1024, 768,0, 0, 16,0,
-    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0,
-    11764, 208, 8, 36, 16, 120, 3 ,
-    0, FB_VMODE_NONINTERLACED };
-#elif ( DEFAULT_MODE == 3 )
-    { /* 640x480@60 , 16bpp glide default ?*/
-    640, 480, 640, 480, 0, 0, 16, 0,
-    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0,
-    39721 ,  38, 26 ,  25 ,18  , 96 ,2,
-    0, FB_VMODE_NONINTERLACED };
-#elif
-    #error "Invalid DEFAULT_MODE value !"
-#endif
-
 
 /*
  * debug functions
  */
 
-static void sstfb_drawdebugimage(struct fb_info *info);
-static int sstfb_dump_regs(struct fb_info *info);
-
-
 #if (SST_DEBUG_REG > 0)
 static void sst_dbg_print_read_reg(u32 reg, u32 val) {
        const char *regname;
@@ -726,51 +689,77 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        return 0;
 }
 
-static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
+static void sstfb_setvgapass( struct fb_info *info, int enable )
 {
        struct sstfb_par *par = info->par;
        struct pci_dev *sst_dev = par->dev;
-       u32 fbiinit0, tmp, val;
-       u_long p;
+       u32 fbiinit0, tmp;
+
+       enable = enable ? 1:0;
+       if (par->vgapass == enable)
+               return;
+       par->vgapass = enable;
+
+       pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              tmp | PCI_EN_INIT_WR );
+       fbiinit0 = sst_read (FBIINIT0);
+       if (par->vgapass) {
+               sst_write(FBIINIT0, fbiinit0 & ~DIS_VGA_PASSTHROUGH);
+               printk(KERN_INFO "fb%d: Enabling VGA pass-through\n", info->node );
+       } else {
+               sst_write(FBIINIT0, fbiinit0 | DIS_VGA_PASSTHROUGH);
+               printk(KERN_INFO "fb%d: Disabling VGA pass-through\n", info->node );
+       }
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
+}
+
+static ssize_t store_vgapass(struct device *device, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct fb_info *info = dev_get_drvdata(device);
+       char ** last = NULL;
+       int val;
+
+       val = simple_strtoul(buf, last, 0);
+       sstfb_setvgapass(info, val);
+
+       return count;
+}
+
+static ssize_t show_vgapass(struct device *device, struct device_attribute *attr,
+                       char *buf)
+{
+       struct fb_info *info = dev_get_drvdata(device);
+       struct sstfb_par *par = info->par;
+       return snprintf(buf, PAGE_SIZE, "%d\n", par->vgapass);
+}
+
+static struct device_attribute device_attrs[] = {
+       __ATTR(vgapass, S_IRUGO|S_IWUSR, show_vgapass, store_vgapass)
+       };
+
+static int sstfb_ioctl(struct fb_info *info, unsigned int cmd,
+                       unsigned long arg)
+{
+       struct sstfb_par *par;
+       u32 val;
 
        switch (cmd) {
-               
-       /* dump current FBIINIT values to system log */
-       case _IO('F', 0xdb):            /* 0x46db */
-               return sstfb_dump_regs(info);
-               
-       /* fills lfb with #arg pixels */
-       case _IOW('F', 0xdc, u32):      /* 0x46dc */
+       /* set/get VGA pass_through mode */
+       case SSTFB_SET_VGAPASS:
                if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
                        return -EFAULT;
-               if (val > info->fix.smem_len)
-                       val = info->fix.smem_len;
-               for (p = 0 ; p < val; p += 2)
-                       writew(p >> 6, info->screen_base + p);
+               sstfb_setvgapass(info, val);
                return 0;
-               
-       /* change VGA pass_through mode */
-       case _IOW('F', 0xdd, u32):      /* 0x46dd */
-               if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
+       case SSTFB_GET_VGAPASS:
+               par = info->par;
+               val = par->vgapass;
+               if (copy_to_user((void __user *)arg, &val, sizeof(val)))
                        return -EFAULT;
-               pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
-               pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
-                                      tmp | PCI_EN_INIT_WR );
-               fbiinit0 = sst_read (FBIINIT0);
-               if (val)
-                       sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
-               else
-                       sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
-               pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
-               return 0;
-               
-       /* draw test image  */
-       case _IO('F', 0xde):            /* 0x46de */
-               f_dprintk("test color display at %d bpp\n",
-                                       info->var.bits_per_pixel);
-               sstfb_drawdebugimage(info);
                return 0;
        }
+
        return -EINVAL;
 }
 
@@ -804,6 +793,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 /*
  * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
  */
+#if 0
 static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
        struct sstfb_par *par = info->par;
@@ -825,6 +815,7 @@ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
                 | (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) );
        sst_wait_idle();
 }
+#endif
 
 
 
@@ -1156,6 +1147,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
        struct pll_timing gfx_timings;
        struct sst_spec *spec;
        int Fout;
+       int gfx_clock;
 
        spec = &voodoo_spec[par->type];
        f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
@@ -1196,15 +1188,15 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
        }
 
        /* set graphic clock */
-       par->gfx_clock = spec->default_gfx_clock;
+       gfx_clock = spec->default_gfx_clock;
        if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
                printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
-                par->gfx_clock = gfxclk *1000;
+                gfx_clock = gfxclk *1000;
        } else if (gfxclk) {
                printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
        }
 
-       sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
+       sst_calc_pll(gfx_clock, &Fout, &gfx_timings);
        par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
 
        /* disable fbiinit remap */
@@ -1215,10 +1207,11 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
        fbiinit0 = FBIINIT0_DEFAULT;
        fbiinit1 = FBIINIT1_DEFAULT;
        fbiinit4 = FBIINIT4_DEFAULT;
-       if (vgapass)
-               fbiinit0 &= ~EN_VGA_PASSTHROUGH;
+       par->vgapass = vgapass;
+       if (par->vgapass)
+               fbiinit0 &= ~DIS_VGA_PASSTHROUGH;
        else
-               fbiinit0 |= EN_VGA_PASSTHROUGH;
+               fbiinit0 |= DIS_VGA_PASSTHROUGH;
        if (slowpci) {
                fbiinit1 |= SLOW_PCI_WRITES;
                fbiinit4 |= SLOW_PCI_READS;
@@ -1267,7 +1260,7 @@ static void  __devexit sst_shutdown(struct fb_info *info)
        /* TODO maybe shutdown the dac, vrefresh and so on... */
        pci_write_config_dword(dev, PCI_INIT_ENABLE,
                               PCI_EN_INIT_WR);
-       sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
+       sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | DIS_VGA_PASSTHROUGH);
        pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
        /* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct
         * from start ? */
@@ -1278,8 +1271,7 @@ static void  __devexit sst_shutdown(struct fb_info *info)
 /*
  * Interface to the world
  */
-#ifndef MODULE
-static int  __init sstfb_setup(char *options)
+static int  __devinit sstfb_setup(char *options)
 {
        char *this_opt;
 
@@ -1312,7 +1304,7 @@ static int  __init sstfb_setup(char *options)
        }
        return 0;
 }
-#endif
+
 
 static struct fb_ops sstfb_ops = {
        .owner          = THIS_MODULE,
@@ -1416,15 +1408,10 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
         */
        fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
        
-       if ( mode_option &&
-            fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
-               printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
-               info->var = sstfb_default;
-       } else
-               info->var = sstfb_default;
+       fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16);
 
        if (sstfb_check_var(&info->var, info)) {
-               printk(KERN_ERR "sstfb: invalid default video mode.\n");
+               printk(KERN_ERR "sstfb: invalid video mode.\n");
                goto fail;
        }
 
@@ -1442,10 +1429,11 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
                goto fail;
        }
 
-       if (1) /* set to 0 to see an initial bitmap instead */
-               sstfb_clear_screen(info);
-       else
-               sstfb_drawdebugimage(info);
+       sstfb_clear_screen(info);
+
+       if (device_create_file(info->dev, &device_attrs[0]))
+               printk(KERN_WARNING "sstfb: can't create sysfs entry.\n");
+
 
        printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n",
               info->node, fix->id, info->screen_base);
@@ -1453,6 +1441,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        return 0;
 
 fail:
+       fb_dealloc_cmap(&info->cmap);
        iounmap(info->screen_base);
 fail_fb_remap:
        iounmap(par->mmio_vbase);
@@ -1473,21 +1462,23 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
        info = pci_get_drvdata(pdev);
        par = info->par;
        
+       device_remove_file(info->dev, &device_attrs[0]);
        sst_shutdown(info);
-       unregister_framebuffer(info);
        iounmap(info->screen_base);
        iounmap(par->mmio_vbase);
        release_mem_region(info->fix.smem_start, 0x400000);
        release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+       fb_dealloc_cmap(&info->cmap);
+       unregister_framebuffer(info);
        framebuffer_release(info);
 }
 
 
-static struct pci_device_id sstfb_id_tbl[] = {
-       { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 },
-       { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 },
+static const struct pci_device_id sstfb_id_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO ),
+               .driver_data = ID_VOODOO1, },
+       { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2),
+               .driver_data = ID_VOODOO2, },
        { 0 },
 };
 
@@ -1501,142 +1492,23 @@ static struct pci_driver sstfb_driver = {
 
 static int __devinit sstfb_init(void)
 {
-#ifndef MODULE
        char *option = NULL;
 
        if (fb_get_options("sstfb", &option))
                return -ENODEV;
        sstfb_setup(option);
-#endif
+
        return pci_register_driver(&sstfb_driver);
 }
 
-#ifdef MODULE
 static void __devexit sstfb_exit(void)
 {
        pci_unregister_driver(&sstfb_driver);
 }
-#endif
 
 
-/*
- * testing and debugging functions
- */
-
-static int sstfb_dump_regs(struct fb_info *info)
-{
-#ifdef SST_DEBUG
-       static struct { u32 reg ; const char *reg_name;}  pci_regs[] = {
-               { PCI_INIT_ENABLE, "initenable"},
-               { PCI_VCLK_ENABLE, "enable vclk"},
-               { PCI_VCLK_DISABLE, "disable vclk"},
-       };
-
-       static struct { u32 reg ; const char *reg_name;}  sst_regs[] = {
-               {FBIINIT0,"fbiinit0"},
-               {FBIINIT1,"fbiinit1"},
-               {FBIINIT2,"fbiinit2"},
-               {FBIINIT3,"fbiinit3"},
-               {FBIINIT4,"fbiinit4"},
-               {FBIINIT5,"fbiinit5"},
-               {FBIINIT6,"fbiinit6"},
-               {FBIINIT7,"fbiinit7"},
-               {LFBMODE,"lfbmode"},
-               {FBZMODE,"fbzmode"},
-       };
-
-       const int pci_s = ARRAY_SIZE(pci_regs);
-       const int sst_s = ARRAY_SIZE(sst_regs);
-       struct sstfb_par *par = info->par;
-       struct pci_dev *dev = par->dev;
-       u32 pci_res[pci_s];
-       u32 sst_res[sst_s];
-       int i;
-
-       for (i=0; i<pci_s; i++) {
-               pci_read_config_dword(dev, pci_regs[i].reg, &pci_res[i]);
-       }
-       for (i=0; i<sst_s; i++) {
-               sst_res[i] = sst_read(sst_regs[i].reg);
-       }
-
-       dprintk("hardware register dump:\n");
-       for (i=0; i<pci_s; i++) {
-               dprintk("%s %0#10x\n", pci_regs[i].reg_name, pci_res[i]);
-       }
-       for (i=0; i<sst_s; i++) {
-               dprintk("%s %0#10x\n", sst_regs[i].reg_name, sst_res[i]);
-       }
-       return 0;
-#else
-       return -EINVAL;
-#endif
-}
-
-static void sstfb_fillrect_softw( struct fb_info *info, const struct fb_fillrect *rect)
-{
-       u8 __iomem *fbbase_virt = info->screen_base;
-       int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
-       u32 color = rect->color, height = rect->height;
-       u8 __iomem *p;
-       
-       if (w==2) color |= color<<16;
-       for (y=rect->dy; height; y++, height--) {
-               p = fbbase_virt + y*info->fix.line_length + rect->dx*w;
-               x = rect->width;
-               if (w==2) x>>=1;
-               while (x) {
-                       writel(color, p);
-                       p += 4;
-                       x--;
-               }
-       }
-}
-
-static void sstfb_drawrect_XY( struct fb_info *info, int x, int y,
-               int w, int h, int color, int hwfunc)
-{
-       struct fb_fillrect rect;
-       rect.dx = x;
-       rect.dy = y;
-       rect.height = h;
-       rect.width = w;
-       rect.color = color;
-       rect.rop = ROP_COPY;
-       if (hwfunc)
-               sstfb_fillrect(info, &rect);
-       else
-               sstfb_fillrect_softw(info, &rect);
-}
-
-/* print some squares on the fb */
-static void sstfb_drawdebugimage(struct fb_info *info)
-{
-       static int idx;
-
-       /* clear screen */
-       sstfb_clear_screen(info);
-       
-       idx = (idx+1) & 1;
-
-       /* white rect */
-       sstfb_drawrect_XY(info, 0, 0, 50, 50, 0xffff, idx);
-       
-       /* blue rect */
-       sstfb_drawrect_XY(info, 50, 50, 50, 50, 0x001f, idx);
-
-       /* green rect */
-       sstfb_drawrect_XY(info, 100, 100, 80, 80, 0x07e0, idx);
-       
-       /* red rect */
-       sstfb_drawrect_XY(info, 250, 250, 120, 100, 0xf800, idx);
-}
-
 module_init(sstfb_init);
-
-#ifdef MODULE
 module_exit(sstfb_exit);
-#endif
 
 MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
 MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
@@ -1652,3 +1524,6 @@ module_param(gfxclk, int, 0);
 MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
 module_param(slowpci, bool, 0);
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Initial video mode (default=" DEFAULT_VIDEO_MODE ")");
+
index d18d6424cd21b11322ea8b0f8f9324b5c4e4bc74..904e5aeb696c41a8692dab99c6851f8eb0cb78f0 100644 (file)
@@ -9,7 +9,7 @@ config W1_SLAVE_THERM
        tristate "Thermal family implementation"
        depends on W1
        help
-         Say Y here if you want to connect 1-wire thermal sensors to you
+         Say Y here if you want to connect 1-wire thermal sensors to your
          wire.
 
 config W1_SLAVE_SMEM
@@ -17,7 +17,7 @@ config W1_SLAVE_SMEM
        depends on W1
        help
          Say Y here if you want to connect 1-wire
-         simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
+         simple 64bit memory rom(ds2401/ds2411/ds1990*) to your wire.
 
 config W1_SLAVE_DS2433
        tristate "4kb EEPROM family support (DS2433)"
index d3a6ec2c9627e1e58a769c93398f2a3787bdfda8..5f577a63bdf0e18ed51a39047e599e073f1a48bf 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -586,7 +586,7 @@ static void use_mm(struct mm_struct *mm)
         * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise
         * it won't work. Update it accordingly if you change it here
         */
-       activate_mm(active_mm, mm);
+       switch_mm(active_mm, mm, tsk);
        task_unlock(tsk);
 
        mmdrop(active_mm);
index 9c48250fd726406fc040816c96b4fa42e8d305ce..e8f6c5ad3e904a785c9a8fb73eac9af0b0b18633 100644 (file)
@@ -313,7 +313,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
        struct autofs_sb_info *sbi;
        struct autofs_info *ino;
 
-       sbi = (struct autofs_sb_info *) kmalloc(sizeof(*sbi), GFP_KERNEL);
+       sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
        if ( !sbi )
                goto fail_unlock;
        DPRINTK("starting up, sbi = %p",sbi);
index 81b042ee24e650339445504e5e83a9ecda9ca384..af5bb93276f855ab6a3bdc8ec9cf632be8b5e22c 100644 (file)
@@ -260,7 +260,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds,
                goto error;
        }
 
-       this_node = (befs_btree_node *) kmalloc(sizeof (befs_btree_node),
+       this_node = kmalloc(sizeof (befs_btree_node),
                                                GFP_NOFS);
        if (!this_node) {
                befs_error(sb, "befs_btree_find() failed to allocate %u "
index e831a8f30849a98a088d46394742cc3b4c476182..b8e304a0661e473ba7b44ca74ceebd3e8f228c52 100644 (file)
@@ -28,7 +28,7 @@ void
 befs_error(const struct super_block *sb, const char *fmt, ...)
 {
        va_list args;
-       char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+       char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
        if (err_buf == NULL) {
                printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
                return;
@@ -46,7 +46,7 @@ void
 befs_warning(const struct super_block *sb, const char *fmt, ...)
 {
        va_list args;
-       char *err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+       char *err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
        if (err_buf == NULL) {
                printk(KERN_ERR "could not allocate %d bytes\n", ERRBUFSIZE);
                return;
@@ -70,7 +70,7 @@ befs_debug(const struct super_block *sb, const char *fmt, ...)
        char *err_buf = NULL;
 
        if (BEFS_SB(sb)->mount_opts.debug) {
-               err_buf = (char *) kmalloc(ERRBUFSIZE, GFP_KERNEL);
+               err_buf = kmalloc(ERRBUFSIZE, GFP_KERNEL);
                if (err_buf == NULL) {
                        printk(KERN_ERR "could not allocate %d bytes\n",
                                ERRBUFSIZE);
index eac175ed9f445d999b3f8e5458f3a395de4c4a06..134c99941a639915e10a630674ccacd760bd0c6f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     fs/bfs/inode.c
  *     BFS superblock and inode operations.
- *     Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
+ *     Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
  *     From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
  *
  *      Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
@@ -18,7 +18,7 @@
 #include <asm/uaccess.h>
 #include "bfs.h"
 
-MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>");
+MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
 MODULE_LICENSE("GPL");
 
index 00687ea627385b11f0d03249b8bd038b380165ca..c2e08252af35d5dd3140ff32d1cf79bbfd3521c7 100644 (file)
@@ -311,7 +311,7 @@ static Node *create_entry(const char __user *buffer, size_t count)
 
        err = -ENOMEM;
        memsize = sizeof(Node) + count + 8;
-       e = (Node *) kmalloc(memsize, GFP_USER);
+       e = kmalloc(memsize, GFP_USER);
        if (!e)
                goto out;
 
index 7ec737eda72bba71718d433820eae4e0c0d6a489..7618bcb1836848737921c48302359a29a583e23b 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -916,7 +916,7 @@ void bio_set_pages_dirty(struct bio *bio)
        }
 }
 
-static void bio_release_pages(struct bio *bio)
+void bio_release_pages(struct bio *bio)
 {
        struct bio_vec *bvec = bio->bi_io_vec;
        int i;
index 197f9392184741809013cd85828e654bb8b1ab14..1715d6b5f411a2d6db22c9a38de9cab971e40bf6 100644 (file)
@@ -129,43 +129,191 @@ blkdev_get_block(struct inode *inode, sector_t iblock,
        return 0;
 }
 
-static int
-blkdev_get_blocks(struct inode *inode, sector_t iblock,
-               struct buffer_head *bh, int create)
+static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
 {
-       sector_t end_block = max_block(I_BDEV(inode));
-       unsigned long max_blocks = bh->b_size >> inode->i_blkbits;
+       struct kiocb *iocb = bio->bi_private;
+       atomic_t *bio_count = &iocb->ki_bio_count;
 
-       if ((iblock + max_blocks) > end_block) {
-               max_blocks = end_block - iblock;
-               if ((long)max_blocks <= 0) {
-                       if (create)
-                               return -EIO;    /* write fully beyond EOF */
-                       /*
-                        * It is a read which is fully beyond EOF.  We return
-                        * a !buffer_mapped buffer
-                        */
-                       max_blocks = 0;
-               }
+       if (bio_data_dir(bio) == READ)
+               bio_check_pages_dirty(bio);
+       else {
+               bio_release_pages(bio);
+               bio_put(bio);
+       }
+
+       /* iocb->ki_nbytes stores error code from LLDD */
+       if (error)
+               iocb->ki_nbytes = -EIO;
+
+       if (atomic_dec_and_test(bio_count)) {
+               if (iocb->ki_nbytes < 0)
+                       aio_complete(iocb, iocb->ki_nbytes, 0);
+               else
+                       aio_complete(iocb, iocb->ki_left, 0);
        }
 
-       bh->b_bdev = I_BDEV(inode);
-       bh->b_blocknr = iblock;
-       bh->b_size = max_blocks << inode->i_blkbits;
-       if (max_blocks)
-               set_buffer_mapped(bh);
        return 0;
 }
 
+#define VEC_SIZE       16
+struct pvec {
+       unsigned short nr;
+       unsigned short idx;
+       struct page *page[VEC_SIZE];
+};
+
+#define PAGES_SPANNED(addr, len)       \
+       (DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
+
+/*
+ * get page pointer for user addr, we internally cache struct page array for
+ * (addr, count) range in pvec to avoid frequent call to get_user_pages.  If
+ * internal page list is exhausted, a batch count of up to VEC_SIZE is used
+ * to get next set of page struct.
+ */
+static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
+                                struct pvec *pvec)
+{
+       int ret, nr_pages;
+       if (pvec->idx == pvec->nr) {
+               nr_pages = PAGES_SPANNED(addr, count);
+               nr_pages = min(nr_pages, VEC_SIZE);
+               down_read(&current->mm->mmap_sem);
+               ret = get_user_pages(current, current->mm, addr, nr_pages,
+                                    rw == READ, 0, pvec->page, NULL);
+               up_read(&current->mm->mmap_sem);
+               if (ret < 0)
+                       return ERR_PTR(ret);
+               pvec->nr = ret;
+               pvec->idx = 0;
+       }
+       return pvec->page[pvec->idx++];
+}
+
 static ssize_t
 blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
-                       loff_t offset, unsigned long nr_segs)
-{
-       struct file *file = iocb->ki_filp;
-       struct inode *inode = file->f_mapping->host;
+                loff_t pos, unsigned long nr_segs)
+{
+       struct inode *inode = iocb->ki_filp->f_mapping->host;
+       unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
+       unsigned blocksize_mask = (1 << blkbits) - 1;
+       unsigned long seg = 0;  /* iov segment iterator */
+       unsigned long nvec;     /* number of bio vec needed */
+       unsigned long cur_off;  /* offset into current page */
+       unsigned long cur_len;  /* I/O len of current page, up to PAGE_SIZE */
+
+       unsigned long addr;     /* user iovec address */
+       size_t count;           /* user iovec len */
+       size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
+       loff_t size;            /* size of block device */
+       struct bio *bio;
+       atomic_t *bio_count = &iocb->ki_bio_count;
+       struct page *page;
+       struct pvec pvec;
+
+       pvec.nr = 0;
+       pvec.idx = 0;
+
+       if (pos & blocksize_mask)
+               return -EINVAL;
+
+       size = i_size_read(inode);
+       if (pos + nbytes > size) {
+               nbytes = size - pos;
+               iocb->ki_left = nbytes;
+       }
+
+       /*
+        * check first non-zero iov alignment, the remaining
+        * iov alignment is checked inside bio loop below.
+        */
+       do {
+               addr = (unsigned long) iov[seg].iov_base;
+               count = min(iov[seg].iov_len, nbytes);
+               if (addr & blocksize_mask || count & blocksize_mask)
+                       return -EINVAL;
+       } while (!count && ++seg < nr_segs);
+       atomic_set(bio_count, 1);
+
+       while (nbytes) {
+               /* roughly estimate number of bio vec needed */
+               nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
+               nvec = max(nvec, nr_segs - seg);
+               nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
+
+               /* bio_alloc should not fail with GFP_KERNEL flag */
+               bio = bio_alloc(GFP_KERNEL, nvec);
+               bio->bi_bdev = I_BDEV(inode);
+               bio->bi_end_io = blk_end_aio;
+               bio->bi_private = iocb;
+               bio->bi_sector = pos >> blkbits;
+same_bio:
+               cur_off = addr & ~PAGE_MASK;
+               cur_len = PAGE_SIZE - cur_off;
+               if (count < cur_len)
+                       cur_len = count;
+
+               page = blk_get_page(addr, count, rw, &pvec);
+               if (unlikely(IS_ERR(page)))
+                       goto backout;
+
+               if (bio_add_page(bio, page, cur_len, cur_off)) {
+                       pos += cur_len;
+                       addr += cur_len;
+                       count -= cur_len;
+                       nbytes -= cur_len;
+
+                       if (count)
+                               goto same_bio;
+                       while (++seg < nr_segs) {
+                               addr = (unsigned long) iov[seg].iov_base;
+                               count = iov[seg].iov_len;
+                               if (!count)
+                                       continue;
+                               if (unlikely(addr & blocksize_mask ||
+                                            count & blocksize_mask)) {
+                                       page = ERR_PTR(-EINVAL);
+                                       goto backout;
+                               }
+                               count = min(count, nbytes);
+                               goto same_bio;
+                       }
+               }
 
-       return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode),
-                               iov, offset, nr_segs, blkdev_get_blocks, NULL);
+               /* bio is ready, submit it */
+               if (rw == READ)
+                       bio_set_pages_dirty(bio);
+               atomic_inc(bio_count);
+               submit_bio(rw, bio);
+       }
+
+completion:
+       iocb->ki_left -= nbytes;
+       nbytes = iocb->ki_left;
+       iocb->ki_pos += nbytes;
+
+       blk_run_address_space(inode->i_mapping);
+       if (atomic_dec_and_test(bio_count))
+               aio_complete(iocb, nbytes, 0);
+
+       return -EIOCBQUEUED;
+
+backout:
+       /*
+        * back out nbytes count constructed so far for this bio,
+        * we will throw away current bio.
+        */
+       nbytes += bio->bi_size;
+       bio_release_pages(bio);
+       bio_put(bio);
+
+       /*
+        * if no bio was submmitted, return the error code.
+        * otherwise, proceed with pending I/O completion.
+        */
+       if (atomic_read(bio_count) == 1)
+               return PTR_ERR(page);
+       goto completion;
 }
 
 static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
index 098790eb2aa161967538c91b734c3fe45fa5d8b7..472e33e0f3cfd7fc3914d8dc78b41b82fa91aa64 100644 (file)
@@ -4876,7 +4876,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
        } else {
                /* Add file to outstanding requests */
                /* BB change to kmem cache alloc */     
-               dnotify_req = (struct dir_notify_req *) kmalloc(
+               dnotify_req = kmalloc(
                                                sizeof(struct dir_notify_req),
                                                 GFP_KERNEL);
                if(dnotify_req) {
index 137d76c3f90a6a87b4a78d2073089a13998790be..c692487346eaa324fb1f1d5950a4af5a5503d184 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/debugfs.h>
+#include <linux/fsnotify.h>
 
 #define DEBUGFS_MAGIC  0x64626720
 
@@ -54,7 +55,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
                        inode->i_op = &simple_dir_inode_operations;
                        inode->i_fop = &simple_dir_operations;
 
-                       /* directory inodes start off with i_nlink == 2 (for "." entry) */
+                       /* directory inodes start off with i_nlink == 2
+                        * (for "." entry) */
                        inc_nlink(inode);
                        break;
                }
@@ -87,15 +89,22 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
        res = debugfs_mknod(dir, dentry, mode, 0);
-       if (!res)
+       if (!res) {
                inc_nlink(dir);
+               fsnotify_mkdir(dir, dentry);
+       }
        return res;
 }
 
 static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
 {
+       int res;
+
        mode = (mode & S_IALLUGO) | S_IFREG;
-       return debugfs_mknod(dir, dentry, mode, 0);
+       res = debugfs_mknod(dir, dentry, mode, 0);
+       if (!res)
+               fsnotify_create(dir, dentry);
+       return res;
 }
 
 static inline int debugfs_positive(struct dentry *dentry)
@@ -135,7 +144,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
         * block. A pointer to that is in the struct vfsmount that we
         * have around.
         */
-       if (!parent ) {
+       if (!parent) {
                if (debugfs_mount && debugfs_mount->mnt_sb) {
                        parent = debugfs_mount->mnt_sb->s_root;
                }
@@ -153,6 +162,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
                        error = debugfs_mkdir(parent->d_inode, *dentry, mode);
                else 
                        error = debugfs_create(parent->d_inode, *dentry, mode);
+               dput(*dentry);
        } else
                error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
@@ -197,13 +207,15 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
 
        pr_debug("debugfs: creating file '%s'\n",name);
 
-       error = simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count);
+       error = simple_pin_fs(&debug_fs_type, &debugfs_mount,
+                             &debugfs_mount_count);
        if (error)
                goto exit;
 
        error = debugfs_create_by_name(name, mode, parent, &dentry);
        if (error) {
                dentry = NULL;
+               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
                goto exit;
        }
 
@@ -262,6 +274,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
 void debugfs_remove(struct dentry *dentry)
 {
        struct dentry *parent;
+       int ret = 0;
        
        if (!dentry)
                return;
@@ -273,11 +286,19 @@ void debugfs_remove(struct dentry *dentry)
        mutex_lock(&parent->d_inode->i_mutex);
        if (debugfs_positive(dentry)) {
                if (dentry->d_inode) {
-                       if (S_ISDIR(dentry->d_inode->i_mode))
-                               simple_rmdir(parent->d_inode, dentry);
-                       else
+                       dget(dentry);
+                       if (S_ISDIR(dentry->d_inode->i_mode)) {
+                               ret = simple_rmdir(parent->d_inode, dentry);
+                               if (ret)
+                                       printk(KERN_ERR
+                                               "DebugFS rmdir on %s failed : "
+                                               "directory not empty.\n",
+                                               dentry->d_name.name);
+                       } else
                                simple_unlink(parent->d_inode, dentry);
-               dput(dentry);
+                       if (!ret)
+                               d_delete(dentry);
+                       dput(dentry);
                }
        }
        mutex_unlock(&parent->d_inode->i_mutex);
index d00de182ecb97fec47c74eb454b89918b6ab3802..bf21dc6d0dbd752d243a2d3b6d92d2d554dc0381 100644 (file)
@@ -1144,7 +1144,6 @@ sector_t bmap(struct inode * inode, sector_t block)
                res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);
        return res;
 }
-
 EXPORT_SYMBOL(bmap);
 
 /**
@@ -1163,27 +1162,43 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
 
        if (IS_RDONLY(inode))
                return;
-
-       if ((inode->i_flags & S_NOATIME) ||
-           (inode->i_sb->s_flags & MS_NOATIME) ||
-           ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
+       if (inode->i_flags & S_NOATIME)
+               return;
+       if (inode->i_sb->s_flags & MS_NOATIME)
+               return;
+       if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))
                return;
 
        /*
         * We may have a NULL vfsmount when coming from NFSD
         */
-       if (mnt &&
-           ((mnt->mnt_flags & MNT_NOATIME) ||
-            ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))))
-               return;
+       if (mnt) {
+               if (mnt->mnt_flags & MNT_NOATIME)
+                       return;
+               if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
+                       return;
 
-       now = current_fs_time(inode->i_sb);
-       if (!timespec_equal(&inode->i_atime, &now)) {
-               inode->i_atime = now;
-               mark_inode_dirty_sync(inode);
+               if (mnt->mnt_flags & MNT_RELATIME) {
+                       /*
+                        * With relative atime, only update atime if the
+                        * previous atime is earlier than either the ctime or
+                        * mtime.
+                        */
+                       if (timespec_compare(&inode->i_mtime,
+                                               &inode->i_atime) < 0 &&
+                           timespec_compare(&inode->i_ctime,
+                                               &inode->i_atime) < 0)
+                               return;
+               }
        }
-}
 
+       now = current_fs_time(inode->i_sb);
+       if (timespec_equal(&inode->i_atime, &now))
+               return;
+
+       inode->i_atime = now;
+       mark_inode_dirty_sync(inode);
+}
 EXPORT_SYMBOL(touch_atime);
 
 /**
index 7b40c69f44ebb07bd60edd7a44ece0b29c4e9e76..43baa1afa0218842ce0ded1007cec8d9f8c5ecf5 100644 (file)
@@ -818,7 +818,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        D1({
                int len = dentry->d_name.len;
-               char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
+               char *_name = kmalloc(len + 1, GFP_KERNEL);
                memcpy(_name, dentry->d_name.name, len);
                _name[len] = '\0';
                printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", "
@@ -964,7 +964,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
        D1({
                int len = dentry->d_name.len;
                const char *name = dentry->d_name.name;
-               char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
+               char *_name = kmalloc(len + 1, GFP_KERNEL);
                memcpy(_name, name, len);
                _name[len] = '\0';
                printk("***jffs_remove(): file = \"%s\", ino = %ld\n", _name, dentry->d_inode->i_ino);
index d0e783f199eafd0a76e42b6f97cc01385d89cbea..6dd18911b44ced8c830caa4a5181fad7bf9cef02 100644 (file)
@@ -436,7 +436,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
        int i, length;
 
        /* Allocate read buffer */
-       read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+       read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
        if (!read_buf) {
                printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");
                return -ENOMEM;
@@ -744,11 +744,11 @@ static int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
 
 
        /* Allocate read buffers */
-       read_buf1 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+       read_buf1 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
        if (!read_buf1)
                return -ENOMEM;
 
-       read_buf2 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+       read_buf2 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
        if (!read_buf2) {
                kfree(read_buf1);
                return -ENOMEM;
@@ -876,7 +876,7 @@ jffs_scan_flash(struct jffs_control *c)
        }
 
        /* Allocate read buffer */
-       read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+       read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
        if (!read_buf) {
                flash_safe_release(fmc->mtd);
                return -ENOMEM;
@@ -1463,7 +1463,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
                        kfree(f->name);
                        DJM(no_name--);
                }
-               if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1,
+               if (!(f->name = kmalloc(raw_inode->nsize + 1,
                                                 GFP_KERNEL))) {
                        return -ENOMEM;
                }
@@ -1737,7 +1737,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
                printk("jffs_find_child(): Found \"%s\".\n", f->name);
        }
        else {
-               char *copy = (char *) kmalloc(len + 1, GFP_KERNEL);
+               char *copy = kmalloc(len + 1, GFP_KERNEL);
                if (copy) {
                        memcpy(copy, name, len);
                        copy[len] = '\0';
@@ -2627,7 +2627,7 @@ jffs_print_tree(struct jffs_file *first_file, int indent)
                return;
        }
 
-       if (!(space = (char *) kmalloc(indent + 1, GFP_KERNEL))) {
+       if (!(space = kmalloc(indent + 1, GFP_KERNEL))) {
                printk("jffs_print_tree(): Out of memory!\n");
                return;
        }
index 47bc0b5d13242c69e8ceb344d837769bb623a929..6d62f3222892cd1fd6c74ce679c724f941e0bda2 100644 (file)
@@ -3777,12 +3777,12 @@ static int ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
        struct component_name lkey;
        struct component_name rkey;
 
-       lkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+       lkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
                                        GFP_KERNEL);
        if (lkey.name == NULL)
                return -ENOMEM;
 
-       rkey.name = (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+       rkey.name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
                                        GFP_KERNEL);
        if (rkey.name == NULL) {
                kfree(lkey.name);
index ee9b473b7b808d7866dfd95db09d775576977943..53f63b47a6d34ec818543ac3a40cb356fb92c24f 100644 (file)
@@ -120,7 +120,7 @@ int diMount(struct inode *ipimap)
         * allocate/initialize the in-memory inode map control structure
         */
        /* allocate the in-memory inode map control structure. */
-       imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
+       imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
        if (imap == NULL) {
                jfs_err("diMount: kmalloc returned NULL!");
                return -ENOMEM;
index 92681c9e9b2009247ce091641cd89311a4025dbb..06270774516296c0928c4c0602348c577783f3bc 100644 (file)
@@ -36,7 +36,7 @@ struct nlm_wait {
        struct nlm_host *       b_host;
        struct file_lock *      b_lock;         /* local file lock */
        unsigned short          b_reclaim;      /* got to reclaim lock */
-       u32                     b_status;       /* grant callback status */
+       __be32                  b_status;       /* grant callback status */
 };
 
 static LIST_HEAD(nlm_blocked);
@@ -53,7 +53,7 @@ struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *
                block->b_host = host;
                block->b_lock = fl;
                init_waitqueue_head(&block->b_wait);
-               block->b_status = NLM_LCK_BLOCKED;
+               block->b_status = nlm_lck_blocked;
                list_add(&block->b_list, &nlm_blocked);
        }
        return block;
@@ -89,7 +89,7 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
         * nlmclnt_lock for an explanation.
         */
        ret = wait_event_interruptible_timeout(block->b_wait,
-                       block->b_status != NLM_LCK_BLOCKED,
+                       block->b_status != nlm_lck_blocked,
                        timeout);
        if (ret < 0)
                return -ERESTARTSYS;
@@ -131,7 +131,7 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock
                /* Alright, we found a lock. Set the return status
                 * and wake up the caller
                 */
-               block->b_status = NLM_LCK_GRANTED;
+               block->b_status = nlm_granted;
                wake_up(&block->b_wait);
                res = nlm_granted;
        }
@@ -211,7 +211,7 @@ restart:
        /* Now, wake up all processes that sleep on a blocked lock */
        list_for_each_entry(block, &nlm_blocked, b_list) {
                if (block->b_host == host) {
-                       block->b_status = NLM_LCK_DENIED_GRACE_PERIOD;
+                       block->b_status = nlm_lck_denied_grace_period;
                        wake_up(&block->b_wait);
                }
        }
index 80a1a6dccc8f293d3d3feda1bad9f293d9876108..0b4acc1c5e7da2a87a4f626f957b913dae5faff3 100644 (file)
@@ -27,7 +27,7 @@
 static int     nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int     nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
 static int     nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
-static int     nlm_stat_to_errno(u32 stat);
+static int     nlm_stat_to_errno(__be32 stat);
 static void    nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
 static int     nlmclnt_cancel(struct nlm_host *, int , struct file_lock *);
 
@@ -325,7 +325,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
                        }
                        break;
                } else
-               if (resp->status == NLM_LCK_DENIED_GRACE_PERIOD) {
+               if (resp->status == nlm_lck_denied_grace_period) {
                        dprintk("lockd: server in grace period\n");
                        if (argp->reclaim) {
                                printk(KERN_WARNING
@@ -411,10 +411,10 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl)
                goto out;
 
        switch (req->a_res.status) {
-               case NLM_LCK_GRANTED:
+               case nlm_granted:
                        fl->fl_type = F_UNLCK;
                        break;
-               case NLM_LCK_DENIED:
+               case nlm_lck_denied:
                        /*
                         * Report the conflicting lock back to the application.
                         */
@@ -524,9 +524,9 @@ again:
                if (!req->a_args.block)
                        break;
                /* Did a reclaimer thread notify us of a server reboot? */
-               if (resp->status ==  NLM_LCK_DENIED_GRACE_PERIOD)
+               if (resp->status ==  nlm_lck_denied_grace_period)
                        continue;
-               if (resp->status != NLM_LCK_BLOCKED)
+               if (resp->status != nlm_lck_blocked)
                        break;
                /* Wait on an NLM blocking lock */
                status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT);
@@ -535,11 +535,11 @@ again:
                 */
                if (status < 0)
                        goto out_unblock;
-               if (resp->status != NLM_LCK_BLOCKED)
+               if (resp->status != nlm_lck_blocked)
                        break;
        }
 
-       if (resp->status == NLM_LCK_GRANTED) {
+       if (resp->status == nlm_granted) {
                down_read(&host->h_rwsem);
                /* Check whether or not the server has rebooted */
                if (fl->fl_u.nfs_fl.state != host->h_state) {
@@ -556,7 +556,7 @@ again:
 out_unblock:
        nlmclnt_finish_block(block);
        /* Cancel the blocked request if it is still pending */
-       if (resp->status == NLM_LCK_BLOCKED)
+       if (resp->status == nlm_lck_blocked)
                nlmclnt_cancel(host, req->a_args.block, fl);
 out:
        nlm_release_call(req);
@@ -585,12 +585,12 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
        req->a_args.reclaim = 1;
 
        if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0
-        && req->a_res.status == NLM_LCK_GRANTED)
+        && req->a_res.status == nlm_granted)
                return 0;
 
        printk(KERN_WARNING "lockd: failed to reclaim lock for pid %d "
                                "(errno %d, status %d)\n", fl->fl_pid,
-                               status, req->a_res.status);
+                               status, ntohl(req->a_res.status));
 
        /*
         * FIXME: This is a serious failure. We can
@@ -637,10 +637,10 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
        if (status < 0)
                goto out;
 
-       if (resp->status == NLM_LCK_GRANTED)
+       if (resp->status == nlm_granted)
                goto out;
 
-       if (resp->status != NLM_LCK_DENIED_NOLOCKS)
+       if (resp->status != nlm_lck_denied_nolocks)
                printk("lockd: unexpected unlock status: %d\n", resp->status);
        /* What to do now? I'm out of my depth... */
        status = -ENOLCK;
@@ -652,7 +652,7 @@ out:
 static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
 {
        struct nlm_rqst *req = data;
-       int             status = req->a_res.status;
+       u32 status = ntohl(req->a_res.status);
 
        if (RPC_ASSASSINATED(task))
                goto die;
@@ -720,6 +720,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl
 static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
 {
        struct nlm_rqst *req = data;
+       u32 status = ntohl(req->a_res.status);
 
        if (RPC_ASSASSINATED(task))
                goto die;
@@ -731,9 +732,9 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
        }
 
        dprintk("lockd: cancel status %u (task %u)\n",
-                       req->a_res.status, task->tk_pid);
+                       status, task->tk_pid);
 
-       switch (req->a_res.status) {
+       switch (status) {
        case NLM_LCK_GRANTED:
        case NLM_LCK_DENIED_GRACE_PERIOD:
        case NLM_LCK_DENIED:
@@ -744,7 +745,7 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
                goto retry_cancel;
        default:
                printk(KERN_NOTICE "lockd: weird return %d for CANCEL call\n",
-                       req->a_res.status);
+                       status);
        }
 
 die:
@@ -768,9 +769,9 @@ static const struct rpc_call_ops nlmclnt_cancel_ops = {
  * Convert an NLM status code to a generic kernel errno
  */
 static int
-nlm_stat_to_errno(u32 status)
+nlm_stat_to_errno(__be32 status)
 {
-       switch(status) {
+       switch(ntohl(status)) {
        case NLM_LCK_GRANTED:
                return 0;
        case NLM_LCK_DENIED:
index 5c054b20fd5e8ced08856105c1a7409364aebfe8..c7db0a5bccdc19bcff9134efe7df604e55cdab22 100644 (file)
@@ -645,7 +645,7 @@ static const struct rpc_call_ops nlmsvc_grant_ops = {
  * block.
  */
 void
-nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
+nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
 {
        struct nlm_block        *block;
 
@@ -655,7 +655,7 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
                return;
 
        if (block) {
-               if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
+               if (status == nlm_lck_denied_grace_period) {
                        /* Try again in a couple of seconds */
                        nlmsvc_insert_block(block, 10 * HZ);
                } else {
index 6220dc2a3f2c246e31817902a674648321fd6873..068886de4dda19b176ab2340da64269c05d87da1 100644 (file)
@@ -39,7 +39,7 @@ nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file,
                        return nlm_lck_denied;
        }
 
-       share = (struct nlm_share *) kmalloc(sizeof(*share) + oh->len,
+       share = kmalloc(sizeof(*share) + oh->len,
                                                GFP_KERNEL);
        if (share == NULL)
                return nlm_lck_denied_nolocks;
index b7c949256e5a3c2b88d7cc74f673462b4ec9be70..34dae5d70738bff79bc78945fd647dc4f16bdbca 100644 (file)
@@ -361,7 +361,7 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return 0;
-       resp->status = ntohl(*p++);
+       resp->status = *p++;
        return xdr_argsize_check(rqstp, p);
 }
 
@@ -407,8 +407,8 @@ nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return -EIO;
-       resp->status = ntohl(*p++);
-       if (resp->status == NLM_LCK_DENIED) {
+       resp->status = *p++;
+       if (resp->status == nlm_lck_denied) {
                struct file_lock        *fl = &resp->lock.fl;
                u32                     excl;
                s32                     start, len, end;
@@ -506,7 +506,7 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return -EIO;
-       resp->status = ntohl(*p++);
+       resp->status = *p++;
        return 0;
 }
 
index f4c0b2b9f75a7e87d778981d001efdf5e158fecd..a78240551219a91ba8d5a34eff83ed8002331bb6 100644 (file)
@@ -367,7 +367,7 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return 0;
-       resp->status = ntohl(*p++);
+       resp->status = *p++;
        return xdr_argsize_check(rqstp, p);
 }
 
@@ -413,8 +413,8 @@ nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return -EIO;
-       resp->status = ntohl(*p++);
-       if (resp->status == NLM_LCK_DENIED) {
+       resp->status = *p++;
+       if (resp->status == nlm_lck_denied) {
                struct file_lock        *fl = &resp->lock.fl;
                u32                     excl;
                s64                     start, end, len;
@@ -512,7 +512,7 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return -EIO;
-       resp->status = ntohl(*p++);
+       resp->status = *p++;
        return 0;
 }
 
index fde8553faa7661677e2210d65620b753eceddaf8..5ef336c1103c2c4a4ecbb5c9bf96cf8923e15454 100644 (file)
@@ -368,6 +368,7 @@ static int show_vfsmnt(struct seq_file *m, void *v)
                { MNT_NOEXEC, ",noexec" },
                { MNT_NOATIME, ",noatime" },
                { MNT_NODIRATIME, ",nodiratime" },
+               { MNT_RELATIME, ",relatime" },
                { 0, NULL }
        };
        struct proc_fs_info *fs_infop;
@@ -1405,9 +1406,11 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                mnt_flags |= MNT_NOATIME;
        if (flags & MS_NODIRATIME)
                mnt_flags |= MNT_NODIRATIME;
+       if (flags & MS_RELATIME)
+               mnt_flags |= MNT_RELATIME;
 
        flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
-                  MS_NOATIME | MS_NODIRATIME);
+                  MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
 
        /* ... and get the mountpoint */
        retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
index 47462ac94474984a2f05b7aa1517e06c6d68b266..67a90bf795d57ef439b5fc1b3f46e09cfc6b78f1 100644 (file)
@@ -327,11 +327,12 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
        char *optarg;
        unsigned long optint;
        int version = 0;
+       int ret;
 
        data->flags = 0;
        data->int_flags = 0;
        data->mounted_uid = 0;
-       data->wdog_pid = -1;
+       data->wdog_pid = NULL;
        data->ncp_fd = ~0;
        data->time_out = 10;
        data->retry_count = 20;
@@ -343,8 +344,9 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
        data->mounted_vol[0] = 0;
        
        while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
-               if (optval < 0)
-                       return optval;
+               ret = optval;
+               if (ret < 0)
+                       goto err;
                switch (optval) {
                        case 'u':
                                data->uid = optint;
@@ -371,7 +373,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
                                data->flags = optint;
                                break;
                        case 'w':
-                               data->wdog_pid = optint;
+                               data->wdog_pid = find_get_pid(optint);
                                break;
                        case 'n':
                                data->ncp_fd = optint;
@@ -380,18 +382,21 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
                                data->info_fd = optint;
                                break;
                        case 'v':
-                               if (optint < NCP_MOUNT_VERSION_V4) {
-                                       return -ECHRNG;
-                               }
-                               if (optint > NCP_MOUNT_VERSION_V5) {
-                                       return -ECHRNG;
-                               }
+                               ret = -ECHRNG;
+                               if (optint < NCP_MOUNT_VERSION_V4)
+                                       goto err;
+                               if (optint > NCP_MOUNT_VERSION_V5)
+                                       goto err;
                                version = optint;
                                break;
                        
                }
        }
        return 0;
+err:
+       put_pid(data->wdog_pid);
+       data->wdog_pid = NULL;
+       return ret;
 }
 
 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
@@ -409,6 +414,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 #endif
        struct ncp_entry_info finfo;
 
+       data.wdog_pid = NULL;
        server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
        if (!server)
                return -ENOMEM;
@@ -425,7 +431,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                data.flags = md->flags;
                                data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
                                data.mounted_uid = md->mounted_uid;
-                               data.wdog_pid = md->wdog_pid;
+                               data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
@@ -445,7 +451,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                                data.flags = md->flags;
                                data.int_flags = 0;
                                data.mounted_uid = md->mounted_uid;
-                               data.wdog_pid = md->wdog_pid;
+                               data.wdog_pid = find_get_pid(md->wdog_pid);
                                data.ncp_fd = md->ncp_fd;
                                data.time_out = md->time_out;
                                data.retry_count = md->retry_count;
@@ -679,6 +685,7 @@ out_fput:
         */
        fput(ncp_filp);
 out:
+       put_pid(data.wdog_pid);
        sb->s_fs_info = NULL;
        kfree(server);
        return error;
@@ -711,7 +718,8 @@ static void ncp_put_super(struct super_block *sb)
        if (server->info_filp)
                fput(server->info_filp);
        fput(server->ncp_filp);
-       kill_proc(server->m.wdog_pid, SIGTERM, 1);
+       kill_pid(server->m.wdog_pid, SIGTERM, 1);
+       put_pid(server->m.wdog_pid);
 
        kfree(server->priv.data);
        kfree(server->auth.object_name);
index ee458aeab24a5ef1ebc1ad8aad1410cd2d64abd9..b3fd29baadc391ff61c822bde3e056e8b3b339e3 100644 (file)
@@ -1877,7 +1877,7 @@ static int nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir,
        struct nfs_server *server = NFS_SERVER(dir->d_inode);
        struct unlink_desc *up;
 
-       up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
+       up = kmalloc(sizeof(*up), GFP_KERNEL);
        if (!up)
                return -ENOMEM;
        
index f37df46d2eaa5d13042a0557c79a27ff2d510873..248dd92e6a56de1f0a93334c4093a45384cbc4e7 100644 (file)
@@ -787,15 +787,20 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
        key.ex_dentry = dentry;
 
        exp = svc_export_lookup(&key);
-       if (exp != NULL) 
-               switch (cache_check(&svc_export_cache, &exp->h, reqp)) {
+       if (exp != NULL)  {
+               int err;
+
+               err = cache_check(&svc_export_cache, &exp->h, reqp);
+               switch (err) {
                case 0: break;
                case -EAGAIN:
-                       exp = ERR_PTR(-EAGAIN);
+               case -ETIMEDOUT:
+                       exp = ERR_PTR(err);
                        break;
                default:
                        exp = NULL;
                }
+       }
 
        return exp;
 }
@@ -950,6 +955,8 @@ exp_export(struct nfsctl_export *nxp)
 
        exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
 
+       memset(&new, 0, sizeof(new));
+
        /* must make sure there won't be an ex_fsid clash */
        if ((nxp->ex_flags & NFSEXP_FSID) &&
            (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) &&
@@ -980,6 +987,9 @@ exp_export(struct nfsctl_export *nxp)
 
        new.h.expiry_time = NEVER;
        new.h.flags = 0;
+       new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL);
+       if (!new.ex_path)
+               goto finish;
        new.ex_client = clp;
        new.ex_mnt = nd.mnt;
        new.ex_dentry = nd.dentry;
@@ -1000,10 +1010,11 @@ exp_export(struct nfsctl_export *nxp)
                /* failed to create at least one index */
                exp_do_unexport(exp);
                cache_flush();
-               err = -ENOMEM;
-       }
-
+       } else
+               err = 0;
 finish:
+       if (new.ex_path)
+               kfree(new.ex_path);
        if (exp)
                exp_put(exp);
        if (fsid_key && !IS_ERR(fsid_key))
@@ -1104,6 +1115,10 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
                 path, nd.dentry, clp->name,
                 inode->i_sb->s_id, inode->i_ino);
        exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
+       if (IS_ERR(exp)) {
+               err = PTR_ERR(exp);
+               goto out;
+       }
        if (!exp) {
                dprintk("nfsd: exp_rootfh export not found.\n");
                goto out;
@@ -1159,12 +1174,10 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
        mk_fsid_v1(fsidv, 0);
 
        exp = exp_find(clp, 1, fsidv, creq);
-       if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
-               return nfserr_dropit;
+       if (IS_ERR(exp))
+               return nfserrno(PTR_ERR(exp));
        if (exp == NULL)
                return nfserr_perm;
-       else if (IS_ERR(exp))
-               return nfserrno(PTR_ERR(exp));
        rv = fh_compose(fhp, exp, exp->ex_dentry, NULL);
        exp_put(exp);
        return rv;
index 11fdaf7721b4e68f53d71ae6994d621b21d90a44..221acd1f11f66c1fd63474287a79530611d690be 100644 (file)
@@ -22,7 +22,7 @@
 /*
  * Note: we hold the dentry use count while the file is open.
  */
-static u32
+static __be32
 nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
 {
        __be32          nfserr;
index 50bc94243ca1b08d77802d785f1de83cbdcd33f6..8522729830db99832d37d2bac393760fe2a58d61 100644 (file)
  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Note: some routines in this file are just trivial wrappers
- * (e.g. nfsd4_lookup()) defined solely for the sake of consistent
- * naming.  Since all such routines have been declared "inline",
- * there shouldn't be any associated overhead.  At some point in
- * the future, I might inline these "by hand" to clean up a
- * little.
  */
 
 #include <linux/param.h>
@@ -161,8 +154,9 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
 }
 
 
-static inline __be32
-nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
+static __be32
+nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+          struct nfsd4_open *open)
 {
        __be32 status;
        dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
@@ -179,11 +173,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
        status = nfsd4_process_open1(open);
        if (status == nfserr_replay_me) {
                struct nfs4_replay *rp = &open->op_stateowner->so_replay;
-               fh_put(current_fh);
-               current_fh->fh_handle.fh_size = rp->rp_openfh_len;
-               memcpy(&current_fh->fh_handle.fh_base, rp->rp_openfh,
+               fh_put(&cstate->current_fh);
+               cstate->current_fh.fh_handle.fh_size = rp->rp_openfh_len;
+               memcpy(&cstate->current_fh.fh_handle.fh_base, rp->rp_openfh,
                                rp->rp_openfh_len);
-               status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+               status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
                if (status)
                        dprintk("nfsd4_open: replay failed"
                                " restoring previous filehandle\n");
@@ -215,7 +209,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
                         * (3) set open->op_truncate if the file is to be
                         * truncated after opening, (4) do permission checking.
                         */
-                       status = do_open_lookup(rqstp, current_fh, open);
+                       status = do_open_lookup(rqstp, &cstate->current_fh,
+                                               open);
                        if (status)
                                goto out;
                        break;
@@ -227,7 +222,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
                         * open->op_truncate if the file is to be truncated
                         * after opening, (3) do permission checking.
                        */
-                       status = do_open_fhandle(rqstp, current_fh, open);
+                       status = do_open_fhandle(rqstp, &cstate->current_fh,
+                                                open);
                        if (status)
                                goto out;
                        break;
@@ -248,11 +244,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
         * successful, it (1) truncates the file if open->op_truncate was
         * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
         */
-       status = nfsd4_process_open2(rqstp, current_fh, open);
+       status = nfsd4_process_open2(rqstp, &cstate->current_fh, open);
 out:
        if (open->op_stateowner) {
                nfs4_get_stateowner(open->op_stateowner);
-               *replay_owner = open->op_stateowner;
+               cstate->replay_owner = open->op_stateowner;
        }
        nfs4_unlock_state();
        return status;
@@ -261,71 +257,80 @@ out:
 /*
  * filehandle-manipulating ops.
  */
-static inline __be32
-nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
+static __be32
+nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct svc_fh **getfh)
 {
-       if (!current_fh->fh_dentry)
+       if (!cstate->current_fh.fh_dentry)
                return nfserr_nofilehandle;
 
-       *getfh = current_fh;
+       *getfh = &cstate->current_fh;
        return nfs_ok;
 }
 
-static inline __be32
-nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh)
+static __be32
+nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct nfsd4_putfh *putfh)
 {
-       fh_put(current_fh);
-       current_fh->fh_handle.fh_size = putfh->pf_fhlen;
-       memcpy(&current_fh->fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen);
-       return fh_verify(rqstp, current_fh, 0, MAY_NOP);
+       fh_put(&cstate->current_fh);
+       cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
+       memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
+              putfh->pf_fhlen);
+       return fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
 }
 
-static inline __be32
-nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
+static __be32
+nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+               void *arg)
 {
        __be32 status;
 
-       fh_put(current_fh);
-       status = exp_pseudoroot(rqstp->rq_client, current_fh,
+       fh_put(&cstate->current_fh);
+       status = exp_pseudoroot(rqstp->rq_client, &cstate->current_fh,
                              &rqstp->rq_chandle);
        return status;
 }
 
-static inline __be32
-nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
+static __be32
+nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+               void *arg)
 {
-       if (!save_fh->fh_dentry)
+       if (!cstate->save_fh.fh_dentry)
                return nfserr_restorefh;
 
-       fh_dup2(current_fh, save_fh);
+       fh_dup2(&cstate->current_fh, &cstate->save_fh);
        return nfs_ok;
 }
 
-static inline __be32
-nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
+static __be32
+nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            void *arg)
 {
-       if (!current_fh->fh_dentry)
+       if (!cstate->current_fh.fh_dentry)
                return nfserr_nofilehandle;
 
-       fh_dup2(save_fh, current_fh);
+       fh_dup2(&cstate->save_fh, &cstate->current_fh);
        return nfs_ok;
 }
 
 /*
  * misc nfsv4 ops
  */
-static inline __be32
-nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access)
+static __be32
+nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_access *access)
 {
        if (access->ac_req_access & ~NFS3_ACCESS_FULL)
                return nfserr_inval;
 
        access->ac_resp_access = access->ac_req_access;
-       return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported);
+       return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
+                          &access->ac_supported);
 }
 
-static inline __be32
-nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit)
+static __be32
+nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_commit *commit)
 {
        __be32 status;
 
@@ -333,14 +338,16 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com
        *p++ = nfssvc_boot.tv_sec;
        *p++ = nfssvc_boot.tv_usec;
 
-       status = nfsd_commit(rqstp, current_fh, commit->co_offset, commit->co_count);
+       status = nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
+                            commit->co_count);
        if (status == nfserr_symlink)
                status = nfserr_inval;
        return status;
 }
 
 static __be32
-nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create)
+nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_create *create)
 {
        struct svc_fh resfh;
        __be32 status;
@@ -348,7 +355,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
 
        fh_init(&resfh, NFS4_FHSIZE);
 
-       status = fh_verify(rqstp, current_fh, S_IFDIR, MAY_CREATE);
+       status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, MAY_CREATE);
        if (status == nfserr_symlink)
                status = nfserr_notdir;
        if (status)
@@ -365,9 +372,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
                 */
                create->cr_linkname[create->cr_linklen] = 0;
 
-               status = nfsd_symlink(rqstp, current_fh, create->cr_name,
-                                     create->cr_namelen, create->cr_linkname,
-                                     create->cr_linklen, &resfh, &create->cr_iattr);
+               status = nfsd_symlink(rqstp, &cstate->current_fh,
+                                     create->cr_name, create->cr_namelen,
+                                     create->cr_linkname, create->cr_linklen,
+                                     &resfh, &create->cr_iattr);
                break;
 
        case NF4BLK:
@@ -375,9 +383,9 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
                if (MAJOR(rdev) != create->cr_specdata1 ||
                    MINOR(rdev) != create->cr_specdata2)
                        return nfserr_inval;
-               status = nfsd_create(rqstp, current_fh, create->cr_name,
-                                    create->cr_namelen, &create->cr_iattr,
-                                    S_IFBLK, rdev, &resfh);
+               status = nfsd_create(rqstp, &cstate->current_fh,
+                                    create->cr_name, create->cr_namelen,
+                                    &create->cr_iattr, S_IFBLK, rdev, &resfh);
                break;
 
        case NF4CHR:
@@ -385,28 +393,28 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
                if (MAJOR(rdev) != create->cr_specdata1 ||
                    MINOR(rdev) != create->cr_specdata2)
                        return nfserr_inval;
-               status = nfsd_create(rqstp, current_fh, create->cr_name,
-                                    create->cr_namelen, &create->cr_iattr,
-                                    S_IFCHR, rdev, &resfh);
+               status = nfsd_create(rqstp, &cstate->current_fh,
+                                    create->cr_name, create->cr_namelen,
+                                    &create->cr_iattr,S_IFCHR, rdev, &resfh);
                break;
 
        case NF4SOCK:
-               status = nfsd_create(rqstp, current_fh, create->cr_name,
-                                    create->cr_namelen, &create->cr_iattr,
-                                    S_IFSOCK, 0, &resfh);
+               status = nfsd_create(rqstp, &cstate->current_fh,
+                                    create->cr_name, create->cr_namelen,
+                                    &create->cr_iattr, S_IFSOCK, 0, &resfh);
                break;
 
        case NF4FIFO:
-               status = nfsd_create(rqstp, current_fh, create->cr_name,
-                                    create->cr_namelen, &create->cr_iattr,
-                                    S_IFIFO, 0, &resfh);
+               status = nfsd_create(rqstp, &cstate->current_fh,
+                                    create->cr_name, create->cr_namelen,
+                                    &create->cr_iattr, S_IFIFO, 0, &resfh);
                break;
 
        case NF4DIR:
                create->cr_iattr.ia_valid &= ~ATTR_SIZE;
-               status = nfsd_create(rqstp, current_fh, create->cr_name,
-                                    create->cr_namelen, &create->cr_iattr,
-                                    S_IFDIR, 0, &resfh);
+               status = nfsd_create(rqstp, &cstate->current_fh,
+                                    create->cr_name, create->cr_namelen,
+                                    &create->cr_iattr, S_IFDIR, 0, &resfh);
                break;
 
        default:
@@ -414,21 +422,22 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
        }
 
        if (!status) {
-               fh_unlock(current_fh);
-               set_change_info(&create->cr_cinfo, current_fh);
-               fh_dup2(current_fh, &resfh);
+               fh_unlock(&cstate->current_fh);
+               set_change_info(&create->cr_cinfo, &cstate->current_fh);
+               fh_dup2(&cstate->current_fh, &resfh);
        }
 
        fh_put(&resfh);
        return status;
 }
 
-static inline __be32
-nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr)
+static __be32
+nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             struct nfsd4_getattr *getattr)
 {
        __be32 status;
 
-       status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+       status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
        if (status)
                return status;
 
@@ -438,26 +447,28 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge
        getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0;
        getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1;
 
-       getattr->ga_fhp = current_fh;
+       getattr->ga_fhp = &cstate->current_fh;
        return nfs_ok;
 }
 
-static inline __be32
-nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
-          struct svc_fh *save_fh, struct nfsd4_link *link)
+static __be32
+nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+          struct nfsd4_link *link)
 {
        __be32 status = nfserr_nofilehandle;
 
-       if (!save_fh->fh_dentry)
+       if (!cstate->save_fh.fh_dentry)
                return status;
-       status = nfsd_link(rqstp, current_fh, link->li_name, link->li_namelen, save_fh);
+       status = nfsd_link(rqstp, &cstate->current_fh,
+                          link->li_name, link->li_namelen, &cstate->save_fh);
        if (!status)
-               set_change_info(&link->li_cinfo, current_fh);
+               set_change_info(&link->li_cinfo, &cstate->current_fh);
        return status;
 }
 
 static __be32
-nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
+nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             void *arg)
 {
        struct svc_fh tmp_fh;
        __be32 ret;
@@ -466,22 +477,27 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
        if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh,
                              &rqstp->rq_chandle)) != 0)
                return ret;
-       if (tmp_fh.fh_dentry == current_fh->fh_dentry) {
+       if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) {
                fh_put(&tmp_fh);
                return nfserr_noent;
        }
        fh_put(&tmp_fh);
-       return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh);
+       return nfsd_lookup(rqstp, &cstate->current_fh,
+                          "..", 2, &cstate->current_fh);
 }
 
-static inline __be32
-nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup)
+static __be32
+nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_lookup *lookup)
 {
-       return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh);
+       return nfsd_lookup(rqstp, &cstate->current_fh,
+                          lookup->lo_name, lookup->lo_len,
+                          &cstate->current_fh);
 }
 
-static inline __be32
-nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
+static __be32
+nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+          struct nfsd4_read *read)
 {
        __be32 status;
 
@@ -493,7 +509,8 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
 
        nfs4_lock_state();
        /* check stateid */
-       if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
+       if ((status = nfs4_preprocess_stateid_op(&cstate->current_fh,
+                               &read->rd_stateid,
                                CHECK_FH | RD_STATE, &read->rd_filp))) {
                dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
                goto out;
@@ -504,12 +521,13 @@ nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read
 out:
        nfs4_unlock_state();
        read->rd_rqstp = rqstp;
-       read->rd_fhp = current_fh;
+       read->rd_fhp = &cstate->current_fh;
        return status;
 }
 
-static inline __be32
-nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir)
+static __be32
+nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             struct nfsd4_readdir *readdir)
 {
        u64 cookie = readdir->rd_cookie;
        static const nfs4_verifier zeroverf;
@@ -527,48 +545,51 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re
                return nfserr_bad_cookie;
 
        readdir->rd_rqstp = rqstp;
-       readdir->rd_fhp = current_fh;
+       readdir->rd_fhp = &cstate->current_fh;
        return nfs_ok;
 }
 
-static inline __be32
-nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink)
+static __be32
+nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+              struct nfsd4_readlink *readlink)
 {
        readlink->rl_rqstp = rqstp;
-       readlink->rl_fhp = current_fh;
+       readlink->rl_fhp = &cstate->current_fh;
        return nfs_ok;
 }
 
-static inline __be32
-nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove)
+static __be32
+nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_remove *remove)
 {
        __be32 status;
 
        if (nfs4_in_grace())
                return nfserr_grace;
-       status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen);
+       status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
+                            remove->rm_name, remove->rm_namelen);
        if (status == nfserr_symlink)
                return nfserr_notdir;
        if (!status) {
-               fh_unlock(current_fh);
-               set_change_info(&remove->rm_cinfo, current_fh);
+               fh_unlock(&cstate->current_fh);
+               set_change_info(&remove->rm_cinfo, &cstate->current_fh);
        }
        return status;
 }
 
-static inline __be32
-nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
-            struct svc_fh *save_fh, struct nfsd4_rename *rename)
+static __be32
+nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_rename *rename)
 {
        __be32 status = nfserr_nofilehandle;
 
-       if (!save_fh->fh_dentry)
+       if (!cstate->save_fh.fh_dentry)
                return status;
-       if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags
+       if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags
                                        & NFSEXP_NOSUBTREECHECK))
                return nfserr_grace;
-       status = nfsd_rename(rqstp, save_fh, rename->rn_sname,
-                            rename->rn_snamelen, current_fh,
+       status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
+                            rename->rn_snamelen, &cstate->current_fh,
                             rename->rn_tname, rename->rn_tnamelen);
 
        /* the underlying filesystem returns different error's than required
@@ -576,27 +597,28 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
        if (status == nfserr_isdir)
                status = nfserr_exist;
        else if ((status == nfserr_notdir) &&
-                  (S_ISDIR(save_fh->fh_dentry->d_inode->i_mode) &&
-                   S_ISDIR(current_fh->fh_dentry->d_inode->i_mode)))
+                  (S_ISDIR(cstate->save_fh.fh_dentry->d_inode->i_mode) &&
+                   S_ISDIR(cstate->current_fh.fh_dentry->d_inode->i_mode)))
                status = nfserr_exist;
        else if (status == nfserr_symlink)
                status = nfserr_notdir;
 
        if (!status) {
-               set_change_info(&rename->rn_sinfo, current_fh);
-               set_change_info(&rename->rn_tinfo, save_fh);
+               set_change_info(&rename->rn_sinfo, &cstate->current_fh);
+               set_change_info(&rename->rn_tinfo, &cstate->save_fh);
        }
        return status;
 }
 
-static inline __be32
-nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
+static __be32
+nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             struct nfsd4_setattr *setattr)
 {
        __be32 status = nfs_ok;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
                nfs4_lock_state();
-               status = nfs4_preprocess_stateid_op(current_fh,
+               status = nfs4_preprocess_stateid_op(&cstate->current_fh,
                        &setattr->sa_stateid, CHECK_FH | WR_STATE, NULL);
                nfs4_unlock_state();
                if (status) {
@@ -606,16 +628,18 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
        }
        status = nfs_ok;
        if (setattr->sa_acl != NULL)
-               status = nfsd4_set_nfs4_acl(rqstp, current_fh, setattr->sa_acl);
+               status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
+                                           setattr->sa_acl);
        if (status)
                return status;
-       status = nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr,
+       status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
                                0, (time_t)0);
        return status;
 }
 
-static inline __be32
-nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
+static __be32
+nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct nfsd4_write *write)
 {
        stateid_t *stateid = &write->wr_stateid;
        struct file *filp = NULL;
@@ -628,7 +652,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
                return nfserr_inval;
 
        nfs4_lock_state();
-       status = nfs4_preprocess_stateid_op(current_fh, stateid,
+       status = nfs4_preprocess_stateid_op(&cstate->current_fh, stateid,
                                        CHECK_FH | WR_STATE, &filp);
        if (filp)
                get_file(filp);
@@ -645,9 +669,9 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
        *p++ = nfssvc_boot.tv_sec;
        *p++ = nfssvc_boot.tv_usec;
 
-       status =  nfsd_write(rqstp, current_fh, filp, write->wr_offset,
-                       rqstp->rq_vec, write->wr_vlen, write->wr_buflen,
-                       &write->wr_how_written);
+       status =  nfsd_write(rqstp, &cstate->current_fh, filp,
+                            write->wr_offset, rqstp->rq_vec, write->wr_vlen,
+                            write->wr_buflen, &write->wr_how_written);
        if (filp)
                fput(filp);
 
@@ -662,13 +686,14 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
  * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
  */
 static __be32
-nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify)
+_nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_verify *verify)
 {
        __be32 *buf, *p;
        int count;
        __be32 status;
 
-       status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
+       status = fh_verify(rqstp, &cstate->current_fh, 0, MAY_NOP);
        if (status)
                return status;
 
@@ -689,8 +714,9 @@ nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ver
        if (!buf)
                return nfserr_resource;
 
-       status = nfsd4_encode_fattr(current_fh, current_fh->fh_export,
-                                   current_fh->fh_dentry, buf,
+       status = nfsd4_encode_fattr(&cstate->current_fh,
+                                   cstate->current_fh.fh_export,
+                                   cstate->current_fh.fh_dentry, buf,
                                    &count, verify->ve_bmval,
                                    rqstp);
 
@@ -712,6 +738,26 @@ out_kfree:
        return status;
 }
 
+static __be32
+nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             struct nfsd4_verify *verify)
+{
+       __be32 status;
+
+       status = _nfsd4_verify(rqstp, cstate, verify);
+       return status == nfserr_not_same ? nfs_ok : status;
+}
+
+static __be32
+nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+            struct nfsd4_verify *verify)
+{
+       __be32 status;
+
+       status = _nfsd4_verify(rqstp, cstate, verify);
+       return status == nfserr_same ? nfs_ok : status;
+}
+
 /*
  * NULL call.
  */
@@ -727,6 +773,42 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
                nfsdstats.nfs4_opcount[opnum]++;
 }
 
+static void cstate_free(struct nfsd4_compound_state *cstate)
+{
+       if (cstate == NULL)
+               return;
+       fh_put(&cstate->current_fh);
+       fh_put(&cstate->save_fh);
+       BUG_ON(cstate->replay_owner);
+       kfree(cstate);
+}
+
+static struct nfsd4_compound_state *cstate_alloc(void)
+{
+       struct nfsd4_compound_state *cstate;
+
+       cstate = kmalloc(sizeof(struct nfsd4_compound_state), GFP_KERNEL);
+       if (cstate == NULL)
+               return NULL;
+       fh_init(&cstate->current_fh, NFS4_FHSIZE);
+       fh_init(&cstate->save_fh, NFS4_FHSIZE);
+       cstate->replay_owner = NULL;
+       return cstate;
+}
+
+typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
+                             void *);
+
+struct nfsd4_operation {
+       nfsd4op_func op_func;
+       u32 op_flags;
+/* Most ops require a valid current filehandle; a few don't: */
+#define ALLOWED_WITHOUT_FH 1
+/* GETATTR and ops not listed as returning NFS4ERR_MOVED: */
+#define ALLOWED_ON_ABSENT_FS 2
+};
+
+static struct nfsd4_operation nfsd4_ops[];
 
 /*
  * COMPOUND call.
@@ -737,21 +819,15 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                    struct nfsd4_compoundres *resp)
 {
        struct nfsd4_op *op;
-       struct svc_fh   *current_fh = NULL;
-       struct svc_fh   *save_fh = NULL;
-       struct nfs4_stateowner *replay_owner = NULL;
-       int             slack_space;    /* in words, not bytes! */
+       struct nfsd4_operation *opdesc;
+       struct nfsd4_compound_state *cstate = NULL;
+       int             slack_bytes;
        __be32          status;
 
        status = nfserr_resource;
-       current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL);
-       if (current_fh == NULL)
-               goto out;
-       fh_init(current_fh, NFS4_FHSIZE);
-       save_fh = kmalloc(sizeof(*save_fh), GFP_KERNEL);
-       if (save_fh == NULL)
+       cstate = cstate_alloc();
+       if (cstate == NULL)
                goto out;
-       fh_init(save_fh, NFS4_FHSIZE);
 
        resp->xbuf = &rqstp->rq_res;
        resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len;
@@ -790,164 +866,44 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                 * failed response to the next operation.  If we don't
                 * have enough room, fail with ERR_RESOURCE.
                 */
-/* FIXME - is slack_space *really* words, or bytes??? - neilb */
-               slack_space = (char *)resp->end - (char *)resp->p;
-               if (slack_space < COMPOUND_SLACK_SPACE + COMPOUND_ERR_SLACK_SPACE) {
-                       BUG_ON(slack_space < COMPOUND_ERR_SLACK_SPACE);
+               slack_bytes = (char *)resp->end - (char *)resp->p;
+               if (slack_bytes < COMPOUND_SLACK_SPACE
+                               + COMPOUND_ERR_SLACK_SPACE) {
+                       BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE);
                        op->status = nfserr_resource;
                        goto encode_op;
                }
 
-               /* All operations except RENEW, SETCLIENTID, RESTOREFH
-               * SETCLIENTID_CONFIRM, PUTFH and PUTROOTFH
-               * require a valid current filehandle
-               */
-               if (!current_fh->fh_dentry) {
-                       if (!((op->opnum == OP_PUTFH) ||
-                             (op->opnum == OP_PUTROOTFH) ||
-                             (op->opnum == OP_SETCLIENTID) ||
-                             (op->opnum == OP_SETCLIENTID_CONFIRM) ||
-                             (op->opnum == OP_RENEW) ||
-                             (op->opnum == OP_RESTOREFH) ||
-                             (op->opnum == OP_RELEASE_LOCKOWNER))) {
+               opdesc = &nfsd4_ops[op->opnum];
+
+               if (!cstate->current_fh.fh_dentry) {
+                       if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
                                op->status = nfserr_nofilehandle;
                                goto encode_op;
                        }
-               }
-               /* Check must be done at start of each operation, except
-                * for GETATTR and ops not listed as returning NFS4ERR_MOVED
-                */
-               else if (current_fh->fh_export->ex_fslocs.migrated &&
-                        !((op->opnum == OP_GETATTR) ||
-                          (op->opnum == OP_PUTROOTFH) ||
-                          (op->opnum == OP_PUTPUBFH) ||
-                          (op->opnum == OP_RENEW) ||
-                          (op->opnum == OP_SETCLIENTID) ||
-                          (op->opnum == OP_RELEASE_LOCKOWNER))) {
+               } else if (cstate->current_fh.fh_export->ex_fslocs.migrated &&
+                         !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
                        op->status = nfserr_moved;
                        goto encode_op;
                }
-               switch (op->opnum) {
-               case OP_ACCESS:
-                       op->status = nfsd4_access(rqstp, current_fh, &op->u.access);
-                       break;
-               case OP_CLOSE:
-                       op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner);
-                       break;
-               case OP_COMMIT:
-                       op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
-                       break;
-               case OP_CREATE:
-                       op->status = nfsd4_create(rqstp, current_fh, &op->u.create);
-                       break;
-               case OP_DELEGRETURN:
-                       op->status = nfsd4_delegreturn(rqstp, current_fh, &op->u.delegreturn);
-                       break;
-               case OP_GETATTR:
-                       op->status = nfsd4_getattr(rqstp, current_fh, &op->u.getattr);
-                       break;
-               case OP_GETFH:
-                       op->status = nfsd4_getfh(current_fh, &op->u.getfh);
-                       break;
-               case OP_LINK:
-                       op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link);
-                       break;
-               case OP_LOCK:
-                       op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner);
-                       break;
-               case OP_LOCKT:
-                       op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt);
-                       break;
-               case OP_LOCKU:
-                       op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner);
-                       break;
-               case OP_LOOKUP:
-                       op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
-                       break;
-               case OP_LOOKUPP:
-                       op->status = nfsd4_lookupp(rqstp, current_fh);
-                       break;
-               case OP_NVERIFY:
-                       op->status = nfsd4_verify(rqstp, current_fh, &op->u.nverify);
-                       if (op->status == nfserr_not_same)
-                               op->status = nfs_ok;
-                       break;
-               case OP_OPEN:
-                       op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner);
-                       break;
-               case OP_OPEN_CONFIRM:
-                       op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner);
-                       break;
-               case OP_OPEN_DOWNGRADE:
-                       op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner);
-                       break;
-               case OP_PUTFH:
-                       op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh);
-                       break;
-               case OP_PUTROOTFH:
-                       op->status = nfsd4_putrootfh(rqstp, current_fh);
-                       break;
-               case OP_READ:
-                       op->status = nfsd4_read(rqstp, current_fh, &op->u.read);
-                       break;
-               case OP_READDIR:
-                       op->status = nfsd4_readdir(rqstp, current_fh, &op->u.readdir);
-                       break;
-               case OP_READLINK:
-                       op->status = nfsd4_readlink(rqstp, current_fh, &op->u.readlink);
-                       break;
-               case OP_REMOVE:
-                       op->status = nfsd4_remove(rqstp, current_fh, &op->u.remove);
-                       break;
-               case OP_RENAME:
-                       op->status = nfsd4_rename(rqstp, current_fh, save_fh, &op->u.rename);
-                       break;
-               case OP_RENEW:
-                       op->status = nfsd4_renew(&op->u.renew);
-                       break;
-               case OP_RESTOREFH:
-                       op->status = nfsd4_restorefh(current_fh, save_fh);
-                       break;
-               case OP_SAVEFH:
-                       op->status = nfsd4_savefh(current_fh, save_fh);
-                       break;
-               case OP_SETATTR:
-                       op->status = nfsd4_setattr(rqstp, current_fh, &op->u.setattr);
-                       break;
-               case OP_SETCLIENTID:
-                       op->status = nfsd4_setclientid(rqstp, &op->u.setclientid);
-                       break;
-               case OP_SETCLIENTID_CONFIRM:
-                       op->status = nfsd4_setclientid_confirm(rqstp, &op->u.setclientid_confirm);
-                       break;
-               case OP_VERIFY:
-                       op->status = nfsd4_verify(rqstp, current_fh, &op->u.verify);
-                       if (op->status == nfserr_same)
-                               op->status = nfs_ok;
-                       break;
-               case OP_WRITE:
-                       op->status = nfsd4_write(rqstp, current_fh, &op->u.write);
-                       break;
-               case OP_RELEASE_LOCKOWNER:
-                       op->status = nfsd4_release_lockowner(rqstp, &op->u.release_lockowner);
-                       break;
-               default:
+
+               if (opdesc->op_func)
+                       op->status = opdesc->op_func(rqstp, cstate, &op->u);
+               else
                        BUG_ON(op->status == nfs_ok);
-                       break;
-               }
 
 encode_op:
                if (op->status == nfserr_replay_me) {
-                       op->replay = &replay_owner->so_replay;
+                       op->replay = &cstate->replay_owner->so_replay;
                        nfsd4_encode_replay(resp, op);
                        status = op->status = op->replay->rp_status;
                } else {
                        nfsd4_encode_operation(resp, op);
                        status = op->status;
                }
-               if (replay_owner && (replay_owner != (void *)(-1))) {
-                       nfs4_put_stateowner(replay_owner);
-                       replay_owner = NULL;
+               if (cstate->replay_owner) {
+                       nfs4_put_stateowner(cstate->replay_owner);
+                       cstate->replay_owner = NULL;
                }
                /* XXX Ugh, we need to get rid of this kind of special case: */
                if (op->opnum == OP_READ && op->u.read.rd_filp)
@@ -958,15 +914,124 @@ encode_op:
 
 out:
        nfsd4_release_compoundargs(args);
-       if (current_fh)
-               fh_put(current_fh);
-       kfree(current_fh);
-       if (save_fh)
-               fh_put(save_fh);
-       kfree(save_fh);
+       cstate_free(cstate);
        return status;
 }
 
+static struct nfsd4_operation nfsd4_ops[OP_RELEASE_LOCKOWNER+1] = {
+       [OP_ACCESS] = {
+               .op_func = (nfsd4op_func)nfsd4_access,
+       },
+       [OP_CLOSE] = {
+               .op_func = (nfsd4op_func)nfsd4_close,
+       },
+       [OP_COMMIT] = {
+               .op_func = (nfsd4op_func)nfsd4_commit,
+       },
+       [OP_CREATE] = {
+               .op_func = (nfsd4op_func)nfsd4_create,
+       },
+       [OP_DELEGRETURN] = {
+               .op_func = (nfsd4op_func)nfsd4_delegreturn,
+       },
+       [OP_GETATTR] = {
+               .op_func = (nfsd4op_func)nfsd4_getattr,
+               .op_flags = ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_GETFH] = {
+               .op_func = (nfsd4op_func)nfsd4_getfh,
+       },
+       [OP_LINK] = {
+               .op_func = (nfsd4op_func)nfsd4_link,
+       },
+       [OP_LOCK] = {
+               .op_func = (nfsd4op_func)nfsd4_lock,
+       },
+       [OP_LOCKT] = {
+               .op_func = (nfsd4op_func)nfsd4_lockt,
+       },
+       [OP_LOCKU] = {
+               .op_func = (nfsd4op_func)nfsd4_locku,
+       },
+       [OP_LOOKUP] = {
+               .op_func = (nfsd4op_func)nfsd4_lookup,
+       },
+       [OP_LOOKUPP] = {
+               .op_func = (nfsd4op_func)nfsd4_lookupp,
+       },
+       [OP_NVERIFY] = {
+               .op_func = (nfsd4op_func)nfsd4_nverify,
+       },
+       [OP_OPEN] = {
+               .op_func = (nfsd4op_func)nfsd4_open,
+       },
+       [OP_OPEN_CONFIRM] = {
+               .op_func = (nfsd4op_func)nfsd4_open_confirm,
+       },
+       [OP_OPEN_DOWNGRADE] = {
+               .op_func = (nfsd4op_func)nfsd4_open_downgrade,
+       },
+       [OP_PUTFH] = {
+               .op_func = (nfsd4op_func)nfsd4_putfh,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_PUTPUBFH] = {
+               /* unsupported; just for future reference: */
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_PUTROOTFH] = {
+               .op_func = (nfsd4op_func)nfsd4_putrootfh,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_READ] = {
+               .op_func = (nfsd4op_func)nfsd4_read,
+       },
+       [OP_READDIR] = {
+               .op_func = (nfsd4op_func)nfsd4_readdir,
+       },
+       [OP_READLINK] = {
+               .op_func = (nfsd4op_func)nfsd4_readlink,
+       },
+       [OP_REMOVE] = {
+               .op_func = (nfsd4op_func)nfsd4_remove,
+       },
+       [OP_RENAME] = {
+               .op_func = (nfsd4op_func)nfsd4_rename,
+       },
+       [OP_RENEW] = {
+               .op_func = (nfsd4op_func)nfsd4_renew,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_RESTOREFH] = {
+               .op_func = (nfsd4op_func)nfsd4_restorefh,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_SAVEFH] = {
+               .op_func = (nfsd4op_func)nfsd4_savefh,
+       },
+       [OP_SETATTR] = {
+               .op_func = (nfsd4op_func)nfsd4_setattr,
+       },
+       [OP_SETCLIENTID] = {
+               .op_func = (nfsd4op_func)nfsd4_setclientid,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_SETCLIENTID_CONFIRM] = {
+               .op_func = (nfsd4op_func)nfsd4_setclientid_confirm,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+       [OP_VERIFY] = {
+               .op_func = (nfsd4op_func)nfsd4_verify,
+       },
+       [OP_WRITE] = {
+               .op_func = (nfsd4op_func)nfsd4_write,
+       },
+       [OP_RELEASE_LOCKOWNER] = {
+               .op_func = (nfsd4op_func)nfsd4_release_lockowner,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS,
+       },
+};
+
 #define nfs4svc_decode_voidargs                NULL
 #define nfs4svc_release_void           NULL
 #define nfsd4_voidres                  nfsd4_voidargs
index b7179bd45a1e959280b24f9199367050478a9ada..9de89df961f42afe3ddd4c79dcc61a9b8aa634b9 100644 (file)
@@ -711,7 +711,8 @@ out_err:
  *
  */
 __be32
-nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
+nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+                 struct nfsd4_setclientid *setclid)
 {
        __be32                  ip_addr = rqstp->rq_addr.sin_addr.s_addr;
        struct xdr_netobj       clname = { 
@@ -876,7 +877,9 @@ out:
  * NOTE: callback information will be processed here in a future patch
  */
 __be32
-nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
+nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
+                        struct nfsd4_compound_state *cstate,
+                        struct nfsd4_setclientid_confirm *setclientid_confirm)
 {
        __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
        struct nfs4_client *conf, *unconf;
@@ -1833,7 +1836,8 @@ static void laundromat_main(struct work_struct *);
 static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main);
 
 __be32
-nfsd4_renew(clientid_t *clid)
+nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           clientid_t *clid)
 {
        struct nfs4_client *clp;
        __be32 status;
@@ -2241,24 +2245,25 @@ check_replay:
 }
 
 __be32
-nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
+nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+                  struct nfsd4_open_confirm *oc)
 {
        __be32 status;
        struct nfs4_stateowner *sop;
        struct nfs4_stateid *stp;
 
        dprintk("NFSD: nfsd4_open_confirm on file %.*s\n",
-                       (int)current_fh->fh_dentry->d_name.len,
-                       current_fh->fh_dentry->d_name.name);
+                       (int)cstate->current_fh.fh_dentry->d_name.len,
+                       cstate->current_fh.fh_dentry->d_name.name);
 
-       status = fh_verify(rqstp, current_fh, S_IFREG, 0);
+       status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0);
        if (status)
                return status;
 
        nfs4_lock_state();
 
-       if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid,
-                                       &oc->oc_req_stateid,
+       if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+                                       oc->oc_seqid, &oc->oc_req_stateid,
                                        CHECK_FH | CONFIRM | OPEN_STATE,
                                        &oc->oc_stateowner, &stp, NULL)))
                goto out; 
@@ -2278,7 +2283,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
 out:
        if (oc->oc_stateowner) {
                nfs4_get_stateowner(oc->oc_stateowner);
-               *replay_owner = oc->oc_stateowner;
+               cstate->replay_owner = oc->oc_stateowner;
        }
        nfs4_unlock_state();
        return status;
@@ -2310,22 +2315,25 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
 }
 
 __be32
-nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
+nfsd4_open_downgrade(struct svc_rqst *rqstp,
+                    struct nfsd4_compound_state *cstate,
+                    struct nfsd4_open_downgrade *od)
 {
        __be32 status;
        struct nfs4_stateid *stp;
        unsigned int share_access;
 
        dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", 
-                       (int)current_fh->fh_dentry->d_name.len,
-                       current_fh->fh_dentry->d_name.name);
+                       (int)cstate->current_fh.fh_dentry->d_name.len,
+                       cstate->current_fh.fh_dentry->d_name.name);
 
        if (!access_valid(od->od_share_access)
                        || !deny_valid(od->od_share_deny))
                return nfserr_inval;
 
        nfs4_lock_state();
-       if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, 
+       if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+                                       od->od_seqid,
                                        &od->od_stateid, 
                                        CHECK_FH | OPEN_STATE, 
                                        &od->od_stateowner, &stp, NULL)))
@@ -2355,7 +2363,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
 out:
        if (od->od_stateowner) {
                nfs4_get_stateowner(od->od_stateowner);
-               *replay_owner = od->od_stateowner;
+               cstate->replay_owner = od->od_stateowner;
        }
        nfs4_unlock_state();
        return status;
@@ -2365,18 +2373,20 @@ out:
  * nfs4_unlock_state() called after encode
  */
 __be32
-nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
+nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct nfsd4_close *close)
 {
        __be32 status;
        struct nfs4_stateid *stp;
 
        dprintk("NFSD: nfsd4_close on file %.*s\n", 
-                       (int)current_fh->fh_dentry->d_name.len,
-                       current_fh->fh_dentry->d_name.name);
+                       (int)cstate->current_fh.fh_dentry->d_name.len,
+                       cstate->current_fh.fh_dentry->d_name.name);
 
        nfs4_lock_state();
        /* check close_lru for replay */
-       if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, 
+       if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
+                                       close->cl_seqid,
                                        &close->cl_stateid, 
                                        CHECK_FH | OPEN_STATE | CLOSE_STATE,
                                        &close->cl_stateowner, &stp, NULL)))
@@ -2397,22 +2407,24 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos
 out:
        if (close->cl_stateowner) {
                nfs4_get_stateowner(close->cl_stateowner);
-               *replay_owner = close->cl_stateowner;
+               cstate->replay_owner = close->cl_stateowner;
        }
        nfs4_unlock_state();
        return status;
 }
 
 __be32
-nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
+nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+                 struct nfsd4_delegreturn *dr)
 {
        __be32 status;
 
-       if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
+       if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0)))
                goto out;
 
        nfs4_lock_state();
-       status = nfs4_preprocess_stateid_op(current_fh, &dr->dr_stateid, DELEG_RET, NULL);
+       status = nfs4_preprocess_stateid_op(&cstate->current_fh,
+                                           &dr->dr_stateid, DELEG_RET, NULL);
        nfs4_unlock_state();
 out:
        return status;
@@ -2635,7 +2647,8 @@ check_lock_length(u64 offset, u64 length)
  *  LOCK operation 
  */
 __be32
-nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
+nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+          struct nfsd4_lock *lock)
 {
        struct nfs4_stateowner *open_sop = NULL;
        struct nfs4_stateowner *lock_sop = NULL;
@@ -2654,7 +2667,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
        if (check_lock_length(lock->lk_offset, lock->lk_length))
                 return nfserr_inval;
 
-       if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
+       if ((status = fh_verify(rqstp, &cstate->current_fh,
+                               S_IFREG, MAY_LOCK))) {
                dprintk("NFSD: nfsd4_lock: permission denied!\n");
                return status;
        }
@@ -2675,7 +2689,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
                        goto out;
 
                /* validate and update open stateid and open seqid */
-               status = nfs4_preprocess_seqid_op(current_fh, 
+               status = nfs4_preprocess_seqid_op(&cstate->current_fh,
                                        lock->lk_new_open_seqid,
                                        &lock->lk_new_open_stateid,
                                        CHECK_FH | OPEN_STATE,
@@ -2702,7 +2716,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
                        goto out;
        } else {
                /* lock (lock owner + lock stateid) already exists */
-               status = nfs4_preprocess_seqid_op(current_fh,
+               status = nfs4_preprocess_seqid_op(&cstate->current_fh,
                                       lock->lk_old_lock_seqid, 
                                       &lock->lk_old_lock_stateid, 
                                       CHECK_FH | LOCK_STATE, 
@@ -2759,7 +2773,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
        conflock.fl_ops = NULL;
        conflock.fl_lmops = NULL;
        err = posix_lock_file_conf(filp, &file_lock, &conflock);
-       dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status);
        switch (-err) {
        case 0: /* success! */
                update_stateid(&lock_stp->st_stateid);
@@ -2785,7 +2798,7 @@ out:
                release_stateowner(lock_sop);
        if (lock->lk_replay_owner) {
                nfs4_get_stateowner(lock->lk_replay_owner);
-               *replay_owner = lock->lk_replay_owner;
+               cstate->replay_owner = lock->lk_replay_owner;
        }
        nfs4_unlock_state();
        return status;
@@ -2795,7 +2808,8 @@ out:
  * LOCKT operation
  */
 __be32
-nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
+nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct nfsd4_lockt *lockt)
 {
        struct inode *inode;
        struct file file;
@@ -2816,14 +2830,14 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
        if (STALE_CLIENTID(&lockt->lt_clientid))
                goto out;
 
-       if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
+       if ((status = fh_verify(rqstp, &cstate->current_fh, S_IFREG, 0))) {
                dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
                if (status == nfserr_symlink)
                        status = nfserr_inval;
                goto out;
        }
 
-       inode = current_fh->fh_dentry->d_inode;
+       inode = cstate->current_fh.fh_dentry->d_inode;
        locks_init_lock(&file_lock);
        switch (lockt->lt_type) {
                case NFS4_READ_LT:
@@ -2862,7 +2876,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
         * only the dentry:inode set.
         */
        memset(&file, 0, sizeof (struct file));
-       file.f_path.dentry = current_fh->fh_dentry;
+       file.f_path.dentry = cstate->current_fh.fh_dentry;
 
        status = nfs_ok;
        if (posix_test_lock(&file, &file_lock, &conflock)) {
@@ -2875,7 +2889,8 @@ out:
 }
 
 __be32
-nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
+nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+           struct nfsd4_locku *locku)
 {
        struct nfs4_stateid *stp;
        struct file *filp = NULL;
@@ -2892,7 +2907,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
 
        nfs4_lock_state();
                                                                                
-       if ((status = nfs4_preprocess_seqid_op(current_fh, 
+       if ((status = nfs4_preprocess_seqid_op(&cstate->current_fh,
                                        locku->lu_seqid, 
                                        &locku->lu_stateid, 
                                        CHECK_FH | LOCK_STATE, 
@@ -2933,7 +2948,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
 out:
        if (locku->lu_stateowner) {
                nfs4_get_stateowner(locku->lu_stateowner);
-               *replay_owner = locku->lu_stateowner;
+               cstate->replay_owner = locku->lu_stateowner;
        }
        nfs4_unlock_state();
        return status;
@@ -2968,7 +2983,9 @@ out:
 }
 
 __be32
-nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
+nfsd4_release_lockowner(struct svc_rqst *rqstp,
+                       struct nfsd4_compound_state *cstate,
+                       struct nfsd4_release_lockowner *rlockowner)
 {
        clientid_t *clid = &rlockowner->rl_clientid;
        struct nfs4_stateowner *sop;
index f3f239db04bb1b0d54f1a18ff78f4ffce3d18ee1..fea46368afb2fb304e8a4c5507f085852cb916f7 100644 (file)
@@ -1845,15 +1845,11 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
 
        exp_get(exp);
        if (d_mountpoint(dentry)) {
-               if (nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp)) {
-               /*
-                * -EAGAIN is the only error returned from
-                * nfsd_cross_mnt() and it indicates that an
-                * up-call has  been initiated to fill in the export
-                * options on exp.  When the answer comes back,
-                * this call will be retried.
-                */
-                       nfserr = nfserr_dropit;
+               int err;
+
+               err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
+               if (err) {
+                       nfserr = nfserrno(err);
                        goto out_put;
                }
 
index 727ab3bd450d54bffee6183ddf8fea3e1d3bdb75..b06bf9f70efc380b0dad39c891d9060584e97fc0 100644 (file)
@@ -169,9 +169,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                        exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
                }
 
-               error = nfserr_dropit;
-               if (IS_ERR(exp) && PTR_ERR(exp) == -EAGAIN)
+               if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
+                               || PTR_ERR(exp) == -ETIMEDOUT)) {
+                       error = nfserrno(PTR_ERR(exp));
                        goto out;
+               }
 
                error = nfserr_stale; 
                if (!exp || IS_ERR(exp))
index 4883d758622983cab8fc870d4bddf7ba67491971..7a79c23aa6d4efe78bbfc03f6260ad64cf6ec589 100644 (file)
@@ -99,7 +99,7 @@ static struct raparm_hbucket  raparm_hash[RAPARM_HASH_SIZE];
 /* 
  * Called from nfsd_lookup and encode_dirent. Check if we have crossed 
  * a mount point.
- * Returns -EAGAIN leaving *dpp and *expp unchanged, 
+ * Returns -EAGAIN or -ETIMEDOUT leaving *dpp and *expp unchanged,
  *  or nfs_ok having possibly changed *dpp and *expp
  */
 int
index edc91ca3792ac2b331a33540ec8d5a8250f24566..f27e5378caf249ecccca6676a8fb2e8beda2be63 100644 (file)
@@ -1959,7 +1959,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb,
                goto bail;
        }
 
-       *tc = kcalloc(1, sizeof(struct ocfs2_truncate_context), GFP_KERNEL);
+       *tc = kzalloc(sizeof(struct ocfs2_truncate_context), GFP_KERNEL);
        if (!(*tc)) {
                status = -ENOMEM;
                mlog_errno(status);
index 4cd9a9580456cdf0313c4a5b75c6f0d4e2560884..a25ef5a5038678115bce74843dd11ec2fe2675de 100644 (file)
@@ -1553,7 +1553,7 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g
        struct o2hb_region *reg = NULL;
        struct config_item *ret = NULL;
 
-       reg = kcalloc(1, sizeof(struct o2hb_region), GFP_KERNEL);
+       reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
        if (reg == NULL)
                goto out; /* ENOMEM */
 
@@ -1679,7 +1679,7 @@ struct config_group *o2hb_alloc_hb_set(void)
        struct o2hb_heartbeat_group *hs = NULL;
        struct config_group *ret = NULL;
 
-       hs = kcalloc(1, sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);
+       hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);
        if (hs == NULL)
                goto out;
 
index 357f1d551771201f4b9587186fc01a97809ad06b..b17333a0606b55cf641ae90c3997918e7ef64992 100644 (file)
@@ -714,7 +714,7 @@ static struct config_item *o2nm_node_group_make_item(struct config_group *group,
        if (strlen(name) > O2NM_MAX_NAME_LEN)
                goto out; /* ENAMETOOLONG */
 
-       node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL);
+       node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
        if (node == NULL)
                goto out; /* ENOMEM */
 
@@ -825,8 +825,8 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
        if (o2nm_single_cluster)
                goto out; /* ENOSPC */
 
-       cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL);
-       ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL);
+       cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
+       ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
        defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
        o2hb_group = o2hb_alloc_hb_set();
        if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL)
index 457753df1ae76719933463a268e7fd44a7dd9fc1..ae4ff4a6636b23759522994898a95c148a4401f1 100644 (file)
@@ -324,7 +324,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
        struct page *page = NULL;
 
        page = alloc_page(GFP_NOFS);
-       sc = kcalloc(1, sizeof(*sc), GFP_NOFS);
+       sc = kzalloc(sizeof(*sc), GFP_NOFS);
        if (sc == NULL || page == NULL)
                goto out;
 
@@ -714,7 +714,7 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
                goto out;
        }
 
-               nmh = kcalloc(1, sizeof(struct o2net_msg_handler), GFP_NOFS);
+               nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS);
        if (nmh == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -1918,9 +1918,9 @@ int o2net_init(void)
 
        o2quo_init();
 
-       o2net_hand = kcalloc(1, sizeof(struct o2net_handshake), GFP_KERNEL);
-       o2net_keep_req = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
-       o2net_keep_resp = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
+       o2net_hand = kzalloc(sizeof(struct o2net_handshake), GFP_KERNEL);
+       o2net_keep_req = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
+       o2net_keep_resp = kzalloc(sizeof(struct o2net_msg), GFP_KERNEL);
        if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) {
                kfree(o2net_hand);
                kfree(o2net_keep_req);
index 420a375a3949826b5b90e4007cdb0807b9f9b966..f0b25f2dd205317d51b3508a6b48cc41c184d0ac 100644 (file)
@@ -920,7 +920,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
 
        mlog_entry("%p", dlm);
 
-       ctxt = kcalloc(1, sizeof(*ctxt), GFP_KERNEL);
+       ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
        if (!ctxt) {
                status = -ENOMEM;
                mlog_errno(status);
@@ -1223,7 +1223,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
        int i;
        struct dlm_ctxt *dlm = NULL;
 
-       dlm = kcalloc(1, sizeof(*dlm), GFP_KERNEL);
+       dlm = kzalloc(sizeof(*dlm), GFP_KERNEL);
        if (!dlm) {
                mlog_errno(-ENOMEM);
                goto leave;
index 42a1b91979b5b5f51e59a1c6fc15666d23a743c5..e5ca3db197f63c647a37c201b70b259a746de2e8 100644 (file)
@@ -408,13 +408,13 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
        struct dlm_lock *lock;
        int kernel_allocated = 0;
 
-       lock = kcalloc(1, sizeof(*lock), GFP_NOFS);
+       lock = kzalloc(sizeof(*lock), GFP_NOFS);
        if (!lock)
                return NULL;
 
        if (!lksb) {
                /* zero memory only if kernel-allocated */
-               lksb = kcalloc(1, sizeof(*lksb), GFP_NOFS);
+               lksb = kzalloc(sizeof(*lksb), GFP_NOFS);
                if (!lksb) {
                        kfree(lock);
                        return NULL;
index 856012b4fa4954534ac6d4471d2ebee25b9bdae9..0ad872055cb36fd095b143b6b5ffcb2b92294aee 100644 (file)
@@ -1939,7 +1939,7 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
                               int ignore_higher, u8 request_from, u32 flags)
 {
        struct dlm_work_item *item;
-       item = kcalloc(1, sizeof(*item), GFP_NOFS);
+       item = kzalloc(sizeof(*item), GFP_NOFS);
        if (!item)
                return -ENOMEM;
 
index fb3e2b0817f17cc647c532ae492b30af57af36b9..367a11e9e2ed3b30f10ca1da7cc3c2d090184dae 100644 (file)
@@ -757,7 +757,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
                }
                BUG_ON(num == dead_node);
 
-               ndata = kcalloc(1, sizeof(*ndata), GFP_NOFS);
+               ndata = kzalloc(sizeof(*ndata), GFP_NOFS);
                if (!ndata) {
                        dlm_destroy_recovery_area(dlm, dead_node);
                        return -ENOMEM;
@@ -842,7 +842,7 @@ int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data)
        }
        BUG_ON(lr->dead_node != dlm->reco.dead_node);
 
-       item = kcalloc(1, sizeof(*item), GFP_NOFS);
+       item = kzalloc(sizeof(*item), GFP_NOFS);
        if (!item) {
                dlm_put(dlm);
                return -ENOMEM;
@@ -1323,7 +1323,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data)
 
        ret = -ENOMEM;
        buf = kmalloc(be16_to_cpu(msg->data_len), GFP_NOFS);
-       item = kcalloc(1, sizeof(*item), GFP_NOFS);
+       item = kzalloc(sizeof(*item), GFP_NOFS);
        if (!buf || !item)
                goto leave;
 
index e9a82ad95c1e234fb4cc439f482d79d346ccd4f1..9fd590b9bde3d69a403902cd60f228e92eea87f6 100644 (file)
@@ -153,6 +153,14 @@ int ocfs2_should_update_atime(struct inode *inode,
            ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
                return 0;
 
+       if (vfsmnt->mnt_flags & MNT_RELATIME) {
+               if ((timespec_compare(&inode->i_atime, &inode->i_mtime) <= 0) ||
+                   (timespec_compare(&inode->i_atime, &inode->i_ctime) <= 0))
+                       return 1;
+
+               return 0;
+       }
+
        now = CURRENT_TIME;
        if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum))
                return 0;
index 698d79a74ef8ec4fea233f591485f9a39b8c9b31..4dedd9789108193eee3b107c84053270255e5a9b 100644 (file)
@@ -776,7 +776,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
 {
        int status;
 
-       *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+       *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
        if (!(*ac)) {
                status = -ENOMEM;
                mlog_errno(status);
index aa6f5aadedc4f9f0d169e8b456e1d1e081b26c92..2d3ac32cb74e9bcaecfffbe405080c6c7b040902 100644 (file)
@@ -175,7 +175,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb)
        struct buffer_head *bh = NULL;
        struct ocfs2_slot_info *si;
 
-       si = kcalloc(1, sizeof(struct ocfs2_slot_info), GFP_KERNEL);
+       si = kzalloc(sizeof(struct ocfs2_slot_info), GFP_KERNEL);
        if (!si) {
                status = -ENOMEM;
                mlog_errno(status);
index 000d71cca6c50dfe919524fb16c7d8e261230701..6dbb1176275973d7088bdc5d696e93227b1668bf 100644 (file)
@@ -488,7 +488,7 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
        int status;
        u32 slot;
 
-       *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+       *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
        if (!(*ac)) {
                status = -ENOMEM;
                mlog_errno(status);
@@ -530,7 +530,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
 {
        int status;
 
-       *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+       *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
        if (!(*ac)) {
                status = -ENOMEM;
                mlog_errno(status);
@@ -595,7 +595,7 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
 
        mlog_entry_void();
 
-       *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+       *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
        if (!(*ac)) {
                status = -ENOMEM;
                mlog_errno(status);
index a6d2f8cc165b85da7c3e607b361913a7db65e02f..6e300a88a47e8253a2d8dfc82d9d4c76112cb69b 100644 (file)
@@ -1231,7 +1231,7 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
 
        BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN);
 
-       osb->uuid_str = kcalloc(1, OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);
+       osb->uuid_str = kzalloc(OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);
        if (osb->uuid_str == NULL)
                return -ENOMEM;
 
@@ -1262,7 +1262,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
 
        mlog_entry_void();
 
-       osb = kcalloc(1, sizeof(struct ocfs2_super), GFP_KERNEL);
+       osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL);
        if (!osb) {
                status = -ENOMEM;
                mlog_errno(status);
@@ -1387,7 +1387,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
         */
        /* initialize our journal structure */
 
-       journal = kcalloc(1, sizeof(struct ocfs2_journal), GFP_KERNEL);
+       journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL);
        if (!journal) {
                mlog(ML_ERROR, "unable to alloc journal\n");
                status = -ENOMEM;
index 0315a8b61ed67b221a33361cac82b052d7af46b5..0afd8b9af70fa3691c2a98c3c66716d259982cda 100644 (file)
@@ -479,7 +479,7 @@ static struct ocfs2_net_wait_ctxt *ocfs2_new_net_wait_ctxt(unsigned int response
 {
        struct ocfs2_net_wait_ctxt *w;
 
-       w = kcalloc(1, sizeof(*w), GFP_NOFS);
+       w = kzalloc(sizeof(*w), GFP_NOFS);
        if (!w) {
                mlog_errno(-ENOMEM);
                goto bail;
@@ -642,7 +642,7 @@ static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb,
 
        BUG_ON(!ocfs2_is_valid_vote_request(type));
 
-       request = kcalloc(1, sizeof(*request), GFP_NOFS);
+       request = kzalloc(sizeof(*request), GFP_NOFS);
        if (!request) {
                mlog_errno(-ENOMEM);
        } else {
index f8b6bdcb879aa8f4ba9ccfa7340edb087d7e2d57..9a06e8e48e8dfb366a8c08bd387985788391a5d8 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -207,7 +207,7 @@ int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf)
        return 0;
 }
 
-static struct pipe_buf_operations anon_pipe_buf_ops = {
+static const struct pipe_buf_operations anon_pipe_buf_ops = {
        .can_merge = 1,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
@@ -243,7 +243,7 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
                if (bufs) {
                        int curbuf = pipe->curbuf;
                        struct pipe_buffer *buf = pipe->bufs + curbuf;
-                       struct pipe_buf_operations *ops = buf->ops;
+                       const struct pipe_buf_operations *ops = buf->ops;
                        void *addr;
                        size_t chars = buf->len;
                        int error, atomic;
@@ -365,7 +365,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
                int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
                                                        (PIPE_BUFFERS-1);
                struct pipe_buffer *buf = pipe->bufs + lastbuf;
-               struct pipe_buf_operations *ops = buf->ops;
+               const struct pipe_buf_operations *ops = buf->ops;
                int offset = buf->offset + buf->len;
 
                if (ops->can_merge && offset + chars <= PAGE_SIZE) {
@@ -756,7 +756,7 @@ const struct file_operations rdwr_fifo_fops = {
        .fasync         = pipe_rdwr_fasync,
 };
 
-static struct file_operations read_pipe_fops = {
+static const struct file_operations read_pipe_fops = {
        .llseek         = no_llseek,
        .read           = do_sync_read,
        .aio_read       = pipe_read,
@@ -768,7 +768,7 @@ static struct file_operations read_pipe_fops = {
        .fasync         = pipe_read_fasync,
 };
 
-static struct file_operations write_pipe_fops = {
+static const struct file_operations write_pipe_fops = {
        .llseek         = no_llseek,
        .read           = bad_pipe_r,
        .write          = do_sync_write,
@@ -780,7 +780,7 @@ static struct file_operations write_pipe_fops = {
        .fasync         = pipe_write_fasync,
 };
 
-static struct file_operations rdwr_pipe_fops = {
+static const struct file_operations rdwr_pipe_fops = {
        .llseek         = no_llseek,
        .read           = do_sync_read,
        .aio_read       = pipe_read,
index 1d3dda4fa70cdac79cffcccb16cb03a279f3268b..707ac21700d31d26ee85d85734e4c3138853dd70 100644 (file)
@@ -450,8 +450,6 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
        return seg;
 }
 
-EXPORT_UNUSED_SYMBOL(iov_shorten);  /*  June 2006  */
-
 ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
                unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
 {
index 97ae1b92bc47d0088a10ff3b1bc6433a70f05bda..5296a29cc5eb51779169525a149a98b3206ed0ad 100644 (file)
@@ -135,7 +135,7 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
        int n;
 
        *size = reiserfs_acl_size(acl->a_count);
-       ext_acl = (reiserfs_acl_header *) kmalloc(sizeof(reiserfs_acl_header) +
+       ext_acl = kmalloc(sizeof(reiserfs_acl_header) +
                                                  acl->a_count *
                                                  sizeof(reiserfs_acl_entry),
                                                  GFP_NOFS);
index 4af4cd729a5a8589706e536d3860175c69b90d2d..84dfe3f3482e3448851e808554fed11cfcf6f7a2 100644 (file)
@@ -482,12 +482,13 @@ smb_put_super(struct super_block *sb)
        smb_close_socket(server);
 
        if (server->conn_pid)
-               kill_proc(server->conn_pid, SIGTERM, 1);
+               kill_pid(server->conn_pid, SIGTERM, 1);
 
        kfree(server->ops);
        smb_unload_nls(server);
        sb->s_fs_info = NULL;
        smb_unlock_server(server);
+       put_pid(server->conn_pid);
        kfree(server);
 }
 
@@ -530,7 +531,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        INIT_LIST_HEAD(&server->xmitq);
        INIT_LIST_HEAD(&server->recvq);
        server->conn_error = 0;
-       server->conn_pid = 0;
+       server->conn_pid = NULL;
        server->state = CONN_INVALID; /* no connection yet */
        server->generation = 0;
 
index a5ced9e0c6c482ed0256a6420a8f47f9d88a23cc..feac46050619075aa90a88f71e4a8e4a31b5cda5 100644 (file)
@@ -877,7 +877,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
                goto out_putf;
 
        server->sock_file = filp;
-       server->conn_pid = current->pid;
+       server->conn_pid = get_pid(task_pid(current));
        server->opt = *opt;
        server->generation += 1;
        server->state = CONN_VALID;
@@ -971,8 +971,8 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
        }
 
        VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
-               server->opt.protocol, server->opt.max_xmit, server->conn_pid,
-               server->opt.capabilities);
+               server->opt.protocol, server->opt.max_xmit,
+               pid_nr(server->conn_pid), server->opt.capabilities);
 
        /* FIXME: this really should be done by smbmount. */
        if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) {
index e675404412880eb6d602cd7d9de3dbe6aef13c0a..89eaf31f1d46c18a42870c604d4b58ced724bfa5 100644 (file)
@@ -152,7 +152,7 @@ int smbiod_retry(struct smb_sb_info *server)
 {
        struct list_head *head;
        struct smb_request *req;
-       pid_t pid = server->conn_pid;
+       struct pid *pid = get_pid(server->conn_pid);
        int result = 0;
 
        VERBOSE("state: %d\n", server->state);
@@ -222,7 +222,7 @@ int smbiod_retry(struct smb_sb_info *server)
        /*
         * Note: use the "priv" flag, as a user process may need to reconnect.
         */
-       result = kill_proc(pid, SIGUSR1, 1);
+       result = kill_pid(pid, SIGUSR1, 1);
        if (result) {
                /* FIXME: this is most likely fatal, umount? */
                printk(KERN_ERR "smb_retry: signal failed [%d]\n", result);
@@ -233,6 +233,7 @@ int smbiod_retry(struct smb_sb_info *server)
        /* FIXME: The retried requests should perhaps get a "time boost". */
 
 out:
+       put_pid(pid);
        return result;
 }
 
index bbd0aeb3f68e1723cc11c4be939137ebabb61dfd..2fca6ebf4cc2d17ceb05ccb6cbe7f93ab3571a87 100644 (file)
@@ -42,7 +42,7 @@ struct splice_pipe_desc {
        struct partial_page *partial;   /* pages[] may not be contig */
        int nr_pages;                   /* number of pages in map */
        unsigned int flags;             /* splice flags */
-       struct pipe_buf_operations *ops;/* ops associated with output pipe */
+       const struct pipe_buf_operations *ops;/* ops associated with output pipe */
 };
 
 /*
@@ -139,7 +139,7 @@ error:
        return err;
 }
 
-static struct pipe_buf_operations page_cache_pipe_buf_ops = {
+static const struct pipe_buf_operations page_cache_pipe_buf_ops = {
        .can_merge = 0,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
@@ -159,7 +159,7 @@ static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe,
        return generic_pipe_buf_steal(pipe, buf);
 }
 
-static struct pipe_buf_operations user_page_pipe_buf_ops = {
+static const struct pipe_buf_operations user_page_pipe_buf_ops = {
        .can_merge = 0,
        .map = generic_pipe_buf_map,
        .unmap = generic_pipe_buf_unmap,
@@ -724,7 +724,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
        for (;;) {
                if (pipe->nrbufs) {
                        struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
-                       struct pipe_buf_operations *ops = buf->ops;
+                       const struct pipe_buf_operations *ops = buf->ops;
 
                        sd.len = buf->len;
                        if (sd.len > sd.total_len)
index 805640b4107815330274fd5699d9531fcb6aa5a0..b686cc7fc44e467d91a449b5e9dea7759cfe23fc 100644 (file)
@@ -6,6 +6,7 @@
 /* Caches aren't brain-dead on the Alpha. */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index f0845646aacb34a05332f7b7348cbbec436ed9f1..378a3a2ce8d93ea717dd1a64009153fd6aa5e96b 100644 (file)
@@ -319,6 +319,8 @@ extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                                unsigned long len, int write);
 #endif
 
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
 /*
  * flush_cache_user_range is used when we want to ensure that the
  * Harvard caches are synchronised for the user space address range.
index d9b8bddc8732ac3b75aa7d64653179c192ffb0ed..5014794f9eb3db955fef7b114322069862ba857b 100644 (file)
@@ -147,6 +147,7 @@ extern void iwmmxt_task_switch(struct thread_info *);
 #define TIF_POLLING_NRFLAG     16
 #define TIF_USING_IWMMXT       17
 #define TIF_MEMDIE             18
+#define TIF_FREEZE             19
 
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
@@ -154,6 +155,7 @@ extern void iwmmxt_task_switch(struct thread_info *);
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT      (1 << TIF_USING_IWMMXT)
+#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 /*
  * Change these and you break ASM code in entry-common.S
index 9c1b9c7f2ebd1513a252501ab4f02d02ee301244..14ae15b6faab8c5040df4b7ecce11bf806bb666d 100644 (file)
@@ -22,6 +22,7 @@
 
 #define flush_cache_all()                       do { } while (0)
 #define flush_cache_mm(mm)                      do { } while (0)
+#define flush_cache_dup_mm(mm)                  do { } while (0)
 #define flush_cache_range(vma,start,end)        do { } while (0)
 #define flush_cache_page(vma,vmaddr,pfn)        do { } while (0)
 #define flush_cache_vmap(start, end)           do { } while (0)
index f1bf1708980e4e292ef8a4c57c6f3be9b8672b2e..dfaaa88cd412bc402fb339cb8ffb516df567426b 100644 (file)
@@ -87,6 +87,7 @@ void invalidate_icache_region(void *start, size_t len);
  */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_cache_vmap(start, end)           do { } while (0)
index 7492cfb92ceddfabcd8eefacf1cea392c06b9b51..bb82e70cde8d048fb01c3594b0233ba8c9d83fbd 100644 (file)
@@ -28,7 +28,7 @@ static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
 {
        unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
-       pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
+       pgd_t *pgd = kmalloc(pgd_size, GFP_KERNEL);
 
        if (pgd)
                memset(pgd, 0, pgd_size);
index 72cc71dffe70e38eb0bc6fe8e163bb4d6f741443..01af2de27c5bcf59eceaf758e27253fc303937f4 100644 (file)
@@ -9,6 +9,7 @@
  */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index eaa5826bc1c8f1627d890f4a7fcda630716c13fb..02500405a6fb26317ad2def7ea098ed3e93a3e0f 100644 (file)
@@ -20,6 +20,7 @@
  */
 #define flush_cache_all()                      do {} while(0)
 #define flush_cache_mm(mm)                     do {} while(0)
+#define flush_cache_dup_mm(mm)                 do {} while(0)
 #define flush_cache_range(mm, start, end)      do {} while(0)
 #define flush_cache_page(vma, vmaddr, pfn)     do {} while(0)
 #define flush_cache_vmap(start, end)           do {} while(0)
index d66c48e6ef144dcaf0259bcf3428ebfae224f28b..d881f518e6a9272c0eaedf748cd9cf6171c0a757 100644 (file)
@@ -116,6 +116,7 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define TIF_RESTORE_SIGMASK    6       /* restore signal mask in do_signal() */
 #define TIF_POLLING_NRFLAG     16      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             17      /* OOM killer killed process */
+#define TIF_FREEZE             18      /* freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1 << TIF_NOTIFY_RESUME)
@@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info asm("gr15");
 #define _TIF_IRET              (1 << TIF_IRET)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x0000FFFE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x0000FFFF      /* work to do on any return to u-space */
index 1e4d95bb5ec9c1d96b201869ee903fe637da5ce5..71210d141b64bb5b2a4d13c5155ec04e8396269e 100644 (file)
@@ -12,6 +12,7 @@
 
 #define flush_cache_all()
 #define        flush_cache_mm(mm)
+#define        flush_cache_dup_mm(mm)          do { } while (0)
 #define        flush_cache_range(vma,a,b)
 #define        flush_cache_page(vma,p,pfn)
 #define        flush_dcache_page(page)
index 7199f7b326f1e3fefc9b904742dabf92042f34b2..74e03c8f2e515e0837a0724aecf5124322ed0ec6 100644 (file)
@@ -7,6 +7,7 @@
 /* Caches aren't brain-dead on the intel. */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index 46d32ad9208256ab045785cdc355b1253860a486..4b187bb377b4278de91c851d4dfeb4a4ef422669 100644 (file)
@@ -134,6 +134,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_MEMDIE             16
 #define TIF_DEBUG              17      /* uses debug registers */
 #define TIF_IO_BITMAP          18      /* uses I/O bitmap */
+#define TIF_FREEZE             19      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -147,6 +148,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_DEBUG             (1<<TIF_DEBUG)
 #define _TIF_IO_BITMAP         (1<<TIF_IO_BITMAP)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK \
index f2dacb4245ec15580b8e8341b460225a7c3edbea..4906916d715b5d3ea95d53659218234afe0f42f3 100644 (file)
@@ -18,6 +18,7 @@
 
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_icache_page(vma,page)            do { } while (0)
index 8adcde0934ca4e127b621278b48f8ba84a2c4a4b..9b505b25544f0bd707063ba48e053a9afdebe030 100644 (file)
@@ -88,6 +88,7 @@ struct thread_info {
 #define TIF_MEMDIE             17
 #define TIF_MCA_INIT           18      /* this task is processing MCA or INIT */
 #define TIF_DB_DISABLED                19      /* debug trap disabled for fsyscall */
+#define TIF_FREEZE             20      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT     (1 << TIF_SYSCALL_AUDIT)
@@ -98,6 +99,7 @@ struct thread_info {
 #define _TIF_POLLING_NRFLAG    (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MCA_INIT          (1 << TIF_MCA_INIT)
 #define _TIF_DB_DISABLED       (1 << TIF_DB_DISABLED)
+#define _TIF_FREEZE            (1 << TIF_FREEZE)
 
 /* "work to do on user-return" bits */
 #define TIF_ALLWORK_MASK       (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
index 8b261b49149e7cac1529bbe95dc153845410997f..56961a9511b2cea9a7f46b04fedc912799c2e05c 100644 (file)
@@ -9,6 +9,7 @@ extern void _flush_cache_copyback_all(void);
 #if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
@@ -29,6 +30,7 @@ extern void smp_flush_cache_all(void);
 #elif defined(CONFIG_CHIP_M32102)
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
@@ -41,6 +43,7 @@ extern void smp_flush_cache_all(void);
 #else
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index 24d3ff44913570cbccb4632b83bf5e3c37747299..16bf375fdbe1c25a36992dfe94c066b074cbe736 100644 (file)
@@ -89,6 +89,8 @@ static inline void flush_cache_mm(struct mm_struct *mm)
                __flush_cache_030();
 }
 
+#define flush_cache_dup_mm(mm)                 flush_cache_mm(mm)
+
 /* flush_cache_range/flush_cache_page must be macros to avoid
    a dependency on linux/mm.h, which includes this file... */
 static inline void flush_cache_range(struct vm_area_struct *vma,
diff --git a/include/asm-m68k/swim_iop.h b/include/asm-m68k/swim_iop.h
deleted file mode 100644 (file)
index f29b678..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * SWIM access through the IOP
- * Written by Joshua M. Thompson
- */
-
-/* IOP number and channel number for the SWIM */
-
-#define SWIM_IOP       IOP_NUM_ISM
-#define SWIM_CHAN      1
-
-/* Command code: */
-
-#define CMD_INIT               0x01    /* Initialize                  */
-#define CMD_SHUTDOWN           0x02    /* Shutdown                    */
-#define CMD_START_POLL         0x03    /* Start insert/eject polling  */
-#define CMD_STOP_POLL          0x04    /* Stop insert/eject polling   */
-#define CMD_SETHFSTAG          0x05    /* Set HFS tag buffer address  */
-#define CMD_STATUS             0x06    /* Status                      */
-#define CMD_EJECT              0x07    /* Eject                       */
-#define CMD_FORMAT             0x08    /* Format                      */
-#define CMD_FORMAT_VERIFY      0x09    /* Format and Verify           */
-#define CMD_WRITE              0x0A    /* Write                       */
-#define CMD_READ               0x0B    /* Read                        */
-#define CMD_READ_VERIFY                0x0C    /* Read and Verify             */
-#define CMD_CACHE_CTRL         0x0D    /* Cache control               */
-#define CMD_TAGBUFF_CTRL       0x0E    /* Tag buffer control          */
-#define CMD_GET_ICON           0x0F    /* Get Icon                    */
-
-/* Drive types: */
-
-/* note: apple sez DRV_FDHD is 4, but I get back a type */
-/*       of 5 when I do a drive status check on my FDHD */
-
-#define        DRV_NONE        0       /* No drive             */
-#define        DRV_UNKNOWN     1       /* Unspecified drive    */
-#define        DRV_400K        2       /* 400K                 */
-#define        DRV_800K        3       /* 400K/800K            */
-#define        DRV_FDHD        5       /* 400K/800K/720K/1440K */
-#define        DRV_HD20        7       /* Apple HD20           */
-
-/* Format types: */
-
-#define        FMT_HD20        0x0001  /*  Apple HD20 */
-#define        FMT_400K        0x0002  /*  400K (GCR) */
-#define        FMT_800K        0x0004  /*  800K (GCR) */
-#define        FMT_720K        0x0008  /*  720K (MFM) */
-#define        FMT_1440K       0x0010  /* 1.44M (MFM) */
-
-#define        FMD_KIND_400K   1
-#define        FMD_KIND_800K   2
-#define        FMD_KIND_720K   3
-#define        FMD_KIND_1440K  1
-
-/* Icon Flags: */
-
-#define        ICON_MEDIA      0x01    /* Have IOP supply media icon */
-#define        ICON_DRIVE      0x01    /* Have IOP supply drive icon */
-
-/* Error codes: */
-
-#define        gcrOnMFMErr     -400    /* GCR (400/800K) on HD media */
-#define        verErr          -84     /* verify failed */
-#define        fmt2Err         -83     /* can't get enough sync during format */
-#define        fmt1Err         -82     /* can't find sector 0 after track format */
-#define        sectNFErr       -81     /* can't find sector */
-#define        seekErr         -80     /* drive error during seek */
-#define        spdAdjErr       -79     /* can't set drive speed */
-#define        twoSideErr      -78     /* drive is single-sided */
-#define        initIWMErr      -77     /* error during initialization */
-#define        tk0badErr       -76     /* track zero is bad */
-#define        cantStepErr     -75     /* drive error during step */
-#define        wrUnderrun      -74     /* write underrun occurred */
-#define        badDBtSlp       -73     /* bad data bitslip marks */
-#define        badDCksum       -72     /* bad data checksum */
-#define        noDtaMkErr      -71     /* can't find data mark */
-#define        badBtSlpErr     -70     /* bad address bitslip marks */
-#define        badCksmErr      -69     /* bad address-mark checksum */
-#define        dataVerErr      -68     /* read-verify failed */
-#define        noAdrMkErr      -67     /* can't find an address mark */
-#define        noNybErr        -66     /* no nybbles? disk is probably degaussed */
-#define        offLinErr       -65     /* no disk in drive */
-#define        noDriveErr      -64     /* drive isn't connected */
-#define        nsDrvErr        -56     /* no such drive */
-#define        paramErr        -50     /* bad positioning information */
-#define        wPrErr          -44     /* write protected */
-#define        openErr         -23     /* already initialized */
-
-#ifndef __ASSEMBLY__
-
-struct swim_drvstatus {
-       __u16   curr_track;     /* Current track number                   */
-       __u8    write_prot;     /* 0x80 if disk is write protected        */
-       __u8    disk_in_drive;  /* 0x01 or 0x02 if a disk is in the drive */
-       __u8    installed;      /* 0x01 if drive installed, 0xFF if not   */
-       __u8    num_sides;      /* 0x80 if two-sided format supported     */
-       __u8    two_sided;      /* 0xff if two-sided format diskette      */
-       __u8    new_interface;  /* 0x00 if old 400K drive, 0xFF if newer  */
-       __u16   errors;         /* Disk error count                       */
-       struct {                /* 32 bits */
-               __u16   reserved;
-               __u16   :4;
-               __u16   external:1;     /* Drive is external        */
-               __u16   scsi:1;         /* Drive is a SCSI drive    */
-               __u16   fixed:1;        /* Drive has fixed media    */
-               __u16   secondary:1;    /* Drive is secondary drive */
-               __u8    type;           /* Drive type               */
-       } info;
-       __u8    mfm_drive;      /* 0xFF if this is an FDHD drive    */
-       __u8    mfm_disk;       /* 0xFF if 720K/1440K (MFM) disk    */
-       __u8    mfm_format;     /* 0x00 if 720K, 0xFF if 1440K      */
-       __u8    ctlr_type;      /* 0x00 if IWM, 0xFF if SWIM        */
-       __u16   curr_format;    /* Current format type              */
-       __u16   allowed_fmt;    /* Allowed format types             */
-       __u32   num_blocks;     /* Number of blocks on disk         */
-       __u8    icon_flags;     /* Icon flags                       */
-       __u8    unusued;
-};
-
-/* Commands issued from the host to the IOP: */
-
-struct swimcmd_init {
-       __u8    code;           /* CMD_INIT */
-       __u8    unusued;
-       __u16   error;
-       __u8    drives[28];     /* drive type list */
-};
-
-struct swimcmd_startpoll {
-       __u8    code;           /* CMD_START_POLL */
-       __u8    unusued;
-       __u16   error;
-};
-
-struct swimcmd_sethfstag {
-       __u8    code;           /* CMD_SETHFSTAG */
-       __u8    unusued;
-       __u16   error;
-       caddr_t tagbuf;         /* HFS tag buffer address */
-};
-
-struct swimcmd_status {
-       __u8    code;           /* CMD_STATUS */
-       __u8    drive_num;
-       __u16   error;
-       struct swim_drvstatus status;
-};
-
-struct swimcmd_eject {
-       __u8    code;           /* CMD_EJECT */
-       __u8    drive_num;
-       __u16   error;
-       struct swim_drvstatus status;
-};
-
-struct swimcmd_format {
-       __u8    code;           /* CMD_FORMAT */
-       __u8    drive_num;
-       __u16   error;
-       union {
-               struct {
-                       __u16 fmt;         /* format kind                  */
-                       __u8  hdrbyte;     /* fmt byte for hdr (0=default) */
-                       __u8  interleave;  /* interleave (0 = default)     */
-                       caddr_t databuf;   /* sector data buff (0=default  */
-                       caddr_t tagbuf;    /* tag data buffer (0=default)  */
-               } f;
-               struct swim_drvstatus status;
-       } p;
-};
-
-struct swimcmd_fmtverify {
-       __u8    code;           /* CMD_FORMAT_VERIFY */
-       __u8    drive_num;
-       __u16   error;
-};
-
-struct swimcmd_rw {
-       __u8    code;           /* CMD_READ, CMD_WRITE or CMD_READ_VERIFY */
-       __u8    drive_num;
-       __u16   error;
-       caddr_t buffer;         /* R/W buffer address */
-       __u32   first_block;    /* Starting block     */
-       __u32   num_blocks;     /* Number of blocks   */
-       __u8    tag[12];        /* tag data           */
-};
-
-struct swimcmd_cachectl {
-       __u8    code;           /* CMD_CACHE_CTRL */
-       __u8    unused;
-       __u16   error;
-       __u8    enable;         /* Nonzero to enable cache                */
-       __u8    install;        /* +1 = install, -1 = remove, 0 = neither */
-};
-
-struct swimcmd_tagbufctl {
-       __u8    code;           /* CMD_TAGBUFF_CTRL */
-       __u8    unused;
-       __u16   error;
-       caddr_t buf;            /* buffer address or 0 to disable */
-};
-
-struct swimcmd_geticon {
-       __u8    code;           /* CMD_GET_ICON */
-       __u8    drive_num;
-       __u16   error;
-       caddr_t buffer;         /* Nuffer address */
-       __u16   kind;           /* 0 = media icon, 1 = drive icon */
-       __u16   unused;
-       __u16   max_bytes;      /* maximum  byte count */
-};
-
-/* Messages from the SWIM IOP to the host CPU: */
-
-struct swimmsg_status {
-       __u8    code;           /* 1 = insert, 2 = eject, 3 = status changed */
-       __u8    drive_num;
-       __u16   error;
-       struct swim_drvstatus status;
-};
-
-#endif /* __ASSEMBLY__ */
index c3aadf3b0d88fd1cbfd9184a4ce237ab694764b7..163dcb1a9689d3687aa6e5775bcaf82eee65932f 100644 (file)
@@ -8,6 +8,7 @@
 
 #define flush_cache_all()                      __flush_cache_all()
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     __flush_cache_all()
 #define flush_cache_page(vma, vmaddr)          do { } while (0)
 #define flush_dcache_range(start,len)          __flush_cache_all()
index e3c9925876a3ce4eb80ec67937362cd7d014ad2f..0ddada3bb0b69594e36831f107caa3caad6e0e04 100644 (file)
@@ -17,6 +17,7 @@
  *
  *  - flush_cache_all() flushes entire cache
  *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_dup mm(mm) handles cache flushing when forking
  *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
  *  - flush_cache_range(vma, start, end) flushes a range of pages
  *  - flush_icache_range(start, end) flush a range of instructions
@@ -31,6 +32,7 @@
 extern void (*flush_cache_all)(void);
 extern void (*__flush_cache_all)(void);
 extern void (*flush_cache_mm)(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
 extern void (*flush_cache_range)(struct vm_area_struct *vma,
        unsigned long start, unsigned long end);
 extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
index 0dc1a45c27eda52d0080ae10aecad2e36f33dcb6..2f9e1a9ec51f2e8c85ee24f79eecffeeff69143c 100644 (file)
@@ -35,7 +35,6 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/pfn.h>
-#include <asm/cpu-features.h>
 #include <asm/io.h>
 
 extern void clear_page(void * page);
@@ -61,16 +60,13 @@ static inline void clear_user_page(void *addr, unsigned long vaddr,
                flush_data_cache_page((unsigned long)addr);
 }
 
-static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
-       struct page *to)
-{
-       extern void (*flush_data_cache_page)(unsigned long addr);
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+       struct page *to);
+struct vm_area_struct;
+extern void copy_user_highpage(struct page *to, struct page *from,
+       unsigned long vaddr, struct vm_area_struct *vma);
 
-       copy_page(vto, vfrom);
-       if (!cpu_has_ic_fills_f_dc ||
-           pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
-               flush_data_cache_page((unsigned long)vto);
-}
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
 
 /*
  * These are used to make use of C type-checking..
index 2bc41f2e0271c21813c6c62273af0875a36db0df..aedb0512cb049bac19f8b7616101abf6d9c4302f 100644 (file)
@@ -15,6 +15,8 @@
 #define flush_cache_mm(mm) flush_cache_all_local()
 #endif
 
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
 #define flush_kernel_dcache_range(start,size) \
        flush_kernel_dcache_range_asm((start), (start)+(size));
 
index 8a740c88d93df265b4f66b1bb31fda5d995e41da..08e93e7892191d40793ea5e6f63ec43a035c65a8 100644 (file)
@@ -18,6 +18,7 @@
  */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_icache_page(vma, page)           do { } while (0)
index d339e2e88b1144f73a95dbf67f8440e7b671916e..3f32ca8bfec9ddfc31056df20962d0b9f2e05211 100644 (file)
@@ -122,6 +122,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTOREALL         12      /* Restore all regs (implies NOERROR) */
 #define TIF_NOERROR            14      /* Force successful syscall return */
 #define TIF_RESTORE_SIGMASK    15      /* Restore signal mask in do_signal */
+#define TIF_FREEZE             16      /* Freezing for suspend */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -138,6 +139,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTOREALL                (1<<TIF_RESTOREALL)
 #define _TIF_NOERROR           (1<<TIF_NOERROR)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
 #define _TIF_SYSCALL_T_OR_A    (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 #define _TIF_USER_WORK_MASK    (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
index e399a8ba2ed76dd2c13a8b06fe64775a4cc867a0..f7cade8083f3378e8297493f984f3749b2552b9e 100644 (file)
@@ -7,6 +7,7 @@
 /* Caches aren't brain-dead on the s390. */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index f556fa80ea97559773f7d4f0c2872f26b815729a..2979efb26de3c1b63eb4a70d7487dfd214e1b3cc 100644 (file)
@@ -15,6 +15,7 @@
  *
  *  - flush_cache_all() flushes entire cache
  *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_dup mm(mm) handles cache flushing when forking
  *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
  *  - flush_cache_range(vma, start, end) flushes a range of pages
  *
@@ -27,6 +28,7 @@
  */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index 03fde97a7fd0eaf9d5ba8f6237f0b3aa5d76958e..f70d8ef76a15f6b3d980bb4e01eb36516b2bae86 100644 (file)
@@ -15,6 +15,7 @@
  *
  *  - flush_cache_all() flushes entire cache
  *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_dup mm(mm) handles cache flushing when forking
  *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
  *  - flush_cache_range(vma, start, end) flushes a range of pages
  *
@@ -39,6 +40,7 @@
 
 void flush_cache_all(void);
 void flush_cache_mm(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
 void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
                               unsigned long end);
 void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
@@ -48,6 +50,7 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page);
 #else
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index 515fd574267c100dba1394ddf48445f67914aeb8..b01a10f312259e9f3e8bef29041a4d47c0f29b04 100644 (file)
@@ -18,6 +18,7 @@
  */
 void flush_cache_all(void);
 void flush_cache_mm(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
 void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
                       unsigned long end);
 void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
index 0c01dc550819e865f52b8c135797220abecce60c..879f741105dbd366ed1bbcfdec6570024ae47662 100644 (file)
@@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18
+#define TIF_FREEZE             19
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -114,6 +115,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 #define _TIF_WORK_MASK         0x000000FE      /* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK      0x000000FF      /* work to do on any return to u-space */
index 55f71aa0aa6b8a007258749543a090bd5ea14e5b..1e53a47bdc9755f84486dc8b021b60515d5a8dca 100644 (file)
@@ -21,6 +21,8 @@ extern void flush_icache_user_range(struct vm_area_struct *vma,
                                    struct page *page, unsigned long addr,
                                    int len);
 
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)      do { } while (0)
 
index b29dd468817e63dd7111b12fd03acd1400115969..cb803e56cb64a20c1d3cba3271177212e05dcd5e 100644 (file)
@@ -41,7 +41,7 @@ static inline void pgd_init(unsigned long page)
 static inline pgd_t *get_pgd_slow(void)
 {
        unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
-       pgd_t *ret = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
+       pgd_t *ret = kmalloc(pgd_size, GFP_KERNEL);
        return ret;
 }
 
index fc632f811cd83eefc733df569ebfdf8840909a87..68ac109102715911f5ff244cfa8ee1a5cfb8d751 100644 (file)
@@ -48,6 +48,7 @@ BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
 
 #define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
 #define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
+#define flush_cache_dup_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
 #define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
 #define flush_cache_page(vma,addr,pfn) BTFIXUP_CALL(flush_cache_page)(vma,addr)
 #define flush_icache_range(start, end)         do { } while (0)
index 745d1ab6037196863cd5c1d03be99f15a0588fa2..122e4058dd9ec745ecc3645c402cc1fd0c674dae 100644 (file)
@@ -12,6 +12,7 @@
 /* These are the same regardless of whether this is an SMP kernel or not. */
 #define flush_cache_mm(__mm) \
        do { if ((__mm) == current->mm) flushw_user(); } while(0)
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
 #define flush_cache_range(vma, start, end) \
        flush_cache_mm((vma)->vm_mm)
 #define flush_cache_page(vma, page, pfn) \
index e1a87f82f1a4bc06817a67720cc2f1a6062f9fe5..9ece05a202ef7fd5afe0a425c27267fc6bba03e2 100644 (file)
@@ -24,6 +24,7 @@
    systems with MMUs, so we don't need them.  */
 #define flush_cache_all()                      ((void)0)
 #define flush_cache_mm(mm)                     ((void)0)
+#define flush_cache_dup_mm(mm)                 ((void)0)
 #define flush_cache_range(vma, start, end)     ((void)0)
 #define flush_cache_page(vma, vmaddr, pfn)     ((void)0)
 #define flush_dcache_page(page)                        ((void)0)
index d32f7f58752a7b6747965dbb981e3a8b3dc8fcc8..ab1cb5c7dc9296c91df181db8fe82b3aaf2ab2ad 100644 (file)
@@ -7,6 +7,7 @@
 /* Caches aren't brain-dead on the intel. */
 #define flush_cache_all()                      do { } while (0)
 #define flush_cache_mm(mm)                     do { } while (0)
+#define flush_cache_dup_mm(mm)                 do { } while (0)
 #define flush_cache_range(vma, start, end)     do { } while (0)
 #define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
 #define flush_dcache_page(page)                        do { } while (0)
index 787a08114b4847c0e4d37de1157515355cc4adce..74a6c74397f72bee7619075dd1fba64d7d13e136 100644 (file)
@@ -122,6 +122,7 @@ static inline struct thread_info *stack_thread_info(void)
 #define TIF_MEMDIE             20
 #define TIF_DEBUG              21      /* uses debug registers */
 #define TIF_IO_BITMAP          22      /* uses I/O bitmap */
+#define TIF_FREEZE             23      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -137,6 +138,7 @@ static inline struct thread_info *stack_thread_info(void)
 #define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
 #define _TIF_DEBUG             (1<<TIF_DEBUG)
 #define _TIF_IO_BITMAP         (1<<TIF_IO_BITMAP)
+#define _TIF_FREEZE            (1<<TIF_FREEZE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK \
index 337765b629de0dd38e42c2b714b4858ce7b2ef03..22ef901b7845fa27087cdfc2586c93047af16513 100644 (file)
@@ -75,6 +75,7 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
 
 #define flush_cache_all()              __flush_invalidate_cache_all();
 #define flush_cache_mm(mm)             __flush_invalidate_cache_all();
+#define flush_cache_dup_mm(mm)         __flush_invalidate_cache_all();
 
 #define flush_cache_vmap(start,end)    __flush_invalidate_cache_all();
 #define flush_cache_vunmap(start,end)  __flush_invalidate_cache_all();
@@ -88,6 +89,7 @@ extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned lon
 
 #define flush_cache_all()                              do { } while (0)
 #define flush_cache_mm(mm)                             do { } while (0)
+#define flush_cache_dup_mm(mm)                         do { } while (0)
 
 #define flush_cache_vmap(start,end)                    do { } while (0)
 #define flush_cache_vunmap(start,end)                  do { } while (0)
index c780593ff5f9080a0cd69dccaca80d2f67f40baa..057b9a3d8f83171114c39cd4dfdff2c02ef4e2f7 100644 (file)
@@ -30,6 +30,17 @@ struct termios {
        cc_t c_cc[NCCS];                /* control characters */
 };
 
+struct ktermios {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+       speed_t c_ispeed;               /* input speed */
+       speed_t c_ospeed;               /* output speed */
+};
+
 /* c_cc characters */
 
 #define VINTR 0
index 88a64e1144d5c716b6218770f93189d614977adf..d6352da05b10b9b29660b5121581dc44ae838423 100644 (file)
@@ -23,7 +23,6 @@
 
 #ifdef __ASSEMBLY__
 
-#define _ASMLANGUAGE
 #include <asm/current.h>
 #include <asm/asm-offsets.h>
 #include <asm/processor.h>
index 3372ec6bf53a25d5d65d540008f75bde975e1c13..a30ef13c9e622c91bfd7706955758e5932fc639e 100644 (file)
@@ -105,6 +105,7 @@ struct kiocb {
        wait_queue_t            ki_wait;
        loff_t                  ki_pos;
 
+       atomic_t                ki_bio_count;   /* num bio used for this iocb */
        void                    *private;
        /* State that we remember to be able to restart/retry  */
        unsigned short          ki_opcode;
index 092dbd0e76586023c76850495c71ca1ab933efc3..08daf3272c0283b808cbe75ec48348c3efc8a71e 100644 (file)
@@ -309,6 +309,7 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
                                gfp_t);
 extern void bio_set_pages_dirty(struct bio *bio);
 extern void bio_check_pages_dirty(struct bio *bio);
+extern void bio_release_pages(struct bio *bio);
 extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
 extern int bio_uncopy_user(struct bio *);
 void zero_fill_bio(struct bio *bio);
index be512cc98791a31b85c0317e6f2b19e1e90c3631..4c2632a8d31b97a4fe3cdac74669a106f359e116 100644 (file)
@@ -64,7 +64,7 @@ void coda_sysctl_clean(void);
 
 #define CODA_ALLOC(ptr, cast, size) do { \
     if (size < PAGE_SIZE) \
-        ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
+        ptr = kmalloc((unsigned long) size, GFP_KERNEL); \
     else \
         ptr = (cast)vmalloc((unsigned long) size); \
     if (!ptr) \
index 8821e1f75b447856a041435d966eb12fb5c94941..826b15e914e2b9986787189dcba1d2efe15e15c3 100644 (file)
@@ -30,10 +30,19 @@ void cpuset_update_task_memory_state(void);
                nodes_subset((nodes), current->mems_allowed)
 int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl);
 
-extern int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
-static int inline cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+extern int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask);
+extern int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask);
+
+static int inline cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
+{
+       return number_of_cpusets <= 1 ||
+               __cpuset_zone_allowed_softwall(z, gfp_mask);
+}
+
+static int inline cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
 {
-       return number_of_cpusets <= 1 || __cpuset_zone_allowed(z, gfp_mask);
+       return number_of_cpusets <= 1 ||
+               __cpuset_zone_allowed_hardwall(z, gfp_mask);
 }
 
 extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
@@ -94,7 +103,12 @@ static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
        return 1;
 }
 
-static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
+{
+       return 1;
+}
+
+static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
 {
        return 1;
 }
index 6fe56aaa6685c3f2c04bd6ceb2f4af1d2c5bbd27..64177ec9a01910e71adee4d777ddb1ad49e29e6d 100644 (file)
@@ -929,8 +929,6 @@ extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max)
 #define FB_MODE_IS_FIRST       16
 #define FB_MODE_IS_FROM_VAR     32
 
-extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
-                              const struct fb_info *fb_info);
 extern int fbmon_dpms(const struct fb_info *fb_info);
 extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
                       struct fb_info *info);
index 393063096134d505cedf33fb216ce943bae23b6e..5e75e26d4787248caf175063afad75010824672a 100644 (file)
@@ -16,16 +16,15 @@ static inline int frozen(struct task_struct *p)
  */
 static inline int freezing(struct task_struct *p)
 {
-       return p->flags & PF_FREEZE;
+       return test_tsk_thread_flag(p, TIF_FREEZE);
 }
 
 /*
  * Request that a process be frozen
- * FIXME: SMP problem. We may not modify other process' flags!
  */
 static inline void freeze(struct task_struct *p)
 {
-       p->flags |= PF_FREEZE;
+       set_tsk_thread_flag(p, TIF_FREEZE);
 }
 
 /*
@@ -33,7 +32,7 @@ static inline void freeze(struct task_struct *p)
  */
 static inline void do_not_freeze(struct task_struct *p)
 {
-       p->flags &= ~PF_FREEZE;
+       clear_tsk_thread_flag(p, TIF_FREEZE);
 }
 
 /*
@@ -54,7 +53,9 @@ static inline int thaw_process(struct task_struct *p)
  */
 static inline void frozen_process(struct task_struct *p)
 {
-       p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN;
+       p->flags |= PF_FROZEN;
+       wmb();
+       clear_tsk_thread_flag(p, TIF_FREEZE);
 }
 
 extern void refrigerator(void);
index adce6e1d70c2cf0c20ec97ce628df2307e025d55..186da813541e574128b1ea2772c8e6fa5e1007e7 100644 (file)
@@ -120,6 +120,7 @@ extern int dir_notify_enable;
 #define MS_PRIVATE     (1<<18) /* change to private */
 #define MS_SLAVE       (1<<19) /* change to slave */
 #define MS_SHARED      (1<<20) /* change to shared */
+#define MS_RELATIME    (1<<21) /* Update atime relative to mtime/ctime. */
 #define MS_ACTIVE      (1<<30)
 #define MS_NOUSER      (1<<31)
 
index 2cdba0c2395707184544ee755e9a5f9ddefbe9a1..afad95272841827445d8258043351ba0d23fcf4c 100644 (file)
@@ -105,7 +105,7 @@ static inline void gameport_set_phys(struct gameport *gameport,
 
 static inline struct gameport *gameport_allocate_port(void)
 {
-       struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL);
+       struct gameport *gameport = kzalloc(sizeof(struct gameport), GFP_KERNEL);
 
        return gameport;
 }
index 3d8768b619e9ef71f71e60ae90205971298ffef8..ca9a602cffd7a2b8ea03c3d7fb0a60c4a1a3acb2 100644 (file)
@@ -96,7 +96,10 @@ static inline void memclear_highpage_flush(struct page *page, unsigned int offse
        kunmap_atomic(kaddr, KM_USER0);
 }
 
-static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr)
+#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
+
+static inline void copy_user_highpage(struct page *to, struct page *from,
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        char *vfrom, *vto;
 
@@ -109,6 +112,8 @@ static inline void copy_user_highpage(struct page *to, struct page *from, unsign
        smp_wmb();
 }
 
+#endif
+
 static inline void copy_highpage(struct page *to, struct page *from)
 {
        char *vfrom, *vto;
index 7ae3c3326643a1d19ad1436192e27a554aa172e4..d38778f2fbecec8ef06fca43f06b3ecc86fa5e89 100644 (file)
 #define I2C_DRIVERID_MTP008 1023
 #define I2C_DRIVERID_DS1621 1024
 #define I2C_DRIVERID_ADM1024 1025
-#define I2C_DRIVERID_IT87 1026
 #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
 #define I2C_DRIVERID_FSCPOS 1028
 #define I2C_DRIVERID_FSCSCY 1029
index b5315150199e9528bbfa1b5fcfe64b669b199058..6383d2d83bb0c5b12e233c5fbfe53e6e47c49578 100644 (file)
@@ -75,7 +75,6 @@ extern struct nsproxy init_nsproxy;
        .pid_ns         = &init_pid_ns,                                 \
        .count          = ATOMIC_INIT(1),                               \
        .nslock         = __SPIN_LOCK_UNLOCKED(nsproxy.nslock),         \
-       .id             = 0,                                            \
        .uts_ns         = &init_uts_ns,                                 \
        .mnt_ns         = NULL,                                         \
        INIT_IPC_NS(ipc_ns)                                             \
index aa50d89eacd77abb748ad7a892f20575b7c4b1bb..246de1d84a2679c96436ce9601ed02183b8b6a87 100644 (file)
@@ -23,7 +23,7 @@ struct svc_rqst;
  * This is the set of functions for lockd->nfsd communication
  */
 struct nlmsvc_binding {
-       u32                     (*fopen)(struct svc_rqst *,
+       __be32                  (*fopen)(struct svc_rqst *,
                                                struct nfs_fh *,
                                                struct file **);
        void                    (*fclose)(struct file *);
index 0c962b82a9debb6d0ada12f09370fe152390cde9..ac25b5649c594a65589ec25f8079a9642333e447 100644 (file)
@@ -191,7 +191,7 @@ __be32                nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long    nlmsvc_retry_blocked(void);
 void             nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
                                        nlm_host_match_fn_t match);
-void             nlmsvc_grant_reply(struct nlm_cookie *, u32);
+void             nlmsvc_grant_reply(struct nlm_cookie *, __be32);
 
 /*
  * File handling for the server personality
index fc61d40964dadfa24a585273fe1b660c31717f38..22a645828f268e5639ae73fec10494ed21ecd05c 100644 (file)
@@ -24,7 +24,7 @@
  * Arguments for all calls to statd
  */
 struct nsm_args {
-       u32             addr;           /* remote address */
+       __be32          addr;           /* remote address */
        u32             prog;           /* RPC callback info */
        u32             vers;
        u32             proc;
index 29e7d9fc9dad68c163c38a6908659540869d0bb4..83a1f9f6237b5f539f52cda2b6b09eeb013dd97c 100644 (file)
@@ -69,7 +69,7 @@ typedef struct nlm_args nlm_args;
  */
 struct nlm_res {
        struct nlm_cookie       cookie;
-       u32                     status;
+       __be32                  status;
        struct nlm_lock         lock;
 };
 
@@ -80,9 +80,9 @@ struct nlm_reboot {
        char *          mon;
        int             len;
        u32             state;
-       u32             addr;
-       u32             vers;
-       u32             proto;
+       __be32          addr;
+       __be32          vers;
+       __be32          proto;
 };
 
 /*
index 498bfbd3b4e1acfdd0ba200e21e6a91c3eab2e3f..ea097dddc44f791d34a599aa12b3a251413aa47d 100644 (file)
@@ -281,15 +281,25 @@ struct lock_class_key { };
 #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
 extern void early_init_irq_lock_class(void);
 #else
-# define early_init_irq_lock_class()           do { } while (0)
+static inline void early_init_irq_lock_class(void)
+{
+}
 #endif
 
 #ifdef CONFIG_TRACE_IRQFLAGS
 extern void early_boot_irqs_off(void);
 extern void early_boot_irqs_on(void);
+extern void print_irqtrace_events(struct task_struct *curr);
 #else
-# define early_boot_irqs_off()                 do { } while (0)
-# define early_boot_irqs_on()                  do { } while (0)
+static inline void early_boot_irqs_off(void)
+{
+}
+static inline void early_boot_irqs_on(void)
+{
+}
+static inline void print_irqtrace_events(struct task_struct *curr)
+{
+}
 #endif
 
 /*
index e357dc86a4de304c0fd77cdcc83fce0ffa475319..1b7e178b0d8472549de308667343b15d4f44aa56 100644 (file)
@@ -27,6 +27,7 @@ struct mnt_namespace;
 #define MNT_NOEXEC     0x04
 #define MNT_NOATIME    0x08
 #define MNT_NODIRATIME 0x10
+#define MNT_RELATIME   0x20
 
 #define MNT_SHRINKABLE 0x100
 
index db4f3776978aafe81c36caf263f001d195e28311..de24af79ebd3bc1c6bc94586cb15f9fda56d774c 100644 (file)
@@ -116,7 +116,7 @@ struct r3964_message;
 
 struct r3964_client_info {
        spinlock_t     lock;
-       pid_t          pid;
+       struct pid    *pid;
        unsigned int   sig_flags;
 
        struct r3964_client_info *next;
index f46bddcdbd3bed4040c6201725e28972d19d523b..a2b549eb1ecaf5624c608eef6b5f4df721219a9a 100644 (file)
@@ -75,7 +75,7 @@ struct ncp_mount_data_kernel {
        unsigned int     int_flags;     /* internal flags */
 #define NCP_IMOUNT_LOGGEDIN_POSSIBLE   0x0001
        __kernel_uid32_t mounted_uid;   /* Who may umount() this filesystem? */
-       __kernel_pid_t   wdog_pid;              /* Who cares for our watchdog packets? */
+       struct pid      *wdog_pid;      /* Who cares for our watchdog packets? */
        unsigned int     ncp_fd;        /* The socket to the ncp port */
        unsigned int     time_out;      /* How long should I wait after
                                           sending a NCP request? */
index edb54c3171b35b792eef3d8c047112698d706fa2..0727774772bab06c22b93e6b8b1e977409aa56b6 100644 (file)
@@ -275,12 +275,12 @@ static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
  * we might process an operation with side effects, and be unable to
  * tell the client that the operation succeeded.
  *
- * COMPOUND_SLACK_SPACE - this is the minimum amount of buffer space
+ * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space
  * needed to encode an "ordinary" _successful_ operation.  (GETATTR,
  * READ, READDIR, and READLINK have their own buffer checks.)  if we
  * fall below this level, we fail the next operation with NFS4ERR_RESOURCE.
  *
- * COMPOUND_ERR_SLACK_SPACE - this is the minimum amount of buffer space
+ * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space
  * needed to encode an operation which has failed with NFS4ERR_RESOURCE.
  * care is taken to ensure that we never fall below this level for any
  * reason.
index c3673f487e841984169419c33d5663cf0db868b3..ab5c236bd9a7c9421eea4652c734ddccd97b3084 100644 (file)
@@ -273,7 +273,6 @@ struct nfs4_stateid {
        ((err) != nfserr_stale_stateid) &&      \
        ((err) != nfserr_bad_stateid))
 
-extern __be32 nfsd4_renew(clientid_t *clid);
 extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
                stateid_t *stateid, int flags, struct file **filp);
 extern void nfs4_lock_state(void);
index 45ca01b5f844ffaa68b8902be92bd47cf4f65ae1..09799bcee0ac6ed01458cdde85f76b1589dd9a18 100644 (file)
 #define NFSD4_MAX_TAGLEN       128
 #define XDR_LEN(n)                     (((n) + 3) & ~3)
 
+struct nfsd4_compound_state {
+       struct svc_fh current_fh;
+       struct svc_fh save_fh;
+       struct nfs4_stateowner *replay_owner;
+};
+
 struct nfsd4_change_info {
        u32             atomic;
        u32             before_ctime_sec;
@@ -430,35 +436,39 @@ __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                       struct dentry *dentry, __be32 *buffer, int *countp,
                       u32 *bmval, struct svc_rqst *);
 extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
                struct nfsd4_setclientid *setclid);
 extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
                struct nfsd4_setclientid_confirm *setclientid_confirm);
 extern __be32 nfsd4_process_open1(struct nfsd4_open *open);
 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open *open);
 extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
-               struct svc_fh *current_fh, struct nfsd4_open_confirm *oc,
-               struct nfs4_stateowner **);
-extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
-               struct nfsd4_close *close,
-               struct nfs4_stateowner **replay_owner);
+               struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc);
+extern __be32 nfsd4_close(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
+               struct nfsd4_close *close);
 extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
-               struct svc_fh *current_fh, struct nfsd4_open_downgrade *od,
-               struct nfs4_stateowner **replay_owner);
-extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
-               struct nfsd4_lock *lock,
-               struct nfs4_stateowner **replay_owner);
-extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh,
+               struct nfsd4_compound_state *,
+               struct nfsd4_open_downgrade *od);
+extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *,
+               struct nfsd4_lock *lock);
+extern __be32 nfsd4_lockt(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
                struct nfsd4_lockt *lockt);
-extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh,
-               struct nfsd4_locku *locku,
-               struct nfs4_stateowner **replay_owner);
+extern __be32 nfsd4_locku(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
+               struct nfsd4_locku *locku);
 extern __be32
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
+               struct nfsd4_compound_state *,
                struct nfsd4_release_lockowner *rlockowner);
 extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
 extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
-               struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
+               struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr);
+extern __be32 nfsd4_renew(struct svc_rqst *rqstp,
+                         struct nfsd4_compound_state *, clientid_t *clid);
 #endif
 
 /*
index fdfb0e44912f1ce68794e52f6ca5cf5756f45ae7..0b9f0dc30d6114a1f5177a7fde829d2199137172 100644 (file)
@@ -24,7 +24,6 @@ struct pid_namespace;
 struct nsproxy {
        atomic_t count;
        spinlock_t nslock;
-       unsigned long id;
        struct uts_namespace *uts_ns;
        struct ipc_namespace *ipc_ns;
        struct mnt_namespace *mnt_ns;
index 51180dba9a98167eb0976f0e4d22bb9246580677..95c1e74afebcc943993d0f876df0d7f882410f02 100644 (file)
 #define PCI_DEVICE_ID_JMICRON_JMB366   0x2366
 #define PCI_DEVICE_ID_JMICRON_JMB368   0x2368
 
+#define PCI_VENDOR_ID_KORENIX          0x1982
+#define PCI_DEVICE_ID_KORENIX_JETCARDF0        0x1600
+#define PCI_DEVICE_ID_KORENIX_JETCARDF1        0x16ff
+
 #define PCI_VENDOR_ID_TEKRAM           0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290     0xdc29
 
index ea4f7cd7bfd85425c96a1d17faa358a2d7cb509f..2e19478e9e84f90e93a6445b53aed3ca78656fa5 100644 (file)
@@ -12,7 +12,7 @@
 struct pipe_buffer {
        struct page *page;
        unsigned int offset, len;
-       struct pipe_buf_operations *ops;
+       const struct pipe_buf_operations *ops;
        unsigned int flags;
 };
 
@@ -41,9 +41,7 @@ struct pipe_buf_operations {
 struct pipe_inode_info {
        wait_queue_head_t wait;
        unsigned int nrbufs, curbuf;
-       struct pipe_buffer bufs[PIPE_BUFFERS];
        struct page *tmp_page;
-       unsigned int start;
        unsigned int readers;
        unsigned int writers;
        unsigned int waiting_writers;
@@ -52,6 +50,7 @@ struct pipe_inode_info {
        struct fasync_struct *fasync_readers;
        struct fasync_struct *fasync_writers;
        struct inode *inode;
+       struct pipe_buffer bufs[PIPE_BUFFERS];
 };
 
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
index 20f47b81d3fad3055a1eb048d7acf47473596c72..8bbd459eafdcbd64532613e3b45820c6986373a2 100644 (file)
@@ -39,7 +39,7 @@ extern struct platform_device *platform_device_register_simple(char *, unsigned
 
 extern struct platform_device *platform_device_alloc(const char *name, unsigned int id);
 extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
-extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
+extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);
 extern int platform_device_add(struct platform_device *pdev);
 extern void platform_device_del(struct platform_device *pdev);
 extern void platform_device_put(struct platform_device *pdev);
diff --git a/include/linux/reciprocal_div.h b/include/linux/reciprocal_div.h
new file mode 100644 (file)
index 0000000..f9c90b3
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LINUX_RECIPROCAL_DIV_H
+#define _LINUX_RECIPROCAL_DIV_H
+
+#include <linux/types.h>
+
+/*
+ * This file describes reciprocical division.
+ *
+ * This optimizes the (A/B) problem, when A and B are two u32
+ * and B is a known value (but not known at compile time)
+ *
+ * The math principle used is :
+ *   Let RECIPROCAL_VALUE(B) be (((1LL << 32) + (B - 1))/ B)
+ *   Then A / B = (u32)(((u64)(A) * (R)) >> 32)
+ *
+ * This replaces a divide by a multiply (and a shift), and
+ * is generally less expensive in CPU cycles.
+ */
+
+/*
+ * Computes the reciprocal value (R) for the value B of the divisor.
+ * Should not be called before each reciprocal_divide(),
+ * or else the performance is slower than a normal divide.
+ */
+extern u32 reciprocal_value(u32 B);
+
+
+static inline u32 reciprocal_divide(u32 A, u32 R)
+{
+       return (u32)(((u64)A * R) >> 32);
+}
+#endif
index ea92e5c890894694533ea42a0d95e2148ff301c9..4463735351904f039b1c3239f6161f52ce88ad77 100644 (file)
@@ -1144,7 +1144,6 @@ static inline void put_task_struct(struct task_struct *t)
 #define PF_MEMALLOC    0x00000800      /* Allocating memory */
 #define PF_FLUSHER     0x00001000      /* responsible for disk writeback */
 #define PF_USED_MATH   0x00002000      /* if unset the fpu must be initialized before use */
-#define PF_FREEZE      0x00004000      /* this task is being frozen for suspend now */
 #define PF_NOFREEZE    0x00008000      /* this thread should not be frozen */
 #define PF_FROZEN      0x00010000      /* frozen for system suspend */
 #define PF_FSTRANS     0x00020000      /* inside a filesystem transaction */
index 2271886744f87a5fb43d5f307b7c062dc54528c1..1ef822e31c774892ffc08d668fd58d357bef5d29 100644 (file)
@@ -1,7 +1,9 @@
 /*
- * linux/include/linux/slab.h
- * Written by Mark Hemment, 1996.
- * (markhe@nextd.demon.co.uk)
+ * Written by Mark Hemment, 1996 (markhe@nextd.demon.co.uk).
+ *
+ * (C) SGI 2006, Christoph Lameter <clameter@sgi.com>
+ *     Cleaned up and restructured to ease the addition of alternative
+ *     implementations of SLAB allocators.
  */
 
 #ifndef _LINUX_SLAB_H
 #ifdef __KERNEL__
 
 #include <linux/gfp.h>
-#include <linux/init.h>
 #include <linux/types.h>
-#include <asm/page.h>          /* kmalloc_sizes.h needs PAGE_SIZE */
-#include <asm/cache.h>         /* kmalloc_sizes.h needs L1_CACHE_BYTES */
-#include <linux/compiler.h>
 
-/* kmem_cache_t exists for legacy reasons and is not used by code in mm */
 typedef struct kmem_cache kmem_cache_t __deprecated;
 
-/* flags to pass to kmem_cache_create().
- * The first 3 are only valid when the allocator as been build
- * SLAB_DEBUG_SUPPORT.
+/*
+ * Flags to pass to kmem_cache_create().
+ * The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set.
  */
-#define        SLAB_DEBUG_FREE         0x00000100UL    /* Peform (expensive) checks on free */
-#define        SLAB_DEBUG_INITIAL      0x00000200UL    /* Call constructor (as verifier) */
-#define        SLAB_RED_ZONE           0x00000400UL    /* Red zone objs in a cache */
-#define        SLAB_POISON             0x00000800UL    /* Poison objects */
-#define        SLAB_HWCACHE_ALIGN      0x00002000UL    /* align objs on a h/w cache lines */
-#define SLAB_CACHE_DMA         0x00004000UL    /* use GFP_DMA memory */
-#define SLAB_MUST_HWCACHE_ALIGN        0x00008000UL    /* force alignment */
-#define SLAB_STORE_USER                0x00010000UL    /* store the last owner for bug hunting */
-#define SLAB_RECLAIM_ACCOUNT   0x00020000UL    /* track pages allocated to indicate
-                                                  what is reclaimable later*/
-#define SLAB_PANIC             0x00040000UL    /* panic if kmem_cache_create() fails */
-#define SLAB_DESTROY_BY_RCU    0x00080000UL    /* defer freeing pages to RCU */
+#define SLAB_DEBUG_FREE                0x00000100UL    /* DEBUG: Perform (expensive) checks on free */
+#define SLAB_DEBUG_INITIAL     0x00000200UL    /* DEBUG: Call constructor (as verifier) */
+#define SLAB_RED_ZONE          0x00000400UL    /* DEBUG: Red zone objs in a cache */
+#define SLAB_POISON            0x00000800UL    /* DEBUG: Poison objects */
+#define SLAB_HWCACHE_ALIGN     0x00002000UL    /* Align objs on cache lines */
+#define SLAB_CACHE_DMA         0x00004000UL    /* Use GFP_DMA memory */
+#define SLAB_MUST_HWCACHE_ALIGN        0x00008000UL    /* Force alignment even if debuggin is active */
+#define SLAB_STORE_USER                0x00010000UL    /* DEBUG: Store the last owner for bug hunting */
+#define SLAB_RECLAIM_ACCOUNT   0x00020000UL    /* Objects are reclaimable */
+#define SLAB_PANIC             0x00040000UL    /* Panic if kmem_cache_create() fails */
+#define SLAB_DESTROY_BY_RCU    0x00080000UL    /* Defer freeing slabs to RCU */
 #define SLAB_MEM_SPREAD                0x00100000UL    /* Spread some memory over cpuset */
 
-/* flags passed to a constructor func */
-#define        SLAB_CTOR_CONSTRUCTOR   0x001UL         /* if not set, then deconstructor */
-#define SLAB_CTOR_ATOMIC       0x002UL         /* tell constructor it can't sleep */
-#define        SLAB_CTOR_VERIFY        0x004UL         /* tell constructor it's a verify call */
+/* Flags passed to a constructor functions */
+#define SLAB_CTOR_CONSTRUCTOR  0x001UL         /* If not set, then deconstructor */
+#define SLAB_CTOR_ATOMIC       0x002UL         /* Tell constructor it can't sleep */
+#define SLAB_CTOR_VERIFY       0x004UL         /* Tell constructor it's a verify call */
 
-#ifndef CONFIG_SLOB
-
-/* prototypes */
-extern void __init kmem_cache_init(void);
+/*
+ * struct kmem_cache related prototypes
+ */
+void __init kmem_cache_init(void);
+extern int slab_is_available(void);
 
-extern struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
+struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
                        unsigned long,
                        void (*)(void *, struct kmem_cache *, unsigned long),
                        void (*)(void *, struct kmem_cache *, unsigned long));
-extern void kmem_cache_destroy(struct kmem_cache *);
-extern int kmem_cache_shrink(struct kmem_cache *);
-extern void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
-extern void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
-extern void kmem_cache_free(struct kmem_cache *, void *);
-extern unsigned int kmem_cache_size(struct kmem_cache *);
-extern const char *kmem_cache_name(struct kmem_cache *);
+void kmem_cache_destroy(struct kmem_cache *);
+int kmem_cache_shrink(struct kmem_cache *);
+void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
+void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
+void kmem_cache_free(struct kmem_cache *, void *);
+unsigned int kmem_cache_size(struct kmem_cache *);
+const char *kmem_cache_name(struct kmem_cache *);
+int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
+
+#ifdef CONFIG_NUMA
+extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
+#else
+static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
+                                       gfp_t flags, int node)
+{
+       return kmem_cache_alloc(cachep, flags);
+}
+#endif
+
+/*
+ * Common kmalloc functions provided by all allocators
+ */
+void *__kmalloc(size_t, gfp_t);
+void *__kzalloc(size_t, gfp_t);
+void kfree(const void *);
+unsigned int ksize(const void *);
+
+/**
+ * kcalloc - allocate memory for an array. The memory is set to zero.
+ * @n: number of elements.
+ * @size: element size.
+ * @flags: the type of memory to allocate.
+ */
+static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+       if (n != 0 && size > ULONG_MAX / n)
+               return NULL;
+       return __kzalloc(n * size, flags);
+}
 
-/* Size description struct for general caches. */
-struct cache_sizes {
-       size_t                  cs_size;
-       struct kmem_cache       *cs_cachep;
-       struct kmem_cache       *cs_dmacachep;
-};
-extern struct cache_sizes malloc_sizes[];
+/*
+ * Allocator specific definitions. These are mainly used to establish optimized
+ * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by selecting
+ * the appropriate general cache at compile time.
+ */
 
-extern void *__kmalloc(size_t, gfp_t);
+#ifdef CONFIG_SLAB
+#include <linux/slab_def.h>
+#else
+/*
+ * Fallback definitions for an allocator not wanting to provide
+ * its own optimized kmalloc definitions (like SLOB).
+ */
 
 /**
  * kmalloc - allocate memory
@@ -116,46 +149,9 @@ extern void *__kmalloc(size_t, gfp_t);
  */
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
-       if (__builtin_constant_p(size)) {
-               int i = 0;
-#define CACHE(x) \
-               if (size <= x) \
-                       goto found; \
-               else \
-                       i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
-               {
-                       extern void __you_cannot_kmalloc_that_much(void);
-                       __you_cannot_kmalloc_that_much();
-               }
-found:
-               return kmem_cache_alloc((flags & GFP_DMA) ?
-                       malloc_sizes[i].cs_dmacachep :
-                       malloc_sizes[i].cs_cachep, flags);
-       }
        return __kmalloc(size, flags);
 }
 
-/*
- * kmalloc_track_caller is a special version of kmalloc that records the
- * calling function of the routine calling it for slab leak tracking instead
- * of just the calling function (confusing, eh?).
- * It's useful when the call to kmalloc comes from a widely-used standard
- * allocator where we care about the real place the memory allocation
- * request comes from.
- */
-#ifndef CONFIG_DEBUG_SLAB
-#define kmalloc_track_caller(size, flags) \
-       __kmalloc(size, flags)
-#else
-extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
-#define kmalloc_track_caller(size, flags) \
-       __kmalloc_track_caller(size, flags, __builtin_return_address(0))
-#endif
-
-extern void *__kzalloc(size_t, gfp_t);
-
 /**
  * kzalloc - allocate memory. The memory is set to zero.
  * @size: how many bytes of memory are required.
@@ -163,71 +159,40 @@ extern void *__kzalloc(size_t, gfp_t);
  */
 static inline void *kzalloc(size_t size, gfp_t flags)
 {
-       if (__builtin_constant_p(size)) {
-               int i = 0;
-#define CACHE(x) \
-               if (size <= x) \
-                       goto found; \
-               else \
-                       i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
-               {
-                       extern void __you_cannot_kzalloc_that_much(void);
-                       __you_cannot_kzalloc_that_much();
-               }
-found:
-               return kmem_cache_zalloc((flags & GFP_DMA) ?
-                       malloc_sizes[i].cs_dmacachep :
-                       malloc_sizes[i].cs_cachep, flags);
-       }
        return __kzalloc(size, flags);
 }
+#endif
 
-/**
- * kcalloc - allocate memory for an array. The memory is set to zero.
- * @n: number of elements.
- * @size: element size.
- * @flags: the type of memory to allocate.
- */
-static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+#ifndef CONFIG_NUMA
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
-       if (n != 0 && size > ULONG_MAX / n)
-               return NULL;
-       return kzalloc(n * size, flags);
+       return kmalloc(size, flags);
 }
 
-extern void kfree(const void *);
-extern unsigned int ksize(const void *);
-extern int slab_is_available(void);
-
-#ifdef CONFIG_NUMA
-extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
-extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
-
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+static inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
 {
-       if (__builtin_constant_p(size)) {
-               int i = 0;
-#define CACHE(x) \
-               if (size <= x) \
-                       goto found; \
-               else \
-                       i++;
-#include "kmalloc_sizes.h"
-#undef CACHE
-               {
-                       extern void __you_cannot_kmalloc_that_much(void);
-                       __you_cannot_kmalloc_that_much();
-               }
-found:
-               return kmem_cache_alloc_node((flags & GFP_DMA) ?
-                       malloc_sizes[i].cs_dmacachep :
-                       malloc_sizes[i].cs_cachep, flags, node);
-       }
-       return __kmalloc_node(size, flags, node);
+       return __kmalloc(size, flags);
 }
+#endif /* !CONFIG_NUMA */
 
+/*
+ * kmalloc_track_caller is a special version of kmalloc that records the
+ * calling function of the routine calling it for slab leak tracking instead
+ * of just the calling function (confusing, eh?).
+ * It's useful when the call to kmalloc comes from a widely-used standard
+ * allocator where we care about the real place the memory allocation
+ * request comes from.
+ */
+#ifdef CONFIG_DEBUG_SLAB
+extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
+#define kmalloc_track_caller(size, flags) \
+       __kmalloc_track_caller(size, flags, __builtin_return_address(0))
+#else
+#define kmalloc_track_caller(size, flags) \
+       __kmalloc(size, flags)
+#endif /* DEBUG_SLAB */
+
+#ifdef CONFIG_NUMA
 /*
  * kmalloc_node_track_caller is a special version of kmalloc_node that
  * records the calling function of the routine calling it for slab leak
@@ -236,70 +201,23 @@ found:
  * standard allocator where we care about the real place the memory
  * allocation request comes from.
  */
-#ifndef CONFIG_DEBUG_SLAB
-#define kmalloc_node_track_caller(size, flags, node) \
-       __kmalloc_node(size, flags, node)
-#else
+#ifdef CONFIG_DEBUG_SLAB
 extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
 #define kmalloc_node_track_caller(size, flags, node) \
        __kmalloc_node_track_caller(size, flags, node, \
                        __builtin_return_address(0))
+#else
+#define kmalloc_node_track_caller(size, flags, node) \
+       __kmalloc_node(size, flags, node)
 #endif
+
 #else /* CONFIG_NUMA */
-static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
-                                       gfp_t flags, int node)
-{
-       return kmem_cache_alloc(cachep, flags);
-}
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
-{
-       return kmalloc(size, flags);
-}
 
 #define kmalloc_node_track_caller(size, flags, node) \
        kmalloc_track_caller(size, flags)
-#endif
 
-extern int FASTCALL(kmem_cache_reap(int));
-extern int FASTCALL(kmem_ptr_validate(struct kmem_cache *cachep, void *ptr));
-
-#else /* CONFIG_SLOB */
-
-/* SLOB allocator routines */
-
-void kmem_cache_init(void);
-struct kmem_cache *kmem_cache_create(const char *c, size_t, size_t,
-       unsigned long,
-       void (*)(void *, struct kmem_cache *, unsigned long),
-       void (*)(void *, struct kmem_cache *, unsigned long));
-void kmem_cache_destroy(struct kmem_cache *c);
-void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags);
-void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
-void kmem_cache_free(struct kmem_cache *c, void *b);
-const char *kmem_cache_name(struct kmem_cache *);
-void *kmalloc(size_t size, gfp_t flags);
-void *__kzalloc(size_t size, gfp_t flags);
-void kfree(const void *m);
-unsigned int ksize(const void *m);
-unsigned int kmem_cache_size(struct kmem_cache *c);
-
-static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
-{
-       return __kzalloc(n * size, flags);
-}
-
-#define kmem_cache_shrink(d) (0)
-#define kmem_cache_reap(a)
-#define kmem_ptr_validate(a, b) (0)
-#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
-#define kmalloc_node(s, f, n) kmalloc(s, f)
-#define kzalloc(s, f) __kzalloc(s, f)
-#define kmalloc_track_caller kmalloc
-
-#define kmalloc_node_track_caller kmalloc_node
-
-#endif /* CONFIG_SLOB */
+#endif /* DEBUG_SLAB */
 
 #endif /* __KERNEL__ */
-
 #endif /* _LINUX_SLAB_H */
+
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
new file mode 100644 (file)
index 0000000..4b463e6
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef _LINUX_SLAB_DEF_H
+#define        _LINUX_SLAB_DEF_H
+
+/*
+ * Definitions unique to the original Linux SLAB allocator.
+ *
+ * What we provide here is a way to optimize the frequent kmalloc
+ * calls in the kernel by selecting the appropriate general cache
+ * if kmalloc was called with a size that can be established at
+ * compile time.
+ */
+
+#include <linux/init.h>
+#include <asm/page.h>          /* kmalloc_sizes.h needs PAGE_SIZE */
+#include <asm/cache.h>         /* kmalloc_sizes.h needs L1_CACHE_BYTES */
+#include <linux/compiler.h>
+
+/* Size description struct for general caches. */
+struct cache_sizes {
+       size_t                  cs_size;
+       struct kmem_cache       *cs_cachep;
+       struct kmem_cache       *cs_dmacachep;
+};
+extern struct cache_sizes malloc_sizes[];
+
+static inline void *kmalloc(size_t size, gfp_t flags)
+{
+       if (__builtin_constant_p(size)) {
+               int i = 0;
+#define CACHE(x) \
+               if (size <= x) \
+                       goto found; \
+               else \
+                       i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+               {
+                       extern void __you_cannot_kmalloc_that_much(void);
+                       __you_cannot_kmalloc_that_much();
+               }
+found:
+               return kmem_cache_alloc((flags & GFP_DMA) ?
+                       malloc_sizes[i].cs_dmacachep :
+                       malloc_sizes[i].cs_cachep, flags);
+       }
+       return __kmalloc(size, flags);
+}
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+       if (__builtin_constant_p(size)) {
+               int i = 0;
+#define CACHE(x) \
+               if (size <= x) \
+                       goto found; \
+               else \
+                       i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+               {
+                       extern void __you_cannot_kzalloc_that_much(void);
+                       __you_cannot_kzalloc_that_much();
+               }
+found:
+               return kmem_cache_zalloc((flags & GFP_DMA) ?
+                       malloc_sizes[i].cs_dmacachep :
+                       malloc_sizes[i].cs_cachep, flags);
+       }
+       return __kzalloc(size, flags);
+}
+
+#ifdef CONFIG_NUMA
+extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
+
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+       if (__builtin_constant_p(size)) {
+               int i = 0;
+#define CACHE(x) \
+               if (size <= x) \
+                       goto found; \
+               else \
+                       i++;
+#include "kmalloc_sizes.h"
+#undef CACHE
+               {
+                       extern void __you_cannot_kmalloc_that_much(void);
+                       __you_cannot_kmalloc_that_much();
+               }
+found:
+               return kmem_cache_alloc_node((flags & GFP_DMA) ?
+                       malloc_sizes[i].cs_dmacachep :
+                       malloc_sizes[i].cs_cachep, flags, node);
+       }
+       return __kmalloc_node(size, flags, node);
+}
+
+#endif /* CONFIG_NUMA */
+
+#endif /* _LINUX_SLAB_DEF_H */
index 5b4ae2cc445c0a740bc8a4ece188eb9770a3dfe6..3aa97aa4277f3905467db75021bda4892033969e 100644 (file)
@@ -55,7 +55,7 @@ struct smb_sb_info {
         * generation is incremented.
         */
        unsigned int generation;
-       pid_t conn_pid;
+       struct pid *conn_pid;
        struct smb_conn_opt opt;
        wait_queue_head_t conn_wq;
        int conn_complete;
index 9df8833670cbc9b4f01b3b622bc1074f40020d8e..98a1d8cfb73d1902d7f55466bc9aa034e8436b2b 100644 (file)
@@ -37,23 +37,37 @@ struct sysrq_key_op {
 
 #ifdef CONFIG_MAGIC_SYSRQ
 
+extern int sysrq_on(void);
+
+/*
+ * Do not use this one directly:
+ */
+extern int __sysrq_enabled;
+
 /* Generic SysRq interface -- you may call it from any device driver, supplying
  * ASCII code of the key, pointer to registers and kbd/tty structs (if they
  * are available -- else NULL's).
  */
 
-void handle_sysrq(int, struct tty_struct *);
-void __handle_sysrq(int, struct tty_struct *, int check_mask);
-int register_sysrq_key(int, struct sysrq_key_op *);
-int unregister_sysrq_key(int, struct sysrq_key_op *);
+void handle_sysrq(int key, struct tty_struct *tty);
+void __handle_sysrq(int key, struct tty_struct *tty, int check_mask);
+int register_sysrq_key(int key, struct sysrq_key_op *op);
+int unregister_sysrq_key(int key, struct sysrq_key_op *op);
 struct sysrq_key_op *__sysrq_get_key_op(int key);
 
 #else
 
+static inline int sysrq_on(void)
+{
+       return 0;
+}
 static inline int __reterr(void)
 {
        return -EINVAL;
 }
+static inline void handle_sysrq(int key, struct tty_struct *tty)
+{
+}
 
 #define register_sysrq_key(ig,nore) __reterr()
 #define unregister_sysrq_key(ig,nore) __reterr()
index 10a3eec191fd2bf6110fbd0b4dadaa6fbdf2af8a..41456c148842d92bf2e0fdc0e0ca73fc774db63f 100644 (file)
@@ -739,13 +739,13 @@ struct sockaddr_hci {
 struct hci_filter {
        unsigned long type_mask;
        unsigned long event_mask[2];
-       __u16   opcode;
+       __le16   opcode;
 };
 
 struct hci_ufilter {
        __u32   type_mask;
        __u32   event_mask[2];
-       __u16   opcode;
+       __le16   opcode;
 };
 
 #define HCI_FLT_TYPE_BITS      31
index 5dbf5e7e50a8c1c659261b796f7985150e6e9637..baa163f770abd7ceba1d7aa273b8b5450bd4916d 100644 (file)
 #define BACKPORCH              0x0208
 #define VIDEODIMENSIONS                0x020c
 #define FBIINIT0               0x0210          /* misc+fifo  controls */
-#  define EN_VGA_PASSTHROUGH     BIT(0)
+#  define DIS_VGA_PASSTHROUGH    BIT(0)
 #  define FBI_RESET              BIT(1)
 #  define FIFO_RESET             BIT(2)
 #define FBIINIT1               0x0214          /* PCI + video controls */
 #  define DACREG_ICS_CLK1_A      0     /* bit4 */
 
 /* sst default init registers */
-#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+#define FBIINIT0_DEFAULT DIS_VGA_PASSTHROUGH
 
 #define FBIINIT1_DEFAULT       \
        (                       \
  *
  */
 
+/* ioctl to enable/disable VGA passthrough */
+#define SSTFB_SET_VGAPASS      _IOW('F', 0xdd, __u32)
+#define SSTFB_GET_VGAPASS      _IOR('F', 0xdd, __u32)
+
+
 /* used to know witch clock to set */
 enum {
        VID_CLOCK=0,
@@ -317,7 +322,7 @@ struct pll_timing {
 };
 
 struct dac_switch {
-       char * name;
+       const char *name;
        int (*detect) (struct fb_info *info);
        int (*set_pll) (struct fb_info *info, const struct pll_timing *t, const int clock);
        void (*set_vidmod) (struct fb_info *info, const int bpp);
@@ -345,7 +350,7 @@ struct sstfb_par {
        struct pci_dev          *dev;
        int     type;
        u8      revision;
-       int     gfx_clock;      /* status */
+       u8      vgapass;        /* VGA pass through: 1=enabled, 0=disabled */
 };
 
 #endif /* _SSTFB_H_ */
index 0992616eeed6fee540337d595800667db4bf838d..c82c215693d7c9c54ae93dfa90d7f162085900d5 100644 (file)
@@ -36,7 +36,7 @@ struct msg_msg *load_msg(const void __user *src, int len)
        if (alen > DATALEN_MSG)
                alen = DATALEN_MSG;
 
-       msg = (struct msg_msg *)kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
+       msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
        if (msg == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -56,7 +56,7 @@ struct msg_msg *load_msg(const void __user *src, int len)
                alen = len;
                if (alen > DATALEN_SEG)
                        alen = DATALEN_SEG;
-               seg = (struct msg_msgseg *)kmalloc(sizeof(*seg) + alen,
+               seg = kmalloc(sizeof(*seg) + alen,
                                                 GFP_KERNEL);
                if (seg == NULL) {
                        err = -ENOMEM;
index 2c3b4431472bec305dc41dec0c180c23d009ad58..232aed2b10f9a403346cc6e4a425c4ed8613a4d1 100644 (file)
@@ -2342,32 +2342,48 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
 }
 
 /**
- * cpuset_zone_allowed - Can we allocate memory on zone z's memory node?
+ * cpuset_zone_allowed_softwall - Can we allocate on zone z's memory node?
  * @z: is this zone on an allowed node?
- * @gfp_mask: memory allocation flags (we use __GFP_HARDWALL)
+ * @gfp_mask: memory allocation flags
  *
- * If we're in interrupt, yes, we can always allocate.  If zone
+ * If we're in interrupt, yes, we can always allocate.  If
+ * __GFP_THISNODE is set, yes, we can always allocate.  If zone
  * z's node is in our tasks mems_allowed, yes.  If it's not a
  * __GFP_HARDWALL request and this zone's nodes is in the nearest
  * mem_exclusive cpuset ancestor to this tasks cpuset, yes.
  * Otherwise, no.
  *
+ * If __GFP_HARDWALL is set, cpuset_zone_allowed_softwall()
+ * reduces to cpuset_zone_allowed_hardwall().  Otherwise,
+ * cpuset_zone_allowed_softwall() might sleep, and might allow a zone
+ * from an enclosing cpuset.
+ *
+ * cpuset_zone_allowed_hardwall() only handles the simpler case of
+ * hardwall cpusets, and never sleeps.
+ *
+ * The __GFP_THISNODE placement logic is really handled elsewhere,
+ * by forcibly using a zonelist starting at a specified node, and by
+ * (in get_page_from_freelist()) refusing to consider the zones for
+ * any node on the zonelist except the first.  By the time any such
+ * calls get to this routine, we should just shut up and say 'yes'.
+ *
  * GFP_USER allocations are marked with the __GFP_HARDWALL bit,
  * and do not allow allocations outside the current tasks cpuset.
  * GFP_KERNEL allocations are not so marked, so can escape to the
- * nearest mem_exclusive ancestor cpuset.
+ * nearest enclosing mem_exclusive ancestor cpuset.
  *
- * Scanning up parent cpusets requires callback_mutex.  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 callback_mutex mutex.
+ * Scanning up parent cpusets requires callback_mutex.  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 callback_mutex
+ * mutex.
  *
  * The first call here from mm/page_alloc:get_page_from_freelist()
- * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, so
- * no allocation on a node outside the cpuset is allowed (unless in
- * interrupt, of course).
+ * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets,
+ * so no allocation on a node outside the cpuset is allowed (unless
+ * in interrupt, of course).
  *
  * The second pass through get_page_from_freelist() doesn't even call
  * here for GFP_ATOMIC calls.  For those calls, the __alloc_pages()
@@ -2380,12 +2396,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
  *     GFP_USER     - only nodes in current tasks mems allowed ok.
  *
  * Rule:
- *    Don't call cpuset_zone_allowed() if you can't sleep, unless you
+ *    Don't call cpuset_zone_allowed_softwall if you can't sleep, unless you
  *    pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
  *    the code that might scan up ancestor cpusets and sleep.
- **/
+ */
 
-int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
 {
        int node;                       /* node that zone z is on */
        const struct cpuset *cs;        /* current cpuset ancestors */
@@ -2415,6 +2431,40 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
        return allowed;
 }
 
+/*
+ * cpuset_zone_allowed_hardwall - Can we allocate on zone z's memory node?
+ * @z: is this zone on an allowed node?
+ * @gfp_mask: memory allocation flags
+ *
+ * If we're in interrupt, yes, we can always allocate.
+ * If __GFP_THISNODE is set, yes, we can always allocate.  If zone
+ * z's node is in our tasks mems_allowed, yes.   Otherwise, no.
+ *
+ * The __GFP_THISNODE placement logic is really handled elsewhere,
+ * by forcibly using a zonelist starting at a specified node, and by
+ * (in get_page_from_freelist()) refusing to consider the zones for
+ * any node on the zonelist except the first.  By the time any such
+ * calls get to this routine, we should just shut up and say 'yes'.
+ *
+ * Unlike the cpuset_zone_allowed_softwall() variant, above,
+ * this variant requires that the zone be in the current tasks
+ * mems_allowed or that we're in interrupt.  It does not scan up the
+ * cpuset hierarchy for the nearest enclosing mem_exclusive cpuset.
+ * It never sleeps.
+ */
+
+int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
+{
+       int node;                       /* node that zone z is on */
+
+       if (in_interrupt() || (gfp_mask & __GFP_THISNODE))
+               return 1;
+       node = zone_to_nid(z);
+       if (node_isset(node, current->mems_allowed))
+               return 1;
+       return 0;
+}
+
 /**
  * cpuset_lock - lock out any changes to cpuset structures
  *
index d16c566eb645a6b7aae1bd7dd5a5489eeb3d3db9..fc723e595cd5ba2c95499ba058636005dd9946e3 100644 (file)
@@ -203,7 +203,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
        struct mempolicy *pol;
 
        down_write(&oldmm->mmap_sem);
-       flush_cache_mm(oldmm);
+       flush_cache_dup_mm(oldmm);
        /*
         * Not linked in yet - no deadlock potential:
         */
index b02032476dc2e88967940060a84b5bc5742f1a5e..01e75055903435d1d6ce452f8bbc7a8931e20cff 100644 (file)
 #include "lockdep_internals.h"
 
 /*
- * hash_lock: protects the lockdep hashes and class/list/hash allocators.
+ * lockdep_lock: protects the lockdep graph, the hashes and the
+ *               class/list/hash allocators.
  *
  * This is one of the rare exceptions where it's justified
  * to use a raw spinlock - we really dont want the spinlock
- * code to recurse back into the lockdep code.
+ * code to recurse back into the lockdep code...
  */
-static raw_spinlock_t hash_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+static raw_spinlock_t lockdep_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+static int graph_lock(void)
+{
+       __raw_spin_lock(&lockdep_lock);
+       /*
+        * Make sure that if another CPU detected a bug while
+        * walking the graph we dont change it (while the other
+        * CPU is busy printing out stuff with the graph lock
+        * dropped already)
+        */
+       if (!debug_locks) {
+               __raw_spin_unlock(&lockdep_lock);
+               return 0;
+       }
+       return 1;
+}
+
+static inline int graph_unlock(void)
+{
+       __raw_spin_unlock(&lockdep_lock);
+       return 0;
+}
+
+/*
+ * Turn lock debugging off and return with 0 if it was off already,
+ * and also release the graph lock:
+ */
+static inline int debug_locks_off_graph_unlock(void)
+{
+       int ret = debug_locks_off();
+
+       __raw_spin_unlock(&lockdep_lock);
+
+       return ret;
+}
 
 static int lockdep_initialized;
 
@@ -57,14 +93,15 @@ unsigned long nr_list_entries;
 static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
 
 /*
- * Allocate a lockdep entry. (assumes hash_lock held, returns
+ * Allocate a lockdep entry. (assumes the graph_lock held, returns
  * with NULL on failure)
  */
 static struct lock_list *alloc_list_entry(void)
 {
        if (nr_list_entries >= MAX_LOCKDEP_ENTRIES) {
-               __raw_spin_unlock(&hash_lock);
-               debug_locks_off();
+               if (!debug_locks_off_graph_unlock())
+                       return NULL;
+
                printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n");
                printk("turning off the locking correctness validator.\n");
                return NULL;
@@ -145,9 +182,7 @@ EXPORT_SYMBOL(lockdep_on);
  */
 
 #define VERBOSE                        0
-#ifdef VERBOSE
-# define VERY_VERBOSE          0
-#endif
+#define VERY_VERBOSE           0
 
 #if VERBOSE
 # define HARDIRQ_VERBOSE       1
@@ -172,8 +207,8 @@ static int class_filter(struct lock_class *class)
                        !strcmp(class->name, "&struct->lockfield"))
                return 1;
 #endif
-       /* Allow everything else. 0 would be filter everything else */
-       return 1;
+       /* Filter everything else. 1 would be to allow everything else */
+       return 0;
 }
 #endif
 
@@ -207,7 +242,7 @@ static int softirq_verbose(struct lock_class *class)
 
 /*
  * Stack-trace: tightly packed array of stack backtrace
- * addresses. Protected by the hash_lock.
+ * addresses. Protected by the graph_lock.
  */
 unsigned long nr_stack_trace_entries;
 static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES];
@@ -226,18 +261,15 @@ static int save_trace(struct stack_trace *trace)
        trace->max_entries = trace->nr_entries;
 
        nr_stack_trace_entries += trace->nr_entries;
-       if (DEBUG_LOCKS_WARN_ON(nr_stack_trace_entries > MAX_STACK_TRACE_ENTRIES)) {
-               __raw_spin_unlock(&hash_lock);
-               return 0;
-       }
 
        if (nr_stack_trace_entries == MAX_STACK_TRACE_ENTRIES) {
-               __raw_spin_unlock(&hash_lock);
-               if (debug_locks_off()) {
-                       printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
-                       printk("turning off the locking correctness validator.\n");
-                       dump_stack();
-               }
+               if (!debug_locks_off_graph_unlock())
+                       return 0;
+
+               printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
+               printk("turning off the locking correctness validator.\n");
+               dump_stack();
+
                return 0;
        }
 
@@ -526,9 +558,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
 {
        struct task_struct *curr = current;
 
-       __raw_spin_unlock(&hash_lock);
-       debug_locks_off();
-       if (debug_locks_silent)
+       if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
        printk("\n=======================================================\n");
@@ -556,12 +586,10 @@ static noinline int print_circular_bug_tail(void)
        if (debug_locks_silent)
                return 0;
 
-       /* hash_lock unlocked by the header */
-       __raw_spin_lock(&hash_lock);
        this.class = check_source->class;
        if (!save_trace(&this.trace))
                return 0;
-       __raw_spin_unlock(&hash_lock);
+
        print_circular_bug_entry(&this, 0);
 
        printk("\nother info that might help us debug this:\n\n");
@@ -577,8 +605,10 @@ static noinline int print_circular_bug_tail(void)
 
 static int noinline print_infinite_recursion_bug(void)
 {
-       __raw_spin_unlock(&hash_lock);
-       DEBUG_LOCKS_WARN_ON(1);
+       if (!debug_locks_off_graph_unlock())
+               return 0;
+
+       WARN_ON(1);
 
        return 0;
 }
@@ -713,9 +743,7 @@ print_bad_irq_dependency(struct task_struct *curr,
                         enum lock_usage_bit bit2,
                         const char *irqclass)
 {
-       __raw_spin_unlock(&hash_lock);
-       debug_locks_off();
-       if (debug_locks_silent)
+       if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
        printk("\n======================================================\n");
@@ -796,9 +824,7 @@ static int
 print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
                   struct held_lock *next)
 {
-       debug_locks_off();
-       __raw_spin_unlock(&hash_lock);
-       if (debug_locks_silent)
+       if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
        printk("\n=============================================\n");
@@ -974,14 +1000,14 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
         * Debugging printouts:
         */
        if (verbose(prev->class) || verbose(next->class)) {
-               __raw_spin_unlock(&hash_lock);
+               graph_unlock();
                printk("\n new dependency: ");
                print_lock_name(prev->class);
                printk(" => ");
                print_lock_name(next->class);
                printk("\n");
                dump_stack();
-               __raw_spin_lock(&hash_lock);
+               return graph_lock();
        }
        return 1;
 }
@@ -1046,8 +1072,10 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
        }
        return 1;
 out_bug:
-       __raw_spin_unlock(&hash_lock);
-       DEBUG_LOCKS_WARN_ON(1);
+       if (!debug_locks_off_graph_unlock())
+               return 0;
+
+       WARN_ON(1);
 
        return 0;
 }
@@ -1201,7 +1229,10 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
        hash_head = classhashentry(key);
 
        raw_local_irq_save(flags);
-       __raw_spin_lock(&hash_lock);
+       if (!graph_lock()) {
+               raw_local_irq_restore(flags);
+               return NULL;
+       }
        /*
         * We have to do the hash-walk again, to avoid races
         * with another CPU:
@@ -1214,9 +1245,12 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
         * the hash:
         */
        if (nr_lock_classes >= MAX_LOCKDEP_KEYS) {
-               __raw_spin_unlock(&hash_lock);
+               if (!debug_locks_off_graph_unlock()) {
+                       raw_local_irq_restore(flags);
+                       return NULL;
+               }
                raw_local_irq_restore(flags);
-               debug_locks_off();
+
                printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
                printk("turning off the locking correctness validator.\n");
                return NULL;
@@ -1237,18 +1271,23 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
        list_add_tail_rcu(&class->hash_entry, hash_head);
 
        if (verbose(class)) {
-               __raw_spin_unlock(&hash_lock);
+               graph_unlock();
                raw_local_irq_restore(flags);
+
                printk("\nnew class %p: %s", class->key, class->name);
                if (class->name_version > 1)
                        printk("#%d", class->name_version);
                printk("\n");
                dump_stack();
+
                raw_local_irq_save(flags);
-               __raw_spin_lock(&hash_lock);
+               if (!graph_lock()) {
+                       raw_local_irq_restore(flags);
+                       return NULL;
+               }
        }
 out_unlock_set:
-       __raw_spin_unlock(&hash_lock);
+       graph_unlock();
        raw_local_irq_restore(flags);
 
        if (!subclass || force)
@@ -1264,7 +1303,7 @@ out_unlock_set:
  * add it and return 0 - in this case the new dependency chain is
  * validated. If the key is already hashed, return 1.
  */
-static inline int lookup_chain_cache(u64 chain_key)
+static inline int lookup_chain_cache(u64 chain_key, struct lock_class *class)
 {
        struct list_head *hash_head = chainhashentry(chain_key);
        struct lock_chain *chain;
@@ -1278,34 +1317,32 @@ static inline int lookup_chain_cache(u64 chain_key)
                if (chain->chain_key == chain_key) {
 cache_hit:
                        debug_atomic_inc(&chain_lookup_hits);
-                       /*
-                        * In the debugging case, force redundant checking
-                        * by returning 1:
-                        */
-#ifdef CONFIG_DEBUG_LOCKDEP
-                       __raw_spin_lock(&hash_lock);
-                       return 1;
-#endif
+                       if (very_verbose(class))
+                               printk("\nhash chain already cached, key: %016Lx tail class: [%p] %s\n", chain_key, class->key, class->name);
                        return 0;
                }
        }
+       if (very_verbose(class))
+               printk("\nnew hash chain, key: %016Lx tail class: [%p] %s\n", chain_key, class->key, class->name);
        /*
         * Allocate a new chain entry from the static array, and add
         * it to the hash:
         */
-       __raw_spin_lock(&hash_lock);
+       if (!graph_lock())
+               return 0;
        /*
         * We have to walk the chain again locked - to avoid duplicates:
         */
        list_for_each_entry(chain, hash_head, entry) {
                if (chain->chain_key == chain_key) {
-                       __raw_spin_unlock(&hash_lock);
+                       graph_unlock();
                        goto cache_hit;
                }
        }
        if (unlikely(nr_lock_chains >= MAX_LOCKDEP_CHAINS)) {
-               __raw_spin_unlock(&hash_lock);
-               debug_locks_off();
+               if (!debug_locks_off_graph_unlock())
+                       return 0;
+
                printk("BUG: MAX_LOCKDEP_CHAINS too low!\n");
                printk("turning off the locking correctness validator.\n");
                return 0;
@@ -1381,9 +1418,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
                        struct held_lock *this, int forwards,
                        const char *irqclass)
 {
-       __raw_spin_unlock(&hash_lock);
-       debug_locks_off();
-       if (debug_locks_silent)
+       if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
        printk("\n=========================================================\n");
@@ -1453,7 +1488,7 @@ check_usage_backwards(struct task_struct *curr, struct held_lock *this,
        return print_irq_inversion_bug(curr, backwards_match, this, 0, irqclass);
 }
 
-static inline void print_irqtrace_events(struct task_struct *curr)
+void print_irqtrace_events(struct task_struct *curr)
 {
        printk("irq event stamp: %u\n", curr->irq_events);
        printk("hardirqs last  enabled at (%u): ", curr->hardirq_enable_event);
@@ -1466,19 +1501,13 @@ static inline void print_irqtrace_events(struct task_struct *curr)
        print_ip_sym(curr->softirq_disable_ip);
 }
 
-#else
-static inline void print_irqtrace_events(struct task_struct *curr)
-{
-}
 #endif
 
 static int
 print_usage_bug(struct task_struct *curr, struct held_lock *this,
                enum lock_usage_bit prev_bit, enum lock_usage_bit new_bit)
 {
-       __raw_spin_unlock(&hash_lock);
-       debug_locks_off();
-       if (debug_locks_silent)
+       if (!debug_locks_off_graph_unlock() || debug_locks_silent)
                return 0;
 
        printk("\n=================================\n");
@@ -1539,12 +1568,13 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
        if (likely(this->class->usage_mask & new_mask))
                return 1;
 
-       __raw_spin_lock(&hash_lock);
+       if (!graph_lock())
+               return 0;
        /*
         * Make sure we didnt race:
         */
        if (unlikely(this->class->usage_mask & new_mask)) {
-               __raw_spin_unlock(&hash_lock);
+               graph_unlock();
                return 1;
        }
 
@@ -1730,16 +1760,16 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
                debug_atomic_dec(&nr_unused_locks);
                break;
        default:
-               __raw_spin_unlock(&hash_lock);
-               debug_locks_off();
+               if (!debug_locks_off_graph_unlock())
+                       return 0;
                WARN_ON(1);
                return 0;
        }
 
-       __raw_spin_unlock(&hash_lock);
+       graph_unlock();
 
        /*
-        * We must printk outside of the hash_lock:
+        * We must printk outside of the graph_lock:
         */
        if (ret == 2) {
                printk("\nmarked lock as {%s}:\n", usage_str[new_bit]);
@@ -2137,9 +2167,9 @@ out_calc_hash:
         * We look up the chain_key and do the O(N^2) check and update of
         * the dependencies only if this is a new dependency chain.
         * (If lookup_chain_cache() returns with 1 it acquires
-        * hash_lock for us)
+        * graph_lock for us)
         */
-       if (!trylock && (check == 2) && lookup_chain_cache(chain_key)) {
+       if (!trylock && (check == 2) && lookup_chain_cache(chain_key, class)) {
                /*
                 * Check whether last held lock:
                 *
@@ -2170,7 +2200,7 @@ out_calc_hash:
                if (!chain_head && ret != 2)
                        if (!check_prevs_add(curr, hlock))
                                return 0;
-               __raw_spin_unlock(&hash_lock);
+               graph_unlock();
        }
        curr->lockdep_depth++;
        check_chain_key(curr);
@@ -2433,6 +2463,7 @@ EXPORT_SYMBOL_GPL(lock_release);
 void lockdep_reset(void)
 {
        unsigned long flags;
+       int i;
 
        raw_local_irq_save(flags);
        current->curr_chain_key = 0;
@@ -2443,6 +2474,8 @@ void lockdep_reset(void)
        nr_softirq_chains = 0;
        nr_process_chains = 0;
        debug_locks = 1;
+       for (i = 0; i < CHAINHASH_SIZE; i++)
+               INIT_LIST_HEAD(chainhash_table + i);
        raw_local_irq_restore(flags);
 }
 
@@ -2479,7 +2512,7 @@ void lockdep_free_key_range(void *start, unsigned long size)
        int i;
 
        raw_local_irq_save(flags);
-       __raw_spin_lock(&hash_lock);
+       graph_lock();
 
        /*
         * Unhash all classes that were created by this module:
@@ -2493,7 +2526,7 @@ void lockdep_free_key_range(void *start, unsigned long size)
                                zap_class(class);
        }
 
-       __raw_spin_unlock(&hash_lock);
+       graph_unlock();
        raw_local_irq_restore(flags);
 }
 
@@ -2521,20 +2554,20 @@ void lockdep_reset_lock(struct lockdep_map *lock)
         * Debug check: in the end all mapped classes should
         * be gone.
         */
-       __raw_spin_lock(&hash_lock);
+       graph_lock();
        for (i = 0; i < CLASSHASH_SIZE; i++) {
                head = classhash_table + i;
                if (list_empty(head))
                        continue;
                list_for_each_entry_safe(class, next, head, hash_entry) {
                        if (unlikely(class == lock->class_cache)) {
-                               __raw_spin_unlock(&hash_lock);
-                               DEBUG_LOCKS_WARN_ON(1);
+                               if (debug_locks_off_graph_unlock())
+                                       WARN_ON(1);
                                goto out_restore;
                        }
                }
        }
-       __raw_spin_unlock(&hash_lock);
+       graph_unlock();
 
 out_restore:
        raw_local_irq_restore(flags);
index d9eae45d0145a077d6b32d2b29156f9d3b18bfdd..b565eaeff7e6d73ffcd94d6f531ed3df8fd1b041 100644 (file)
@@ -824,9 +824,34 @@ static inline void module_unload_init(struct module *mod)
 }
 #endif /* CONFIG_MODULE_UNLOAD */
 
+static ssize_t show_initstate(struct module_attribute *mattr,
+                          struct module *mod, char *buffer)
+{
+       const char *state = "unknown";
+
+       switch (mod->state) {
+       case MODULE_STATE_LIVE:
+               state = "live";
+               break;
+       case MODULE_STATE_COMING:
+               state = "coming";
+               break;
+       case MODULE_STATE_GOING:
+               state = "going";
+               break;
+       }
+       return sprintf(buffer, "%s\n", state);
+}
+
+static struct module_attribute initstate = {
+       .attr = { .name = "initstate", .mode = 0444, .owner = THIS_MODULE },
+       .show = show_initstate,
+};
+
 static struct module_attribute *modinfo_attrs[] = {
        &modinfo_version,
        &modinfo_srcversion,
+       &initstate,
 #ifdef CONFIG_MODULE_UNLOAD
        &refcnt,
 #endif
index e2ce748e96afaca08cf0e5b2821d4cf6e8cab823..f5b9ee6f6bbb02733cef1e64fabe4dc521efc767 100644 (file)
@@ -46,10 +46,8 @@ static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
        struct nsproxy *ns;
 
        ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
-       if (ns) {
+       if (ns)
                atomic_set(&ns->count, 1);
-               ns->id = -1;
-       }
        return ns;
 }
 
index 710ed084e7c5667b96da2362f67025fb8e521d50..ed296225dcd4a66119d6785d64ddd488cc77f24c 100644 (file)
@@ -20,13 +20,14 @@ config PM
          sending the processor to sleep and saving power.
 
 config PM_LEGACY
-       bool "Legacy Power Management API"
+       bool "Legacy Power Management API (DEPRECATED)"
        depends on PM
-       default y
+       default n
        ---help---
-          Support for pm_register() and friends.
+          Support for pm_register() and friends.  This old API is obsoleted
+          by the driver model.
 
-          If unsure, say Y.
+          If unsure, say N.
 
 config PM_DEBUG
        bool "Power Management Debug Support"
index 99eeb119b06db1d350d04de044fdb624f4627a19..6d566bf7085c0b4fd7803a14cbaabef07269198e 100644 (file)
@@ -28,8 +28,7 @@ static inline int freezeable(struct task_struct * p)
        if ((p == current) || 
            (p->flags & PF_NOFREEZE) ||
            (p->exit_state == EXIT_ZOMBIE) ||
-           (p->exit_state == EXIT_DEAD) ||
-           (p->state == TASK_STOPPED))
+           (p->exit_state == EXIT_DEAD))
                return 0;
        return 1;
 }
@@ -61,10 +60,16 @@ static inline void freeze_process(struct task_struct *p)
        unsigned long flags;
 
        if (!freezing(p)) {
-               freeze(p);
-               spin_lock_irqsave(&p->sighand->siglock, flags);
-               signal_wake_up(p, 0);
-               spin_unlock_irqrestore(&p->sighand->siglock, flags);
+               rmb();
+               if (!frozen(p)) {
+                       if (p->state == TASK_STOPPED)
+                               force_sig_specific(SIGSTOP, p);
+
+                       freeze(p);
+                       spin_lock_irqsave(&p->sighand->siglock, flags);
+                       signal_wake_up(p, p->state == TASK_STOPPED);
+                       spin_unlock_irqrestore(&p->sighand->siglock, flags);
+               }
        }
 }
 
@@ -103,9 +108,7 @@ static unsigned int try_to_freeze_tasks(int freeze_user_space)
                        if (frozen(p))
                                continue;
 
-                       if (p->state == TASK_TRACED &&
-                           (frozen(p->parent) ||
-                            p->parent->state == TASK_STOPPED)) {
+                       if (p->state == TASK_TRACED && frozen(p->parent)) {
                                cancel_freezing(p);
                                continue;
                        }
index 818e514729cf0f033d4b5bc98cfd7570a8879ce2..a4701e7ba7d0967195ac6397a37729205e1cb97d 100644 (file)
@@ -138,7 +138,7 @@ depopulate:
  */
 struct rchan_buf *relay_create_buf(struct rchan *chan)
 {
-       struct rchan_buf *buf = kcalloc(1, sizeof(struct rchan_buf), GFP_KERNEL);
+       struct rchan_buf *buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
        if (!buf)
                return NULL;
 
@@ -479,7 +479,7 @@ struct rchan *relay_open(const char *base_filename,
        if (!(subbuf_size && n_subbufs))
                return NULL;
 
-       chan = kcalloc(1, sizeof(struct rchan), GFP_KERNEL);
+       chan = kzalloc(sizeof(struct rchan), GFP_KERNEL);
        if (!chan)
                return NULL;
 
index 8a0afb97af71c99f14a01f7974a88886fd7d8f08..5cd833bc217367add6a2b07feaf923cab5c8d801 100644 (file)
@@ -3429,6 +3429,8 @@ asmlinkage void __sched schedule(void)
                        "%s/0x%08x/%d\n",
                        current->comm, preempt_count(), current->pid);
                debug_show_held_locks(current);
+               if (irqs_disabled())
+                       print_irqtrace_events(current);
                dump_stack();
        }
        profile_hit(SCHED_PROFILING, __builtin_return_address(0));
@@ -6977,6 +6979,8 @@ void __might_sleep(char *file, int line)
                printk("in_atomic():%d, irqs_disabled():%d\n",
                        in_atomic(), irqs_disabled());
                debug_show_held_locks(current);
+               if (irqs_disabled())
+                       print_irqtrace_events(current);
                dump_stack();
        }
 #endif
index 1921ffdc5e777eee98081639ff6960b9baf49010..5630255d2e2a958f6e58eea4596a62b0dea3f91a 100644 (file)
@@ -1705,7 +1705,9 @@ finish_stop(int stop_count)
                read_unlock(&tasklist_lock);
        }
 
-       schedule();
+       do {
+               schedule();
+       } while (try_to_freeze());
        /*
         * Now we don't run again until continued.
         */
index 130c5ec9ee0b3f699c3da72617db844154ce5910..600b33358ded97ea54e90b6cc39dafef8e03fa40 100644 (file)
@@ -65,7 +65,6 @@ extern int sysctl_overcommit_memory;
 extern int sysctl_overcommit_ratio;
 extern int sysctl_panic_on_oom;
 extern int max_threads;
-extern int sysrq_enabled;
 extern int core_uses_pid;
 extern int suid_dumpable;
 extern char core_pattern[];
@@ -543,7 +542,7 @@ static ctl_table kern_table[] = {
        {
                .ctl_name       = KERN_SYSRQ,
                .procname       = "sysrq",
-               .data           = &sysrq_enabled,
+               .data           = &__sysrq_enabled,
                .maxlen         = sizeof (int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
index 0256ab443d8a36445f2ab755b08503c2e28cdd9c..feddf817baa57f1180a01db876e2a4d17752daf0 100644 (file)
@@ -1146,11 +1146,15 @@ static inline void calc_load(unsigned long ticks)
        unsigned long active_tasks; /* fixed-point */
        static int count = LOAD_FREQ;
 
-       active_tasks = count_active_tasks();
-       for (count -= ticks; count < 0; count += LOAD_FREQ) {
-               CALC_LOAD(avenrun[0], EXP_1, active_tasks);
-               CALC_LOAD(avenrun[1], EXP_5, active_tasks);
-               CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+       count -= ticks;
+       if (unlikely(count < 0)) {
+               active_tasks = count_active_tasks();
+               do {
+                       CALC_LOAD(avenrun[0], EXP_1, active_tasks);
+                       CALC_LOAD(avenrun[1], EXP_5, active_tasks);
+                       CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+                       count += LOAD_FREQ;
+               } while (count < 0);
        }
 }
 
index 47b172df3e312775f4accaa804fd42256d5331f7..9b03581cdecb3d746186e1c0fa1ab2685cdbcfcc 100644 (file)
@@ -101,4 +101,9 @@ config TEXTSEARCH_FSM
 config PLIST
        boolean
 
+config IOMAP_COPY
+       boolean
+       depends on !UML
+       default y
+
 endmenu
index 2d6106af53cdf88773e2798a2c90cad0cb6cee53..77b4bad7d441be4185001773a14ebf71aae06d32 100644 (file)
@@ -5,20 +5,21 @@
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
         bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
         idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
-        sha1.o irq_regs.o
+        sha1.o irq_regs.o reciprocal_div.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
 
 lib-y  += kobject.o kref.o kobject_uevent.o klist.o
 
-obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o random32.o
+obj-y += sort.o parser.o halfmd4.o debug_locks.o random32.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
 CFLAGS_kobject_uevent.o += -DDEBUG
 endif
 
+obj-$(CONFIG_IOMAP_COPY) += iomap_copy.o
 obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
 obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
index 99fa277f9f7b7345d7394ba0d5185c7acc815486..a9e4415b02dcca58a5fbdf4d8c81b9821356c714 100644 (file)
@@ -5,7 +5,6 @@
  *
  * (C) Copyright 1995 1996 Linus Torvalds
  */
-#include <linux/io.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 
diff --git a/lib/reciprocal_div.c b/lib/reciprocal_div.c
new file mode 100644 (file)
index 0000000..6a3bd48
--- /dev/null
@@ -0,0 +1,9 @@
+#include <asm/div64.h>
+#include <linux/reciprocal_div.h>
+
+u32 reciprocal_value(u32 k)
+{
+       u64 val = (1LL << 32) + (k - 1);
+       do_div(val, k);
+       return (u32)val;
+}
index 0ccc7f2302529b0e3a237c556f895ab4ddfb3911..cb362f761f174b926c1c41b72ec2940c5d45763d 100644 (file)
@@ -44,14 +44,14 @@ static void clear_huge_page(struct page *page, unsigned long addr)
 }
 
 static void copy_huge_page(struct page *dst, struct page *src,
-                          unsigned long addr)
+                          unsigned long addr, struct vm_area_struct *vma)
 {
        int i;
 
        might_sleep();
        for (i = 0; i < HPAGE_SIZE/PAGE_SIZE; i++) {
                cond_resched();
-               copy_user_highpage(dst + i, src + i, addr + i*PAGE_SIZE);
+               copy_user_highpage(dst + i, src + i, addr + i*PAGE_SIZE, vma);
        }
 }
 
@@ -73,7 +73,7 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
 
        for (z = zonelist->zones; *z; z++) {
                nid = zone_to_nid(*z);
-               if (cpuset_zone_allowed(*z, GFP_HIGHUSER) &&
+               if (cpuset_zone_allowed_softwall(*z, GFP_HIGHUSER) &&
                    !list_empty(&hugepage_freelists[nid]))
                        break;
        }
@@ -442,7 +442,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
        }
 
        spin_unlock(&mm->page_table_lock);
-       copy_huge_page(new_page, old_page, address);
+       copy_huge_page(new_page, old_page, address, vma);
        spin_lock(&mm->page_table_lock);
 
        ptep = huge_pte_offset(mm, address & HPAGE_MASK);
index bf6100236e6270336651229acbb2056021a68991..c00bac66ce9f2af4a651205c579b8b528565740f 100644 (file)
@@ -1441,7 +1441,7 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
        return pte;
 }
 
-static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va)
+static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va, struct vm_area_struct *vma)
 {
        /*
         * If the source page was a PFN mapping, we don't have
@@ -1464,9 +1464,9 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
                kunmap_atomic(kaddr, KM_USER0);
                flush_dcache_page(dst);
                return;
-               
+
        }
-       copy_user_highpage(dst, src, va);
+       copy_user_highpage(dst, src, va, vma);
 }
 
 /*
@@ -1577,7 +1577,7 @@ gotten:
                new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
                if (!new_page)
                        goto oom;
-               cow_user_page(new_page, old_page, address);
+               cow_user_page(new_page, old_page, address, vma);
        }
 
        /*
@@ -2200,7 +2200,7 @@ retry:
                        page = alloc_page_vma(GFP_HIGHUSER, vma, address);
                        if (!page)
                                goto oom;
-                       copy_user_highpage(page, new_page, address);
+                       copy_user_highpage(page, new_page, address, vma);
                        page_cache_release(new_page);
                        new_page = page;
                        anon = 1;
index 223d9ccb7d64b6b28f5642ba3ab12629a170419a..64cf3c2146348b0e1cba3fd98d64354bcb466c4a 100644 (file)
@@ -177,7 +177,7 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask)
        nodemask_t nodes = node_online_map;
 
        for (z = zonelist->zones; *z; z++)
-               if (cpuset_zone_allowed(*z, gfp_mask))
+               if (cpuset_zone_allowed_softwall(*z, gfp_mask))
                        node_clear(zone_to_nid(*z), nodes);
                else
                        return CONSTRAINT_CPUSET;
index e6b17b2989e099636dcb1ec64587f130b8ad27c0..8c1a116875bc71d520069686dcb2483a79659604 100644 (file)
@@ -1162,7 +1162,7 @@ zonelist_scan:
                        zone->zone_pgdat != zonelist->zones[0]->zone_pgdat))
                                break;
                if ((alloc_flags & ALLOC_CPUSET) &&
-                       !cpuset_zone_allowed(zone, gfp_mask))
+                       !cpuset_zone_allowed_softwall(zone, gfp_mask))
                                goto try_next_zone;
 
                if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
index 2c655532f5efcefac182e20cd2bb325decb92407..909975f6e0903f4a4f065ded0f109a338193173f 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
 #include       <linux/mutex.h>
 #include       <linux/fault-inject.h>
 #include       <linux/rtmutex.h>
+#include       <linux/reciprocal_div.h>
 
 #include       <asm/cacheflush.h>
 #include       <asm/tlbflush.h>
@@ -386,6 +387,7 @@ struct kmem_cache {
        unsigned int shared;
 
        unsigned int buffer_size;
+       u32 reciprocal_buffer_size;
 /* 3) touched by every alloc & free from the backend */
        struct kmem_list3 *nodelists[MAX_NUMNODES];
 
@@ -627,10 +629,17 @@ static inline void *index_to_obj(struct kmem_cache *cache, struct slab *slab,
        return slab->s_mem + cache->buffer_size * idx;
 }
 
-static inline unsigned int obj_to_index(struct kmem_cache *cache,
-                                       struct slab *slab, void *obj)
+/*
+ * We want to avoid an expensive divide : (offset / cache->buffer_size)
+ *   Using the fact that buffer_size is a constant for a particular cache,
+ *   we can replace (offset / cache->buffer_size) by
+ *   reciprocal_divide(offset, cache->reciprocal_buffer_size)
+ */
+static inline unsigned int obj_to_index(const struct kmem_cache *cache,
+                                       const struct slab *slab, void *obj)
 {
-       return (unsigned)(obj - slab->s_mem) / cache->buffer_size;
+       u32 offset = (obj - slab->s_mem);
+       return reciprocal_divide(offset, cache->reciprocal_buffer_size);
 }
 
 /*
@@ -1427,6 +1436,8 @@ void __init kmem_cache_init(void)
 
        cache_cache.buffer_size = ALIGN(cache_cache.buffer_size,
                                        cache_line_size());
+       cache_cache.reciprocal_buffer_size =
+               reciprocal_value(cache_cache.buffer_size);
 
        for (order = 0; order < MAX_ORDER; order++) {
                cache_estimate(order, cache_cache.buffer_size,
@@ -2313,6 +2324,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        if (flags & SLAB_CACHE_DMA)
                cachep->gfpflags |= GFP_DMA;
        cachep->buffer_size = size;
+       cachep->reciprocal_buffer_size = reciprocal_value(size);
 
        if (flags & CFLGS_OFF_SLAB) {
                cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
@@ -3252,6 +3264,7 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
        struct zone **z;
        void *obj = NULL;
        int nid;
+       gfp_t local_flags = (flags & GFP_LEVEL_MASK);
 
 retry:
        /*
@@ -3261,7 +3274,7 @@ retry:
        for (z = zonelist->zones; *z && !obj; z++) {
                nid = zone_to_nid(*z);
 
-               if (cpuset_zone_allowed(*z, flags | __GFP_HARDWALL) &&
+               if (cpuset_zone_allowed_hardwall(*z, flags) &&
                        cache->nodelists[nid] &&
                        cache->nodelists[nid]->free_objects)
                                obj = ____cache_alloc_node(cache,
@@ -3275,7 +3288,12 @@ retry:
                 * We may trigger various forms of reclaim on the allowed
                 * set and go into memory reserves if necessary.
                 */
+               if (local_flags & __GFP_WAIT)
+                       local_irq_enable();
+               kmem_flagcheck(cache, flags);
                obj = kmem_getpages(cache, flags, -1);
+               if (local_flags & __GFP_WAIT)
+                       local_irq_disable();
                if (obj) {
                        /*
                         * Insert into the appropriate per node queues
@@ -3535,7 +3553,7 @@ EXPORT_SYMBOL(kmem_cache_zalloc);
  *
  * Currently only used for dentry validation.
  */
-int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)
+int fastcall kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 {
        unsigned long addr = (unsigned long)ptr;
        unsigned long min_addr = PAGE_OFFSET;
index 542394184a58e6c825a3b24cc7dfe1ad0e6e4fba..2e9236e10ed12bc0ac7f1a67261d0de3abd634e4 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -157,7 +157,7 @@ static int fastcall find_order(int size)
        return order;
 }
 
-void *kmalloc(size_t size, gfp_t gfp)
+void *__kmalloc(size_t size, gfp_t gfp)
 {
        slob_t *m;
        bigblock_t *bb;
@@ -186,8 +186,7 @@ void *kmalloc(size_t size, gfp_t gfp)
        slob_free(bb, sizeof(bigblock_t));
        return 0;
 }
-
-EXPORT_SYMBOL(kmalloc);
+EXPORT_SYMBOL(__kmalloc);
 
 void kfree(const void *block)
 {
@@ -329,6 +328,17 @@ EXPORT_SYMBOL(kmem_cache_name);
 static struct timer_list slob_timer = TIMER_INITIALIZER(
        (void (*)(unsigned long))kmem_cache_init, 0, 0);
 
+int kmem_cache_shrink(struct kmem_cache *d)
+{
+       return 0;
+}
+EXPORT_SYMBOL(kmem_cache_shrink);
+
+int kmem_ptr_validate(struct kmem_cache *a, const void *b)
+{
+       return 0;
+}
+
 void kmem_cache_init(void)
 {
        void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);
index 093f5fe6dd7795cc5d0ca15f5918eedc822b87f4..e9813b06c7a32f2be3b534722c521457a384e028 100644 (file)
@@ -984,7 +984,7 @@ static unsigned long shrink_zones(int priority, struct zone **zones,
                if (!populated_zone(zone))
                        continue;
 
-               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+               if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
                        continue;
 
                note_zone_scanning_priority(zone, priority);
@@ -1034,7 +1034,7 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
        for (i = 0; zones[i] != NULL; i++) {
                struct zone *zone = zones[i];
 
-               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+               if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
                        continue;
 
                lru_pages += zone->nr_active + zone->nr_inactive;
@@ -1089,7 +1089,7 @@ out:
        for (i = 0; zones[i] != 0; i++) {
                struct zone *zone = zones[i];
 
-               if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+               if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
                        continue;
 
                zone->prev_priority = priority;
@@ -1354,7 +1354,7 @@ void wakeup_kswapd(struct zone *zone, int order)
                return;
        if (pgdat->kswapd_max_order < order)
                pgdat->kswapd_max_order = order;
-       if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
+       if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
                return;
        if (!waitqueue_active(&pgdat->kswapd_wait))
                return;
index 711a085eca5b3436bc13e528a7b03904f74beba2..dbf98c49dbaaa0edeaf3b37e38b595f4ba79a237 100644 (file)
@@ -123,10 +123,10 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
                        if (flt->opcode &&
                            ((evt == HCI_EV_CMD_COMPLETE &&
                              flt->opcode !=
-                             get_unaligned((__u16 *)(skb->data + 3))) ||
+                             get_unaligned((__le16 *)(skb->data + 3))) ||
                             (evt == HCI_EV_CMD_STATUS &&
                              flt->opcode !=
-                             get_unaligned((__u16 *)(skb->data + 4)))))
+                             get_unaligned((__le16 *)(skb->data + 4)))))
                                continue;
                }
 
index 700353b330fd3ddaa359c95bd5b53f020c46aaab..066c64a97fd87fafd5e48411b82bae5abb574393 100644 (file)
@@ -804,19 +804,19 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
 
        integ_len = svc_getnl(&buf->head[0]);
        if (integ_len & 3)
-               goto out;
+               return stat;
        if (integ_len > buf->len)
-               goto out;
+               return stat;
        if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
                BUG();
        /* copy out mic... */
        if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
                BUG();
        if (mic.len > RPC_MAX_AUTH_SIZE)
-               goto out;
+               return stat;
        mic.data = kmalloc(mic.len, GFP_KERNEL);
        if (!mic.data)
-               goto out;
+               return stat;
        if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
                goto out;
        maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
@@ -826,6 +826,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
                goto out;
        stat = 0;
 out:
+       kfree(mic.data);
        return stat;
 }
 
@@ -1065,7 +1066,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
                }
                switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
                case -EAGAIN:
-                       goto drop;
+               case -ETIMEDOUT:
                case -ENOENT:
                        goto drop;
                case 0:
index 80aff047457255647a293471087f6d1713a15306..14274490f92e8d9b521b5396320c5e76178adb5e 100644 (file)
@@ -34,7 +34,7 @@
 
 #define         RPCDBG_FACILITY RPCDBG_CACHE
 
-static void cache_defer_req(struct cache_req *req, struct cache_head *item);
+static int cache_defer_req(struct cache_req *req, struct cache_head *item);
 static void cache_revisit_request(struct cache_head *item);
 
 static void cache_init(struct cache_head *h)
@@ -185,6 +185,7 @@ static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h);
  *
  * Returns 0 if the cache_head can be used, or cache_puts it and returns
  * -EAGAIN if upcall is pending,
+ * -ETIMEDOUT if upcall failed and should be retried,
  * -ENOENT if cache entry was negative
  */
 int cache_check(struct cache_detail *detail,
@@ -236,7 +237,8 @@ int cache_check(struct cache_detail *detail,
        }
 
        if (rv == -EAGAIN)
-               cache_defer_req(rqstp, h);
+               if (cache_defer_req(rqstp, h) != 0)
+                       rv = -ETIMEDOUT;
 
        if (rv)
                cache_put(h, detail);
@@ -523,14 +525,21 @@ static LIST_HEAD(cache_defer_list);
 static struct list_head cache_defer_hash[DFR_HASHSIZE];
 static int cache_defer_cnt;
 
-static void cache_defer_req(struct cache_req *req, struct cache_head *item)
+static int cache_defer_req(struct cache_req *req, struct cache_head *item)
 {
        struct cache_deferred_req *dreq;
        int hash = DFR_HASH(item);
 
+       if (cache_defer_cnt >= DFR_MAX) {
+               /* too much in the cache, randomly drop this one,
+                * or continue and drop the oldest below
+                */
+               if (net_random()&1)
+                       return -ETIMEDOUT;
+       }
        dreq = req->defer(req);
        if (dreq == NULL)
-               return;
+               return -ETIMEDOUT;
 
        dreq->item = item;
        dreq->recv_time = get_seconds();
@@ -546,17 +555,8 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
        /* it is in, now maybe clean up */
        dreq = NULL;
        if (++cache_defer_cnt > DFR_MAX) {
-               /* too much in the cache, randomly drop
-                * first or last
-                */
-               if (net_random()&1) 
-                       dreq = list_entry(cache_defer_list.next,
-                                         struct cache_deferred_req,
-                                         recent);
-               else
-                       dreq = list_entry(cache_defer_list.prev,
-                                         struct cache_deferred_req,
-                                         recent);
+               dreq = list_entry(cache_defer_list.prev,
+                                 struct cache_deferred_req, recent);
                list_del(&dreq->recent);
                list_del(&dreq->hash);
                cache_defer_cnt--;
@@ -571,6 +571,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
                /* must have just been validated... */
                cache_revisit_request(item);
        }
+       return 0;
 }
 
 static void cache_revisit_request(struct cache_head *item)
index eb44ec929ca115a5944b7dd8f380a79d3b057249..f3001f3626f631fca51ef9d911f3f521814162f3 100644 (file)
@@ -308,7 +308,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 
        serv->sv_nrpools = npools;
        serv->sv_pools =
-               kcalloc(sizeof(struct svc_pool), serv->sv_nrpools,
+               kcalloc(serv->sv_nrpools, sizeof(struct svc_pool),
                        GFP_KERNEL);
        if (!serv->sv_pools) {
                kfree(serv);
index a0a953a430c29957e7204b03061da0604d8c4cf5..0d1e8fb83b930ee4e9e472d07e2f265875389b02 100644 (file)
@@ -53,6 +53,10 @@ struct auth_domain *unix_domain_find(char *name)
                        return NULL;
                kref_init(&new->h.ref);
                new->h.name = kstrdup(name, GFP_KERNEL);
+               if (new->h.name == NULL) {
+                       kfree(new);
+                       return NULL;
+               }
                new->h.flavour = &svcauth_unix;
                new->addr_changes = 0;
                rv = auth_domain_lookup(name, &new->h);
@@ -435,6 +439,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
                default:
                        BUG();
                case -EAGAIN:
+               case -ETIMEDOUT:
                        return SVC_DROP;
                case -ENOENT:
                        return SVC_DENIED;
index 458a2c46cef3d5a022947fbe85350bacdda17317..baf55c459c8bc15b2e2b514642656889a1e123a2 100644 (file)
@@ -208,7 +208,7 @@ static void cfg_cmd_event(struct tipc_cmd_msg *msg,
 
                        if (mng.link_subscriptions > 64)
                                break;
-                       sub = (struct subscr_data *)kmalloc(sizeof(*sub),
+                       sub = kmalloc(sizeof(*sub),
                                                            GFP_ATOMIC);
                        if (sub == NULL) {
                                warn("Memory squeeze; dropped remote link subscription\n");
index 4dcb8867b5f4d3ac3940758eef48ef8f312271f8..124b341a18c02190e30bba8b7d28c8ce29aac57c 100644 (file)
@@ -600,7 +600,7 @@ int main(int ac, char **av)
                        input_mode = ask_silent;
                        valid_stdin = 1;
                }
-       } else if (sym_change_count) {
+       } else if (conf_get_changed()) {
                name = getenv("KCONFIG_NOSILENTUPDATE");
                if (name && *name) {
                        fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n"));
index 66b15ef029313468b3918a3dcf89ae1dd65c9aa2..664fe29dacef5b3f9e0d36353fe0968bccc01347 100644 (file)
@@ -100,7 +100,7 @@ int conf_read_simple(const char *name, int def)
                in = zconf_fopen(name);
                if (in)
                        goto load;
-               sym_change_count++;
+               sym_add_change_count(1);
                if (!sym_defconfig_list)
                        return 1;
 
@@ -312,7 +312,7 @@ int conf_read(const char *name)
        struct expr *e;
        int i, flags;
 
-       sym_change_count = 0;
+       sym_set_change_count(0);
 
        if (conf_read_simple(name, S_DEF_USER))
                return 1;
@@ -364,7 +364,7 @@ int conf_read(const char *name)
                sym->flags &= flags | ~SYMBOL_DEF_USER;
        }
 
-       sym_change_count += conf_warnings || conf_unsaved;
+       sym_add_change_count(conf_warnings || conf_unsaved);
 
        return 0;
 }
@@ -432,7 +432,7 @@ int conf_write(const char *name)
                     use_timestamp ? "# " : "",
                     use_timestamp ? ctime(&now) : "");
 
-       if (!sym_change_count)
+       if (!conf_get_changed())
                sym_clear_all_valid();
 
        menu = rootmenu.list;
@@ -528,7 +528,7 @@ int conf_write(const char *name)
                 "# configuration written to %s\n"
                 "#\n"), newname);
 
-       sym_change_count = 0;
+       sym_set_change_count(0);
 
        return 0;
 }
@@ -765,3 +765,30 @@ int conf_write_autoconf(void)
 
        return 0;
 }
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+       int _sym_change_count = sym_change_count;
+       sym_change_count = count;
+       if (conf_changed_callback &&
+           (bool)_sym_change_count != (bool)count)
+               conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+       sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+       return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+       conf_changed_callback = fn;
+}
index 7b0d3a93d5c08ffe78b96fc0a9243adc59cf33d4..61d8166166ef86177cf28b65575a9004f7113c08 100644 (file)
@@ -38,8 +38,6 @@ static gboolean show_all = FALSE;
 static gboolean show_debug = FALSE;
 static gboolean resizeable = FALSE;
 
-static gboolean config_changed = FALSE;
-
 static char nohelp_text[] =
     N_("Sorry, no help available for this option yet.\n");
 
@@ -50,6 +48,8 @@ GtkWidget *text_w = NULL;
 GtkWidget *hpaned = NULL;
 GtkWidget *vpaned = NULL;
 GtkWidget *back_btn = NULL;
+GtkWidget *save_btn = NULL;
+GtkWidget *save_menu_item = NULL;
 
 GtkTextTag *tag1, *tag2;
 GdkColor color;
@@ -75,7 +75,7 @@ static void display_tree_part(void);
 static void update_tree(struct menu *src, GtkTreeIter * dst);
 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
 static gchar **fill_row(struct menu *menu);
-
+static void conf_changed(void);
 
 /* Helping/Debugging Functions */
 
@@ -224,6 +224,10 @@ void init_main_window(const gchar * glade_file)
        gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
                                       show_value);
 
+       save_btn = glade_xml_get_widget(xml, "button3");
+       save_menu_item = glade_xml_get_widget(xml, "save1");
+       conf_set_changed_callback(conf_changed);
+
        style = gtk_widget_get_style(main_wnd);
        widget = glade_xml_get_widget(xml, "toolbar1");
 
@@ -512,14 +516,14 @@ static void text_insert_msg(const char *title, const char *message)
 
 /* Main Windows Callbacks */
 
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
 gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
                                 gpointer user_data)
 {
        GtkWidget *dialog, *label;
        gint result;
 
-       if (config_changed == FALSE)
+       if (!conf_get_changed())
                return FALSE;
 
        dialog = gtk_dialog_new_with_buttons(_("Warning !"),
@@ -543,7 +547,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
        result = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (result) {
        case GTK_RESPONSE_YES:
-               on_save1_activate(NULL, NULL);
+               on_save_activate(NULL, NULL);
                return FALSE;
        case GTK_RESPONSE_NO:
                return FALSE;
@@ -621,12 +625,10 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
 }
 
 
-void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
+void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
 {
        if (conf_write(NULL))
                text_insert_msg(_("Error"), _("Unable to save configuration !"));
-
-       config_changed = FALSE;
 }
 
 
@@ -819,12 +821,6 @@ void on_load_clicked(GtkButton * button, gpointer user_data)
 }
 
 
-void on_save_clicked(GtkButton * button, gpointer user_data)
-{
-       on_save1_activate(NULL, user_data);
-}
-
-
 void on_single_clicked(GtkButton * button, gpointer user_data)
 {
        view_mode = SINGLE_VIEW;
@@ -899,7 +895,6 @@ static void renderer_edited(GtkCellRendererText * cell,
 
        sym_set_string_value(sym, new_def);
 
-       config_changed = TRUE;
        update_tree(&rootmenu, NULL);
 
        gtk_tree_path_free(path);
@@ -930,7 +925,6 @@ static void change_sym_value(struct menu *menu, gint col)
                if (!sym_tristate_within_range(sym, newval))
                        newval = yes;
                sym_set_tristate_value(sym, newval);
-               config_changed = TRUE;
                if (view_mode == FULL_VIEW)
                        update_tree(&rootmenu, NULL);
                else if (view_mode == SPLIT_VIEW) {
@@ -1633,3 +1627,10 @@ int main(int ac, char *av[])
 
        return 0;
 }
+
+static void conf_changed(void)
+{
+       bool changed = conf_get_changed();
+       gtk_widget_set_sensitive(save_btn, changed);
+       gtk_widget_set_sensitive(save_menu_item, changed);
+}
index f8744ed64967add665e453ee721174e4a9c2ccb3..803233fdd6ddbca62e255beb8db64b743553863e 100644 (file)
@@ -70,7 +70,7 @@
                      <property name="tooltip" translatable="yes">Save the config in .config</property>
                      <property name="label" translatable="yes">_Save</property>
                      <property name="use_underline">True</property>
-                     <signal name="activate" handler="on_save1_activate"/>
+                     <signal name="activate" handler="on_save_activate"/>
                      <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
                      <child internal-child="image">
                  <property name="visible_horizontal">True</property>
                  <property name="visible_vertical">True</property>
                  <property name="is_important">False</property>
-                 <signal name="clicked" handler="on_save_clicked"/>
+                 <signal name="clicked" handler="on_save_activate"/>
                </widget>
                <packing>
                  <property name="expand">False</property>
index 2628023a1fe1d0b95ff99927b53e7652620aa6e8..9b2706a41548d3b5224caed652b2a4f74f68eed4 100644 (file)
@@ -65,6 +65,8 @@ char *zconf_curname(void);
 
 /* confdata.c */
 char *conf_get_default_confname(void);
+void sym_set_change_count(int count);
+void sym_add_change_count(int count);
 
 /* kconfig_load.c */
 void kconfig_load(void);
index a263746cfa7de239ba0513b5011b0a090a267d11..15030770d1ad4e937272a6f03d7d704ebad70dff 100644 (file)
@@ -5,6 +5,8 @@ P(conf_read,int,(const char *name));
 P(conf_read_simple,int,(const char *name, int));
 P(conf_write,int,(const char *name));
 P(conf_write_autoconf,int,(void));
+P(conf_get_changed,bool,(void));
+P(conf_set_changed_callback, void,(void (*fn)(void)));
 
 /* menu.c */
 P(rootmenu,struct menu,);
@@ -16,7 +18,6 @@ P(menu_get_parent_menu,struct menu *,(struct menu *menu));
 
 /* symbol.c */
 P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
-P(sym_change_count,int,);
 
 P(sym_lookup,struct symbol *,(const char *name, int isconst));
 P(sym_find,struct symbol *,(const char *name));
index 08a4c7af93ea0ffd9d19b9efcbf02572d7fb94ac..3f9a1321b3e60caa47418b72beba0d27f6e118f3 100644 (file)
@@ -890,14 +890,19 @@ int main(int ac, char **av)
        do {
                conf(&rootmenu);
                dialog_clear();
-               res = dialog_yesno(NULL,
-                                  _("Do you wish to save your "
-                                    "new kernel configuration?\n"
-                                    "<ESC><ESC> to continue."),
-                                  6, 60);
+               if (conf_get_changed())
+                       res = dialog_yesno(NULL,
+                                          _("Do you wish to save your "
+                                            "new kernel configuration?\n"
+                                            "<ESC><ESC> to continue."),
+                                          6, 60);
+               else
+                       res = -1;
        } while (res == KEY_ESC);
        end_dialog();
-       if (res == 0) {
+
+       switch (res) {
+       case 0:
                if (conf_write(NULL)) {
                        fprintf(stderr, _("\n\n"
                                "Error during writing of the kernel configuration.\n"
@@ -905,11 +910,13 @@ int main(int ac, char **av)
                                "\n\n"));
                        return 1;
                }
+       case -1:
                printf(_("\n\n"
                        "*** End of Linux kernel configuration.\n"
                        "*** Execute 'make' to build the kernel or try 'make help'."
                        "\n\n"));
-       } else {
+               break;
+       default:
                fprintf(stderr, _("\n\n"
                        "Your kernel configuration changes were NOT saved."
                        "\n\n"));
index f5628c57640b134fe2f8689fd3993d43f011ca3e..0b2fcc417f590a0eed79b5709f0e48d50c8dda11 100644 (file)
@@ -38,6 +38,8 @@
 static QApplication *configApp;
 static ConfigSettings *configSettings;
 
+QAction *ConfigMainWindow::saveAction;
+
 static inline QString qgettext(const char* str)
 {
        return QString::fromLocal8Bit(gettext(str));
@@ -1306,8 +1308,11 @@ ConfigMainWindow::ConfigMainWindow(void)
          connect(quitAction, SIGNAL(activated()), SLOT(close()));
        QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
          connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
-       QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
+       saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
          connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+       conf_set_changed_callback(conf_changed);
+       // Set saveAction's initial state
+       conf_changed();
        QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
          connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
        QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
@@ -1585,7 +1590,7 @@ void ConfigMainWindow::showFullView(void)
  */
 void ConfigMainWindow::closeEvent(QCloseEvent* e)
 {
-       if (!sym_change_count) {
+       if (!conf_get_changed()) {
                e->accept();
                return;
        }
@@ -1658,6 +1663,12 @@ void ConfigMainWindow::saveSettings(void)
        configSettings->writeSizes("/split2", split2->sizes());
 }
 
+void ConfigMainWindow::conf_changed(void)
+{
+       if (saveAction)
+               saveAction->setEnabled(conf_get_changed());
+}
+
 void fixup_rootmenu(struct menu *menu)
 {
        struct menu *child;
index 6a9e3b14c227ce6ff43befbe35d764a3423735ef..6fc1c5f14425162aab07eb5e35f8d24f0c8ccadc 100644 (file)
@@ -297,6 +297,9 @@ protected:
 
 class ConfigMainWindow : public QMainWindow {
        Q_OBJECT
+
+       static QAction *saveAction;
+       static void conf_changed(void);
 public:
        ConfigMainWindow(void);
 public slots:
index ee225ced2ce450359a2d2c42c383ce36f0f20717..8f06c474d800fe8d6749c49e30f9dd365dc354ed 100644 (file)
@@ -30,7 +30,6 @@ struct symbol symbol_yes = {
        .flags = SYMBOL_VALID,
 };
 
-int sym_change_count;
 struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
 tristate modules_val;
@@ -379,7 +378,7 @@ void sym_clear_all_valid(void)
 
        for_all_symbols(i, sym)
                sym->flags &= ~SYMBOL_VALID;
-       sym_change_count++;
+       sym_add_change_count(1);
        if (modules_sym)
                sym_calc_value(modules_sym);
 }
index 2fb0a4fc61d01d04bb768a1afb6cd172b5e6643a..d777fe85627f0bc3a3d5ff7594ecbacb21452dbc 100644 (file)
@@ -2135,7 +2135,7 @@ void conf_parse(const char *name)
                sym_check_deps(sym);
         }
 
-       sym_change_count = 1;
+       sym_set_change_count(1);
 }
 
 const char *zconf_tokenname(int token)
index ab44feb3c600bec91062057803bc620fac176c88..04a5864c03b1b482653917b08c57a3b884d69fa9 100644 (file)
@@ -504,7 +504,7 @@ void conf_parse(const char *name)
                sym_check_deps(sym);
         }
 
-       sym_change_count = 1;
+       sym_set_change_count(1);
 }
 
 const char *zconf_tokenname(int token)
index ac0a582229924d3d65d7903724fe2900a424088a..15ab5d02e80a1689a554dac4893cd1edb910c26c 100644 (file)
@@ -997,6 +997,7 @@ static int exit_section_ref_ok(const char *name)
                "__bug_table", /* used by powerpc for BUG() */
                ".exitcall.exit",
                ".eh_frame",
+               ".parainstructions",
                ".stab",
                "__ex_table",
                ".fixup",
index f4c67042e3ac16ba72bb6effe6a2e93550fc7bf5..3391f2a9b4d167150114deec246ce3cc7082978e 100644 (file)
@@ -1023,7 +1023,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mix
        }
        up_read(&mixer->card->controls_rwsem);
        if (slot.present != 0) {
-               pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
+               pslot = kmalloc(sizeof(slot), GFP_KERNEL);
                if (! pslot)
                        return -ENOMEM;
                *pslot = slot;
index 0ffa9970bf0ff307cee68b9698c3bffc63f3eee9..7cf9913a47b26ca4e3adb02a25e2538542913463 100644 (file)
@@ -1992,7 +1992,7 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback,
                        devc->audio_flags |= DMA_DUPLEX;
        }
 
-       portc = (ad1848_port_info *) kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
+       portc = kmalloc(sizeof(ad1848_port_info), GFP_KERNEL);
        if(portc==NULL) {
                release_region(devc->base, 4);
                return -1;
index b6924c7f1484f5c6c01f1684d3654dec21f7f0fe..de40e21bf2798c6d248de7f8dbf6d0fc643cf0ab 100644 (file)
@@ -408,7 +408,7 @@ static int __init cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_
 {
        struct address_info *isapnpcfg;
 
-       isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
+       isapnpcfg = kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
        if (!isapnpcfg)
                return -ENOMEM;
 
index 49f902f35c280a32d6441bcb6f1808fe811f1e46..efcf589d7083401450d2c743d36b65e5cedbf6ee 100644 (file)
@@ -1139,7 +1139,7 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
 
 match:
 
-       wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
+       wave_dev = kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL);
 
        if (wave_dev == NULL) { 
                ERROR();
@@ -1155,7 +1155,7 @@ match:
                /* Recording */
                struct wiinst *wiinst;
 
-               if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
+               if ((wiinst = kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
                        ERROR();
                        kfree(wave_dev);
                        return -ENOMEM;
@@ -1211,7 +1211,7 @@ match:
                struct woinst *woinst;
                int i;
 
-               if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
+               if ((woinst = kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
                        ERROR();
                        kfree(wave_dev);
                        return -ENOMEM;
index 0545814cc67dc08a0da0776356df6ebfc34fff76..57674f8c8a2e73f1f5a5dc95ec90d87d63393271 100644 (file)
@@ -157,7 +157,7 @@ int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *card_mpuin, struct midi_hdr *
        midihdr->flags |= MIDIBUF_INQUEUE;      /* set */
        midihdr->flags &= ~MIDIBUF_DONE;        /* clear */
 
-       if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
+       if ((midiq = kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
                /* Message lost */
                return -1;
        }
index 5938d31f9e219d4ea81de5b5c07734f4bf3a4530..a8cc75db3e45274a3ed9e3f644d8f0f8296be391 100644 (file)
@@ -117,7 +117,7 @@ int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihd
        midihdr->flags |= MIDIBUF_INQUEUE;
        midihdr->flags &= ~MIDIBUF_DONE;
 
-       if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
+       if ((midiq = kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
                /* Message lost */
                return -1;
        }
index 8ac77df86397134c3087e0b87b0eeae1ede96946..cca3dad2bdf4bf2550f48668286687cb1dc33ed1 100644 (file)
@@ -58,7 +58,7 @@ static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hd
 {
        struct midi_hdr *midihdr;
 
-       if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
+       if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
                ERROR();
                return -EINVAL;
        }
@@ -128,7 +128,7 @@ match:
                mutex_lock(&card->open_sem);
        }
 
-       if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
+       if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
                return -EINVAL;
 
        midi_dev->card = card;
@@ -328,7 +328,7 @@ static ssize_t emu10k1_midi_write(struct file *file, const char __user *buffer,
        if (!access_ok(VERIFY_READ, buffer, count))
                return -EFAULT;
 
-       if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
+       if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
                return -EINVAL;
 
        midihdr->bufferlength = count;
@@ -490,7 +490,7 @@ int emu10k1_seq_midi_open(int dev, int mode,
                        
        DPF(2, "emu10k1_seq_midi_open()\n");
        
-       if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
+       if ((midi_dev = kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
                return -EINVAL;
 
        midi_dev->card = card;
@@ -540,7 +540,7 @@ int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
 
        card = midi_devs[dev]->devc;
 
-       if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
+       if ((midihdr = kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
                return -EINVAL;
 
        midihdr->bufferlength = 1;
index cbcaaa34189abc9bbf66119e2b524681948445c1..6419796c2ed7b665e442547dfea1447e6f7590a4 100644 (file)
@@ -194,7 +194,7 @@ static int emu10k1_private_mixer(struct emu10k1_card *card, unsigned int cmd, un
 
        case SOUND_MIXER_PRIVATE3:
 
-               ctl = (struct mixer_private_ioctl *) kmalloc(sizeof(struct mixer_private_ioctl), GFP_KERNEL);
+               ctl = kmalloc(sizeof(struct mixer_private_ioctl), GFP_KERNEL);
                if (ctl == NULL)
                        return -ENOMEM;
 
index 784bdd707055ede1e4ae3cdf176fd3ba262e26d1..d18286ccc14d244ee18d55b9ac9d04c48b0c2c50 100644 (file)
@@ -1435,7 +1435,7 @@ static int hal2_init_card(struct hal2_card **phal2, struct hpc3_regs *hpc3)
        int ret = 0;
        struct hal2_card *hal2;
 
-       hal2 = (struct hal2_card *) kmalloc(sizeof(struct hal2_card), GFP_KERNEL);
+       hal2 = kmalloc(sizeof(struct hal2_card), GFP_KERNEL);
        if (!hal2)
                return -ENOMEM;
        memset(hal2, 0, sizeof(struct hal2_card));
index e96220541971498a0c25c31f98ebb36cc11d6f6f..2796c0ef985fc5c08d62af8c33b92da2c83e1240 100644 (file)
@@ -1023,7 +1023,7 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
                                devc->capabilities |= MPU_CAP_INTLG;    /* Supports intelligent mode */
 
 
-       mpu401_synth_operations[m] = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
+       mpu401_synth_operations[m] = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
 
        if (mpu401_synth_operations[m] == NULL)
        {
index 4799bc77f987223308da7adc3aa22bae581122b7..2e8cfa5481f28c4e1e7d7f2d40b5326538bd02d7 100644 (file)
@@ -166,7 +166,7 @@ int opl3_detect(int ioaddr, int *osp)
                return 0;
        }
 
-       devc = (struct opl_devinfo *)kmalloc(sizeof(*devc), GFP_KERNEL);
+       devc = kmalloc(sizeof(*devc), GFP_KERNEL);
 
        if (devc == NULL)
        {
index 440537c72604f467bdf359414d216fc5c8662546..07cbacf63824602d3a2763984efc3368c5c0f4ad 100644 (file)
@@ -625,7 +625,7 @@ int sb_dsp_detect(struct address_info *hw_config, int pci, int pciio, struct sb_
         */
 
 
-       detected_devc = (sb_devc *)kmalloc(sizeof(sb_devc), GFP_KERNEL);
+       detected_devc = kmalloc(sizeof(sb_devc), GFP_KERNEL);
        if (detected_devc == NULL)
        {
                printk(KERN_ERR "sb: Can't allocate memory for device information\n");
index 2e3bc045cabaf67d35a0d00d981dbba1e3df5866..8b796704e1120a15caaed0c96edffa67a34e8006 100644 (file)
@@ -173,7 +173,7 @@ void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
                return;
        }
        std_midi_synth.midi_dev = devc->my_mididev = dev;
-       midi_devs[dev] = (struct midi_operations *)kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
+       midi_devs[dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
        if (midi_devs[dev] == NULL)
        {
                printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
@@ -189,7 +189,7 @@ void sb_dsp_midi_init(sb_devc * devc, struct module *owner)
        midi_devs[dev]->devc = devc;
 
 
-       midi_devs[dev]->converter = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
+       midi_devs[dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
        if (midi_devs[dev]->converter == NULL)
        {
                  printk(KERN_WARNING "Sound Blaster:  failed to allocate MIDI memory.\n");
index 238e2cf44b082bb1b702a3065baed77172d0c1b0..fad1a4f25ad6db0402de24f24f0c21e1be301c54 100644 (file)
@@ -734,7 +734,7 @@ int sb_mixer_init(sb_devc * devc, struct module *owner)
        if (m == -1)
                return 0;
 
-       mixer_devs[m] = (struct mixer_operations *)kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
+       mixer_devs[m] = kmalloc(sizeof(struct mixer_operations), GFP_KERNEL);
        if (mixer_devs[m] == NULL)
        {
                printk(KERN_ERR "sb_mixer: Can't allocate memory\n");
index d952b2264da1da46fc0cb70e4e7228b0cf0f4817..103940fd5b4f46e9e2ae7c8435acf64938679faa 100644 (file)
@@ -183,7 +183,7 @@ static void __init attach_v_midi (struct address_info *hw_config)
                return;
        }
        
-       m=(struct vmidi_memory *)kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
+       m = kmalloc(sizeof(struct vmidi_memory), GFP_KERNEL);
        if (m == NULL)
        {
                printk(KERN_WARNING "Loopback MIDI: Failed to allocate memory\n");
index c5bf363d32c2fb055e9639a2040e4501fb989fd7..26a7c6af95bcc5c18992cbe2a2ebea1763f741c7 100644 (file)
@@ -1267,7 +1267,7 @@ static int __init waveartist_init(wavnc_info *devc)
        conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
                     devc->hw.dma, devc->hw.dma2);
 
-       portc = (wavnc_port_info *)kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
+       portc = kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
        if (portc == NULL)
                goto nomem;