]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Tue, 10 Jan 2006 16:28:53 +0000 (08:28 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 10 Jan 2006 16:28:53 +0000 (08:28 -0800)
486 files changed:
Documentation/CodingStyle
Documentation/DocBook/.gitignore [new file with mode: 0644]
Documentation/DocBook/kernel-api.tmpl
Documentation/applying-patches.txt
Documentation/filesystems/ext3.txt
Documentation/hrtimers.txt [new file with mode: 0644]
Documentation/kbuild/makefiles.txt
Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/locks.txt
Documentation/stable_kernel_rules.txt
Kbuild
MAINTAINERS
Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/mm/init.c
arch/arm/plat-omap/dma.c
arch/arm26/kernel/armksyms.c
arch/cris/kernel/crisksyms.c
arch/cris/kernel/process.c
arch/frv/Kconfig
arch/frv/boot/Makefile
arch/frv/kernel/frv_ksyms.c
arch/frv/kernel/process.c
arch/h8300/kernel/gpio.c
arch/h8300/kernel/h8300_ksyms.c
arch/h8300/kernel/process.c
arch/h8300/platform/h8300h/ptrace_h8300h.c
arch/h8300/platform/h8s/ints.c
arch/h8300/platform/h8s/ints_h8s.c
arch/i386/Kconfig
arch/i386/Makefile
arch/i386/boot/Makefile
arch/i386/boot/install.sh
arch/i386/boot/video.S
arch/i386/kernel/Makefile
arch/i386/kernel/crash.c
arch/i386/kernel/crash_dump.c [new file with mode: 0644]
arch/i386/kernel/kprobes.c
arch/i386/kernel/setup.c
arch/i386/kernel/traps.c
arch/ia64/Makefile
arch/ia64/ia32/Makefile
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/ia32_ioctl.c [deleted file]
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/kprobes.c
arch/m32r/Kconfig
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/process.c
arch/m68k/kernel/m68k_ksyms.c
arch/m68knommu/kernel/m68k_ksyms.c
arch/m68knommu/kernel/process.c
arch/mips/kernel/Makefile
arch/mips/kernel/ioctl32.c [deleted file]
arch/parisc/kernel/Makefile
arch/parisc/kernel/ioctl32.c [deleted file]
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/ioctl32.c [deleted file]
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/sys_ppc32.c
arch/powerpc/kernel/systbl.S
arch/powerpc/mm/pgtable_64.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/eeh_cache.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/eeh_driver.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/eeh_event.c
arch/ppc/Makefile
arch/ppc/kernel/machine_kexec.c
arch/s390/Kconfig
arch/s390/kernel/Makefile
arch/s390/kernel/compat_ioctl.c [deleted file]
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/crash.c
arch/s390/kernel/process.c
arch/s390/kernel/s390_ksyms.c
arch/sh/kernel/process.c
arch/sh/kernel/sh_ksyms.c
arch/sh64/Kconfig
arch/sh64/kernel/process.c
arch/sh64/kernel/sh_ksyms.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc64/kernel/Makefile
arch/sparc64/kernel/binfmt_aout32.c
arch/sparc64/kernel/ioctl32.c [deleted file]
arch/sparc64/kernel/kprobes.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/um/drivers/chan_kern.c
arch/um/kernel/time.c
arch/v850/kernel/process.c
arch/v850/kernel/v850_ksyms.c
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/boot/Makefile
arch/x86_64/boot/install.sh
arch/x86_64/ia32/Makefile
arch/x86_64/ia32/ia32_ioctl.c [deleted file]
arch/x86_64/ia32/ia32entry.S
arch/x86_64/ia32/sys_ia32.c
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/crash.c
arch/x86_64/kernel/crash_dump.c [moved from kernel/crash_dump.c with 60% similarity]
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/x8664_ksyms.c
arch/xtensa/Kconfig
drivers/base/core.c
drivers/base/cpu.c
drivers/bluetooth/hci_ldisc.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/amiserial.c
drivers/char/cs5535_gpio.c [new file with mode: 0644]
drivers/char/cyclades.c
drivers/char/drm/drm_ioc32.c
drivers/char/drm/i915_ioc32.c
drivers/char/drm/mga_ioc32.c
drivers/char/drm/r128_ioc32.c
drivers/char/drm/radeon_ioc32.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/hvc_console.c
drivers/char/hvcs.c
drivers/char/hvsi.c
drivers/char/ip2/i2lib.c
drivers/char/ip2main.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_poweroff.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/n_hdlc.c
drivers/char/n_r3964.c
drivers/char/n_tty.c
drivers/char/nvram.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/pty.c
drivers/char/rio/rio_linux.c
drivers/char/rio/riointr.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/selection.c
drivers/char/ser_a2232.c
drivers/char/serial167.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/tty_io.c
drivers/char/viocons.c
drivers/char/vme_scc.c
drivers/char/vr41xx_rtc.c
drivers/char/vt.c
drivers/connector/cn_proc.c
drivers/ide/pci/pdc202xx_new.c
drivers/ide/pci/via82cxxx.c
drivers/ieee1394/amdtp.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/video1394.c
drivers/input/serio/serport.c
drivers/isdn/capi/capi.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_common.h
drivers/isdn/i4l/isdn_tty.c
drivers/md/multipath.c
drivers/media/radio/radio-maestro.c
drivers/message/fusion/mptctl.c
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/spia.c
drivers/net/8139too.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/irda/irport.c
drivers/net/irda/irtty-sir.c
drivers/net/pci-skeleton.c
drivers/net/ppp_async.c
drivers/net/ppp_synctty.c
drivers/net/r8169.c
drivers/net/sis190.c
drivers/net/slip.c
drivers/net/wan/pc300_tty.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/strip.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_ioctl.c
drivers/s390/char/con3215.c
drivers/s390/char/fs3270.c
drivers/s390/char/sclp_tty.c
drivers/s390/char/sclp_vt220.c
drivers/s390/char/tape_char.c
drivers/s390/crypto/z90main.c
drivers/s390/net/ctctty.c
drivers/scsi/aacraid/linit.c
drivers/scsi/ch.c
drivers/scsi/megaraid/megaraid_mm.h
drivers/serial/21285.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/Kconfig
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/au1x00_uart.c
drivers/serial/clps711x.c
drivers/serial/dz.c
drivers/serial/icom.c
drivers/serial/imx.c
drivers/serial/ioc4_serial.c
drivers/serial/ip22zilog.c
drivers/serial/m32r_sio.c
drivers/serial/mcfserial.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/mux.c
drivers/serial/pmac_zilog.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_lh7a40x.c
drivers/serial/serial_txx9.c
drivers/serial/sh-sci.c
drivers/serial/sn_console.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/vr41xx_siu.c
drivers/usb/atm/speedtch.c
drivers/usb/class/cdc-acm.c
drivers/usb/gadget/serial.c
drivers/usb/image/microtek.c
drivers/usb/serial/Kconfig
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/generic.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/video/Kconfig
drivers/video/arcfb.c
drivers/video/asiliantfb.c
drivers/video/aty/Makefile
drivers/video/aty/atyfb.h
drivers/video/aty/atyfb_base.c
drivers/video/aty/mach64_ct.c
drivers/video/aty/xlinit.c [deleted file]
drivers/video/console/bitblit.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/fbcon_ccw.c
drivers/video/console/fbcon_cw.c
drivers/video/console/fbcon_rotate.c
drivers/video/console/fbcon_rotate.h
drivers/video/console/fbcon_ud.c
drivers/video/console/softcursor.c
drivers/video/console/tileblit.c
drivers/video/fbcvt.c
drivers/video/fbmem.c
drivers/video/fbmon.c
drivers/video/fbsysfs.c
drivers/video/hgafb.c
drivers/video/i810/i810-i2c.c
drivers/video/i810/i810_accel.c
drivers/video/i810/i810_gtf.c
drivers/video/i810/i810_main.c
drivers/video/i810/i810_main.h
drivers/video/imsttfb.c
drivers/video/kyro/STG4000InitDevice.c
drivers/video/kyro/STG4000Interface.h
drivers/video/kyro/STG4000OverlayDevice.c
drivers/video/kyro/fbdev.c
drivers/video/matrox/matroxfb_base.h
drivers/video/matrox/matroxfb_g450.c
drivers/video/matrox/matroxfb_misc.c
drivers/video/neofb.c
drivers/video/nvidia/nv_hw.c
drivers/video/nvidia/nv_i2c.c
drivers/video/nvidia/nv_proto.h
drivers/video/nvidia/nv_setup.c
drivers/video/nvidia/nvidia.c
drivers/video/pm2fb.c
drivers/video/riva/fbdev.c
drivers/video/riva/rivafb-i2c.c
drivers/video/s3c2410fb.c
drivers/video/savage/savagefb-i2c.c
drivers/video/savage/savagefb_accel.c
drivers/video/savage/savagefb_driver.c
drivers/video/skeletonfb.c
drivers/video/sstfb.c
drivers/video/tdfxfb.c
drivers/video/vesafb.c
drivers/video/vga16fb.c
drivers/video/vgastate.c
fs/9p/vfs_super.c
fs/Kconfig
fs/Makefile
fs/autofs4/root.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/cifs/cifs_uniupr.h
fs/compat_ioctl.c
fs/dcache.c
fs/exec.c
fs/ext2/bitmap.c
fs/ext2/xattr.c
fs/ext2/xattr_trusted.c
fs/ext2/xattr_user.c
fs/ext3/balloc.c
fs/ext3/bitmap.c
fs/ext3/bitmap.h [deleted file]
fs/ext3/ialloc.c
fs/ext3/xattr.c
fs/ext3/xattr_trusted.c
fs/ext3/xattr_user.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/hfsplus/super.c
fs/inode.c
fs/jfs/xattr.c
fs/namespace.c
fs/ncpfs/file.c
fs/nfs/inode.c
fs/nfsd/vfs.c
fs/ntfs/file.c
fs/ntfs/inode.c
fs/ntfs/super.c
fs/ocfs2/mmap.c
fs/pipe.c
fs/proc/array.c
fs/proc/vmcore.c
fs/reiserfs/file.c
fs/reiserfs/xattr.c
fs/reiserfs/xattr_user.c
fs/xattr.c
fs/xfs/Kbuild [new file with mode: 0644]
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_ioctl32.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/xfs_attr.c
include/asm-arm/ioctl.h
include/asm-arm26/ioctl.h
include/asm-cris/ioctl.h
include/asm-frv/ioctl.h
include/asm-generic/ioctl.h [new file with mode: 0644]
include/asm-h8300/ioctl.h
include/asm-i386/ioctl.h
include/asm-i386/kexec.h
include/asm-i386/kprobes.h
include/asm-ia64/ioctl.h
include/asm-ia64/kprobes.h
include/asm-m32r/ioctl.h
include/asm-m68k/ioctl.h
include/asm-m68knommu/ioctl.h
include/asm-powerpc/eeh.h
include/asm-powerpc/eeh_event.h
include/asm-powerpc/kexec.h
include/asm-powerpc/kprobes.h
include/asm-powerpc/pci-bridge.h
include/asm-powerpc/ppc-pci.h
include/asm-powerpc/serial.h
include/asm-s390/ioctl.h
include/asm-s390/kexec.h
include/asm-sh/ioctl.h
include/asm-sh64/io.h
include/asm-sh64/ioctl.h
include/asm-sh64/mmu_context.h
include/asm-sh64/pgalloc.h
include/asm-sh64/pgtable.h
include/asm-sh64/processor.h
include/asm-sh64/system.h
include/asm-sh64/tlbflush.h
include/asm-sh64/uaccess.h
include/asm-sparc64/kprobes.h
include/asm-um/processor-generic.h
include/asm-v850/ioctl.h
include/asm-x86_64/e820.h
include/asm-x86_64/ioctl.h
include/asm-x86_64/kexec.h
include/asm-x86_64/kprobes.h
include/asm-xtensa/ioctl.h
include/linux/calc64.h [new file with mode: 0644]
include/linux/compat_ioctl.h
include/linux/fs.h
include/linux/hrtimer.h [new file with mode: 0644]
include/linux/isicom.h
include/linux/jiffies.h
include/linux/kbd_kern.h
include/linux/kernel.h
include/linux/kexec.h
include/linux/kprobes.h
include/linux/ktime.h [new file with mode: 0644]
include/linux/list.h
include/linux/mount.h
include/linux/namei.h
include/linux/pci_ids.h
include/linux/posix-timers.h
include/linux/rio_drv.h
include/linux/sched.h
include/linux/screen_info.h
include/linux/time.h
include/linux/timer.h
include/linux/tty.h
include/linux/tty_flip.h
include/linux/tty_ldisc.h
include/linux/xattr.h
include/linux/zlib.h
include/sound/core.h
include/video/kyro.h
include/video/neomagic.h
include/video/newport.h
include/video/sstfb.h
include/video/tdfx.h
init/Kconfig
init/main.c
kernel/Makefile
kernel/compat.c
kernel/exit.c
kernel/fork.c
kernel/hrtimer.c [new file with mode: 0644]
kernel/itimer.c
kernel/kexec.c
kernel/kprobes.c
kernel/ksysfs.c
kernel/posix-cpu-timers.c
kernel/posix-timers.c
kernel/resource.c
kernel/stop_machine.c
kernel/time.c
kernel/timer.c
lib/Kconfig.debug
lib/spinlock_debug.c
lib/zlib_deflate/deflate.c
lib/zlib_deflate/deflate_syms.c
lib/zlib_inflate/infblock.c
lib/zlib_inflate/infblock.h
lib/zlib_inflate/inflate_syms.c
lib/zlib_inflate/inflate_sync.c
mm/filemap.c
mm/filemap_xip.c
net/bluetooth/rfcomm/tty.c
net/core/net-sysfs.c
net/sunrpc/clnt.c
scripts/Kbuild.include
scripts/Makefile.build
scripts/kconfig/lxdialog/Makefile
scripts/kconfig/lxdialog/check-lxdialog.sh [new file with mode: 0644]
scripts/kernel-doc
scripts/mod/file2alias.c
scripts/reference_discarded.pl
scripts/setlocalversion
security/selinux/ss/services.c
sound/pci/cs5535audio/cs5535audio.c

index ce780ef648f1d5c5e0504f8f290add2b5e738876..ce5d2c038cf54603d76c32b25e563456ebcf6711 100644 (file)
@@ -199,7 +199,7 @@ The rationale is:
     modifications are prevented
 - saves the compiler work to optimize redundant code away ;)
 
-int fun(int )
+int fun(int a)
 {
        int result = 0;
        char *buffer = kmalloc(SIZE);
diff --git a/Documentation/DocBook/.gitignore b/Documentation/DocBook/.gitignore
new file mode 100644 (file)
index 0000000..c102c02
--- /dev/null
@@ -0,0 +1,6 @@
+*.xml
+*.ps
+*.pdf
+*.html
+*.9.gz
+*.9
index 3c47a3f0dc552ed5e0e24e20d3651eab82d2f9e7..8c9c6704e85bab5e26b6f28b2240e96346cc5660 100644 (file)
 !Iinclude/linux/sched.h
 !Ekernel/sched.c
 !Ekernel/timer.c
+     </sect1>
+     <sect1><title>High-resolution timers</title>
+!Iinclude/linux/ktime.h
+!Iinclude/linux/hrtimer.h
+!Ekernel/hrtimer.c
      </sect1>
      <sect1><title>Internal Functions</title>
 !Ikernel/exit.c
index 05a08c2c18897d0125c488671bf5da6616c0aee0..a083ba35d1adf8f0b6f676f468a21853be3ddf0e 100644 (file)
@@ -3,8 +3,7 @@
        ------------------------------------
 
        Original by: Jesper Juhl, August 2005
-       Last update: 2005-12-02
-
+       Last update: 2006-01-05
 
 
 A frequently asked question on the Linux Kernel Mailing List is how to apply
@@ -77,7 +76,7 @@ instead:
 
 If you wish to uncompress the patch file by hand first before applying it
 (what I assume you've done in the examples below), then you simply run
-gunzip or bunzip2 on the file - like this:
+gunzip or bunzip2 on the file -- like this:
        gunzip patch-x.y.z.gz
        bunzip2 patch-x.y.z.bz2
 
@@ -95,7 +94,7 @@ Common errors when patching
 ---
  When patch applies a patch file it attempts to verify the sanity of the
 file in different ways.
-Checking that the file looks like a valid patch file, checking the code
+Checking that the file looks like a valid patch file & checking the code
 around the bits being modified matches the context provided in the patch are
 just two of the basic sanity checks patch does.
 
@@ -122,7 +121,7 @@ outright and leaves a file with a .rej extension (a reject file). You can
 read this file to see exactly what change couldn't be applied, so you can
 go fix it up by hand if you wish.
 
-If you don't have any third party patches applied to your kernel source, but
+If you don't have any third-party patches applied to your kernel source, but
 only patches from kernel.org and you apply the patches in the correct order,
 and have made no modifications yourself to the source files, then you should
 never see a fuzz or reject message from patch. If you do see such messages
@@ -137,7 +136,7 @@ If patch stops and presents a "File to patch:" prompt, then patch could not
 find a file to be patched. Most likely you forgot to specify -p1 or you are
 in the wrong directory. Less often, you'll find patches that need to be
 applied with -p0 instead of -p1 (reading the patch file should reveal if
-this is the case - if so, then this is an error by the person who created
+this is the case -- if so, then this is an error by the person who created
 the patch but is not fatal).
 
 If you get "Hunk #2 succeeded at 1887 with fuzz 2 (offset 7 lines)." or a
@@ -168,13 +167,17 @@ the patch will in fact apply it.
 
 A message similar to "patch: **** unexpected end of file in patch" or "patch
 unexpectedly ends in middle of line" means that patch could make no sense of
-the file you fed to it. Either your download is broken or you tried to feed
-patch a compressed patch file without uncompressing it first.
+the file you fed to it. Either your download is broken, you tried to feed
+patch a compressed patch file without uncompressing it first, or the patch
+file that you are using has been mangled by a mail client or mail transfer
+agent along the way somewhere, e.g., by splitting a long line into two lines.
+Often these warnings can easily be fixed by joining (concatenating) the
+two lines that had been split.
 
 As I already mentioned above, these errors should never happen if you apply
 a patch from kernel.org to the correct version of an unmodified source tree.
 So if you get these errors with kernel.org patches then you should probably
-assume that either your patch file or your tree is broken and I'd advice you
+assume that either your patch file or your tree is broken and I'd advise you
 to start over with a fresh download of a full kernel tree and the patch you
 wish to apply.
 
@@ -200,10 +203,10 @@ do the additional steps since interdiff can get things wrong in some cases.
  Another alternative is `ketchup', which is a python script for automatic
 downloading and applying of patches (http://www.selenic.com/ketchup/).
 
- Other nice tools are diffstat which shows a summary of changes made by a
-patch, lsdiff which displays a short listing of affected files in a patch
-file, along with (optionally) the line numbers of the start of each patch
-and grepdiff which displays a list of the files modified by a patch where
+ Other nice tools are diffstat, which shows a summary of changes made by a
+patch; lsdiff, which displays a short listing of affected files in a patch
+file, along with (optionally) the line numbers of the start of each patch;
+and grepdiff, which displays a list of the files modified by a patch where
 the patch contains a given regular expression.
 
 
@@ -228,8 +231,8 @@ The -mm kernels live at
 In place of ftp.kernel.org you can use ftp.cc.kernel.org, where cc is a
 country code. This way you'll be downloading from a mirror site that's most
 likely geographically closer to you, resulting in faster downloads for you,
-less bandwidth used globally and less load on the main kernel.org servers -
-these are good things, do use mirrors when possible.
+less bandwidth used globally and less load on the main kernel.org servers --
+these are good things, so do use mirrors when possible.
 
 
 The 2.6.x kernels
@@ -237,14 +240,14 @@ The 2.6.x kernels
  These are the base stable releases released by Linus. The highest numbered
 release is the most recent.
 
-If regressions or other serious flaws are found then a -stable fix patch
+If regressions or other serious flaws are found, then a -stable fix patch
 will be released (see below) on top of this base. Once a new 2.6.x base
 kernel is released, a patch is made available that is a delta between the
 previous 2.6.x kernel and the new one.
 
-To apply a patch moving from 2.6.11 to 2.6.12 you'd do the following (note
+To apply a patch moving from 2.6.11 to 2.6.12, you'd do the following (note
 that such patches do *NOT* apply on top of 2.6.x.y kernels but on top of the
-base 2.6.x kernel - if you need to move from 2.6.x.y to 2.6.x+1 you need to
+base 2.6.x kernel -- if you need to move from 2.6.x.y to 2.6.x+1 you need to
 first revert the 2.6.x.y patch).
 
 Here are some examples:
@@ -266,7 +269,7 @@ $ mv linux-2.6.11.1 linux-2.6.12            # rename source dir
 
 The 2.6.x.y kernels
 ---
- Kernels with 4 digit versions are -stable kernels. They contain small(ish)
+ Kernels with 4-digit versions are -stable kernels. They contain small(ish)
 critical fixes for security problems or significant regressions discovered
 in a given 2.6.x kernel.
 
@@ -277,9 +280,14 @@ versions.
 If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is
 the current stable kernel.
 
+ note: the -stable team usually do make incremental patches available as well
+ as patches against the latest mainline release, but I only cover the
+ non-incremental ones below. The incremental ones can be found at
+ ftp://ftp.kernel.org/pub/linux/kernel/v2.6/incr/
+
 These patches are not incremental, meaning that for example the 2.6.12.3
 patch does not apply on top of the 2.6.12.2 kernel source, but rather on top
-of the base 2.6.12 kernel source.
+of the base 2.6.12 kernel source .
 So, in order to apply the 2.6.12.3 patch to your existing 2.6.12.2 kernel
 source you have to first back out the 2.6.12.2 patch (so you are left with a
 base 2.6.12 kernel source) and then apply the new 2.6.12.3 patch.
@@ -345,12 +353,12 @@ The -git kernels
 repository, hence the name).
 
 These patches are usually released daily and represent the current state of
-Linus' tree. They are more experimental than -rc kernels since they are
+Linus's tree. They are more experimental than -rc kernels since they are
 generated automatically without even a cursory glance to see if they are
 sane.
 
 -git patches are not incremental and apply either to a base 2.6.x kernel or
-a base 2.6.x-rc kernel - you can see which from their name.
+a base 2.6.x-rc kernel -- you can see which from their name.
 A patch named 2.6.12-git1 applies to the 2.6.12 kernel source and a patch
 named 2.6.13-rc3-git2 applies to the source of the 2.6.13-rc3 kernel.
 
@@ -393,12 +401,12 @@ You should generally strive to get your patches into mainline via -mm to
 ensure maximum testing.
 
 This branch is in constant flux and contains many experimental features, a
-lot of debugging patches not appropriate for mainline etc and is the most
+lot of debugging patches not appropriate for mainline etc., and is the most
 experimental of the branches described in this document.
 
 These kernels are not appropriate for use on systems that are supposed to be
 stable and they are more risky to run than any of the other branches (make
-sure you have up-to-date backups - that goes for any experimental kernel but
+sure you have up-to-date backups -- that goes for any experimental kernel but
 even more so for -mm kernels).
 
 These kernels in addition to all the other experimental patches they contain
index 22e4040564d51d51a7d123e57e855f40d044dab6..f4d0de6bac636306135b1ae19dd003a1f6adf67b 100644 (file)
@@ -2,11 +2,11 @@
 Ext3 Filesystem
 ===============
 
-ext3 was originally released in September 1999. Written by Stephen Tweedie
-for 2.2 branch, and ported to 2.4 kernels by Peter Braam, Andreas Dilger, 
+Ext3 was originally released in September 1999. Written by Stephen Tweedie
+for the 2.2 branch, and ported to 2.4 kernels by Peter Braam, Andreas Dilger,
 Andrew Morton, Alexander Viro, Ted Ts'o and Stephen Tweedie.
 
-ext3 is ext2 filesystem enhanced with journalling capabilities. 
+Ext3 is the ext2 filesystem enhanced with journalling capabilities.
 
 Options
 =======
@@ -14,69 +14,71 @@ Options
 When mounting an ext3 filesystem, the following option are accepted:
 (*) == default
 
-jounal=update          Update the ext3 file system's journal to the 
-                       current format.
+journal=update         Update the ext3 file system's journal to the current
+                       format.
 
-journal=inum           When a journal already exists, this option is 
-                       ignored. Otherwise, it specifies the number of
-                       the inode which will represent the ext3 file
-                       system's journal file.
+journal=inum           When a journal already exists, this option is ignored.
+                       Otherwise, it specifies the number of the inode which
+                       will represent the ext3 file system's journal file.
 
 journal_dev=devnum     When the external journal device's major/minor numbers
-                       have changed, this option allows to specify the new
-                       journal location. The journal device is identified
-                       through its new major/minor numbers encoded in devnum.
+                       have changed, this option allows the user to specify
+                       the new journal location.  The journal device is
+                       identified through its new major/minor numbers encoded
+                       in devnum.
 
 noload                 Don't load the journal on mounting.
 
-data=journal           All data are committed into the journal prior
-                       to being written into the main file system.
+data=journal           All data are committed into the journal prior to being
+                       written into the main file system.
 
 data=ordered   (*)     All data are forced directly out to the main file
-                       system prior to its metadata being committed to
-                       the journal.
+                       system prior to its metadata being committed to the
+                       journal.
 
-data=writeback         Data ordering is not preserved, data may be
-                       written into the main file system after its
-                       metadata has been committed to the journal.
+data=writeback         Data ordering is not preserved, data may be written
+                       into the main file system after its metadata has been
+                       committed to the journal.
 
 commit=nrsec   (*)     Ext3 can be told to sync all its data and metadata
                        every 'nrsec' seconds. The default value is 5 seconds.
-                       This means that if you lose your power, you will lose,
-                       as much, the latest 5 seconds of work (your filesystem
-                       will not be damaged though, thanks to journaling). This
-                       default value (or any low value) will hurt performance,
-                       but it's good for data-safety. Setting it to 0 will
-                       have the same effect than leaving the default 5 sec.
+                       This means that if you lose your power, you will lose
+                       as much as the latest 5 seconds of work (your
+                       filesystem will not be damaged though, thanks to the
+                       journaling).  This default value (or any low value)
+                       will hurt performance, but it's good for data-safety.
+                       Setting it to 0 will have the same effect as leaving
+                       it at the default (5 seconds).
                        Setting it to very large values will improve
                        performance.
 
-barrier=1              This enables/disables barriers. barrier=0 disables it,
-                       barrier=1 enables it.
+barrier=1              This enables/disables barriers.  barrier=0 disables
+                       it, barrier=1 enables it.
 
-orlov          (*)     This enables the new Orlov block allocator. It's enabled
-                       by default.
+orlov          (*)     This enables the new Orlov block allocator. It is
+                       enabled by default.
 
-oldalloc               This disables the Orlov block allocator and enables the
-                       old block allocator. Orlov should have better performance,
-                       we'd like to get some feedback if it's the contrary for
-                       you.
+oldalloc               This disables the Orlov block allocator and enables
+                       the old block allocator.  Orlov should have better
+                       performance - we'd like to get some feedback if it's
+                       the contrary for you.
 
-user_xattr             Enables Extended User Attributes. Additionally, you need
-                       to have extended attribute support enabled in the kernel
-                       configuration (CONFIG_EXT3_FS_XATTR). See the attr(5)
-                       manual page and http://acl.bestbits.at to learn more
-                       about extended attributes.
+user_xattr             Enables Extended User Attributes.  Additionally, you
+                       need to have extended attribute support enabled in the
+                       kernel configuration (CONFIG_EXT3_FS_XATTR).  See the
+                       attr(5) manual page and http://acl.bestbits.at/ to
+                       learn more about extended attributes.
 
 nouser_xattr           Disables Extended User Attributes.
 
-acl                    Enables POSIX Access Control Lists support.  Additionally,
-                       you need to have ACL support enabled in the kernel
-                       configuration (CONFIG_EXT3_FS_POSIX_ACL). See the acl(5)
-                       manual page and http://acl.bestbits.at for more
-                       information.
+acl                    Enables POSIX Access Control Lists support.
+                       Additionally, you need to have ACL support enabled in
+                       the kernel configuration (CONFIG_EXT3_FS_POSIX_ACL).
+                       See the acl(5) manual page and http://acl.bestbits.at/
+                       for more information.
 
-noacl                  This option disables POSIX Access Control List support.
+noacl                  This option disables POSIX Access Control List
+                       support.
 
 reservation
 
@@ -88,7 +90,7 @@ bsddf                 (*)     Make 'df' act like BSD.
 minixdf                        Make 'df' act like Minix.
 
 check=none             Don't do extra checking of bitmaps on mount.
-nocheck                
+nocheck
 
 debug                  Extra debugging information is sent to syslog.
 
@@ -97,7 +99,7 @@ errors=continue               Keep going on a filesystem error.
 errors=panic           Panic and halt the machine if an error occurs.
 
 grpid                  Give objects the same group ID as their creator.
-bsdgroups              
+bsdgroups
 
 nogrpid                (*)     New objects have the group ID of their creator.
 sysvgroups
@@ -108,81 +110,81 @@ resuid=n          The user ID which may use the reserved blocks.
 
 sb=n                   Use alternate superblock at this location.
 
-quota                  Quota options are currently silently ignored.
-noquota                        (see fs/ext3/super.c, line 594)
+quota
+noquota
 grpquota
 usrquota
 
 
 Specification
 =============
-ext3 shares all disk implementation with ext2 filesystem, and add
-transactions capabilities to ext2.  Journaling is done by the
-Journaling block device layer.
+Ext3 shares all disk implementation with the ext2 filesystem, and adds
+transactions capabilities to ext2.  Journaling is done by the Journaling Block
+Device layer.
 
 Journaling Block Device layer
 -----------------------------
-The Journaling Block Device layer (JBD) isn't ext3 specific.  It was
-design to add journaling capabilities on a block device.  The ext3
-filesystem code will inform the JBD of modifications it is performing
-(Call a transaction).  the journal support the transactions start and
-stop, and in case of crash, the journal can replayed the transactions
-to put the partition on a consistent state fastly.
+The Journaling Block Device layer (JBD) isn't ext3 specific.  It was design to
+add journaling capabilities on a block device.  The ext3 filesystem code will
+inform the JBD of modifications it is performing (called a transaction).  The
+journal supports the transactions start and stop, and in case of crash, the
+journal can replayed the transactions to put the partition back in a
+consistent state fast.
 
-handles represent a single atomic update to a filesystem.  JBD can
-handle external journal on a block device.
+Handles represent a single atomic update to a filesystem.  JBD can handle an
+external journal on a block device.
 
 Data Mode
 ---------
-There's 3 different data modes:
+There are 3 different data modes:
 
 * writeback mode
-In data=writeback mode, ext3 does not journal data at all.  This mode
-provides a similar level of journaling as XFS, JFS, and ReiserFS in its
-default mode - metadata journaling.  A crash+recovery can cause
-incorrect data to appear in files which were written shortly before the
-crash.  This mode will typically provide the best ext3 performance.
+In data=writeback mode, ext3 does not journal data at all.  This mode provides
+a similar level of journaling as that of XFS, JFS, and ReiserFS in its default
+mode - metadata journaling.  A crash+recovery can cause incorrect data to
+appear in files which were written shortly before the crash.  This mode will
+typically provide the best ext3 performance.
 
 * ordered mode
-In data=ordered mode, ext3 only officially journals metadata, but it
-logically groups metadata and data blocks into a single unit called a
-transaction.  When it's time to write the new metadata out to disk, the
-associated data blocks are written first.  In general, this mode
-perform slightly slower than writeback but significantly faster than
-journal mode.
+In data=ordered mode, ext3 only officially journals metadata, but it logically
+groups metadata and data blocks into a single unit called a transaction.  When
+it's time to write the new metadata out to disk, the associated data blocks
+are written first.  In general, this mode performs slightly slower than
+writeback but significantly faster than journal mode.
 
 * journal mode
-data=journal mode provides full data and metadata journaling.  All new
-data is written to the journal first, and then to its final location. 
-In the event of a crash, the journal can be replayed, bringing both
-data and metadata into a consistent state.  This mode is the slowest
-except when data needs to be read from and written to disk at the same
-time where it outperform all others mode.
+data=journal mode provides full data and metadata journaling.  All new data is
+written to the journal first, and then to its final location.
+In the event of a crash, the journal can be replayed, bringing both data and
+metadata into a consistent state.  This mode is the slowest except when data
+needs to be read from and written to disk at the same time where it
+outperforms all others modes.
 
 Compatibility
 -------------
 
 Ext2 partitions can be easily convert to ext3, with `tune2fs -j <dev>`.
-Ext3 is fully compatible with Ext2.  Ext3 partitions can easily be
-mounted as Ext2.
+Ext3 is fully compatible with Ext2.  Ext3 partitions can easily be mounted as
+Ext2.
+
 
 External Tools
 ==============
-see manual pages to know more.
+See manual pages to learn more.
+
+tune2fs:       create a ext3 journal on a ext2 partition with the -j flag.
+mke2fs:        create a ext3 partition with the -j flag.
+debugfs:       ext2 and ext3 file system debugger.
 
-tune2fs:       create a ext3 journal on a ext2 partition with the -j flags
-mke2fs:        create a ext3 partition with the -j flags
-debugfs:       ext2 and ext3 file system debugger
 
 References
 ==========
 
-kernel source: file:/usr/src/linux/fs/ext3
-               file:/usr/src/linux/fs/jbd
+kernel source: <file:fs/ext3/>
+               <file:fs/jbd/>
 
-programs:      http://e2fsprogs.sourceforge.net
+programs:      http://e2fsprogs.sourceforge.net/
 
-useful link:
-               http://www.zip.com.au/~akpm/linux/ext3/ext3-usage.html
+useful links:  http://www.zip.com.au/~akpm/linux/ext3/ext3-usage.html
                http://www-106.ibm.com/developerworks/linux/library/l-fs7/
                http://www-106.ibm.com/developerworks/linux/library/l-fs8/
diff --git a/Documentation/hrtimers.txt b/Documentation/hrtimers.txt
new file mode 100644 (file)
index 0000000..7620ff7
--- /dev/null
@@ -0,0 +1,178 @@
+
+hrtimers - subsystem for high-resolution kernel timers
+----------------------------------------------------
+
+This patch introduces a new subsystem for high-resolution kernel timers.
+
+One might ask the question: we already have a timer subsystem
+(kernel/timers.c), why do we need two timer subsystems? After a lot of
+back and forth trying to integrate high-resolution and high-precision
+features into the existing timer framework, and after testing various
+such high-resolution timer implementations in practice, we came to the
+conclusion that the timer wheel code is fundamentally not suitable for
+such an approach. We initially didnt believe this ('there must be a way
+to solve this'), and spent a considerable effort trying to integrate
+things into the timer wheel, but we failed. In hindsight, there are
+several reasons why such integration is hard/impossible:
+
+- the forced handling of low-resolution and high-resolution timers in
+  the same way leads to a lot of compromises, macro magic and #ifdef
+  mess. The timers.c code is very "tightly coded" around jiffies and
+  32-bitness assumptions, and has been honed and micro-optimized for a
+  relatively narrow use case (jiffies in a relatively narrow HZ range)
+  for many years - and thus even small extensions to it easily break
+  the wheel concept, leading to even worse compromises. The timer wheel
+  code is very good and tight code, there's zero problems with it in its
+  current usage - but it is simply not suitable to be extended for
+  high-res timers.
+
+- the unpredictable [O(N)] overhead of cascading leads to delays which
+  necessiate a more complex handling of high resolution timers, which
+  in turn decreases robustness. Such a design still led to rather large
+  timing inaccuracies. Cascading is a fundamental property of the timer
+  wheel concept, it cannot be 'designed out' without unevitably
+  degrading other portions of the timers.c code in an unacceptable way.
+
+- the implementation of the current posix-timer subsystem on top of
+  the timer wheel has already introduced a quite complex handling of
+  the required readjusting of absolute CLOCK_REALTIME timers at
+  settimeofday or NTP time - further underlying our experience by
+  example: that the timer wheel data structure is too rigid for high-res
+  timers.
+
+- the timer wheel code is most optimal for use cases which can be
+  identified as "timeouts". Such timeouts are usually set up to cover
+  error conditions in various I/O paths, such as networking and block
+  I/O. The vast majority of those timers never expire and are rarely
+  recascaded because the expected correct event arrives in time so they
+  can be removed from the timer wheel before any further processing of
+  them becomes necessary. Thus the users of these timeouts can accept
+  the granularity and precision tradeoffs of the timer wheel, and
+  largely expect the timer subsystem to have near-zero overhead.
+  Accurate timing for them is not a core purpose - in fact most of the
+  timeout values used are ad-hoc. For them it is at most a necessary
+  evil to guarantee the processing of actual timeout completions
+  (because most of the timeouts are deleted before completion), which
+  should thus be as cheap and unintrusive as possible.
+
+The primary users of precision timers are user-space applications that
+utilize nanosleep, posix-timers and itimer interfaces. Also, in-kernel
+users like drivers and subsystems which require precise timed events
+(e.g. multimedia) can benefit from the availability of a seperate
+high-resolution timer subsystem as well.
+
+While this subsystem does not offer high-resolution clock sources just
+yet, the hrtimer subsystem can be easily extended with high-resolution
+clock capabilities, and patches for that exist and are maturing quickly.
+The increasing demand for realtime and multimedia applications along
+with other potential users for precise timers gives another reason to
+separate the "timeout" and "precise timer" subsystems.
+
+Another potential benefit is that such a seperation allows even more
+special-purpose optimization of the existing timer wheel for the low
+resolution and low precision use cases - once the precision-sensitive
+APIs are separated from the timer wheel and are migrated over to
+hrtimers. E.g. we could decrease the frequency of the timeout subsystem
+from 250 Hz to 100 HZ (or even smaller).
+
+hrtimer subsystem implementation details
+----------------------------------------
+
+the basic design considerations were:
+
+- simplicity
+
+- data structure not bound to jiffies or any other granularity. All the
+  kernel logic works at 64-bit nanoseconds resolution - no compromises.
+
+- simplification of existing, timing related kernel code
+
+another basic requirement was the immediate enqueueing and ordering of
+timers at activation time. After looking at several possible solutions
+such as radix trees and hashes, we chose the red black tree as the basic
+data structure. Rbtrees are available as a library in the kernel and are
+used in various performance-critical areas of e.g. memory management and
+file systems. The rbtree is solely used for time sorted ordering, while
+a separate list is used to give the expiry code fast access to the
+queued timers, without having to walk the rbtree.
+
+(This seperate list is also useful for later when we'll introduce
+high-resolution clocks, where we need seperate pending and expired
+queues while keeping the time-order intact.)
+
+Time-ordered enqueueing is not purely for the purposes of
+high-resolution clocks though, it also simplifies the handling of
+absolute timers based on a low-resolution CLOCK_REALTIME. The existing
+implementation needed to keep an extra list of all armed absolute
+CLOCK_REALTIME timers along with complex locking. In case of
+settimeofday and NTP, all the timers (!) had to be dequeued, the
+time-changing code had to fix them up one by one, and all of them had to
+be enqueued again. The time-ordered enqueueing and the storage of the
+expiry time in absolute time units removes all this complex and poorly
+scaling code from the posix-timer implementation - the clock can simply
+be set without having to touch the rbtree. This also makes the handling
+of posix-timers simpler in general.
+
+The locking and per-CPU behavior of hrtimers was mostly taken from the
+existing timer wheel code, as it is mature and well suited. Sharing code
+was not really a win, due to the different data structures. Also, the
+hrtimer functions now have clearer behavior and clearer names - such as
+hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly
+equivalent to del_timer() and del_timer_sync()] - so there's no direct
+1:1 mapping between them on the algorithmical level, and thus no real
+potential for code sharing either.
+
+Basic data types: every time value, absolute or relative, is in a
+special nanosecond-resolution type: ktime_t. The kernel-internal
+representation of ktime_t values and operations is implemented via
+macros and inline functions, and can be switched between a "hybrid
+union" type and a plain "scalar" 64bit nanoseconds representation (at
+compile time). The hybrid union type optimizes time conversions on 32bit
+CPUs. This build-time-selectable ktime_t storage format was implemented
+to avoid the performance impact of 64-bit multiplications and divisions
+on 32bit CPUs. Such operations are frequently necessary to convert
+between the storage formats provided by kernel and userspace interfaces
+and the internal time format. (See include/linux/ktime.h for further
+details.)
+
+hrtimers - rounding of timer values
+-----------------------------------
+
+the hrtimer code will round timer events to lower-resolution clocks
+because it has to. Otherwise it will do no artificial rounding at all.
+
+one question is, what resolution value should be returned to the user by
+the clock_getres() interface. This will return whatever real resolution
+a given clock has - be it low-res, high-res, or artificially-low-res.
+
+hrtimers - testing and verification
+----------------------------------
+
+We used the high-resolution clock subsystem ontop of hrtimers to verify
+the hrtimer implementation details in praxis, and we also ran the posix
+timer tests in order to ensure specification compliance. We also ran
+tests on low-resolution clocks.
+
+The hrtimer patch converts the following kernel functionality to use
+hrtimers:
+
+ - nanosleep
+ - itimers
+ - posix-timers
+
+The conversion of nanosleep and posix-timers enabled the unification of
+nanosleep and clock_nanosleep.
+
+The code was successfully compiled for the following platforms:
+
+ i386, x86_64, ARM, PPC, PPC64, IA64
+
+The code was run-tested on the following platforms:
+
+ i386(UP/SMP), x86_64(UP/SMP), ARM, PPC
+
+hrtimers were also integrated into the -rt tree, along with a
+hrtimers-based high-resolution clock implementation, so the hrtimers
+code got a healthy amount of testing and use in practice.
+
+       Thomas Gleixner, Ingo Molnar
index d802ce88bedc923e5d5a6f49ec9bdc2deacb85bc..443230b43e092804b7573a16619e4b668803d864 100644 (file)
@@ -1033,9 +1033,9 @@ When kbuild executes the following steps are followed (roughly):
 
        Example:
                #arch/i386/Makefile
-               GCC_VERSION := $(call cc-version)
                cflags-y += $(shell \
-               if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
+               if [ $(call cc-version) -ge 0300 ] ; then \
+                       echo "-mregparm=3"; fi ;)
 
        In the above example -mregparm=3 is only used for gcc version greater
        than or equal to gcc 3.0.
index 5f08f9ce60464bdb03e7dd6c82398c79c0bd2eba..212cf3c21abf8849e39b5964607263e23da8e77f 100644 (file)
@@ -4,10 +4,10 @@ Documentation for kdump - the kexec-based crash dumping solution
 DESIGN
 ======
 
-Kdump uses kexec to reboot to a second kernel whenever a dump needs to be taken.
-This second kernel is booted with very little memory. The first kernel reserves
-the section of memory that the second kernel uses. This ensures that on-going
-DMA from the first kernel does not corrupt the second kernel.
+Kdump uses kexec to reboot to a second kernel whenever a dump needs to be
+taken. This second kernel is booted with very little memory. The first kernel
+reserves the section of memory that the second kernel uses. This ensures that
+on-going DMA from the first kernel does not corrupt the second kernel.
 
 All the necessary information about Core image is encoded in ELF format and
 stored in reserved area of memory before crash. Physical address of start of
@@ -35,77 +35,82 @@ In the second kernel, "old memory" can be accessed in two ways.
 SETUP
 =====
 
-1) Download http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz
-   and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch
-   and after that build the source.
+1) Download the upstream kexec-tools userspace package from
+   http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz.
 
-2) Download and build the appropriate (2.6.13-rc1 onwards) vanilla kernel.
+   Apply the latest consolidated kdump patch on top of kexec-tools-1.101
+   from http://lse.sourceforge.net/kdump/. This arrangment has been made
+   till all the userspace patches supporting kdump are integrated with
+   upstream kexec-tools userspace.
 
+2) Download and build the appropriate (2.6.13-rc1 onwards) vanilla kernels.
    Two kernels need to be built in order to get this feature working.
+   Following are the steps to properly configure the two kernels specific
+   to kexec and kdump features:
 
-  A) First kernel:
+  A) First kernel or regular kernel:
+  ----------------------------------
    a) Enable "kexec system call" feature (in Processor type and features).
-       CONFIG_KEXEC=y
-   b) This kernel's physical load address should be the default value of
-      0x100000 (0x100000, 1 MB) (in Processor type and features).
-       CONFIG_PHYSICAL_START=0x100000
-   c) Enable "sysfs file system support" (in Pseudo filesystems).
-       CONFIG_SYSFS=y
+      CONFIG_KEXEC=y
+   b) Enable "sysfs file system support" (in Pseudo filesystems).
+      CONFIG_SYSFS=y
+   c) make
    d) Boot into first kernel with the command line parameter "crashkernel=Y@X".
       Use appropriate values for X and Y. Y denotes how much memory to reserve
-      for the second kernel, and X denotes at what physical address the reserved
-      memory section starts. For example: "crashkernel=64M@16M".
-
-  B) Second kernel:
-   a) Enable "kernel crash dumps" feature (in Processor type and features).
-       CONFIG_CRASH_DUMP=y
-   b) Specify a suitable value for "Physical address where the kernel is
-      loaded" (in Processor type and features). Typically this value
-      should be same as X (See option d) above, e.g., 16 MB or 0x1000000.
-       CONFIG_PHYSICAL_START=0x1000000
-   c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems).
-       CONFIG_PROC_VMCORE=y
-   d) Disable SMP support and build a UP kernel (Until it is fixed).
-       CONFIG_SMP=n
-   e) Enable "Local APIC support on uniprocessors".
-       CONFIG_X86_UP_APIC=y
-   f) Enable "IO-APIC support on uniprocessors"
-       CONFIG_X86_UP_IOAPIC=y
-
-  Note:   i) Options a) and b) depend upon "Configure standard kernel features
-            (for small systems)" (under General setup).
-        ii) Option a) also depends on CONFIG_HIGHMEM (under Processor
-               type and features).
-       iii) Both option a) and b) are under "Processor type and features".
-
-3) Boot into the first kernel. You are now ready to try out kexec-based crash
-   dumps.
-
-4) Load the second kernel to be booted using:
+      for the second kernel, and X denotes at what physical address the
+      reserved memory section starts. For example: "crashkernel=64M@16M".
+
+
+  B) Second kernel or dump capture kernel:
+  ---------------------------------------
+   a) For i386 architecture enable Highmem support
+      CONFIG_HIGHMEM=y
+   b) Enable "kernel crash dumps" feature (under "Processor type and features")
+      CONFIG_CRASH_DUMP=y
+   c) Make sure a suitable value for "Physical address where the kernel is
+      loaded" (under "Processor type and features"). By default this value
+      is 0x1000000 (16MB) and it should be same as X (See option d above),
+      e.g., 16 MB or 0x1000000.
+      CONFIG_PHYSICAL_START=0x1000000
+   d) Enable "/proc/vmcore support" (Optional, under "Pseudo filesystems").
+      CONFIG_PROC_VMCORE=y
+
+3) After booting to regular kernel or first kernel, load the second kernel
+   using the following command:
 
    kexec -p <second-kernel> --args-linux --elf32-core-headers
-   --append="root=<root-dev> init 1 irqpoll"
-
-   Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work,
-           as of now.
-       ii) By default ELF headers are stored in ELF64 format. Option
-           --elf32-core-headers forces generation of ELF32 headers. gdb can
-           not open ELF64 headers on 32 bit systems. So creating ELF32
-           headers can come handy for users who have got non-PAE systems and
-           hence have memory less than 4GB.
-       iii) Specify "irqpoll" as command line parameter. This reduces driver
-            initialization failures in second kernel due to shared interrupts.
-        iv) <root-dev> needs to be specified in a format corresponding to
-            the root device name in the output of mount command.
-         v) If you have built the drivers required to mount root file
-            system as modules in <second-kernel>, then, specify
-            --initrd=<initrd-for-second-kernel>.
-
-5) System reboots into the second kernel when a panic occurs. A module can be
-   written to force the panic or "ALT-SysRq-c" can be used initiate a crash
-   dump for testing purposes.
-
-6) Write out the dump file using
+   --append="root=<root-dev> init 1 irqpoll maxcpus=1"
+
+   Notes:
+   ======
+     i) <second-kernel> has to be a vmlinux image ie uncompressed elf image.
+        bzImage will not work, as of now.
+    ii) --args-linux has to be speicfied as if kexec it loading an elf image,
+        it needs to know that the arguments supplied are of linux type.
+   iii) By default ELF headers are stored in ELF64 format to support systems
+        with more than 4GB memory. Option --elf32-core-headers forces generation
+        of ELF32 headers. The reason for this option being, as of now gdb can
+        not open vmcore file with ELF64 headers on a 32 bit systems. So ELF32
+        headers can be used if one has non-PAE systems and hence memory less
+        than 4GB.
+    iv) Specify "irqpoll" as command line parameter. This reduces driver
+         initialization failures in second kernel due to shared interrupts.
+     v) <root-dev> needs to be specified in a format corresponding to the root
+        device name in the output of mount command.
+    vi) If you have built the drivers required to mount root file system as
+        modules in <second-kernel>, then, specify
+        --initrd=<initrd-for-second-kernel>.
+   vii) Specify maxcpus=1 as, if during first kernel run, if panic happens on
+        non-boot cpus, second kernel doesn't seem to be boot up all the cpus.
+        The other option is to always built the second kernel without SMP
+        support ie CONFIG_SMP=n
+
+4) After successfully loading the second kernel as above, if a panic occurs
+   system reboots into the second kernel. A module can be written to force
+   the panic or "ALT-SysRq-c" can be used initiate a crash dump for testing
+   purposes.
+
+5) Once the second kernel has booted, write out the dump file using
 
    cp /proc/vmcore <dump-file>
 
@@ -119,9 +124,9 @@ SETUP
 
    Entire memory:  dd if=/dev/oldmem of=oldmem.001
 
+
 ANALYSIS
 ========
-
 Limited analysis can be done using gdb on the dump file copied out of
 /proc/vmcore. Use vmlinux built with -g and run
 
@@ -132,15 +137,19 @@ work fine.
 
 Note: gdb cannot analyse core files generated in ELF64 format for i386.
 
+Latest "crash" (crash-4.0-2.18) as available on Dave Anderson's site
+http://people.redhat.com/~anderson/ works well with kdump format.
+
+
 TODO
 ====
-
 1) Provide a kernel pages filtering mechanism so that core file size is not
    insane on systems having huge memory banks.
-2) Modify "crash" tool to make it recognize this dump.
+2) Relocatable kernel can help in maintaining multiple kernels for crashdump
+   and same kernel as the first kernel can be used to capture the dump.
+
 
 CONTACT
 =======
-
 Vivek Goyal (vgoyal@in.ibm.com)
 Maneesh Soni (maneesh@in.ibm.com)
index 0dc848bf0b56bb59b0c69eacfc3fb4d6a593fb7c..dd0bfc291a682e60c39441d07ef0be026dceabee 100644 (file)
@@ -475,10 +475,11 @@ running once the system is up.
                        See Documentation/block/as-iosched.txt and
                        Documentation/block/deadline-iosched.txt for details.
 
-       elfcorehdr=     [IA-32]
+       elfcorehdr=     [IA-32, X86_64]
                        Specifies physical address of start of kernel core
-                       image elf header.
-                       See Documentation/kdump.txt for details.
+                       image elf header. Generally kexec loader will
+                       pass this option to capture kernel.
+                       See Documentation/kdump/kdump.txt for details.
 
        enforcing       [SELINUX] Set initial enforcing status.
                        Format: {"0" | "1"}
@@ -832,7 +833,7 @@ running once the system is up.
        mem=nopentium   [BUGS=IA-32] Disable usage of 4MB pages for kernel
                        memory.
 
-       memmap=exactmap [KNL,IA-32] Enable setting of an exact
+       memmap=exactmap [KNL,IA-32,X86_64] Enable setting of an exact
                        E820 memory map, as specified by the user.
                        Such memmap=exactmap lines can be constructed based on
                        BIOS output or other requirements. See the memmap=nn@ss
index ce1be79edfb8e0f3143c3c2f41bff99ecc7742ed..e3b402ef33bd9f3da6614bf45f09e13b72b29cd1 100644 (file)
@@ -65,20 +65,3 @@ The default is to disallow mandatory locking. The intention is that
 mandatory locking only be enabled on a local filesystem as the specific need
 arises.
 
-Until an updated version of mount(8) becomes available you may have to apply
-this patch to the mount sources (based on the version distributed with Rick
-Faith's util-linux-2.5 package):
-
-*** mount.c.orig       Sat Jun  8 09:14:31 1996
---- mount.c    Sat Jun  8 09:13:02 1996
-***************
-*** 100,105 ****
---- 100,107 ----
-    { "noauto",        0, MS_NOAUTO    },      /* Can  only be mounted explicitly */
-    { "user",  0, MS_USER      },      /* Allow ordinary user to mount */
-    { "nouser",        1, MS_USER      },      /* Forbid ordinary user to mount */
-+   { "mand",  0, MS_MANDLOCK  },      /* Allow mandatory locks on this FS */
-+   { "nomand",        1, MS_MANDLOCK  },      /* Forbid mandatory locks on this FS */
-    /* add new options here */
-  #ifdef MS_NOSUB
-    { "sub",   1, MS_NOSUB     },      /* allow submounts */
index 2c81305090dffa5abe196add167f24a51ba796d8..e409e5d0748601db721967bbaf631a87e3020832 100644 (file)
@@ -1,58 +1,56 @@
 Everything you ever wanted to know about Linux 2.6 -stable releases.
 
-Rules on what kind of patches are accepted, and what ones are not, into
-the "-stable" tree:
+Rules on what kind of patches are accepted, and which ones are not, into the
+"-stable" tree:
 
  - It must be obviously correct and tested.
- - It can not bigger than 100 lines, with context.
+ - It can not be bigger than 100 lines, with context.
  - It must fix only one thing.
  - It must fix a real bug that bothers people (not a, "This could be a
-   problem..." type thing.)
+   problem..." type thing).
  - It must fix a problem that causes a build error (but not for things
    marked CONFIG_BROKEN), an oops, a hang, data corruption, a real
-   security issue, or some "oh, that's not good" issue.  In short,
-   something critical.
- - No "theoretical race condition" issues, unless an explanation of how
-   the race can be exploited.
+   security issue, or some "oh, that's not good" issue.  In short, something
+   critical.
+ - No "theoretical race condition" issues, unless an explanation of how the
+   race can be exploited is also provided.
  - It can not contain any "trivial" fixes in it (spelling changes,
-   whitespace cleanups, etc.)
+   whitespace cleanups, etc).
  - It must be accepted by the relevant subsystem maintainer.
- - It must follow Documentation/SubmittingPatches rules.
+ - It must follow the Documentation/SubmittingPatches rules.
 
 
 Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
    stable@kernel.org.
- - The sender will receive an ack when the patch has been accepted into
-   the queue, or a nak if the patch is rejected.  This response might
-   take a few days, according to the developer's schedules.
- - If accepted, the patch will be added to the -stable queue, for review
-   by other developers.
+ - The sender will receive an ACK when the patch has been accepted into the
+   queue, or a NAK if the patch is rejected.  This response might take a few
+   days, according to the developer's schedules.
+ - If accepted, the patch will be added to the -stable queue, for review by
+   other developers.
  - Security patches should not be sent to this alias, but instead to the
-   documented security@kernel.org.
+   documented security@kernel.org address.
 
 
 Review cycle:
 
- - When the -stable maintainers decide for a review cycle, the patches
-   will be sent to the review committee, and the maintainer of the
-   affected area of the patch (unless the submitter is the maintainer of
-   the area) and CC: to the linux-kernel mailing list.
- - The review committee has 48 hours in which to ack or nak the patch.
+ - When the -stable maintainers decide for a review cycle, the patches will be
+   sent to the review committee, and the maintainer of the affected area of
+   the patch (unless the submitter is the maintainer of the area) and CC: to
+   the linux-kernel mailing list.
+ - The review committee has 48 hours in which to ACK or NAK the patch.
  - If the patch is rejected by a member of the committee, or linux-kernel
-   members object to the patch, bringing up issues that the maintainers
-   and members did not realize, the patch will be dropped from the
-   queue.
- - At the end of the review cycle, the acked patches will be added to
-   the latest -stable release, and a new -stable release will happen.
- - Security patches will be accepted into the -stable tree directly from
-   the security kernel team, and not go through the normal review cycle.
+   members object to the patch, bringing up issues that the maintainers and
+   members did not realize, the patch will be dropped from the queue.
+ - At the end of the review cycle, the ACKed patches will be added to the
+   latest -stable release, and a new -stable release will happen.
+ - Security patches will be accepted into the -stable tree directly from the
+   security kernel team, and not go through the normal review cycle.
    Contact the kernel security team for more details on this procedure.
 
 
 Review committe:
 
- - This will be made up of a number of kernel developers who have
-   volunteered for this task, and a few that haven't.
-
+ - This is made up of a number of kernel developers who have volunteered for
+   this task, and a few that haven't.
diff --git a/Kbuild b/Kbuild
index 79003918f37f2593e157778734f2bb83d131abb1..95d6a00bace08c0ac50b80356847d5f19f6dc55a 100644 (file)
--- a/Kbuild
+++ b/Kbuild
@@ -22,8 +22,6 @@ sed-$(CONFIG_MIPS) := "/^@@@/s///p"
 
 quiet_cmd_offsets = GEN     $@
 define cmd_offsets
-       mkdir -p $(dir $@); \
-       cat $< | \
        (set -e; \
         echo "#ifndef __ASM_OFFSETS_H__"; \
         echo "#define __ASM_OFFSETS_H__"; \
@@ -34,7 +32,7 @@ define cmd_offsets
         echo " *"; \
         echo " */"; \
         echo ""; \
-        sed -ne $(sed-y); \
+        sed -ne $(sed-y) $<; \
         echo ""; \
         echo "#endif" ) > $@
 endef
@@ -45,5 +43,6 @@ arch/$(ARCH)/kernel/asm-offsets.s: arch/$(ARCH)/kernel/asm-offsets.c FORCE
        $(call if_changed_dep,cc_s_c)
 
 $(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild
+       $(Q)mkdir -p $(dir $@)
        $(call cmd,offsets)
 
index 07420161e669054211c639cedf55c56127ccb943..090e10b65b093d77cdf199d4e5b218df10ed6bf5 100644 (file)
@@ -804,6 +804,7 @@ S:  Maintained
 DOCBOOK FOR DOCUMENTATION
 P:     Martin Waitz
 M:     tali@admingilde.org
+T:     git http://tali.admingilde.org/git/linux-docbook.git
 S:     Maintained
 
 DOUBLETALK DRIVER
index fb497ea8bc748d00f72c842861c0be9aad46d57b..deedaf79cdca2325936f63b511b3744163587bd6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -141,24 +141,6 @@ VPATH              := $(srctree)
 
 export srctree objtree VPATH TOPDIR
 
-nullstring :=
-space      := $(nullstring) # end of line
-
-# Take the contents of any files called localversion* and the config
-# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE. Be
-# careful not to include files twice if building in the source
-# directory. LOCALVERSION from the command line override all of this
-
-localver := $(objtree)/localversion* $(srctree)/localversion*
-localver := $(sort $(wildcard $(localver)))
-# skip backup files (containing '~')
-localver := $(foreach f, $(localver), $(if $(findstring ~, $(f)),,$(f)))
-
-LOCALVERSION = $(subst $(space),, \
-              $(shell cat /dev/null $(localver)) \
-              $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
-
-KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
 
 # SUBARCH tells the usermode build what the underlying arch is.  That is set
 # first, and if a usermode build is happening, the "ARCH=um" on the command
@@ -353,7 +335,10 @@ CFLAGS             := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -ffreestanding
 AFLAGS         := -D__ASSEMBLY__
 
-export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION LOCALVERSION KERNELRELEASE \
+# Read KERNELRELEASE from .kernelrelease (if it exists)
+KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
+
+export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE \
        ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
        CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
        HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
@@ -551,26 +536,6 @@ export KBUILD_IMAGE ?= vmlinux
 # images. Default is /boot, but you can set it to other values
 export INSTALL_PATH ?= /boot
 
-# If CONFIG_LOCALVERSION_AUTO is set, we automatically perform some tests
-# and try to determine if the current source tree is a release tree, of any sort,
-# or if is a pure development tree.
-#
-# A 'release tree' is any tree with a git TAG associated
-# with it.  The primary goal of this is to make it safe for a native
-# git/CVS/SVN user to build a release tree (i.e, 2.6.9) and also to
-# continue developing against the current Linus tree, without having the Linus
-# tree overwrite the 2.6.9 tree when installed.
-#
-# Currently, only git is supported.
-# Other SCMs can edit scripts/setlocalversion and add the appropriate
-# checks as needed.
-
-
-ifdef CONFIG_LOCALVERSION_AUTO
-       localversion-auto := $(shell $(PERL) $(srctree)/scripts/setlocalversion $(srctree))
-       LOCALVERSION := $(LOCALVERSION)$(localversion-auto)
-endif
-
 #
 # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
 # relocations required by build roots.  This is not defined in the
@@ -782,6 +747,50 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
 $(vmlinux-dirs): prepare scripts
        $(Q)$(MAKE) $(build)=$@
 
+# Build the kernel release string
+# The KERNELRELEASE is stored in a file named .kernelrelease
+# to be used when executing for example make install or make modules_install
+#
+# Take the contents of any files called localversion* and the config
+# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE.
+# LOCALVERSION from the command line override all of this
+
+nullstring :=
+space      := $(nullstring) # end of line
+
+___localver = $(objtree)/localversion* $(srctree)/localversion*
+__localver  = $(sort $(wildcard $(___localver)))
+# skip backup files (containing '~')
+_localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f)))
+
+localver = $(subst $(space),, \
+          $(shell cat /dev/null $(_localver)) \
+          $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
+              
+# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
+# and if the SCM is know a tag from the SCM is appended.
+# The appended tag is determinded by the SCM used.
+#
+# Currently, only git is supported.
+# Other SCMs can edit scripts/setlocalversion and add the appropriate
+# checks as needed.
+ifdef CONFIG_LOCALVERSION_AUTO
+       _localver-auto = $(shell $(CONFIG_SHELL) \
+                         $(srctree)/scripts/setlocalversion $(srctree))
+       localver-auto  = $(LOCALVERSION)$(_localver-auto)
+endif
+
+localver-full = $(localver)$(localver-auto)
+
+# Store (new) KERNELRELASE string in .kernelrelease
+kernelrelease = \
+       $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(localver-full)
+.kernelrelease: FORCE
+       $(Q)rm -f .kernelrelease
+       $(Q)echo $(kernelrelease) > .kernelrelease
+       $(Q)echo "  Building kernel $(kernelrelease)"
+
+
 # Things we need to do before we recursively start building the kernel
 # or the modules are listed in "prepare".
 # A multi level approach is used. prepareN is processed before prepareN-1.
@@ -798,8 +807,7 @@ $(vmlinux-dirs): prepare scripts
 # and if so do:
 # 1) Check that make has not been executed in the kernel src $(srctree)
 # 2) Create the include2 directory, used for the second asm symlink
-
-prepare3:
+prepare3: .kernelrelease
 ifneq ($(KBUILD_SRC),)
        @echo '  Using $(srctree) as source for kernel'
        $(Q)if [ -f $(srctree)/.config ]; then \
@@ -984,9 +992,9 @@ CLEAN_FILES +=      vmlinux System.map \
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include2
-MRPROPER_FILES += .config .config.old include/asm .version \
+MRPROPER_FILES += .config .config.old include/asm .version .old_version \
                   include/linux/autoconf.h include/linux/version.h \
-                  Module.symvers tags TAGS cscope*
+                 .kernelrelease Module.symvers tags TAGS cscope*
 
 # clean - Delete most, but leave enough to build external modules
 #
@@ -1072,6 +1080,7 @@ help:
        @echo  '  tags/TAGS       - Generate tags file for editors'
        @echo  '  cscope          - Generate cscope index'
        @echo  '  kernelrelease   - Output the release version string'
+       @echo  '  kernelversion   - Output the version stored in Makefile'
        @echo  ''
        @echo  'Static analysers'
        @echo  '  buildcheck      - List dangling references to vmlinux discarded sections'
@@ -1293,6 +1302,8 @@ checkstack:
 
 kernelrelease:
        @echo $(KERNELRELEASE)
+kernelversion:
+       @echo $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
 # FIXME Should go into a make.lib or something 
 # ===========================================================================
index f3e98f837784b13d7226d907e31032eb68f75970..1898ea79d0e29f3bdbb922b2d9d0af1c0462078b 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/unistd.h>
 
 extern struct hwrpb_struct *hwrpb;
-extern void dump_thread(struct pt_regs *, struct user *);
 extern spinlock_t rtc_lock;
 
 /* these are C runtime functions with special calling conventions: */
index 90752f6d88679984151930d36beba92c8010a578..486d7945583d1d59fde2dbff8e2f919f1ef06273 100644 (file)
@@ -7,6 +7,7 @@
 /* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea@suse.de> */
 
 #include <linux/config.h>
+#include <linux/pagemap.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
index f5cc21ad09565cba72c2e1c46fd921919b8e1612..a4e5ac77f6dfc7be5fb546271a9b68569410040e 100644 (file)
@@ -64,7 +64,7 @@ static int dma_chan_count;
 static spinlock_t dma_chan_lock;
 static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
 
-const static u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
+static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
        INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
        INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
        INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
index 35514b398e2e26ce7f2e52401f39428ce3f284b4..811a6376c6243d79cc8876b27acbdf216aadcc4e 100644 (file)
@@ -35,7 +35,6 @@
 #include <asm/checksum.h>
 #include <asm/mach-types.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(struct pt_regs *, struct user_fp_struct *);
 extern void inswb(unsigned int port, void *to, int len);
 extern void outswb(unsigned int port, const void *to, int len);
index 85833d704ebb2579a137779893830a96c0e5080b..de39725da9202e1940230bb42eb66203ad71d1b4 100644 (file)
@@ -21,7 +21,6 @@
 #include <asm/pgtable.h>
 #include <asm/fasttimer.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern unsigned long get_cmos_time(void);
 extern void __Udiv(void);
 extern void __Umod(void);
@@ -33,7 +32,6 @@ extern void __lshrdi3(void);
 extern void iounmap(volatile void * __iomem);
 
 /* Platform dependent support */
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(loops_per_usec);
index 7c80afb1046077d2fb219d2542c3b815c7d3916d..4ab3e87115b602a513e72495e3f6d34d0ad73cc1 100644 (file)
@@ -257,34 +257,6 @@ void flush_thread(void)
 {
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-#if 0
-       int i;
-
-       /* changed the size calculations - should hopefully work better. lbt */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
-       dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-       dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-       for (i = 0; i < 8; i++)
-               dump->u_debugreg[i] = current->debugreg[i];  
-
-       if (dump->start_stack < TASK_SIZE)
-               dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
-
-       dump->regs = *regs;
-
-       dump->u_fpvalid = dump_fpu (regs, &dump->i387);
-#endif 
-}
-
 /* Fill in the fpu structure for a core dump. */
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
 {
index 61261b78ced7617571f349edbb683050d2f51741..60a617aff8ba465d83b38f09ebf9cbdc1dbe684c 100644 (file)
@@ -6,10 +6,6 @@ config FRV
        bool
        default y
 
-config UID16
-       bool
-       default y
-
 config RWSEM_GENERIC_SPINLOCK
        bool
        default y
index d75e0d7713660fcadc21afb72b78428bc827e87f..5dfc93fd945a9c25dff66c2b2c17c4a09946d6b9 100644 (file)
@@ -57,10 +57,10 @@ initrd:
 # installation
 #
 install: $(CONFIGURE) Image
-       sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+       sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
 zinstall: $(CONFIGURE) zImage
-       sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+       sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
 #
 # miscellany
index 5f118c89d091f82a5dedcaf2f3a4696fdf5117f6..0f1c6cbc4f50706e50267be0f41b666784afa83e 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/hardirq.h>
 #include <asm/cacheflush.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern long __memcpy_user(void *dst, const void *src, size_t count);
 extern long __memset_user(void *dst, const void *src, size_t count);
 
@@ -27,7 +26,6 @@ extern long __memset_user(void *dst, const void *src, size_t count);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
index 54a452136f00e8f93cabd0bcdf8e5a450d662b26..c4488379ac3bf022998274d629f78baccb03f513 100644 (file)
@@ -243,28 +243,6 @@ int copy_thread(int nr, unsigned long clone_flags,
        return 0;
 } /* end copy_thread() */
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs *regs, struct user *dump)
-{
-#if 0
-       /* changed the size calculations - should hopefully work better. lbt */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = user_stack(regs) & ~(PAGE_SIZE - 1);
-       dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-       dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-
-       if (dump->start_stack < TASK_SIZE)
-               dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
-
-       dump->regs = *(struct user_context *) regs;
-#endif
-}
-
 /*
  * sys_execve() executes a new program.
  */
index 795682b873e201e3af44149fcfb51f302735b086..d195568ca8a27ed1a44ed3897d47eb53cafe97a8 100644 (file)
@@ -122,7 +122,7 @@ int h8300_get_gpio_dir(int port_bit)
 static char *port_status(int portno)
 {
        static char result[10];
-       const static char io[2]={'I','O'};
+       static const char io[2]={'I','O'};
        char *rp;
        int c;
        unsigned char used,ddr;
@@ -143,7 +143,7 @@ static int gpio_proc_read(char *buf, char **start, off_t offset,
                           int len, int *unused_i, void *unused_v)
 {
        int c,outlen;
-       const static char port_name[]="123456789ABCDEFGH";
+       static const char port_name[]="123456789ABCDEFGH";
        outlen = 0;
        for (c = 0; c < MAX_PORT; c++) {
                if (ddrs[c] == NULL)
index 5a630233112ff2e77bdb5788a61813bb415eff77..3e0d80ea4464b4023d876a70f897e432a5fa73e4 100644 (file)
 //asmlinkage long long __lshrdi3 (long long, int);
 extern char h8300_debug_device[];
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 /* platform dependent support */
 
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
index fe21adf3e75e8c26e2619e71bbc5167edabc84a7..585ed5efd0f719fa5d490c6f65a7fb318dbf5550 100644 (file)
@@ -207,34 +207,6 @@ int copy_thread(int nr, unsigned long clone_flags,
        return 0;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-/* changed the size calculations - should hopefully work better. lbt */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
-       dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-       dump->u_dsize = ((unsigned long) (current->mm->brk +
-                                         (PAGE_SIZE-1))) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-
-       dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump)));
-       dump->regs.er0 = regs->er0;
-       dump->regs.er1 = regs->er1;
-       dump->regs.er2 = regs->er2;
-       dump->regs.er3 = regs->er3;
-       dump->regs.er4 = regs->er4;
-       dump->regs.er5 = regs->er5;
-       dump->regs.er6 = regs->er6;
-       dump->regs.orig_er0 = regs->orig_er0;
-       dump->regs.ccr = regs->ccr;
-       dump->regs.pc  = regs->pc;
-}
-
 /*
  * sys_execve() executes a new program.
  */
index 6ac93c05a1ae9cff1e03d797d87ee67e5ad155d5..746b1ae672a11b9af40e1afec28a84601c960bef 100644 (file)
@@ -98,7 +98,7 @@ struct optable {
                .type       = jmp, \
        }
 
-const static struct optable optable_0[] = {
+static const struct optable optable_0[] = {
        OPTABLE(0x00,0xff, 1,none), /* 0x00 */
        OPTABLE(0x01,0xff,-1,none), /* 0x01 */
        OPTABLE(0x02,0xfe, 1,none), /* 0x02-0x03 */
@@ -131,31 +131,31 @@ const static struct optable optable_0[] = {
        OPTABLE(0x80,0x80, 1,none), /* 0x80-0xff */
 };
 
-const static struct optable optable_1[] = {
+static const struct optable optable_1[] = {
        OPTABLE(0x00,0xff,-3,none), /* 0x0100 */
        OPTABLE(0x40,0xf0,-3,none), /* 0x0140-0x14f */
        OPTABLE(0x80,0xf0, 1,none), /* 0x0180-0x018f */
        OPTABLE(0xc0,0xc0, 2,none), /* 0x01c0-0x01ff */
 };
 
-const static struct optable optable_2[] = {
+static const struct optable optable_2[] = {
        OPTABLE(0x00,0x20, 2,none), /* 0x6a0?/0x6a8?/0x6b0?/0x6b8? */
        OPTABLE(0x20,0x20, 3,none), /* 0x6a2?/0x6aa?/0x6b2?/0x6ba? */
 };
 
-const static struct optable optable_3[] = {
+static const struct optable optable_3[] = {
        OPTABLE(0x69,0xfb, 2,none), /* 0x010069/0x01006d/014069/0x01406d */
        OPTABLE(0x6b,0xff,-4,none), /* 0x01006b/0x01406b */
        OPTABLE(0x6f,0xff, 3,none), /* 0x01006f/0x01406f */
        OPTABLE(0x78,0xff, 5,none), /* 0x010078/0x014078 */
 };
 
-const static struct optable optable_4[] = {
+static const struct optable optable_4[] = {
        OPTABLE(0x00,0x78, 3,none), /* 0x0100690?/0x01006d0?/0140690/0x01406d0?/0x0100698?/0x01006d8?/0140698?/0x01406d8? */
        OPTABLE(0x20,0x78, 4,none), /* 0x0100692?/0x01006d2?/0140692/0x01406d2?/0x010069a?/0x01006da?/014069a?/0x01406da? */
 };
 
-const static struct optables_list {
+static const struct optables_list {
        const struct optable *ptr;
        int size;
 } optables[] = {
index 5441cdd12a3996d46464380aba12679394cde975..f6ed663bdde0ed184874e72c02cfc435e7a86d0b 100644 (file)
@@ -52,7 +52,7 @@ struct irq_pins {
        unsigned char bit_no;
 };
 /* ISTR = 0 */
-const static struct irq_pins irq_assign_table0[16]={
+static const struct irq_pins irq_assign_table0[16]={
         {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
        {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
        {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
@@ -63,7 +63,7 @@ const static struct irq_pins irq_assign_table0[16]={
        {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
 };
 /* ISTR = 1 */
-const static struct irq_pins irq_assign_table1[16]={
+static const struct irq_pins irq_assign_table1[16]={
        {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
        {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
        {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
index f53de493e3e80c0107d44430351ca27bd603ac2e..8268dfd12f1f3c1a54ae9d943a6ed03fda099057 100644 (file)
@@ -42,7 +42,7 @@ struct irq_pins {
        unsigned char bit_no;
 } __attribute__((aligned(1),packed));
 /* ISTR = 0 */
-const static struct irq_pins irq_assign_table0[16]={
+static const struct irq_pins irq_assign_table0[16]={
         {H8300_GPIO_P5,H8300_GPIO_B0},{H8300_GPIO_P5,H8300_GPIO_B1},
        {H8300_GPIO_P5,H8300_GPIO_B2},{H8300_GPIO_P5,H8300_GPIO_B3},
        {H8300_GPIO_P5,H8300_GPIO_B4},{H8300_GPIO_P5,H8300_GPIO_B5},
@@ -53,7 +53,7 @@ const static struct irq_pins irq_assign_table0[16]={
        {H8300_GPIO_PF,H8300_GPIO_B1},{H8300_GPIO_PF,H8300_GPIO_B2},
 }; 
 /* ISTR = 1 */
-const static struct irq_pins irq_assign_table1[16]={
+static const struct irq_pins irq_assign_table1[16]={
        {H8300_GPIO_P8,H8300_GPIO_B0},{H8300_GPIO_P8,H8300_GPIO_B1},
        {H8300_GPIO_P8,H8300_GPIO_B2},{H8300_GPIO_P8,H8300_GPIO_B3},
        {H8300_GPIO_P8,H8300_GPIO_B4},{H8300_GPIO_P8,H8300_GPIO_B5},
index d849c6870e3a3a7e7a44014020f709a3286874bf..815878ebd30f0d9e1699d040e45b854320ab054a 100644 (file)
@@ -645,17 +645,6 @@ config SECCOMP
 
 source kernel/Kconfig.hz
 
-config PHYSICAL_START
-       hex "Physical address where the kernel is loaded" if EMBEDDED
-       default "0x100000"
-       help
-         This gives the physical address where the kernel is loaded.
-         Primarily used in the case of kexec on panic where the
-         fail safe kernel needs to run at a different address than
-         the panic-ed kernel.
-
-         Don't change this unless you know what you are doing.
-
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
        depends on EXPERIMENTAL
@@ -675,11 +664,31 @@ config KEXEC
 
 config CRASH_DUMP
        bool "kernel crash dumps (EXPERIMENTAL)"
-       depends on EMBEDDED
        depends on EXPERIMENTAL
        depends on HIGHMEM
        help
          Generate crash dump after being started by kexec.
+
+config PHYSICAL_START
+       hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
+
+       default "0x1000000" if CRASH_DUMP
+       default "0x100000"
+       help
+         This gives the physical address where the kernel is loaded. Normally
+         for regular kernels this value is 0x100000 (1MB). But in the case
+         of kexec on panic the fail safe kernel needs to run at a different
+         address than the panic-ed kernel. This option is used to set the load
+         address for kernels used to capture crash dump on being kexec'ed
+         after panic. The default value for crash dump kernels is
+         0x1000000 (16MB). This can also be set based on the "X" value as
+         specified in the "crashkernel=YM@XM" command line boot parameter
+         passed to the panic-ed kernel. Typically this parameter is set as
+         crashkernel=64M@16M. Please take a look at
+         Documentation/kdump/kdump.txt for more details about crash dumps.
+
+         Don't change this unless you know what you are doing.
+
 endmenu
 
 
@@ -1051,3 +1060,7 @@ config X86_TRAMPOLINE
        bool
        depends on X86_SMP || (X86_VOYAGER && SMP)
        default y
+
+config KTIME_SCALAR
+       bool
+       default y
index b84119f9cc63a1ff2df55dd1e3fad00e5211b3b6..d3c0409d201cebcd2a258c1ab2bb1983959e5d23 100644 (file)
@@ -37,7 +37,10 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
 # CPU-specific tuning. Anything which can be shared with UML should go here.
 include $(srctree)/arch/i386/Makefile.cpu
 
-cflags-$(CONFIG_REGPARM)       += -mregparm=3
+# -mregparm=3 works ok on gcc-3.0 and later
+#
+cflags-$(CONFIG_REGPARM) += $(shell if [ $(call cc-version) -ge 0300 ] ; then \
+                            echo "-mregparm=3"; fi ;)
 
 # Disable unit-at-a-time mode, it makes gcc use a lot more stack
 # due to the lack of sharing of stacklots.
@@ -100,7 +103,7 @@ AFLAGS += $(mflags-y)
 boot := arch/i386/boot
 
 .PHONY: zImage bzImage compressed zlilo bzlilo \
-       zdisk bzdisk fdimage fdimage144 fdimage288 install kernel_install
+       zdisk bzdisk fdimage fdimage144 fdimage288 install
 
 all: bzImage
 
@@ -122,8 +125,7 @@ zdisk bzdisk: vmlinux
 fdimage fdimage144 fdimage288: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
 
-install: vmlinux
-install kernel_install:
+install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
 
 archclean:
index 1e71382d413a99b40f3a1e759ee0254acff94539..0fea75dd4e318569f0dad27c126c50cc94636261 100644 (file)
@@ -100,5 +100,5 @@ zlilo: $(BOOTIMAGE)
        cp System.map $(INSTALL_PATH)/
        if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
-install: $(BOOTIMAGE)
+install:
        sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
index f17b40dfc0f4bde512541ded9c67a88570eb3460..5e44c736eea81700dc7559c97462b21514e25850 100644 (file)
 #   $4 - default install path (blank if root directory)
 #
 
+verify () {
+       if [ ! -f "$1" ]; then
+               echo ""                                                   1>&2
+               echo " *** Missing file: $1"                              1>&2
+               echo ' *** You need to run "make" before "make install".' 1>&2
+               echo ""                                                   1>&2
+               exit 1
+       fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
 # User may have a custom install script
 
 if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
index 92f6694701420a1ef102f9155d2c1e1c349c91f5..2ac40c8244c47145fb1d7feae7c42b9fe03bf1d8 100644 (file)
@@ -97,7 +97,6 @@
 #define PARAM_VESAPM_OFF       0x30
 #define PARAM_LFB_PAGES                0x32
 #define PARAM_VESA_ATTRIB      0x34
-#define PARAM_CAPABILITIES      0x36
 
 /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
 #ifdef CONFIG_VIDEO_RETAIN
@@ -234,10 +233,6 @@ mopar_gr:
        movw    18(%di), %ax
        movl    %eax, %fs:(PARAM_LFB_SIZE)
 
-# store mode capabilities
-       movl    10(%di), %eax
-       movl    %eax, %fs:(PARAM_CAPABILITIES)
-
 # switching the DAC to 8-bit is for <= 8 bpp only
        movw    %fs:(PARAM_LFB_DEPTH), %ax
        cmpw    $8, %ax
index be1880bb75b48ddace3a08ceb642b803b37413a0..60c3f76dfca42efa00e71f9ae34a85d837511e27 100644 (file)
@@ -25,6 +25,7 @@ obj-$(CONFIG_X86_LOCAL_APIC)  += apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
+obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_X86_NUMAQ)                += numaq.o
 obj-$(CONFIG_X86_SUMMIT_NUMA)  += summit.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
index 0248e084017ceddd74bcc7e92052cef801b897ff..d49dbe8dc96b345efa52c579e96782db3ecc3b3b 100644 (file)
@@ -25,7 +25,6 @@
 #include <mach_ipi.h>
 
 
-note_buf_t crash_notes[NR_CPUS];
 /* This keeps a track of which one is crashing cpu. */
 static int crashing_cpu;
 
@@ -72,7 +71,9 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
         * squirrelled away.  ELF notes happen to provide
         * all of that that no need to invent something new.
         */
-       buf = &crash_notes[cpu][0];
+       buf = (u32*)per_cpu_ptr(crash_notes, cpu);
+       if (!buf)
+               return;
        memset(&prstatus, 0, sizeof(prstatus));
        prstatus.pr_pid = current->pid;
        elf_core_copy_regs(&prstatus.pr_reg, regs);
@@ -81,51 +82,12 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
        final_note(buf);
 }
 
-static void crash_get_current_regs(struct pt_regs *regs)
-{
-       __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
-       __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
-       __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
-       __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
-       __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
-       __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
-       __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
-       __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
-       __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
-       __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
-       __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
-       __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
-       __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
-
-       regs->eip = (unsigned long)current_text_addr();
-}
-
-/* CPU does not save ss and esp on stack if execution is already
- * running in kernel mode at the time of NMI occurrence. This code
- * fixes it.
- */
-static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
-{
-       memcpy(newregs, oldregs, sizeof(*newregs));
-       newregs->esp = (unsigned long)&(oldregs->esp);
-       __asm__ __volatile__("xorl %eax, %eax;");
-       __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
-}
-
-/* We may have saved_regs from where the error came from
- * or it is NULL if via a direct panic().
- */
-static void crash_save_self(struct pt_regs *saved_regs)
+static void crash_save_self(struct pt_regs *regs)
 {
-       struct pt_regs regs;
        int cpu;
 
        cpu = smp_processor_id();
-       if (saved_regs)
-               crash_setup_regs(&regs, saved_regs);
-       else
-               crash_get_current_regs(&regs);
-       crash_save_this_cpu(&regs, cpu);
+       crash_save_this_cpu(regs, cpu);
 }
 
 #ifdef CONFIG_SMP
@@ -144,7 +106,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
        local_irq_disable();
 
        if (!user_mode(regs)) {
-               crash_setup_regs(&fixed_regs, regs);
+               crash_fixup_ss_esp(&fixed_regs, regs);
                regs = &fixed_regs;
        }
        crash_save_this_cpu(regs, cpu);
diff --git a/arch/i386/kernel/crash_dump.c b/arch/i386/kernel/crash_dump.c
new file mode 100644 (file)
index 0000000..3f532df
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *     kernel/crash_dump.c - Memory preserving reboot related code.
+ *
+ *     Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *     Copyright (C) IBM Corporation, 2004. All rights reserved
+ */
+
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
+
+#include <asm/uaccess.h>
+
+static void *kdump_buf_page;
+
+/**
+ * copy_oldmem_page - copy one page from "oldmem"
+ * @pfn: page frame number to be copied
+ * @buf: target memory address for the copy; this can be in kernel address
+ *     space or user address space (see @userbuf)
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
+ *     otherwise @buf is in kernel address space, use memcpy().
+ *
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
+ *
+ * Calling copy_to_user() in atomic context is not desirable. Hence first
+ * copying the data to a pre-allocated kernel page and then copying to user
+ * space in non-atomic context.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+                               size_t csize, unsigned long offset, int userbuf)
+{
+       void  *vaddr;
+
+       if (!csize)
+               return 0;
+
+       vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
+
+       if (!userbuf) {
+               memcpy(buf, (vaddr + offset), csize);
+               kunmap_atomic(vaddr, KM_PTE0);
+       } else {
+               if (!kdump_buf_page) {
+                       printk(KERN_WARNING "Kdump: Kdump buffer page not"
+                               " allocated\n");
+                       return -EFAULT;
+               }
+               copy_page(kdump_buf_page, vaddr);
+               kunmap_atomic(vaddr, KM_PTE0);
+               if (copy_to_user(buf, (kdump_buf_page + offset), csize))
+                       return -EFAULT;
+       }
+
+       return csize;
+}
+
+static int __init kdump_buf_page_init(void)
+{
+       int ret = 0;
+
+       kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!kdump_buf_page) {
+               printk(KERN_WARNING "Kdump: Failed to allocate kdump buffer"
+                        " page\n");
+               ret = -ENOMEM;
+       }
+
+       return ret;
+}
+arch_initcall(kdump_buf_page_init);
index 19edcd526ba4800f9c71c66ef7ad18da5eb1b7bc..2f372dbd34fd54a80c77b6a6380fc5794b3ba781 100644 (file)
@@ -57,14 +57,10 @@ static inline int is_IF_modifier(kprobe_opcode_t opcode)
 }
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
-       return 0;
-}
-
-void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
        memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
        p->opcode = *p->addr;
+       return 0;
 }
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
@@ -81,10 +77,6 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
                           (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void __kprobes arch_remove_kprobe(struct kprobe *p)
-{
-}
-
 static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
index 27c956db0461508f1d0e64d108d47990e3709d9d..f685637a100d7ab266f013ed7973197be297d6bc 100644 (file)
@@ -898,7 +898,7 @@ static void __init parse_cmdline_early (char ** cmdline_p)
                        }
                }
 #endif
-#ifdef CONFIG_CRASH_DUMP
+#ifdef CONFIG_PROC_VMCORE
                /* elfcorehdr= specifies the location of elf core header
                 * stored by the crashed kernel.
                 */
index 53ad954e3ba489a5929871812f3a7bb3f7f1c5bf..b9f0030a2ebbc38494bfaee9ae47656672ac0336 100644 (file)
@@ -120,7 +120,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
 #ifdef CONFIG_FRAME_POINTER
        while (valid_stack_ptr(tinfo, (void *)ebp)) {
                addr = *(unsigned long *)(ebp + 4);
-               printk(" [<%08lx>] ", addr);
+               printk(KERN_EMERG " [<%08lx>] ", addr);
                print_symbol("%s", addr);
                printk("\n");
                ebp = *(unsigned long *)ebp;
@@ -129,7 +129,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
        while (valid_stack_ptr(tinfo, stack)) {
                addr = *stack++;
                if (__kernel_text_address(addr)) {
-                       printk(" [<%08lx>]", addr);
+                       printk(KERN_EMERG " [<%08lx>]", addr);
                        print_symbol(" %s", addr);
                        printk("\n");
                }
@@ -161,7 +161,7 @@ void show_trace(struct task_struct *task, unsigned long * stack)
                stack = (unsigned long*)context->previous_esp;
                if (!stack)
                        break;
-               printk(" =======================\n");
+               printk(KERN_EMERG " =======================\n");
        }
 }
 
@@ -178,14 +178,15 @@ void show_stack(struct task_struct *task, unsigned long *esp)
        }
 
        stack = esp;
+       printk(KERN_EMERG);
        for(i = 0; i < kstack_depth_to_print; i++) {
                if (kstack_end(stack))
                        break;
                if (i && ((i % 8) == 0))
-                       printk("\n       ");
+                       printk("\n" KERN_EMERG "       ");
                printk("%08lx ", *stack++);
        }
-       printk("\nCall Trace:\n");
+       printk("\n" KERN_EMERG "Call Trace:\n");
        show_trace(task, esp);
 }
 
@@ -216,18 +217,18 @@ void show_registers(struct pt_regs *regs)
                ss = regs->xss & 0xffff;
        }
        print_modules();
-       printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\nEFLAGS: %08lx"
-                       "   (%s) \n",
+       printk(KERN_EMERG "CPU:    %d\nEIP:    %04x:[<%08lx>]    %s VLI\n"
+                       "EFLAGS: %08lx   (%s) \n",
                smp_processor_id(), 0xffff & regs->xcs, regs->eip,
                print_tainted(), regs->eflags, system_utsname.release);
-       print_symbol("EIP is at %s\n", regs->eip);
-       printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+       print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
+       printk(KERN_EMERG "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
-       printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
+       printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
                regs->esi, regs->edi, regs->ebp, esp);
-       printk("ds: %04x   es: %04x   ss: %04x\n",
+       printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
                regs->xds & 0xffff, regs->xes & 0xffff, ss);
-       printk("Process %s (pid: %d, threadinfo=%p task=%p)",
+       printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)",
                current->comm, current->pid, current_thread_info(), current);
        /*
         * When in-kernel, we also print out the stack and code at the
@@ -236,10 +237,10 @@ void show_registers(struct pt_regs *regs)
        if (in_kernel) {
                u8 __user *eip;
 
-               printk("\nStack: ");
+               printk("\n" KERN_EMERG "Stack: ");
                show_stack(NULL, (unsigned long*)esp);
 
-               printk("Code: ");
+               printk(KERN_EMERG "Code: ");
 
                eip = (u8 __user *)regs->eip - 43;
                for (i = 0; i < 64; i++, eip++) {
@@ -280,15 +281,15 @@ static void handle_BUG(struct pt_regs *regs)
                (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
                file = "<bad filename>";
 
-       printk("------------[ cut here ]------------\n");
-       printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
+       printk(KERN_EMERG "------------[ cut here ]------------\n");
+       printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
 
 no_bug:
        return;
 
        /* Here we know it was a BUG but file-n-line is unavailable */
 bug:
-       printk("Kernel BUG\n");
+       printk(KERN_EMERG "Kernel BUG\n");
 }
 
 /* This is gone through when something in the kernel
@@ -321,16 +322,20 @@ void die(const char * str, struct pt_regs * regs, long err)
        if (++die.lock_owner_depth < 3) {
                int nl = 0;
                handle_BUG(regs);
-               printk(KERN_ALERT "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+               printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
-               printk("PREEMPT ");
+               printk(KERN_EMERG "PREEMPT ");
                nl = 1;
 #endif
 #ifdef CONFIG_SMP
+               if (!nl)
+                       printk(KERN_EMERG);
                printk("SMP ");
                nl = 1;
 #endif
 #ifdef CONFIG_DEBUG_PAGEALLOC
+               if (!nl)
+                       printk(KERN_EMERG);
                printk("DEBUG_PAGEALLOC");
                nl = 1;
 #endif
@@ -339,7 +344,7 @@ void die(const char * str, struct pt_regs * regs, long err)
        notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
                show_registers(regs);
        } else
-               printk(KERN_ERR "Recursive die() failure, output suppressed\n");
+               printk(KERN_EMERG "Recursive die() failure, output suppressed\n");
 
        bust_spinlocks(0);
        die.lock_owner = -1;
@@ -527,8 +532,10 @@ gp_in_kernel:
 
 static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
 {
-       printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
-       printk("You probably have a hardware problem with your RAM chips\n");
+       printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying "
+                       "to continue\n");
+       printk(KERN_EMERG "You probably have a hardware problem with your RAM "
+                       "chips\n");
 
        /* Clear and disable the memory parity error line. */
        clear_mem_error(reason);
@@ -538,7 +545,7 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs)
 {
        unsigned long i;
 
-       printk("NMI: IOCK error (debug interrupt?)\n");
+       printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
        show_registers(regs);
 
        /* Re-enable the IOCK line, wait for a few seconds */
@@ -580,11 +587,11 @@ void die_nmi (struct pt_regs *regs, const char *msg)
        * to get a message out.
        */
        bust_spinlocks(1);
-       printk(msg);
+       printk(KERN_EMERG "%s", msg);
        printk(" on CPU%d, eip %08lx, registers:\n",
                smp_processor_id(), regs->eip);
        show_registers(regs);
-       printk("console shuts up ...\n");
+       printk(KERN_EMERG "console shuts up ...\n");
        console_silent();
        spin_unlock(&nmi_print_lock);
        bust_spinlocks(0);
@@ -990,8 +997,8 @@ asmlinkage void math_state_restore(struct pt_regs regs)
 
 asmlinkage void math_emulate(long arg)
 {
-       printk("math-emulation not enabled and no coprocessor found.\n");
-       printk("killing %s.\n",current->comm);
+       printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n");
+       printk(KERN_EMERG "killing %s.\n",current->comm);
        force_sig(SIGFPE,current);
        schedule();
 }
index 57b047c27e4641e092dd485b7c09e6fba1d28fc5..f722e1a25948018826db23c9b482707c20ba8393 100644 (file)
@@ -25,7 +25,6 @@ cflags-y      := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
                   -falign-functions=32 -frename-registers -fno-optimize-sibling-calls
 CFLAGS_KERNEL  := -mconstant-gp
 
-GCC_VERSION     := $(call cc-version)
 GAS_STATUS     = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
 CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
 
@@ -37,7 +36,7 @@ $(error Sorry, you need a newer version of the assember, one that is built from
                ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
-ifeq ($(GCC_VERSION),0304)
+ifeq ($(call cc-version),0304)
        cflags-$(CONFIG_ITANIUM)        += -mtune=merced
        cflags-$(CONFIG_MCKINLEY)       += -mtune=mckinley
 endif
index 2ed90da81166ff6b9ce0126a94f41eee120f29a8..61cb60affd95aec8c828a92a7540bffa6bc7bfba 100644 (file)
@@ -2,11 +2,9 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-obj-y := ia32_entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
+obj-y := ia32_entry.o sys_ia32.o ia32_signal.o \
         ia32_support.o ia32_traps.o binfmt_elf32.o ia32_ldt.o
 
-CFLAGS_ia32_ioctl.o += -Ifs/
-
 # Don't let GCC uses f16-f31 so that save_ia32_fpstate_live() and
 # restore_ia32_fpstate_live() can be sure the live register contain user-level state.
 CFLAGS_ia32_signal.o += -mfixed-range=f16-f31
index 494fad6bf376dfdc845b2c25f3dcdfb40a02ac93..95fe04400f6b65f7cfe10eb5a6c0fac95cf9e51f 100644 (file)
@@ -469,7 +469,7 @@ ia32_syscall_table:
        data8 sys32_epoll_wait
        data8 sys_remap_file_pages
        data8 sys_set_tid_address
-       data8 sys32_timer_create
+       data8 compat_sys_timer_create
        data8 compat_sys_timer_settime  /* 260 */
        data8 compat_sys_timer_gettime
        data8 sys_timer_getoverrun
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
deleted file mode 100644 (file)
index 8873939..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * IA32 Architecture-specific ioctl shim code
- *
- * Copyright (C) 2000 VA Linux Co
- * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
- * Copyright (C) 2001-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/signal.h>      /* argh, msdos_fs.h isn't self-contained... */
-#include <linux/syscalls.h>
-#include "ia32priv.h"
-  
-#define        INCLUDES
-#include "compat_ioctl.c"
-
-#define IOCTL_NR(a)    ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
-
-#define DO_IOCTL(fd, cmd, arg) ({                      \
-       int _ret;                                       \
-       mm_segment_t _old_fs = get_fs();                \
-                                                       \
-       set_fs(KERNEL_DS);                              \
-       _ret = sys_ioctl(fd, cmd, (unsigned long)arg);  \
-       set_fs(_old_fs);                                \
-       _ret;                                           \
-})
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define COMPATIBLE_IOCTL(cmd)          HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler)      { (cmd), (ioctl_trans_handler_t)(handler), NULL },
-#define IOCTL_TABLE_START \
-       struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-       };
-
-IOCTL_TABLE_START
-#define DECLARES
-#include "compat_ioctl.c"
-#include <linux/compat_ioctl.h>
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 9f8e8d5588731066475d8dc235a3f8bc7d608e34..5ea38286d8d5856dc5005a4f159295c834322f9c 100644 (file)
@@ -2553,34 +2553,6 @@ sys32_get_thread_area (struct ia32_user_desc __user *u_info)
        return 0;
 }
 
-asmlinkage long
-sys32_timer_create(u32 clock, struct compat_sigevent __user *se32, timer_t __user *timer_id)
-{
-       struct sigevent se;
-       mm_segment_t oldfs;
-       timer_t t;
-       long err;
-
-       if (se32 == NULL)
-               return sys_timer_create(clock, NULL, timer_id);
-
-       if (get_compat_sigevent(&se, se32))
-               return -EFAULT;
-
-       if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
-               return -EFAULT;
-
-       oldfs = get_fs();
-       set_fs(KERNEL_DS);
-       err = sys_timer_create(clock, (struct sigevent __user *) &se, (timer_t __user *) &t);
-       set_fs(oldfs);
-
-       if (!err)
-               err = __put_user (t, timer_id);
-
-       return err;
-}
-
 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
                        __u32 len_low, __u32 len_high, int advice)
 { 
index 89a70400c4f638efa3ed6face511777cf90bb5b4..4de7f6759093720595fe958f0b757d5adb884cd5 100644 (file)
@@ -467,10 +467,6 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
        flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
 }
 
-void __kprobes arch_remove_kprobe(struct kprobe *p)
-{
-}
-
 /*
  * We are resuming execution after a single step fault, so the pt_regs
  * structure reflects the register state after we executed the instruction
index fae67bbb52f614fa27566636ad7952db512a81cb..a3dcc3fab4b736660ab3b621d3321c730949f501 100644 (file)
@@ -12,10 +12,6 @@ config M32R
 config SBUS
        bool
 
-config UID16
-       bool
-       default n
-
 config GENERIC_ISA_DMA
        bool
        default y
index e5ec134d81d98baa12ca8c3e6741e75d9e794a95..dbc8a392105fba65faa118e5c4670b8a806c6b1a 100644 (file)
@@ -18,8 +18,6 @@
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 extern struct drive_info_struct drive_info;
 EXPORT_SYMBOL(drive_info);
@@ -27,7 +25,6 @@ EXPORT_SYMBOL(drive_info);
 
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
index 3bf55d92933f62f635c1c1be3290f5fa13cc4348..2a1f250349b7027f057a2386c5ed555f0fafa171 100644 (file)
@@ -260,14 +260,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
        return 0;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-       /* M32R_FIXME */
-}
-
 /*
  * Capture the user space registers if the task is not running (in user space)
  */
index 73e2f5e168ddd17706a22333303e3e6c486e872b..3d7f2000b7146dcff56f1927ff58f3d5cdf71097 100644 (file)
@@ -23,8 +23,6 @@ asmlinkage long long __lshrdi3 (long long, int);
 asmlinkage long long __muldi3 (long long, long long);
 extern char m68k_debug_device[];
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 /* platform dependent support */
 
 EXPORT_SYMBOL(m68k_machtype);
index b2c62eeb3bab6624807c0ee1f05e4041eb371cfa..eddb8d3e130ab116e7957349e2a17beb0566646b 100644 (file)
@@ -18,7 +18,6 @@
 #include <asm/checksum.h>
 #include <asm/current.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
 /* platform dependent support */
@@ -26,7 +25,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
index 82e7ec8888064589dcf642e336f11d32e209dd0b..8b3cf57ba706f04043a3da3f11e590ea5d7052a0 100644 (file)
@@ -275,52 +275,6 @@ int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
        return 1;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-       struct switch_stack *sw;
-
-       /* changed the size calculations - should hopefully work better. lbt */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
-       dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-       dump->u_dsize = ((unsigned long) (current->mm->brk +
-                                         (PAGE_SIZE-1))) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-
-       if (dump->start_stack < TASK_SIZE)
-               dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
-
-       dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
-       sw = ((struct switch_stack *)regs) - 1;
-       dump->regs.d1 = regs->d1;
-       dump->regs.d2 = regs->d2;
-       dump->regs.d3 = regs->d3;
-       dump->regs.d4 = regs->d4;
-       dump->regs.d5 = regs->d5;
-       dump->regs.d6 = sw->d6;
-       dump->regs.d7 = sw->d7;
-       dump->regs.a0 = regs->a0;
-       dump->regs.a1 = regs->a1;
-       dump->regs.a2 = regs->a2;
-       dump->regs.a3 = sw->a3;
-       dump->regs.a4 = sw->a4;
-       dump->regs.a5 = sw->a5;
-       dump->regs.a6 = sw->a6;
-       dump->regs.d0 = regs->d0;
-       dump->regs.orig_d0 = regs->orig_d0;
-       dump->regs.stkadj = regs->stkadj;
-       dump->regs.sr = regs->sr;
-       dump->regs.pc = regs->pc;
-       dump->regs.fmtvec = (regs->format << 12) | regs->vector;
-       /* dump floating point stuff */
-       dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
-}
-
 /*
  *     Generic dumping code. Used for panic and debug.
  */
index 72f2126ad19d95fb3cc724ad6d4728971e2eb9ef..f36c4f20ee8af09bbeca3658cf96ba15a410d8b2 100644 (file)
@@ -50,7 +50,7 @@ obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
 obj-$(CONFIG_32BIT)            += scall32-o32.o
 obj-$(CONFIG_64BIT)            += scall64-64.o
 obj-$(CONFIG_BINFMT_IRIX)      += binfmt_irix.o
-obj-$(CONFIG_MIPS32_COMPAT)    += ioctl32.o linux32.o signal32.o
+obj-$(CONFIG_MIPS32_COMPAT)    += linux32.o signal32.o
 obj-$(CONFIG_MIPS32_N32)       += binfmt_elfn32.o scall64-n32.o signal_n32.o
 obj-$(CONFIG_MIPS32_O32)       += binfmt_elfo32.o scall64-o32.o ptrace32.o
 
@@ -60,6 +60,5 @@ obj-$(CONFIG_PROC_FS)         += proc.o
 obj-$(CONFIG_64BIT)            += cpu-bugs64.o
 
 CFLAGS_cpu-bugs64.o    = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
-CFLAGS_ioctl32.o       += -Ifs/
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c
deleted file mode 100644 (file)
index 9ea1fc7..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Written by Ulf Carlsson (ulfc@engr.sgi.com)
- * Copyright (C) 2000, 2004 Ralf Baechle
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
- */
-#define INCLUDES
-#include "compat_ioctl.c"
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/compat.h>
-#include <linux/ioctl32.h>
-#include <linux/syscalls.h>
-
-#ifdef CONFIG_SIBYTE_TBPROF
-#include <asm/sibyte/trace_prof.h>
-#endif
-
-#define A(__x) ((unsigned long)(__x))
-
-long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define COMPATIBLE_IOCTL(cmd)          HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler)      { (cmd), (ioctl_trans_handler_t)(handler), NULL },
-#define IOCTL_TABLE_START \
-       struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-       };
-
-IOCTL_TABLE_START
-
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-
-/*HANDLE_IOCTL(RTC_IRQP_READ, w_long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
-*/
-
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 171f9c239f60c8c80e7cfa856c0591268f5bf891..27827bc3717e8fcf4b1e8ae0d6cf5b6771debf60 100644 (file)
@@ -6,7 +6,6 @@ extra-y                 := init_task.o head.o vmlinux.lds
 
 AFLAGS_entry.o := -traditional
 AFLAGS_pacache.o := -traditional
-CFLAGS_ioctl32.o := -Ifs/
 
 obj-y          := cache.o pacache.o setup.o traps.o time.o irq.o \
                   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
@@ -19,6 +18,6 @@ obj-$(CONFIG_SMP)     += smp.o
 obj-$(CONFIG_PA11)     += pci-dma.o
 obj-$(CONFIG_PCI)      += pci.o
 obj-$(CONFIG_MODULES)  += module.o
-obj-$(CONFIG_64BIT)    += binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
+obj-$(CONFIG_64BIT)    += binfmt_elf32.o sys_parisc32.o signal32.o
 # only supported for PCX-W/U in 64-bit mode at the moment
 obj-$(CONFIG_64BIT)    += perf.o perf_asm.o
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
deleted file mode 100644 (file)
index 4eada1b..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* $Id: ioctl32.c,v 1.5 2002/10/18 00:21:43 varenet Exp $
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#include <linux/syscalls.h>
-
-#define INCLUDES
-#include "compat_ioctl.c"
-
-#include <asm/perf.h>
-#include <asm/ioctls.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
-
-#define IOCTL_TABLE_START  struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END    };
-
-IOCTL_TABLE_START
-#include <linux/compat_ioctl.h>
-
-#define DECLARES
-#include "compat_ioctl.c"
-
-/* And these ioctls need translation */
-HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
-HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
-
-#if defined(CONFIG_GEN_RTC)
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
-HANDLE_IOCTL(RTC_IRQP_READ, w_long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
-#endif
-
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 28004f002ec9f810e3885db237514fab696a42fe..935d965715154ea784aaf66e2a78afe8d596403c 100644 (file)
@@ -275,6 +275,7 @@ config PPC_PSERIES
        select PPC_I8259
        select PPC_RTAS
        select RTAS_ERROR_LOGGING
+       select PPC_UDBG_16550
        default y
 
 config PPC_CHRP
@@ -284,6 +285,7 @@ config PPC_CHRP
        select PPC_INDIRECT_PCI
        select PPC_RTAS
        select PPC_MPC106
+       select PPC_UDBG_16550
        default y
 
 config PPC_PMAC
@@ -306,6 +308,7 @@ config PPC_PREP
        depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
        select PPC_I8259
        select PPC_INDIRECT_PCI
+       select PPC_UDBG_16550
        default y
 
 config PPC_MAPLE
@@ -314,6 +317,7 @@ config PPC_MAPLE
        select U3_DART
        select MPIC_BROKEN_U3
        select GENERIC_TBSYNC
+       select PPC_UDBG_16550
        default n
        help
           This option enables support for the Maple 970FX Evaluation Board.
@@ -324,6 +328,7 @@ config PPC_CELL
        depends on PPC_MULTIPLATFORM && PPC64
        select PPC_RTAS
        select MMIO_NVRAM
+       select PPC_UDBG_16550
 
 config PPC_OF
        def_bool y
@@ -370,6 +375,10 @@ config MPIC_BROKEN_U3
        depends on PPC_MAPLE
        default y
 
+config PPC_UDBG_16550
+       bool
+       default n
+
 config CELL_IIC
        depends on PPC_CELL
        bool
@@ -403,7 +412,7 @@ config PPC_MPC106
 
 config GENERIC_TBSYNC
        bool
-       default y if CONFIG_PPC32 && CONFIG_SMP
+       default y if PPC32 && SMP
        default n
 
 source "drivers/cpufreq/Kconfig"
index 5f80e58e5cb34aa4d20e1c0a8c2d13e8c04b2fb3..d3654a264ef7533a8811f9e170fb4f7b4c5499ab 100644 (file)
@@ -76,8 +76,7 @@ LINUXINCLUDE    += $(LINUXINCLUDE-y)
 CHECKFLAGS     += -m$(SZ) -D__powerpc__ -D__powerpc$(SZ)__
 
 ifeq ($(CONFIG_PPC64),y)
-GCC_VERSION     := $(call cc-version)
-GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi)
+GCC_BROKEN_VEC := $(shell if [ $(call cc-version) -lt 0400 ] ; then echo "y"; fi)
 
 ifeq ($(CONFIG_POWER4_ONLY),y)
 ifeq ($(CONFIG_ALTIVEC),y)
@@ -189,10 +188,9 @@ TOUT       := .tmp_gas_check
 # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
 # instructions.
 # gcc-3.4 and binutils-2.14 are a fatal combination.
-GCC_VERSION    := $(call cc-version)
 
 checkbin:
-       @if test "$(GCC_VERSION)" = "0304" ; then \
+       @if test "$(call cc-version)" = "0304" ; then \
                if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
                        echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
                        echo 'correctly with gcc-3.4 and your version of binutils.'; \
index 509399eab6f58e8717587916799ad13719fc4a25..347f4391db8d656092c35fec26f8ec210d74ee63 100644 (file)
@@ -861,7 +861,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_PMACZILOG is not set
 CONFIG_SERIAL_ICOM=m
-CONFIG_SERIAL_JSM=m
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
index 6e03b595b6c83220e10e97b937f267ada37d2875..144e284d21dde7889b1353f1c14ce1a558bd66cc 100644 (file)
@@ -4,7 +4,6 @@
 
 ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS   += -mno-minimal-toc
-CFLAGS_ioctl32.o += -Ifs/
 endif
 ifeq ($(CONFIG_PPC32),y)
 CFLAGS_prom_init.o      += -fPIC
@@ -16,7 +15,7 @@ obj-y                         := semaphore.o cputable.o ptrace.o syscalls.o \
 obj-y                          += vdso32/
 obj-$(CONFIG_PPC64)            += setup_64.o binfmt_elf32.o sys_ppc32.o \
                                   signal_64.o ptrace32.o systbl.o \
-                                  paca.o ioctl32.o cpu_setup_power4.o \
+                                  paca.o cpu_setup_power4.o \
                                   firmware.o sysfs.o idle_64.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
@@ -55,7 +54,7 @@ obj-$(CONFIG_BOOTX_TEXT)      += btext.o
 obj-$(CONFIG_6xx)              += idle_6xx.o
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
-obj-$(CONFIG_SERIAL_8250)      += legacy_serial.o udbg_16550.o
+obj-$(CONFIG_PPC_UDBG_16550)   += legacy_serial.o udbg_16550.o
 module-$(CONFIG_PPC64)         += module_64.o
 obj-$(CONFIG_MODULES)          += $(module-y)
 
diff --git a/arch/powerpc/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c
deleted file mode 100644 (file)
index 0fa3d27..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Based on sparc64 ioctl32.c by:
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- *
- * ppc64 changes:
- *
- * Copyright (C) 2000  Ken Aaker (kdaaker@rchland.vnet.ibm.com)
- * Copyright (C) 2001  Anton Blanchard (antonb@au.ibm.com)
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- *
- * 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.
- */
-
-#define INCLUDES
-#include "compat_ioctl.c"
-#include <linux/syscalls.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define HANDLE_IOCTL(cmd,handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-
-#define IOCTL_TABLE_START \
-       struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-       };
-
-IOCTL_TABLE_START
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 5368f9c2e6bff7707c040812f1260c8269d1373d..27b0c40601fb5d6db8a13b9915ad2d626152173f 100644 (file)
@@ -35,7 +35,6 @@
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
 
-static DECLARE_MUTEX(kprobe_mutex);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
@@ -54,19 +53,17 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 
        /* insn must be on a special executable page on ppc64 */
        if (!ret) {
-               down(&kprobe_mutex);
                p->ainsn.insn = get_insn_slot();
-               up(&kprobe_mutex);
                if (!p->ainsn.insn)
                        ret = -ENOMEM;
        }
-       return ret;
-}
 
-void __kprobes arch_copy_kprobe(struct kprobe *p)
-{
-       memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-       p->opcode = *p->addr;
+       if (!ret) {
+               memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+               p->opcode = *p->addr;
+       }
+
+       return ret;
 }
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
index fc60a773af7db3a4652ded23e5f0e9ada5e0cb63..ba21a6c4f4672be54309a6710c0444eb4176aa40 100644 (file)
@@ -381,7 +381,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
        dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
        dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
 
-       dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/
+       dev->cfg_size = pci_cfg_space_size(dev);
 
        sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
index b2758148a0de54461b04d735e8fb347ec1884b55..16d9a904f3cbc35b24a6341a1928663829d163ed 100644 (file)
@@ -244,7 +244,6 @@ EXPORT_SYMBOL(set_context);
 extern long mol_trampoline;
 EXPORT_SYMBOL(mol_trampoline); /* For MOL */
 EXPORT_SYMBOL(flush_hash_pages); /* For MOL */
-EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
 #ifdef CONFIG_SMP
 extern int mmu_hash_lock;
 EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */
index 45b8109951fe49d74aa11e986428ee05e5d60f85..5579f65599127aca6e11cbc2255ffdb5ca5e8dba 100644 (file)
@@ -72,7 +72,7 @@ static int of_device_available(struct device_node * dn)
         return 0;
 }
 
-static int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
 {
        int returnval = -1;
        unsigned long buid, addr;
index e5d285adb49687534680d6797e7fd43f4c125f6d..db72a92943bf63e4cb9f1c1e583f027a6be06698 100644 (file)
@@ -299,9 +299,7 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.init_early)
                ppc_md.init_early();
 
-#ifdef CONFIG_SERIAL_8250
        find_legacy_serial_ports();
-#endif
        finish_device_tree();
 
        smp_setup_cpu_maps();
index 81567e931260e951a31083aa2bf2fb3da9c865cf..c4b76961d6de78f57e86c256211d4e0844f7ed22 100644 (file)
@@ -472,9 +472,7 @@ void __init setup_system(void)
         * hash table management for us, thus ioremap works. We do that early
         * so that further code can be debugged
         */
-#ifdef CONFIG_SERIAL_8250
        find_legacy_serial_ports();
-#endif
 
        /*
         * "Finish" the device-tree, that is do the actual parsing of
index 9c921d1c4084484b186249eed4ab7daa2e9ce550..475249dc2350db4f735761252db0aff01c13b0ec 100644 (file)
@@ -552,30 +552,6 @@ asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec
        return ret;
 }
 
-asmlinkage int compat_sys_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
-{
-       return sys_pciconfig_read((unsigned long) bus,
-                                 (unsigned long) dfn,
-                                 (unsigned long) off,
-                                 (unsigned long) len,
-                                 compat_ptr(ubuf));
-}
-
-asmlinkage int compat_sys_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
-{
-       return sys_pciconfig_write((unsigned long) bus,
-                                  (unsigned long) dfn,
-                                  (unsigned long) off,
-                                  (unsigned long) len,
-                                  compat_ptr(ubuf));
-}
-
-asmlinkage int compat_sys_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
-{
-       return sys_pciconfig_iobase(which, in_bus, in_devfn);
-}
-
-
 /* Note: it is necessary to treat mode as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -956,38 +932,6 @@ long ppc32_fadvise64(int fd, u32 unused, u32 offset_high, u32 offset_low,
                             advice);
 }
 
-long ppc32_timer_create(clockid_t clock,
-                       struct compat_sigevent __user *ev32,
-                       timer_t __user *timer_id)
-{
-       sigevent_t event;
-       timer_t t;
-       long err;
-       mm_segment_t savefs;
-
-       if (ev32 == NULL)
-               return sys_timer_create(clock, NULL, timer_id);
-
-       if (get_compat_sigevent(&event, ev32))
-               return -EFAULT;
-
-       if (!access_ok(VERIFY_WRITE, timer_id, sizeof(timer_t)))
-               return -EFAULT;
-
-       savefs = get_fs();
-       set_fs(KERNEL_DS);
-       /* The __user pointer casts are valid due to the set_fs() */
-       err = sys_timer_create(clock,
-               (sigevent_t __user *) &event,
-               (timer_t __user *) &t);
-       set_fs(savefs);
-
-       if (err == 0)
-               err = __put_user(t, timer_id);
-
-       return err;
-}
-
 asmlinkage long compat_sys_add_key(const char __user *_type,
                              const char __user *_description,
                              const void __user *_payload,
index 65463a1076e8afc5e3abbe3e17726784ad27fb43..68013179a503ca5fe4c2a3bd1157e06a198d58db 100644 (file)
@@ -239,9 +239,9 @@ SYS32ONLY(ftruncate64)
 SYSX(sys_ni_syscall,sys_stat64,sys_stat64)
 SYSX(sys_ni_syscall,sys_lstat64,sys_lstat64)
 SYSX(sys_ni_syscall,sys_fstat64,sys_fstat64)
-COMPAT_SYS(pciconfig_read)
-COMPAT_SYS(pciconfig_write)
-COMPAT_SYS(pciconfig_iobase)
+SYSCALL(pciconfig_read)
+SYSCALL(pciconfig_write)
+SYSCALL(pciconfig_iobase)
 SYSCALL(ni_syscall)
 SYSCALL(getdents64)
 SYSCALL(pivot_root)
@@ -281,7 +281,7 @@ SYSCALL(epoll_create)
 SYSCALL(epoll_ctl)
 SYSCALL(epoll_wait)
 SYSCALL(remap_file_pages)
-SYSX(sys_timer_create,ppc32_timer_create,sys_timer_create)
+SYSX(sys_timer_create,compat_sys_timer_create,sys_timer_create)
 COMPAT_SYS(timer_settime)
 COMPAT_SYS(timer_gettime)
 SYSCALL(timer_getoverrun)
index 2ffca63602c507ba1a201005e7441aee85ccfd3d..7b278d83739ee64614ab0651ecfbc959749a1204 100644 (file)
@@ -174,7 +174,7 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
        pa = addr & PAGE_MASK;
        size = PAGE_ALIGN(addr + size) - pa;
 
-       if (size == 0)
+       if ((size == 0) || (pa == 0))
                return NULL;
 
        if (mem_init_done) {
index d2ba358c6e3896694c2ce46dd88ce403b1cc04e6..b3962c3a03480ca16a36dcdb98c44cf4dc6839ad 100644 (file)
@@ -138,7 +138,7 @@ static void spufs_prune_dir(struct dentry *dir)
 {
        struct dentry *dentry, *tmp;
        mutex_lock(&dir->d_inode->i_mutex);
-       list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
+       list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
                spin_lock(&dcache_lock);
                spin_lock(&dentry->d_lock);
                if (!(d_unhashed(dentry)) && dentry->d_inode) {
index dd73e38bfb7d04f353b88c30a59e238bcdab76c3..a1cb4d2367204ecd01b3df138f8ac9dd4f7d7f86 100644 (file)
@@ -71,9 +71,6 @@
 #define DBG(fmt...)
 #endif
 
-extern void generic_find_legacy_serial_ports(u64 *physport,
-               unsigned int *default_speed);
-
 static void maple_restart(char *cmd)
 {
        unsigned int maple_nvram_base;
index 6accdd1555058861a08ab43fadf6caa0582ad415..61616d1440729371060f711226672852addf82b4 100644 (file)
@@ -4,7 +4,7 @@ obj-$(CONFIG_SMP)       += smp.o
 obj-$(CONFIG_IBMVIO)   += vio.o
 obj-$(CONFIG_XICS)     += xics.o
 obj-$(CONFIG_SCANLOG)  += scanlog.o
-obj-$(CONFIG_EEH)      += eeh.o eeh_event.o
+obj-$(CONFIG_EEH)      += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
 
 obj-$(CONFIG_HVC_CONSOLE)      += hvconsole.o
 obj-$(CONFIG_HVCS)             += hvcserver.o
index 7fbfd16d72b703b91b2e1e91a5f60935018e0af2..17cea7f2afd3a5dca0e918474ff83ea40fb05d6e 100644 (file)
  */
 #define EEH_MAX_FAILS  100000
 
-/* Misc forward declaraions */
-static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn);
-
 /* RTAS tokens */
 static int ibm_set_eeh_option;
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
 static int ibm_read_slot_reset_state2;
 static int ibm_slot_error_detail;
+static int ibm_get_config_addr_info;
+static int ibm_configure_bridge;
 
 int eeh_subsystem_enabled;
 EXPORT_SYMBOL(eeh_subsystem_enabled);
@@ -98,308 +97,23 @@ static DEFINE_SPINLOCK(slot_errbuf_lock);
 static int eeh_error_buf_size;
 
 /* System monitoring statistics */
-static DEFINE_PER_CPU(unsigned long, no_device);
-static DEFINE_PER_CPU(unsigned long, no_dn);
-static DEFINE_PER_CPU(unsigned long, no_cfg_addr);
-static DEFINE_PER_CPU(unsigned long, ignored_check);
-static DEFINE_PER_CPU(unsigned long, total_mmio_ffs);
-static DEFINE_PER_CPU(unsigned long, false_positives);
-static DEFINE_PER_CPU(unsigned long, ignored_failures);
-static DEFINE_PER_CPU(unsigned long, slot_resets);
-
-/**
- * The pci address cache subsystem.  This subsystem places
- * PCI device address resources into a red-black tree, sorted
- * according to the address range, so that given only an i/o
- * address, the corresponding PCI device can be **quickly**
- * found. It is safe to perform an address lookup in an interrupt
- * context; this ability is an important feature.
- *
- * Currently, the only customer of this code is the EEH subsystem;
- * thus, this code has been somewhat tailored to suit EEH better.
- * In particular, the cache does *not* hold the addresses of devices
- * for which EEH is not enabled.
- *
- * (Implementation Note: The RB tree seems to be better/faster
- * than any hash algo I could think of for this problem, even
- * with the penalty of slow pointer chases for d-cache misses).
- */
-struct pci_io_addr_range
-{
-       struct rb_node rb_node;
-       unsigned long addr_lo;
-       unsigned long addr_hi;
-       struct pci_dev *pcidev;
-       unsigned int flags;
-};
-
-static struct pci_io_addr_cache
-{
-       struct rb_root rb_root;
-       spinlock_t piar_lock;
-} pci_io_addr_cache_root;
-
-static inline struct pci_dev *__pci_get_device_by_addr(unsigned long addr)
-{
-       struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
-
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-               if (addr < piar->addr_lo) {
-                       n = n->rb_left;
-               } else {
-                       if (addr > piar->addr_hi) {
-                               n = n->rb_right;
-                       } else {
-                               pci_dev_get(piar->pcidev);
-                               return piar->pcidev;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
-/**
- * pci_get_device_by_addr - Get device, given only address
- * @addr: mmio (PIO) phys address or i/o port number
- *
- * Given an mmio phys address, or a port number, find a pci device
- * that implements this address.  Be sure to pci_dev_put the device
- * when finished.  I/O port numbers are assumed to be offset
- * from zero (that is, they do *not* have pci_io_addr added in).
- * It is safe to call this function within an interrupt.
- */
-static struct pci_dev *pci_get_device_by_addr(unsigned long addr)
-{
-       struct pci_dev *dev;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       dev = __pci_get_device_by_addr(addr);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-       return dev;
-}
-
-#ifdef DEBUG
-/*
- * Handy-dandy debug print routine, does nothing more
- * than print out the contents of our addr cache.
- */
-static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
-{
-       struct rb_node *n;
-       int cnt = 0;
-
-       n = rb_first(&cache->rb_root);
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
-                      (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
-                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
-               cnt++;
-               n = rb_next(n);
-       }
-}
-#endif
-
-/* Insert address range into the rb tree. */
-static struct pci_io_addr_range *
-pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
-                     unsigned long ahi, unsigned int flags)
-{
-       struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
-       struct rb_node *parent = NULL;
-       struct pci_io_addr_range *piar;
-
-       /* Walk tree, find a place to insert into tree */
-       while (*p) {
-               parent = *p;
-               piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
-               if (ahi < piar->addr_lo) {
-                       p = &parent->rb_left;
-               } else if (alo > piar->addr_hi) {
-                       p = &parent->rb_right;
-               } else {
-                       if (dev != piar->pcidev ||
-                           alo != piar->addr_lo || ahi != piar->addr_hi) {
-                               printk(KERN_WARNING "PIAR: overlapping address range\n");
-                       }
-                       return piar;
-               }
-       }
-       piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
-       if (!piar)
-               return NULL;
+static unsigned long no_device;
+static unsigned long no_dn;
+static unsigned long no_cfg_addr;
+static unsigned long ignored_check;
+static unsigned long total_mmio_ffs;
+static unsigned long false_positives;
+static unsigned long ignored_failures;
+static unsigned long slot_resets;
 
-       piar->addr_lo = alo;
-       piar->addr_hi = ahi;
-       piar->pcidev = dev;
-       piar->flags = flags;
-
-#ifdef DEBUG
-       printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
-                         alo, ahi, pci_name (dev));
-#endif
-
-       rb_link_node(&piar->rb_node, parent, p);
-       rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
-
-       return piar;
-}
-
-static void __pci_addr_cache_insert_device(struct pci_dev *dev)
-{
-       struct device_node *dn;
-       struct pci_dn *pdn;
-       int i;
-       int inserted = 0;
-
-       dn = pci_device_to_OF_node(dev);
-       if (!dn) {
-               printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
-               return;
-       }
-
-       /* Skip any devices for which EEH is not enabled. */
-       pdn = PCI_DN(dn);
-       if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
-           pdn->eeh_mode & EEH_MODE_NOCHECK) {
-#ifdef DEBUG
-               printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n",
-                      pci_name(dev), pdn->node->full_name);
-#endif
-               return;
-       }
-
-       /* The cache holds a reference to the device... */
-       pci_dev_get(dev);
-
-       /* Walk resources on this device, poke them into the tree */
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-               unsigned long start = pci_resource_start(dev,i);
-               unsigned long end = pci_resource_end(dev,i);
-               unsigned int flags = pci_resource_flags(dev,i);
-
-               /* We are interested only bus addresses, not dma or other stuff */
-               if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
-                       continue;
-               if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
-                        continue;
-               pci_addr_cache_insert(dev, start, end, flags);
-               inserted = 1;
-       }
-
-       /* If there was nothing to add, the cache has no reference... */
-       if (!inserted)
-               pci_dev_put(dev);
-}
-
-/**
- * pci_addr_cache_insert_device - Add a device to the address cache
- * @dev: PCI device whose I/O addresses we are interested in.
- *
- * In order to support the fast lookup of devices based on addresses,
- * we maintain a cache of devices that can be quickly searched.
- * This routine adds a device to that cache.
- */
-static void pci_addr_cache_insert_device(struct pci_dev *dev)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       __pci_addr_cache_insert_device(dev);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
-{
-       struct rb_node *n;
-       int removed = 0;
-
-restart:
-       n = rb_first(&pci_io_addr_cache_root.rb_root);
-       while (n) {
-               struct pci_io_addr_range *piar;
-               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
-
-               if (piar->pcidev == dev) {
-                       rb_erase(n, &pci_io_addr_cache_root.rb_root);
-                       removed = 1;
-                       kfree(piar);
-                       goto restart;
-               }
-               n = rb_next(n);
-       }
-
-       /* The cache no longer holds its reference to this device... */
-       if (removed)
-               pci_dev_put(dev);
-}
-
-/**
- * pci_addr_cache_remove_device - remove pci device from addr cache
- * @dev: device to remove
- *
- * Remove a device from the addr-cache tree.
- * This is potentially expensive, since it will walk
- * the tree multiple times (once per resource).
- * But so what; device removal doesn't need to be that fast.
- */
-static void pci_addr_cache_remove_device(struct pci_dev *dev)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
-       __pci_addr_cache_remove_device(dev);
-       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
-}
-
-/**
- * pci_addr_cache_build - Build a cache of I/O addresses
- *
- * Build a cache of pci i/o addresses.  This cache will be used to
- * find the pci device that corresponds to a given address.
- * This routine scans all pci busses to build the cache.
- * Must be run late in boot process, after the pci controllers
- * have been scaned for devices (after all device resources are known).
- */
-void __init pci_addr_cache_build(void)
-{
-       struct device_node *dn;
-       struct pci_dev *dev = NULL;
-
-       if (!eeh_subsystem_enabled)
-               return;
-
-       spin_lock_init(&pci_io_addr_cache_root.piar_lock);
-
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               /* Ignore PCI bridges ( XXX why ??) */
-               if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
-                       continue;
-               }
-               pci_addr_cache_insert_device(dev);
-
-               /* Save the BAR's; firmware doesn't restore these after EEH reset */
-               dn = pci_device_to_OF_node(dev);
-               eeh_save_bars(dev, PCI_DN(dn));
-       }
-
-#ifdef DEBUG
-       /* Verify tree built up above, echo back the list of addrs. */
-       pci_addr_cache_print(&pci_io_addr_cache_root);
-#endif
-}
+#define IS_BRIDGE(class_code) (((class_code)<<16) == PCI_BASE_CLASS_BRIDGE)
 
 /* --------------------------------------------------------------- */
-/* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */
+/* Below lies the EEH event infrastructure */
 
 void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
 {
+       int config_addr;
        unsigned long flags;
        int rc;
 
@@ -407,8 +121,13 @@ void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
        spin_lock_irqsave(&slot_errbuf_lock, flags);
        memset(slot_errbuf, 0, eeh_error_buf_size);
 
+       /* Use PE configuration address, if present */
+       config_addr = pdn->eeh_config_addr;
+       if (pdn->eeh_pe_config_addr)
+               config_addr = pdn->eeh_pe_config_addr;
+
        rc = rtas_call(ibm_slot_error_detail,
-                      8, 1, NULL, pdn->eeh_config_addr,
+                      8, 1, NULL, config_addr,
                       BUID_HI(pdn->phb->buid),
                       BUID_LO(pdn->phb->buid), NULL, 0,
                       virt_to_phys(slot_errbuf),
@@ -428,6 +147,7 @@ void eeh_slot_error_detail (struct pci_dn *pdn, int severity)
 static int read_slot_reset_state(struct pci_dn *pdn, int rets[])
 {
        int token, outputs;
+       int config_addr;
 
        if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) {
                token = ibm_read_slot_reset_state2;
@@ -438,7 +158,12 @@ static int read_slot_reset_state(struct pci_dn *pdn, int rets[])
                outputs = 3;
        }
 
-       return rtas_call(token, 3, outputs, rets, pdn->eeh_config_addr,
+       /* Use PE configuration address, if present */
+       config_addr = pdn->eeh_config_addr;
+       if (pdn->eeh_pe_config_addr)
+               config_addr = pdn->eeh_pe_config_addr;
+
+       return rtas_call(token, 3, outputs, rets, config_addr,
                         BUID_HI(pdn->phb->buid), BUID_LO(pdn->phb->buid));
 }
 
@@ -462,7 +187,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token)
 /** 
  * Return the "partitionable endpoint" (pe) under which this device lies
  */
-static struct device_node * find_device_pe(struct device_node *dn)
+struct device_node * find_device_pe(struct device_node *dn)
 {
        while ((dn->parent) && PCI_DN(dn->parent) &&
              (PCI_DN(dn->parent)->eeh_mode & EEH_MODE_SUPPORTED)) {
@@ -485,6 +210,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
                if (PCI_DN(dn)) {
                        PCI_DN(dn)->eeh_mode |= mode_flag;
 
+                       /* Mark the pci device driver too */
+                       struct pci_dev *dev = PCI_DN(dn)->pcidev;
+                       if (dev && dev->driver)
+                               dev->error_state = pci_channel_io_frozen;
+
                        if (dn->child)
                                __eeh_mark_slot (dn->child, mode_flag);
                }
@@ -495,6 +225,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
 void eeh_mark_slot (struct device_node *dn, int mode_flag)
 {
        dn = find_device_pe (dn);
+
+       /* Back up one, since config addrs might be shared */
+       if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
+               dn = dn->parent;
+
        PCI_DN(dn)->eeh_mode |= mode_flag;
        __eeh_mark_slot (dn->child, mode_flag);
 }
@@ -516,7 +251,13 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
 {
        unsigned long flags;
        spin_lock_irqsave(&confirm_error_lock, flags);
+       
        dn = find_device_pe (dn);
+       
+       /* Back up one, since config addrs might be shared */
+       if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr)
+               dn = dn->parent;
+
        PCI_DN(dn)->eeh_mode &= ~mode_flag;
        PCI_DN(dn)->eeh_check_count = 0;
        __eeh_clear_slot (dn->child, mode_flag);
@@ -544,15 +285,16 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        int rets[3];
        unsigned long flags;
        struct pci_dn *pdn;
+       enum pci_channel_state state;
        int rc = 0;
 
-       __get_cpu_var(total_mmio_ffs)++;
+       total_mmio_ffs++;
 
        if (!eeh_subsystem_enabled)
                return 0;
 
        if (!dn) {
-               __get_cpu_var(no_dn)++;
+               no_dn++;
                return 0;
        }
        pdn = PCI_DN(dn);
@@ -560,7 +302,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        /* Access to IO BARs might get this far and still not want checking. */
        if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
            pdn->eeh_mode & EEH_MODE_NOCHECK) {
-               __get_cpu_var(ignored_check)++;
+               ignored_check++;
 #ifdef DEBUG
                printk ("EEH:ignored check (%x) for %s %s\n", 
                        pdn->eeh_mode, pci_name (dev), dn->full_name);
@@ -568,8 +310,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
                return 0;
        }
 
-       if (!pdn->eeh_config_addr) {
-               __get_cpu_var(no_cfg_addr)++;
+       if (!pdn->eeh_config_addr && !pdn->eeh_pe_config_addr) {
+               no_cfg_addr++;
                return 0;
        }
 
@@ -611,7 +353,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        if (ret != 0) {
                printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n",
                       ret, dn->full_name);
-               __get_cpu_var(false_positives)++;
+               false_positives++;
                rc = 0;
                goto dn_unlock;
        }
@@ -620,14 +362,14 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        if (rets[1] != 1) {
                printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n",
                       ret, dn->full_name);
-               __get_cpu_var(false_positives)++;
+               false_positives++;
                rc = 0;
                goto dn_unlock;
        }
 
        /* If not the kind of error we know about, punt. */
        if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) {
-               __get_cpu_var(false_positives)++;
+               false_positives++;
                rc = 0;
                goto dn_unlock;
        }
@@ -635,12 +377,12 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        /* Note that config-io to empty slots may fail;
         * we recognize empty because they don't have children. */
        if ((rets[0] == 5) && (dn->child == NULL)) {
-               __get_cpu_var(false_positives)++;
+               false_positives++;
                rc = 0;
                goto dn_unlock;
        }
 
-       __get_cpu_var(slot_resets)++;
+       slot_resets++;
  
        /* Avoid repeated reports of this failure, including problems
         * with other functions on this device, and functions under
@@ -648,8 +390,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
        eeh_mark_slot (dn, EEH_MODE_ISOLATED);
        spin_unlock_irqrestore(&confirm_error_lock, flags);
 
-       eeh_send_failure_event (dn, dev, rets[0], rets[2]);
-       
+       state = pci_channel_io_normal;
+       if ((rets[0] == 2) || (rets[0] == 4))
+               state = pci_channel_io_frozen;
+       if (rets[0] == 5)
+               state = pci_channel_io_perm_failure;
+       eeh_send_failure_event (dn, dev, state, rets[2]);
+
        /* Most EEH events are due to device driver bugs.  Having
         * a stack trace will help the device-driver authors figure
         * out what happened.  So print that out. */
@@ -685,7 +432,7 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon
        addr = eeh_token_to_phys((unsigned long __force) token);
        dev = pci_get_device_by_addr(addr);
        if (!dev) {
-               __get_cpu_var(no_device)++;
+               no_device++;
                return val;
        }
 
@@ -716,11 +463,16 @@ eeh_slot_availability(struct pci_dn *pdn)
        if (rc) return rc;
 
        if (rets[1] == 0) return -1;  /* EEH is not supported */
-       if (rets[0] == 0)  return 0;  /* Oll Korrect */
+       if (rets[0] == 0) return 0;   /* Oll Korrect */
        if (rets[0] == 5) {
                if (rets[2] == 0) return -1; /* permanently unavailable */
                return rets[2]; /* number of millisecs to wait */
        }
+       if (rets[0] == 1)
+               return 250;
+
+       printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n",
+               rc, rets[0], rets[1], rets[2]);
        return -1;
 }
 
@@ -737,6 +489,7 @@ eeh_slot_availability(struct pci_dn *pdn)
 static void
 rtas_pci_slot_reset(struct pci_dn *pdn, int state)
 {
+       int config_addr;
        int rc;
 
        BUG_ON (pdn==NULL); 
@@ -747,8 +500,13 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
                return;
        }
 
+       /* Use PE configuration address, if present */
+       config_addr = pdn->eeh_config_addr;
+       if (pdn->eeh_pe_config_addr)
+               config_addr = pdn->eeh_pe_config_addr;
+
        rc = rtas_call(ibm_set_slot_reset,4,1, NULL,
-                      pdn->eeh_config_addr,
+                      config_addr,
                       BUID_HI(pdn->phb->buid),
                       BUID_LO(pdn->phb->buid),
                       state);
@@ -761,9 +519,11 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
 
 /** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
  *  dn -- device node to be reset.
+ *
+ *  Return 0 if success, else a non-zero value.
  */
 
-void
+int
 rtas_set_slot_reset(struct pci_dn *pdn)
 {
        int i, rc;
@@ -793,10 +553,21 @@ rtas_set_slot_reset(struct pci_dn *pdn)
         * ready to be used; if not, wait for recovery. */
        for (i=0; i<10; i++) {
                rc = eeh_slot_availability (pdn);
-               if (rc <= 0) break;
+               if (rc < 0)
+                       printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
+               if (rc == 0)
+                       return 0;
+               if (rc < 0)
+                       return -1;
 
                msleep (rc+100);
        }
+
+       rc = eeh_slot_availability (pdn);
+       if (rc)
+               printk (KERN_ERR "EEH: timeout resetting slot %s\n", pdn->node->full_name);
+
+       return rc;
 }
 
 /* ------------------------------------------------------- */
@@ -851,7 +622,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
        if (!pdn) 
                return;
        
-       if (! pdn->eeh_is_bridge)
+       if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
                __restore_bars (pdn);
 
        dn = pdn->node->child;
@@ -869,30 +640,30 @@ void eeh_restore_bars(struct pci_dn *pdn)
  * PCI devices are added individuallly; but, for the restore,
  * an entire slot is reset at a time.
  */
-static void eeh_save_bars(struct pci_dev * pdev, struct pci_dn *pdn)
+static void eeh_save_bars(struct pci_dn *pdn)
 {
        int i;
 
-       if (!pdev || !pdn )
+       if (!pdn )
                return;
        
        for (i = 0; i < 16; i++)
-               pci_read_config_dword(pdev, i * 4, &pdn->config_space[i]);
-
-       if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-               pdn->eeh_is_bridge = 1;
+               rtas_read_config(pdn, i * 4, 4, &pdn->config_space[i]);
 }
 
 void
 rtas_configure_bridge(struct pci_dn *pdn)
 {
-       int token = rtas_token ("ibm,configure-bridge");
+       int config_addr;
        int rc;
 
-       if (token == RTAS_UNKNOWN_SERVICE)
-               return;
-       rc = rtas_call(token,3,1, NULL,
-                      pdn->eeh_config_addr,
+       /* Use PE configuration address, if present */
+       config_addr = pdn->eeh_config_addr;
+       if (pdn->eeh_pe_config_addr)
+               config_addr = pdn->eeh_pe_config_addr;
+
+       rc = rtas_call(ibm_configure_bridge,3,1, NULL,
+                      config_addr,
                       BUID_HI(pdn->phb->buid),
                       BUID_LO(pdn->phb->buid));
        if (rc) {
@@ -927,6 +698,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
        int enable;
        struct pci_dn *pdn = PCI_DN(dn);
 
+       pdn->class_code = 0;
        pdn->eeh_mode = 0;
        pdn->eeh_check_count = 0;
        pdn->eeh_freeze_count = 0;
@@ -943,6 +715,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
                pdn->eeh_mode |= EEH_MODE_NOCHECK;
                return NULL;
        }
+       pdn->class_code = *class_code;
 
        /*
         * Now decide if we are going to "Disable" EEH checking
@@ -953,8 +726,10 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
         * But there are a few cases like display devices that make sense.
         */
        enable = 1;     /* i.e. we will do checking */
+#if 0
        if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
                enable = 0;
+#endif
 
        if (!enable)
                pdn->eeh_mode |= EEH_MODE_NOCHECK;
@@ -973,8 +748,22 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
                        eeh_subsystem_enabled = 1;
                        pdn->eeh_mode |= EEH_MODE_SUPPORTED;
                        pdn->eeh_config_addr = regs[0];
+
+                       /* If the newer, better, ibm,get-config-addr-info is supported, 
+                        * then use that instead. */
+                       pdn->eeh_pe_config_addr = 0;
+                       if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
+                               unsigned int rets[2];
+                               ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, 
+                                       pdn->eeh_config_addr, 
+                                       info->buid_hi, info->buid_lo,
+                                       0);
+                               if (ret == 0)
+                                       pdn->eeh_pe_config_addr = rets[0];
+                       }
 #ifdef DEBUG
-                       printk(KERN_DEBUG "EEH: %s: eeh enabled\n", dn->full_name);
+                       printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
+                              dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);
 #endif
                } else {
 
@@ -993,6 +782,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
                       dn->full_name);
        }
 
+       eeh_save_bars(pdn);
        return NULL;
 }
 
@@ -1026,6 +816,8 @@ void __init eeh_init(void)
        ibm_read_slot_reset_state2 = rtas_token("ibm,read-slot-reset-state2");
        ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
        ibm_slot_error_detail = rtas_token("ibm,slot-error-detail");
+       ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
+       ibm_configure_bridge = rtas_token ("ibm,configure-bridge");
 
        if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
                return;
@@ -1080,12 +872,10 @@ void eeh_add_device_early(struct device_node *dn)
        if (!dn || !PCI_DN(dn))
                return;
        phb = PCI_DN(dn)->phb;
-       if (NULL == phb || 0 == phb->buid) {
-               printk(KERN_WARNING "EEH: Expected buid but found none for %s\n",
-                      dn->full_name);
-               dump_stack();
+
+       /* USB Bus children of PCI devices will not have BUID's */
+       if (NULL == phb || 0 == phb->buid)
                return;
-       }
 
        info.buid_hi = BUID_HI(phb->buid);
        info.buid_lo = BUID_LO(phb->buid);
@@ -1127,7 +917,6 @@ void eeh_add_device_late(struct pci_dev *dev)
        pdn->pcidev = dev;
 
        pci_addr_cache_insert_device (dev);
-       eeh_save_bars(dev, pdn);
 }
 EXPORT_SYMBOL_GPL(eeh_add_device_late);
 
@@ -1175,25 +964,9 @@ EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
 
 static int proc_eeh_show(struct seq_file *m, void *v)
 {
-       unsigned int cpu;
-       unsigned long ffs = 0, positives = 0, failures = 0;
-       unsigned long resets = 0;
-       unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0;
-
-       for_each_cpu(cpu) {
-               ffs += per_cpu(total_mmio_ffs, cpu);
-               positives += per_cpu(false_positives, cpu);
-               failures += per_cpu(ignored_failures, cpu);
-               resets += per_cpu(slot_resets, cpu);
-               no_dev += per_cpu(no_device, cpu);
-               no_dn += per_cpu(no_dn, cpu);
-               no_cfg += per_cpu(no_cfg_addr, cpu);
-               no_check += per_cpu(ignored_check, cpu);
-       }
-
        if (0 == eeh_subsystem_enabled) {
                seq_printf(m, "EEH Subsystem is globally disabled\n");
-               seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs);
+               seq_printf(m, "eeh_total_mmio_ffs=%ld\n", total_mmio_ffs);
        } else {
                seq_printf(m, "EEH Subsystem is enabled\n");
                seq_printf(m,
@@ -1205,8 +978,10 @@ static int proc_eeh_show(struct seq_file *m, void *v)
                                "eeh_false_positives=%ld\n"
                                "eeh_ignored_failures=%ld\n"
                                "eeh_slot_resets=%ld\n",
-                               no_dev, no_dn, no_cfg, no_check,
-                               ffs, positives, failures, resets);
+                               no_device, no_dn, no_cfg_addr, 
+                               ignored_check, total_mmio_ffs, 
+                               false_positives, ignored_failures, 
+                               slot_resets);
        }
 
        return 0;
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
new file mode 100644 (file)
index 0000000..d4a402c
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * eeh_cache.c
+ * PCI address cache; allows the lookup of PCI devices based on I/O address
+ *
+ * Copyright (C) 2004 Linas Vepstas <linas@austin.ibm.com> IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+#undef DEBUG
+
+/**
+ * The pci address cache subsystem.  This subsystem places
+ * PCI device address resources into a red-black tree, sorted
+ * according to the address range, so that given only an i/o
+ * address, the corresponding PCI device can be **quickly**
+ * found. It is safe to perform an address lookup in an interrupt
+ * context; this ability is an important feature.
+ *
+ * Currently, the only customer of this code is the EEH subsystem;
+ * thus, this code has been somewhat tailored to suit EEH better.
+ * In particular, the cache does *not* hold the addresses of devices
+ * for which EEH is not enabled.
+ *
+ * (Implementation Note: The RB tree seems to be better/faster
+ * than any hash algo I could think of for this problem, even
+ * with the penalty of slow pointer chases for d-cache misses).
+ */
+struct pci_io_addr_range
+{
+       struct rb_node rb_node;
+       unsigned long addr_lo;
+       unsigned long addr_hi;
+       struct pci_dev *pcidev;
+       unsigned int flags;
+};
+
+static struct pci_io_addr_cache
+{
+       struct rb_root rb_root;
+       spinlock_t piar_lock;
+} pci_io_addr_cache_root;
+
+static inline struct pci_dev *__pci_get_device_by_addr(unsigned long addr)
+{
+       struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node;
+
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+               if (addr < piar->addr_lo) {
+                       n = n->rb_left;
+               } else {
+                       if (addr > piar->addr_hi) {
+                               n = n->rb_right;
+                       } else {
+                               pci_dev_get(piar->pcidev);
+                               return piar->pcidev;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+/**
+ * pci_get_device_by_addr - Get device, given only address
+ * @addr: mmio (PIO) phys address or i/o port number
+ *
+ * Given an mmio phys address, or a port number, find a pci device
+ * that implements this address.  Be sure to pci_dev_put the device
+ * when finished.  I/O port numbers are assumed to be offset
+ * from zero (that is, they do *not* have pci_io_addr added in).
+ * It is safe to call this function within an interrupt.
+ */
+struct pci_dev *pci_get_device_by_addr(unsigned long addr)
+{
+       struct pci_dev *dev;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       dev = __pci_get_device_by_addr(addr);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+       return dev;
+}
+
+#ifdef DEBUG
+/*
+ * Handy-dandy debug print routine, does nothing more
+ * than print out the contents of our addr cache.
+ */
+static void pci_addr_cache_print(struct pci_io_addr_cache *cache)
+{
+       struct rb_node *n;
+       int cnt = 0;
+
+       n = rb_first(&cache->rb_root);
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+               printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n",
+                      (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt,
+                      piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev));
+               cnt++;
+               n = rb_next(n);
+       }
+}
+#endif
+
+/* Insert address range into the rb tree. */
+static struct pci_io_addr_range *
+pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
+                     unsigned long ahi, unsigned int flags)
+{
+       struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node;
+       struct rb_node *parent = NULL;
+       struct pci_io_addr_range *piar;
+
+       /* Walk tree, find a place to insert into tree */
+       while (*p) {
+               parent = *p;
+               piar = rb_entry(parent, struct pci_io_addr_range, rb_node);
+               if (ahi < piar->addr_lo) {
+                       p = &parent->rb_left;
+               } else if (alo > piar->addr_hi) {
+                       p = &parent->rb_right;
+               } else {
+                       if (dev != piar->pcidev ||
+                           alo != piar->addr_lo || ahi != piar->addr_hi) {
+                               printk(KERN_WARNING "PIAR: overlapping address range\n");
+                       }
+                       return piar;
+               }
+       }
+       piar = (struct pci_io_addr_range *)kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC);
+       if (!piar)
+               return NULL;
+
+       piar->addr_lo = alo;
+       piar->addr_hi = ahi;
+       piar->pcidev = dev;
+       piar->flags = flags;
+
+#ifdef DEBUG
+       printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
+                         alo, ahi, pci_name (dev));
+#endif
+
+       rb_link_node(&piar->rb_node, parent, p);
+       rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root);
+
+       return piar;
+}
+
+static void __pci_addr_cache_insert_device(struct pci_dev *dev)
+{
+       struct device_node *dn;
+       struct pci_dn *pdn;
+       int i;
+       int inserted = 0;
+
+       dn = pci_device_to_OF_node(dev);
+       if (!dn) {
+               printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev));
+               return;
+       }
+
+       /* Skip any devices for which EEH is not enabled. */
+       pdn = PCI_DN(dn);
+       if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
+           pdn->eeh_mode & EEH_MODE_NOCHECK) {
+#ifdef DEBUG
+               printk(KERN_INFO "PCI: skip building address cache for=%s - %s\n",
+                      pci_name(dev), pdn->node->full_name);
+#endif
+               return;
+       }
+
+       /* The cache holds a reference to the device... */
+       pci_dev_get(dev);
+
+       /* Walk resources on this device, poke them into the tree */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               unsigned long start = pci_resource_start(dev,i);
+               unsigned long end = pci_resource_end(dev,i);
+               unsigned int flags = pci_resource_flags(dev,i);
+
+               /* We are interested only bus addresses, not dma or other stuff */
+               if (0 == (flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+                       continue;
+               if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
+                        continue;
+               pci_addr_cache_insert(dev, start, end, flags);
+               inserted = 1;
+       }
+
+       /* If there was nothing to add, the cache has no reference... */
+       if (!inserted)
+               pci_dev_put(dev);
+}
+
+/**
+ * pci_addr_cache_insert_device - Add a device to the address cache
+ * @dev: PCI device whose I/O addresses we are interested in.
+ *
+ * In order to support the fast lookup of devices based on addresses,
+ * we maintain a cache of devices that can be quickly searched.
+ * This routine adds a device to that cache.
+ */
+void pci_addr_cache_insert_device(struct pci_dev *dev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       __pci_addr_cache_insert_device(dev);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
+{
+       struct rb_node *n;
+       int removed = 0;
+
+restart:
+       n = rb_first(&pci_io_addr_cache_root.rb_root);
+       while (n) {
+               struct pci_io_addr_range *piar;
+               piar = rb_entry(n, struct pci_io_addr_range, rb_node);
+
+               if (piar->pcidev == dev) {
+                       rb_erase(n, &pci_io_addr_cache_root.rb_root);
+                       removed = 1;
+                       kfree(piar);
+                       goto restart;
+               }
+               n = rb_next(n);
+       }
+
+       /* The cache no longer holds its reference to this device... */
+       if (removed)
+               pci_dev_put(dev);
+}
+
+/**
+ * pci_addr_cache_remove_device - remove pci device from addr cache
+ * @dev: device to remove
+ *
+ * Remove a device from the addr-cache tree.
+ * This is potentially expensive, since it will walk
+ * the tree multiple times (once per resource).
+ * But so what; device removal doesn't need to be that fast.
+ */
+void pci_addr_cache_remove_device(struct pci_dev *dev)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags);
+       __pci_addr_cache_remove_device(dev);
+       spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags);
+}
+
+/**
+ * pci_addr_cache_build - Build a cache of I/O addresses
+ *
+ * Build a cache of pci i/o addresses.  This cache will be used to
+ * find the pci device that corresponds to a given address.
+ * This routine scans all pci busses to build the cache.
+ * Must be run late in boot process, after the pci controllers
+ * have been scaned for devices (after all device resources are known).
+ */
+void __init pci_addr_cache_build(void)
+{
+       struct device_node *dn;
+       struct pci_dev *dev = NULL;
+
+       spin_lock_init(&pci_io_addr_cache_root.piar_lock);
+
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               /* Ignore PCI bridges */
+               if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+                       continue;
+
+               pci_addr_cache_insert_device(dev);
+
+               dn = pci_device_to_OF_node(dev);
+               pci_dev_get (dev);  /* matching put is in eeh_remove_device() */
+               PCI_DN(dn)->pcidev = dev;
+       }
+
+#ifdef DEBUG
+       /* Verify tree built up above, echo back the list of addrs. */
+       pci_addr_cache_print(&pci_io_addr_cache_root);
+#endif
+}
+
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
new file mode 100644 (file)
index 0000000..6373372
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * PCI Error Recovery Driver for RPA-compliant PPC64 platform.
+ * Copyright (C) 2004, 2005 Linas Vepstas <linas@linas.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <linas@us.ibm.com>
+ *
+ */
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/pci.h>
+#include <asm/eeh.h>
+#include <asm/eeh_event.h>
+#include <asm/ppc-pci.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+
+
+static inline const char * pcid_name (struct pci_dev *pdev)
+{
+       if (pdev->dev.driver)
+               return pdev->dev.driver->name;
+       return "";
+}
+
+#ifdef DEBUG
+static void print_device_node_tree (struct pci_dn *pdn, int dent)
+{
+       int i;
+       if (!pdn) return;
+       for (i=0;i<dent; i++)
+               printk(" ");
+       printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
+               pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
+               pdn->eeh_pe_config_addr, pdn->node->full_name);
+       dent += 3;
+       struct device_node *pc = pdn->node->child;
+       while (pc) {
+               print_device_node_tree(PCI_DN(pc), dent);
+               pc = pc->sibling;
+       }
+}
+#endif
+
+/** 
+ * irq_in_use - return true if this irq is being used 
+ */
+static int irq_in_use(unsigned int irq)
+{
+       int rc = 0;
+       unsigned long flags;
+   struct irq_desc *desc = irq_desc + irq;
+
+       spin_lock_irqsave(&desc->lock, flags);
+       if (desc->action)
+               rc = 1;
+       spin_unlock_irqrestore(&desc->lock, flags);
+       return rc;
+}
+
+/* ------------------------------------------------------- */
+/** eeh_report_error - report an EEH error to each device,
+ *  collect up and merge the device responses.
+ */
+
+static void eeh_report_error(struct pci_dev *dev, void *userdata)
+{
+       enum pci_ers_result rc, *res = userdata;
+       struct pci_driver *driver = dev->driver;
+
+       dev->error_state = pci_channel_io_frozen;
+
+       if (!driver)
+               return;
+
+       if (irq_in_use (dev->irq)) {
+               struct device_node *dn = pci_device_to_OF_node(dev);
+               PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
+               disable_irq_nosync(dev->irq);
+       }
+       if (!driver->err_handler)
+               return;
+       if (!driver->err_handler->error_detected)
+               return;
+
+       rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
+       if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+       if (*res == PCI_ERS_RESULT_NEED_RESET) return;
+       if (*res == PCI_ERS_RESULT_DISCONNECT &&
+            rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+}
+
+/** eeh_report_reset -- tell this device that the pci slot
+ *  has been reset.
+ */
+
+static void eeh_report_reset(struct pci_dev *dev, void *userdata)
+{
+       struct pci_driver *driver = dev->driver;
+       struct device_node *dn = pci_device_to_OF_node(dev);
+
+       if (!driver)
+               return;
+
+       if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
+               PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
+               enable_irq(dev->irq);
+       }
+       if (!driver->err_handler)
+               return;
+       if (!driver->err_handler->slot_reset)
+               return;
+
+       driver->err_handler->slot_reset(dev);
+}
+
+static void eeh_report_resume(struct pci_dev *dev, void *userdata)
+{
+       struct pci_driver *driver = dev->driver;
+
+       dev->error_state = pci_channel_io_normal;
+
+       if (!driver)
+               return;
+       if (!driver->err_handler)
+               return;
+       if (!driver->err_handler->resume)
+               return;
+
+       driver->err_handler->resume(dev);
+}
+
+static void eeh_report_failure(struct pci_dev *dev, void *userdata)
+{
+       struct pci_driver *driver = dev->driver;
+
+       dev->error_state = pci_channel_io_perm_failure;
+
+       if (!driver)
+               return;
+
+       if (irq_in_use (dev->irq)) {
+               struct device_node *dn = pci_device_to_OF_node(dev);
+               PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
+               disable_irq_nosync(dev->irq);
+       }
+       if (!driver->err_handler)
+               return;
+       if (!driver->err_handler->error_detected)
+               return;
+       driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
+}
+
+/* ------------------------------------------------------- */
+/**
+ * handle_eeh_events -- reset a PCI device after hard lockup.
+ *
+ * pSeries systems will isolate a PCI slot if the PCI-Host
+ * bridge detects address or data parity errors, DMA's
+ * occuring to wild addresses (which usually happen due to
+ * bugs in device drivers or in PCI adapter firmware).
+ * Slot isolations also occur if #SERR, #PERR or other misc
+ * PCI-related errors are detected.
+ *
+ * Recovery process consists of unplugging the device driver
+ * (which generated hotplug events to userspace), then issuing
+ * a PCI #RST to the device, then reconfiguring the PCI config
+ * space for all bridges & devices under this slot, and then
+ * finally restarting the device drivers (which cause a second
+ * set of hotplug events to go out to userspace).
+ */
+
+/**
+ * eeh_reset_device() -- perform actual reset of a pci slot
+ * Args: bus: pointer to the pci bus structure corresponding
+ *            to the isolated slot. A non-null value will
+ *            cause all devices under the bus to be removed
+ *            and then re-added.
+ *     pe_dn: pointer to a "Partionable Endpoint" device node.
+ *            This is the top-level structure on which pci
+ *            bus resets can be performed.
+ */
+
+static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
+{
+       int rc;
+       if (bus)
+               pcibios_remove_pci_devices(bus);
+
+       /* Reset the pci controller. (Asserts RST#; resets config space).
+        * Reconfigure bridges and devices. Don't try to bring the system
+        * up if the reset failed for some reason. */
+       rc = rtas_set_slot_reset(pe_dn);
+       if (rc)
+               return rc;
+
+       /* New-style config addrs might be shared across multiple devices,
+        * Walk over all functions on this device */
+       if (pe_dn->eeh_pe_config_addr) {
+               struct device_node *pe = pe_dn->node;
+               pe = pe->parent->child;
+               while (pe) {
+                       struct pci_dn *ppe = PCI_DN(pe);
+                       if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) {
+                               rtas_configure_bridge(ppe);
+                               eeh_restore_bars(ppe);
+                       }
+                       pe = pe->sibling;
+               }
+       } else {
+               rtas_configure_bridge(pe_dn);
+               eeh_restore_bars(pe_dn);
+       }
+
+       /* Give the system 5 seconds to finish running the user-space
+        * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes, 
+        * this is a hack, but if we don't do this, and try to bring 
+        * the device up before the scripts have taken it down, 
+        * potentially weird things happen.
+        */
+       if (bus) {
+               ssleep (5);
+               pcibios_add_pci_devices(bus);
+       }
+
+       return 0;
+}
+
+/* The longest amount of time to wait for a pci device
+ * to come back on line, in seconds.
+ */
+#define MAX_WAIT_FOR_RECOVERY 15
+
+void handle_eeh_events (struct eeh_event *event)
+{
+       struct device_node *frozen_dn;
+       struct pci_dn *frozen_pdn;
+       struct pci_bus *frozen_bus;
+       int rc = 0;
+       enum pci_ers_result result = PCI_ERS_RESULT_NONE;
+
+       frozen_dn = find_device_pe(event->dn);
+       frozen_bus = pcibios_find_pci_bus(frozen_dn);
+
+       if (!frozen_dn) {
+               printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n",
+                       pci_name(event->dev));
+               return;
+       }
+
+       /* There are two different styles for coming up with the PE.
+        * In the old style, it was the highest EEH-capable device
+        * which was always an EADS pci bridge.  In the new style,
+        * there might not be any EADS bridges, and even when there are,
+        * the firmware marks them as "EEH incapable". So another
+        * two-step is needed to find the pci bus.. */
+       if (!frozen_bus)
+               frozen_bus = pcibios_find_pci_bus (frozen_dn->parent);
+
+       if (!frozen_bus) {
+               printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n",
+                       frozen_dn->full_name);
+               return;
+       }
+
+#if 0
+       /* We may get "permanent failure" messages on empty slots.
+        * These are false alarms. Empty slots have no child dn. */
+       if ((event->state == pci_channel_io_perm_failure) && (frozen_device == NULL))
+               return;
+#endif
+
+       frozen_pdn = PCI_DN(frozen_dn);
+       frozen_pdn->eeh_freeze_count++;
+       
+       if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
+               goto hard_fail;
+
+       /* If the reset state is a '5' and the time to reset is 0 (infinity)
+        * or is more then 15 seconds, then mark this as a permanent failure.
+        */
+       if ((event->state == pci_channel_io_perm_failure) &&
+           ((event->time_unavail <= 0) ||
+            (event->time_unavail > MAX_WAIT_FOR_RECOVERY*1000)))
+               goto hard_fail;
+
+       eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
+       printk(KERN_WARNING
+          "EEH: This PCI device has failed %d times since last reboot: %s - %s\n",
+               frozen_pdn->eeh_freeze_count,
+               pci_name (frozen_pdn->pcidev), 
+               pcid_name(frozen_pdn->pcidev));
+
+       /* Walk the various device drivers attached to this slot through
+        * a reset sequence, giving each an opportunity to do what it needs
+        * to accomplish the reset.  Each child gets a report of the
+        * status ... if any child can't handle the reset, then the entire
+        * slot is dlpar removed and added.
+        */
+       pci_walk_bus(frozen_bus, eeh_report_error, &result);
+
+       /* If all device drivers were EEH-unaware, then shut
+        * down all of the device drivers, and hope they
+        * go down willingly, without panicing the system.
+        */
+       if (result == PCI_ERS_RESULT_NONE) {
+               rc = eeh_reset_device(frozen_pdn, frozen_bus);
+               if (rc)
+                       goto hard_fail;
+       }
+
+       /* If any device called out for a reset, then reset the slot */
+       if (result == PCI_ERS_RESULT_NEED_RESET) {
+               rc = eeh_reset_device(frozen_pdn, NULL);
+               if (rc)
+                       goto hard_fail;
+               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+       }
+
+       /* If all devices reported they can proceed, the re-enable PIO */
+       if (result == PCI_ERS_RESULT_CAN_RECOVER) {
+               /* XXX Not supported; we brute-force reset the device */
+               rc = eeh_reset_device(frozen_pdn, NULL);
+               if (rc)
+                       goto hard_fail;
+               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+       }
+
+       /* Tell all device drivers that they can resume operations */
+       pci_walk_bus(frozen_bus, eeh_report_resume, 0);
+
+       return;
+       
+hard_fail:
+       /*
+        * About 90% of all real-life EEH failures in the field
+        * are due to poorly seated PCI cards. Only 10% or so are
+        * due to actual, failed cards.
+        */
+       printk(KERN_ERR
+          "EEH: PCI device %s - %s has failed %d times \n"
+          "and has been permanently disabled.  Please try reseating\n"
+          "this device or replacing it.\n",
+               pci_name (frozen_pdn->pcidev), 
+               pcid_name(frozen_pdn->pcidev), 
+               frozen_pdn->eeh_freeze_count);
+
+       eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
+
+       /* Notify all devices that they're about to go down. */
+       pci_walk_bus(frozen_bus, eeh_report_failure, 0);
+
+       /* Shut down the device drivers for good. */
+       pcibios_remove_pci_devices(frozen_bus);
+}
+
+/* ---------- end of file ---------- */
index 92497333c2b65af53a4f007e2b1a09c5954f0f4a..9a9961f27480d5736981c5982716ee17fc7c307e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <asm/eeh_event.h>
+#include <asm/ppc-pci.h>
 
 /** Overview:
  *  EEH error states may be detected within exception handlers;
@@ -36,31 +37,6 @@ LIST_HEAD(eeh_eventlist);
 static void eeh_thread_launcher(void *);
 DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
 
-/**
- * eeh_panic - call panic() for an eeh event that cannot be handled.
- * The philosophy of this routine is that it is better to panic and
- * halt the OS than it is to risk possible data corruption by
- * oblivious device drivers that don't know better.
- *
- * @dev pci device that had an eeh event
- * @reset_state current reset state of the device slot
- */
-static void eeh_panic(struct pci_dev *dev, int reset_state)
-{
-       /*
-        * Since the panic_on_oops sysctl is used to halt the system
-        * in light of potential corruption, we can use it here.
-        */
-       if (panic_on_oops) {
-               panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
-                     pci_name(dev));
-       }
-       else {
-               printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
-                      reset_state, pci_name(dev));
-       }
-}
-
 /**
  * eeh_event_handler - dispatch EEH events.  The detection of a frozen
  * slot can occur inside an interrupt, where it can be hard to do
@@ -82,10 +58,16 @@ static int eeh_event_handler(void * dummy)
 
                spin_lock_irqsave(&eeh_eventlist_lock, flags);
                event = NULL;
+
+               /* Unqueue the event, get ready to process. */
                if (!list_empty(&eeh_eventlist)) {
                        event = list_entry(eeh_eventlist.next, struct eeh_event, list);
                        list_del(&event->list);
                }
+               
+               if (event)
+                       eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
+
                spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
                if (event == NULL)
                        break;
@@ -93,8 +75,11 @@ static int eeh_event_handler(void * dummy)
                printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
                       pci_name(event->dev));
 
-               eeh_panic (event->dev, event->state);
+               handle_eeh_events(event);
+
+               eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
 
+               pci_dev_put(event->dev);
                kfree(event);
        }
 
@@ -122,7 +107,7 @@ static void eeh_thread_launcher(void *dummy)
  */
 int eeh_send_failure_event (struct device_node *dn,
                             struct pci_dev *dev,
-                            int state,
+                            enum pci_channel_state state,
                             int time_unavail)
 {
        unsigned long flags;
index e719a4933af1e1bff7d820f42225dda557f310af..98e940beeb3bfe632ca979ae7addaeadd3655579 100644 (file)
@@ -128,10 +128,9 @@ TOUT       := .tmp_gas_check
 # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later for altivec
 # instructions.
 # gcc-3.4 and binutils-2.14 are a fatal combination.
-GCC_VERSION    := $(call cc-version)
 
 checkbin:
-       @if test "$(GCC_VERSION)" = "0304" ; then \
+       @if test "$(call cc-version)" = "0304" ; then \
                if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \
                        echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \
                        echo 'correctly with gcc-3.4 and your version of binutils.'; \
index a882b0dbe8de3e4b28b4216b5d6ed25076b69253..84d65a87191ed6048a81eee508e43d1629055f9b 100644 (file)
@@ -28,12 +28,6 @@ typedef NORET_TYPE void (*relocate_new_kernel_t)(
 const extern unsigned char relocate_new_kernel[];
 const extern unsigned int relocate_new_kernel_size;
 
-/*
- * Provide a dummy crash_notes definition while crash dump arrives to ppc.
- * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
- */
-note_buf_t crash_notes[NR_CPUS];
-
 void machine_shutdown(void)
 {
        if (ppc_md.machine_shutdown)
index 6fe532d82417d8acf89bc3a97217999cd5b09344..b66602ad7b33073fe7a5b0d307703f9d0c6768f9 100644 (file)
@@ -27,11 +27,6 @@ config S390
        bool
        default y
 
-config UID16
-       bool
-       default y
-       depends on !64BIT
-
 source "init/Kconfig"
 
 menu "Base setup"
index 4865e4b494647a3474f6820deb4eef054790f5a6..9269b5788facaf1ce05d7d5dcdc52b55b83d62c9 100644 (file)
@@ -17,8 +17,7 @@ obj-$(CONFIG_MODULES)         += s390_ksyms.o module.o
 obj-$(CONFIG_SMP)              += smp.o
 
 obj-$(CONFIG_COMPAT)           += compat_linux.o compat_signal.o \
-                                       compat_ioctl.o compat_wrapper.o \
-                                       compat_exec_domain.o
+                                       compat_wrapper.o compat_exec_domain.o
 obj-$(CONFIG_BINFMT_ELF32)     += binfmt_elf32.o
 
 obj-$(CONFIG_VIRT_TIMER)       += vtime.o
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
deleted file mode 100644 (file)
index 6504c4e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- *  S390 version
- *    Copyright (C) 2000-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Gerhard Tonn (ton@de.ibm.com)
- *               Arnd Bergmann (arndb@de.ibm.com)
- *
- * Original implementation from 32-bit Sparc compat code which is
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Written by Ulf Carlsson (ulfc@engr.sgi.com) 
- */
-
-#include "compat_linux.h"
-#define INCLUDES
-#define CODE
-#include "../../../fs/compat_ioctl.c"
-#include <asm/dasd.h>
-#include <asm/cmb.h>
-#include <asm/tape390.h>
-#include <asm/ccwdev.h>
-#include "../../../drivers/s390/char/raw3270.h"
-
-static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
-                               unsigned long arg, struct file *f)
-{
-       return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
-}
-
-static int do_ioctl32_ulong(unsigned int fd, unsigned int cmd,
-                               unsigned long arg, struct file *f)
-{
-       return sys_ioctl(fd, cmd, arg);
-}
-
-#define COMPATIBLE_IOCTL(cmd)          HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_pointer)
-#define ULONG_IOCTL(cmd)               HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_ulong)
-#define HANDLE_IOCTL(cmd,handler)      { (cmd), (ioctl_trans_handler_t)(handler), NULL },
-
-struct ioctl_trans ioctl_start[] = {
-/* architecture independent ioctls */
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "../../../fs/compat_ioctl.c"
-
-/* s390 only ioctls */
-COMPATIBLE_IOCTL(DASDAPIVER)
-COMPATIBLE_IOCTL(BIODASDDISABLE)
-COMPATIBLE_IOCTL(BIODASDENABLE)
-COMPATIBLE_IOCTL(BIODASDRSRV)
-COMPATIBLE_IOCTL(BIODASDRLSE)
-COMPATIBLE_IOCTL(BIODASDSLCK)
-COMPATIBLE_IOCTL(BIODASDINFO)
-COMPATIBLE_IOCTL(BIODASDINFO2)
-COMPATIBLE_IOCTL(BIODASDFMT)
-COMPATIBLE_IOCTL(BIODASDPRRST)
-COMPATIBLE_IOCTL(BIODASDQUIESCE)
-COMPATIBLE_IOCTL(BIODASDRESUME)
-COMPATIBLE_IOCTL(BIODASDPRRD)
-COMPATIBLE_IOCTL(BIODASDPSRD)
-COMPATIBLE_IOCTL(BIODASDGATTR)
-COMPATIBLE_IOCTL(BIODASDSATTR)
-COMPATIBLE_IOCTL(BIODASDCMFENABLE)
-COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
-COMPATIBLE_IOCTL(BIODASDREADALLCMB)
-
-COMPATIBLE_IOCTL(TUBICMD)
-COMPATIBLE_IOCTL(TUBOCMD)
-COMPATIBLE_IOCTL(TUBGETI)
-COMPATIBLE_IOCTL(TUBGETO)
-COMPATIBLE_IOCTL(TUBSETMOD)
-COMPATIBLE_IOCTL(TUBGETMOD)
-
-COMPATIBLE_IOCTL(TAPE390_DISPLAY)
-
-/* s390 doesn't need handlers here */
-COMPATIBLE_IOCTL(TIOCGSERIAL)
-COMPATIBLE_IOCTL(TIOCSSERIAL)
-};
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 41b197a3f3a390c58fcac826dd20f2dfc482f910..cd3b3c3e7a9fe9438c423db548214337d01206af 100644 (file)
@@ -1013,38 +1013,6 @@ asmlinkage long sys32_clone(struct pt_regs regs)
                       parent_tidptr, child_tidptr);
 }
 
-/*
- * Wrapper function for sys_timer_create.
- */
-extern asmlinkage long
-sys_timer_create(clockid_t, struct sigevent *, timer_t *);
-
-asmlinkage long
-sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32,
-               timer_t *timer_id)
-{
-       struct sigevent se;
-       timer_t ktimer_id;
-       mm_segment_t old_fs;
-       long ret;
-
-       if (se32 == NULL)
-               return sys_timer_create(which_clock, NULL, timer_id);
-
-       if (get_compat_sigevent(&se, se32))
-               return -EFAULT;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_timer_create(which_clock, &se, &ktimer_id);
-       set_fs(old_fs);
-
-       if (!ret)
-               ret = put_user (ktimer_id, timer_id);
-
-       return ret;
-}
-
 /*
  * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
  * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
index 23fe94e58688ec4d6659f16fa06287ac6e8cb174..cfde1905d07d77c5d2513e14a3c019e1d56f01d6 100644 (file)
@@ -1289,7 +1289,7 @@ sys32_timer_create_wrapper:
        lgfr    %r2,%r2                 # timer_t (int)
        llgtr   %r3,%r3                 # struct compat_sigevent *
        llgtr   %r4,%r4                 # timer_t *
-       jg      sys32_timer_create
+       jg      compat_sys_timer_create
 
        .globl  sys32_timer_settime_wrapper
 sys32_timer_settime_wrapper:
index 7bd169c58b0c229ba636be895444fbaf1ee5dc29..926cceeae0faa27c7d6cb6a44b5141f83aaf46ae 100644 (file)
@@ -10,8 +10,6 @@
 #include <linux/threads.h>
 #include <linux/kexec.h>
 
-note_buf_t crash_notes[NR_CPUS];
-
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 }
index a942bf2d58e91b12836a4b59094f0ada9b127c15..7dd58f8ac6b59848cec44f18fb5931b6d6ee2a47 100644 (file)
@@ -352,27 +352,6 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
        return 1;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-
-/* changed the size calculations - should hopefully work better. lbt */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = regs->gprs[15] & ~(PAGE_SIZE - 1);
-       dump->u_tsize = current->mm->end_code >> PAGE_SHIFT;
-       dump->u_dsize = (current->mm->brk + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-       if (dump->start_stack < TASK_SIZE)
-               dump->u_ssize = (TASK_SIZE - dump->start_stack) >> PAGE_SHIFT;
-       memcpy(&dump->regs, regs, sizeof(s390_regs));
-       dump_fpu (regs, &dump->regs.fp_regs);
-       dump->regs.per_info = current->thread.per_info;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
        struct stack_frame *sf, *low, *high;
index bee654abb6d38fe23cc06983748d897ced735a59..4176c77670c41f222f22311376fc633e48f901d1 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/smp.h>
 #include <linux/syscalls.h>
 #include <linux/interrupt.h>
-#include <linux/ioctl32.h>
 #include <asm/checksum.h>
 #include <asm/cpcmd.h>
 #include <asm/delay.h>
index fd4f240b833d5fc55af05e6de0520eaf9847d248..8a2bea34ddd2635ca344ea564385483c9919c59d 100644 (file)
@@ -305,26 +305,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
        return 0;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-       dump->magic = CMAGIC;
-       dump->start_code = current->mm->start_code;
-       dump->start_data  = current->mm->start_data;
-       dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1);
-       dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
-       dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
-       dump->u_ssize = (current->mm->start_stack - dump->start_stack +
-                        PAGE_SIZE - 1) >> PAGE_SHIFT;
-       /* Debug registers will come here. */
-
-       dump->regs = *regs;
-
-       dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
-}
-
 /* Tracing by user break controller.  */
 static void
 ubc_set_tracing(int asid, unsigned long pc)
index 6954fd62470ae8ace2c382c4044375151bf8c9c9..1cf94a618be3c97fa21207b4811e36e88634f780 100644 (file)
 #include <asm/cacheflush.h>
 #include <asm/checksum.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 extern struct hw_interrupt_type no_irq_type;
 
 EXPORT_SYMBOL(sh_mv);
 
 /* platform dependent support */
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(enable_irq);
index fb35b45dc130074b3fd6d0170c58588f17885f1e..07b172deb872b46478d5d44df926efcddf2acc98 100644 (file)
@@ -17,10 +17,6 @@ config MMU
        bool
        default y
 
-config UID16
-       bool
-       default y
-
 config RWSEM_GENERIC_SPINLOCK
        bool
        default y
index b95d041418554196350b64096a7486e1a7d6a4cb..419b5a71044116c9f6d4d5a396be7e42263286c5 100644 (file)
@@ -775,26 +775,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
        return 0;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-       dump->magic = CMAGIC;
-       dump->start_code = current->mm->start_code;
-       dump->start_data  = current->mm->start_data;
-       dump->start_stack = regs->regs[15] & ~(PAGE_SIZE - 1);
-       dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT;
-       dump->u_dsize = (current->mm->brk + (PAGE_SIZE-1) - dump->start_data) >> PAGE_SHIFT;
-       dump->u_ssize = (current->mm->start_stack - dump->start_stack +
-                        PAGE_SIZE - 1) >> PAGE_SHIFT;
-       /* Debug registers will come here. */
-
-       dump->regs = *regs;
-
-       dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
-}
-
 asmlinkage int sys_fork(unsigned long r2, unsigned long r3,
                        unsigned long r4, unsigned long r5,
                        unsigned long r6, unsigned long r7,
index 0b5497d70bd3766ac40754fad936c53594522c4f..472b450e61be5384bdd9211c8d485796e73f33b3 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
 #if 0
@@ -41,7 +40,6 @@ EXPORT_SYMBOL(drive_info);
 #endif
 
 /* platform dependent support */
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(enable_irq);
index 1c8fd0fd930590ce218d915cbcc4cf128fc4b66d..0b0d492c953b0118114d925cf1672b11500f0926 100644 (file)
@@ -82,8 +82,6 @@ extern int __lshrdi3(int, int);
 extern int __muldi3(int, int);
 extern int __divdi3(int, int);
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 /* Private functions with odd calling conventions. */
 extern void ___atomic24_add(void);
 extern void ___atomic24_sub(void);
index 6f00ab8b9d23ab6b79897acca6899b559c4dbaa4..83d67eb188952efbd941b265b55b005df879e260 100644 (file)
@@ -16,7 +16,7 @@ obj-y         := process.o setup.o cpu.o idprom.o \
 obj-$(CONFIG_PCI)       += ebus.o isa.o pci_common.o pci_iommu.o \
                            pci_psycho.o pci_sabre.o pci_schizo.o
 obj-$(CONFIG_SMP)       += smp.o trampoline.o
-obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
+obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
 obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
 obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
 obj-$(CONFIG_MODULES) += module.o
@@ -40,5 +40,3 @@ endif
 
 head.o: head.S ttable.S itlb_base.S dtlb_base.S dtlb_backend.S dtlb_prot.S \
        etrap.S rtrap.S winfixup.S entry.S
-
-CFLAGS_ioctl32.o += -Ifs/
index edf52d06b28042312c796ac0227884312194658d..202a80c24b6f789cdd11dd7db964158a35a88e56 100644 (file)
@@ -36,8 +36,6 @@ static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout32_library(struct file*);
 static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 static struct linux_binfmt aout32_format = {
        NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump,
        PAGE_SIZE
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
deleted file mode 100644 (file)
index 196b208..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $Id: ioctl32.c,v 1.136 2002/01/14 09:49:52 davem Exp $
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 2003  Pavel Machek (pavel@suse.cz)
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#define INCLUDES
-#include "compat_ioctl.c"
-#include <linux/syscalls.h>
-
-#define CODE
-#include "compat_ioctl.c"
-
-#define COMPATIBLE_IOCTL(cmd)          HANDLE_IOCTL((cmd),sys_ioctl)
-#define HANDLE_IOCTL(cmd,handler)      { (cmd), (ioctl_trans_handler_t)(handler), NULL },
-#define IOCTL_TABLE_START \
-       struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END \
-       };
-
-IOCTL_TABLE_START
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-#if 0
-HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)
-HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)
-#endif
-/* take care of sizeof(sizeof()) breakage */
-IOCTL_TABLE_END
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index a97b0f0727ab15be8ee7678848b5d81ebf282ded..ff5e9d5cad50ed7f2507f3c9a1935e518d34d937 100644 (file)
@@ -42,15 +42,11 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
-       return 0;
-}
-
-void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
        p->ainsn.insn[0] = *p->addr;
        p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
        p->opcode = *p->addr;
+       return 0;
 }
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
@@ -65,10 +61,6 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
        flushi(p->addr);
 }
 
-void __kprobes arch_remove_kprobe(struct kprobe *p)
-{
-}
-
 static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
index fb7a5370dbfcf7c0a8d9c2fda0a70fc736ad30a4..d177d7e5c9d30b26cf5f456e0ba7da88445fbf04 100644 (file)
@@ -94,7 +94,6 @@ extern void (*prom_palette)(int);
 
 extern int __ashrdi3(int, int);
 
-extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
 
 extern unsigned long phys_base;
@@ -241,7 +240,6 @@ EXPORT_SYMBOL(io_remap_pfn_range);
 EXPORT_SYMBOL(_sigpause_common);
 EXPORT_SYMBOL(verify_compat_iovec);
 
-EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(pte_alloc_one_kernel);
 #ifndef CONFIG_SMP
index 7f6239ed252142e52c45f2921de58b339d770086..de342ee3116b05b5412e4e91e01815805872e15e 100644 (file)
@@ -1120,39 +1120,3 @@ long sys32_lookup_dcookie(unsigned long cookie_high,
        return sys_lookup_dcookie((cookie_high << 32) | cookie_low,
                                  buf, len);
 }
-
-extern asmlinkage long
-sys_timer_create(clockid_t which_clock,
-                struct sigevent __user *timer_event_spec,
-                timer_t __user *created_timer_id);
-
-long
-sys32_timer_create(u32 clock, struct compat_sigevent __user *se32,
-                  timer_t __user *timer_id)
-{
-       struct sigevent se;
-       mm_segment_t oldfs;
-       timer_t t;
-       long err;
-
-       if (se32 == NULL)
-               return sys_timer_create(clock, NULL, timer_id);
-
-       if (get_compat_sigevent(&se, se32))
-               return -EFAULT;
-
-       if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
-               return -EFAULT;
-
-       oldfs = get_fs();
-       set_fs(KERNEL_DS);
-       err = sys_timer_create(clock,
-                              (struct sigevent __user *) &se,
-                              (timer_t __user *) &t);
-       set_fs(oldfs);
-
-       if (!err)
-               err = __put_user (t, timer_id);
-
-       return err;
-}
index 4821ef1ea07a2f5ade5020c035eb42dbe769cd7c..98d24bc0004441ea0e57f3ef4cc5feb003d0dff7 100644 (file)
@@ -73,7 +73,7 @@ sys_call_table32:
 /*250*/        .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
        .word sys_ni_syscall, sys32_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
 /*260*/        .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
-       .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
+       .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
 /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
        .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
 /*280*/        .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
index cd13b91b9ff6a9702126282fb6e9dbc7fc0f9f90..ab0d0b17081677eb9a2d2f0b0ddc21c28c1fbdb6 100644 (file)
@@ -186,9 +186,6 @@ static void tty_receive_char(struct tty_struct *tty, char ch)
                }
        }
 
-       if((tty->flip.flag_buf_ptr == NULL) ||
-          (tty->flip.char_buf_ptr == NULL))
-               return;
        tty_insert_flip_char(tty, ch, TTY_NORMAL);
 }
 
@@ -653,8 +650,7 @@ void chan_interrupt(struct list_head *chans, struct work_struct *task,
                chan = list_entry(ele, struct chan, list);
                if(!chan->input || (chan->ops->read == NULL)) continue;
                do {
-                       if((tty != NULL) &&
-                          (tty->flip.count >= TTY_FLIPBUF_SIZE)){
+                       if (tty && !tty_buffer_request_room(tty, 1)) {
                                schedule_delayed_work(task, 1);
                                goto out;
                        }
index 11f518a7e1562538e1cf75e5b87af1c609d50009..8fa2ae7f30261b3c749f2c1f4a666f210dd0f896 100644 (file)
@@ -99,7 +99,8 @@ void uml_idle_timer(void)
        set_interval(ITIMER_REAL);
 }
 
-extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
+extern void ktime_get_ts(struct timespec *ts);
+#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
 
 void time_init(void)
 {
@@ -114,8 +115,8 @@ void time_init(void)
        wall_to_monotonic.tv_nsec = -now.tv_nsec;
 }
 
-/* Declared in linux/time.h, which can't be included here */
-extern void clock_was_set(void);
+/* Defined in linux/ktimer.h, which can't be included here */
+#define clock_was_set()                do { } while (0)
 
 void do_gettimeofday(struct timeval *tv)
 {
index 39cf247cdae4ef4dcbe4d4fa3563432a520f1531..062ffa0a9998100205dcf30f0f503c448e604e89 100644 (file)
@@ -163,30 +163,6 @@ int copy_thread (int nr, unsigned long clone_flags,
        return 0;
 }
 
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread (struct pt_regs *regs, struct user *dump)
-{
-#if 0  /* Later.  XXX */
-       dump->magic = CMAGIC;
-       dump->start_code = 0;
-       dump->start_stack = regs->gpr[GPR_SP];
-       dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
-       dump->u_dsize = ((unsigned long) (current->mm->brk +
-                                         (PAGE_SIZE-1))) >> PAGE_SHIFT;
-       dump->u_dsize -= dump->u_tsize;
-       dump->u_ssize = 0;
-
-       if (dump->start_stack < TASK_SIZE)
-               dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
-
-       dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
-       dump->regs = *regs;
-       dump->u_fpvalid = 0;
-#endif
-}
-
 /*
  * sys_execve() executes a new program.
  */
index 0ca64900dd913c40ec3682b58d921ed99767453f..8ffc29c1c89df749f71e0d3954e01642ede3770d 100644 (file)
@@ -21,8 +21,6 @@ extern void *trap_table;
 EXPORT_SYMBOL (trap_table);
 
 /* platform dependent support */
-extern void dump_thread (struct pt_regs *, struct user *);
-EXPORT_SYMBOL (dump_thread);
 EXPORT_SYMBOL (kernel_thread);
 EXPORT_SYMBOL (enable_irq);
 EXPORT_SYMBOL (disable_irq);
index 4f3e925962c36576f9d2c7ee04fedbcdaf591d21..348b4a0d0d6f69c459240d6fc4d75c152440b132 100644 (file)
@@ -399,17 +399,6 @@ config X86_MCE_AMD
           Additional support for AMD specific MCE features such as
           the DRAM Error Threshold.
 
-config PHYSICAL_START
-       hex "Physical address where the kernel is loaded" if EMBEDDED
-       default "0x100000"
-       help
-         This gives the physical address where the kernel is loaded.
-         Primarily used in the case of kexec on panic where the
-         fail safe kernel needs to run at a different address than
-         the panic-ed kernel.
-
-         Don't change this unless you know what you are doing.
-
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
        depends on EXPERIMENTAL
@@ -427,6 +416,31 @@ config KEXEC
          support.  As of this writing the exact hardware interface is
          strongly in flux, so no good recommendation can be made.
 
+config CRASH_DUMP
+       bool "kernel crash dumps (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+               Generate crash dump after being started by kexec.
+
+config PHYSICAL_START
+       hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
+       default "0x1000000" if CRASH_DUMP
+       default "0x100000"
+       help
+         This gives the physical address where the kernel is loaded. Normally
+         for regular kernels this value is 0x100000 (1MB). But in the case
+         of kexec on panic the fail safe kernel needs to run at a different
+         address than the panic-ed kernel. This option is used to set the load
+         address for kernels used to capture crash dump on being kexec'ed
+         after panic. The default value for crash dump kernels is
+         0x1000000 (16MB). This can also be set based on the "X" value as
+         specified in the "crashkernel=YM@XM" command line boot parameter
+         passed to the panic-ed kernel. Typically this parameter is set as
+         crashkernel=64M@16M. Please take a look at
+         Documentation/kdump/kdump.txt for more details about crash dumps.
+
+         Don't change this unless you know what you are doing.
+
 config SECCOMP
        bool "Enable seccomp to safely compute untrusted bytecode"
        depends on PROC_FS
index a9cd42e61828d8860c41c06b71ed58e1dfb6956f..51d83288d62b499d8b863113a7094ff71f954cc4 100644 (file)
@@ -80,9 +80,12 @@ bzlilo: vmlinux
 bzdisk: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk
 
-install fdimage fdimage144 fdimage288: vmlinux
+fdimage fdimage144 fdimage288: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 
+install:
+       $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
+
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
index 18c6e915d69b84260a43b979b28e5058c60a193a..29f8396ed151c9d0dc12725dc19d4fc729971f2c 100644 (file)
@@ -98,5 +98,5 @@ zlilo: $(BOOTIMAGE)
        cp System.map $(INSTALL_PATH)/
        if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
-install: $(BOOTIMAGE)
+install:
        sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
index 198af15a77586c1abb2cd9c0159cb3e0e0da1643..baaa2369bdb8d8c0c8a7558b7ba4e065c6f194bf 100644 (file)
@@ -1,40 +1,2 @@
 #!/bin/sh
-#
-# arch/x86_64/boot/install.sh
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1995 by Linus Torvalds
-#
-# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
-#
-# "make install" script for i386 architecture
-#
-# Arguments:
-#   $1 - kernel version
-#   $2 - kernel image file
-#   $3 - kernel map file
-#   $4 - default install path (blank if root directory)
-#
-
-# User may have a custom install script
-
-if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
-if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
-
-# Default install - same as make zlilo
-
-if [ -f $4/vmlinuz ]; then
-       mv $4/vmlinuz $4/vmlinuz.old
-fi
-
-if [ -f $4/System.map ]; then
-       mv $4/System.map $4/System.old
-fi
-
-cat $2 > $4/vmlinuz
-cp $3 $4/System.map
-
-if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+. $srctree/arch/i386/boot/install.sh
index f76217d8f5799dd3ca888d6da91680182bf746d5..051608d559208e663851c0d8dd1e9e8d2cdf937c 100644 (file)
@@ -2,8 +2,7 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
-       ia32_signal.o tls32.o \
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o tls32.o \
        ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o
 
 sysv-$(CONFIG_SYSVIPC) := ipc32.o
@@ -29,4 +28,3 @@ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
 
 AFLAGS_vsyscall-sysenter.o = -m32
 AFLAGS_vsyscall-syscall.o = -m32
-CFLAGS_ia32_ioctl.o += -Ifs/
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
deleted file mode 100644 (file)
index e335bd0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $Id: ia32_ioctl.c,v 1.25 2002/10/11 07:17:06 ak Exp $
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs 
- *
- * These routines maintain argument size conversion between 32bit and 64bit
- * ioctls.
- */
-
-#define INCLUDES
-#include <linux/syscalls.h>
-#include "compat_ioctl.c"
-#include <asm/ia32.h>
-
-#define CODE
-#include "compat_ioctl.c"
-  
-#define RTC_IRQP_READ32        _IOR('p', 0x0b, unsigned int)    /* Read IRQ rate   */
-#define RTC_IRQP_SET32 _IOW('p', 0x0c, unsigned int)    /* Set IRQ rate    */
-#define RTC_EPOCH_READ32       _IOR('p', 0x0d, unsigned)        /* Read epoch      */
-#define RTC_EPOCH_SET32                _IOW('p', 0x0e, unsigned)        /* Set epoch       */
-
-static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 
-{ 
-       unsigned long val;
-       mm_segment_t oldfs = get_fs(); 
-       int ret; 
-       
-       switch (cmd) { 
-       case RTC_IRQP_READ32: 
-               set_fs(KERNEL_DS); 
-               ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val); 
-               set_fs(oldfs); 
-               if (!ret)
-                       ret = put_user(val, (unsigned int __user *) arg); 
-               return ret; 
-
-       case RTC_IRQP_SET32: 
-               cmd = RTC_IRQP_SET; 
-               break; 
-
-       case RTC_EPOCH_READ32:
-               set_fs(KERNEL_DS); 
-               ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val); 
-               set_fs(oldfs); 
-               if (!ret)
-                       ret = put_user(val, (unsigned int __user *) arg); 
-               return ret; 
-
-       case RTC_EPOCH_SET32:
-               cmd = RTC_EPOCH_SET; 
-               break; 
-       } 
-       return sys_ioctl(fd,cmd,arg); 
-} 
-
-
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler) }, 
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-
-struct ioctl_trans ioctl_start[] = { 
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "compat_ioctl.c"
-
-/* And these ioctls need translation */
-/* realtime device */
-HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
-HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
-HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
-HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
-HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
-/* take care of sizeof(sizeof()) breakage */
-}; 
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
-
index 1f0ff5adc80e1b0babda930850aa29eb16e4bab0..2ff07b47ea9cfe99318f90663ba601287e36c52d 100644 (file)
@@ -608,7 +608,7 @@ ia32_sys_call_table:
        .quad sys_epoll_wait
        .quad sys_remap_file_pages
        .quad sys_set_tid_address
-       .quad sys32_timer_create
+       .quad compat_sys_timer_create
        .quad compat_sys_timer_settime  /* 260 */
        .quad compat_sys_timer_gettime
        .quad sys_timer_getoverrun
index 5389df610e78277d0a6329f98a16d3f1f52c27d0..54481af5344ab2c19be4427fa1c576bd17b2a5e7 100644 (file)
@@ -969,25 +969,6 @@ long sys32_kill(int pid, int sig)
        return sys_kill(pid, sig);
 }
  
-extern asmlinkage long
-sys_timer_create(clockid_t which_clock,
-                struct sigevent __user *timer_event_spec,
-                timer_t __user * created_timer_id);
-
-long
-sys32_timer_create(u32 clock, struct compat_sigevent __user *se32, timer_t __user *timer_id)
-{
-       struct sigevent __user *p = NULL;
-       if (se32) { 
-               struct sigevent se;
-               p = compat_alloc_user_space(sizeof(struct sigevent));
-               if (get_compat_sigevent(&se, se32) ||
-                   copy_to_user(p, &se, sizeof(se)))
-                       return -EFAULT;
-       } 
-       return sys_timer_create(clock, p, timer_id);
-} 
-
 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
                        __u32 len_low, __u32 len_high, int advice)
 { 
index fe4cbd1c4b2fe2e894e22cb0855467a3e21b5c26..12bc54005e2faa59656ba68b272c1876e48b961f 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_X86_LOCAL_APIC)  += apic.o  nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o mpparse.o \
                genapic.o genapic_cluster.o genapic_flat.o
 obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
+obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_PM)               += suspend.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
 obj-$(CONFIG_CPU_FREQ)         += cpufreq/
index 535e04466079857a09d3f9b0c6649f15f36301e6..4e6c3b729e39793b39c0bcaed3a10e0e1832b0ec 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
+#include <linux/irq.h>
 #include <linux/reboot.h>
 #include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
 #include <asm/nmi.h>
 #include <asm/hw_irq.h>
+#include <asm/mach_apic.h>
 
-note_buf_t crash_notes[NR_CPUS];
+/* This keeps a track of which one is crashing cpu. */
+static int crashing_cpu;
+
+static u32 *append_elf_note(u32 *buf, char *name, unsigned type,
+                                               void *data, size_t data_len)
+{
+       struct elf_note note;
+
+       note.n_namesz = strlen(name) + 1;
+       note.n_descsz = data_len;
+       note.n_type   = type;
+       memcpy(buf, &note, sizeof(note));
+       buf += (sizeof(note) +3)/4;
+       memcpy(buf, name, note.n_namesz);
+       buf += (note.n_namesz + 3)/4;
+       memcpy(buf, data, note.n_descsz);
+       buf += (note.n_descsz + 3)/4;
+
+       return buf;
+}
+
+static void final_note(u32 *buf)
+{
+       struct elf_note note;
+
+       note.n_namesz = 0;
+       note.n_descsz = 0;
+       note.n_type   = 0;
+       memcpy(buf, &note, sizeof(note));
+}
+
+static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
+{
+       struct elf_prstatus prstatus;
+       u32 *buf;
+
+       if ((cpu < 0) || (cpu >= NR_CPUS))
+               return;
+
+       /* Using ELF notes here is opportunistic.
+        * I need a well defined structure format
+        * for the data I pass, and I need tags
+        * on the data to indicate what information I have
+        * squirrelled away.  ELF notes happen to provide
+        * all of that that no need to invent something new.
+        */
+
+       buf = (u32*)per_cpu_ptr(crash_notes, cpu);
+
+       if (!buf)
+               return;
+
+       memset(&prstatus, 0, sizeof(prstatus));
+       prstatus.pr_pid = current->pid;
+       elf_core_copy_regs(&prstatus.pr_reg, regs);
+       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
+                                       sizeof(prstatus));
+       final_note(buf);
+}
+
+static void crash_save_self(struct pt_regs *regs)
+{
+       int cpu;
+
+       cpu = smp_processor_id();
+       crash_save_this_cpu(regs, cpu);
+}
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_crash_ipi;
+
+static int crash_nmi_callback(struct pt_regs *regs, int cpu)
+{
+       /*
+        * Don't do anything if this handler is invoked on crashing cpu.
+        * Otherwise, system will completely hang. Crashing cpu can get
+        * an NMI if system was initially booted with nmi_watchdog parameter.
+        */
+       if (cpu == crashing_cpu)
+               return 1;
+       local_irq_disable();
+
+       crash_save_this_cpu(regs, cpu);
+       disable_local_APIC();
+       atomic_dec(&waiting_for_crash_ipi);
+       /* Assume hlt works */
+       for(;;)
+               asm("hlt");
+
+       return 1;
+}
+
+static void smp_send_nmi_allbutself(void)
+{
+       send_IPI_allbutself(APIC_DM_NMI);
+}
+
+/*
+ * This code is a best effort heuristic to get the
+ * other cpus to stop executing. So races with
+ * cpu hotplug shouldn't matter.
+ */
+
+static void nmi_shootdown_cpus(void)
+{
+       unsigned long msecs;
+
+       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+       set_nmi_callback(crash_nmi_callback);
+
+       /*
+        * Ensure the new callback function is set before sending
+        * out the NMI
+        */
+       wmb();
+
+       smp_send_nmi_allbutself();
+
+       msecs = 1000; /* Wait at most a second for the other cpus to stop */
+       while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+               mdelay(1);
+               msecs--;
+       }
+       /* Leave the nmi callback set */
+       disable_local_APIC();
+}
+#else
+static void nmi_shootdown_cpus(void)
+{
+       /* There are no cpus to shootdown */
+}
+#endif
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
-       /* This function is only called after the system
+       /*
+        * This function is only called after the system
         * has paniced or is otherwise in a critical state.
         * The minimum amount of code to allow a kexec'd kernel
         * to run successfully needs to happen here.
@@ -31,4 +168,19 @@ void machine_crash_shutdown(struct pt_regs *regs)
         * In practice this means shooting down the other cpus in
         * an SMP system.
         */
+       /* The kernel is broken so disable interrupts */
+       local_irq_disable();
+
+       /* Make a note of crashing cpu. Will be used in NMI callback.*/
+       crashing_cpu = smp_processor_id();
+       nmi_shootdown_cpus();
+
+       if(cpu_has_apic)
+                disable_local_APIC();
+
+#if defined(CONFIG_X86_IO_APIC)
+       disable_IO_APIC();
+#endif
+
+       crash_save_self(regs);
 }
similarity index 60%
rename from kernel/crash_dump.c
rename to arch/x86_64/kernel/crash_dump.c
index fccb27dbc623b95405d2a6defaaf38696d2269d5..942deac4d43aa1e2b8eb0e3118933f9b4a140e58 100644 (file)
@@ -5,21 +5,12 @@
  *     Copyright (C) IBM Corporation, 2004. All rights reserved
  */
 
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/bootmem.h>
-#include <linux/highmem.h>
 #include <linux/crash_dump.h>
 
-#include <asm/io.h>
 #include <asm/uaccess.h>
-#include <asm/kexec.h>
-
-/* Stores the physical address of elf header of crash image. */
-unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+#include <asm/io.h>
 
-#ifndef HAVE_ARCH_COPY_OLDMEM_PAGE
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -34,31 +25,23 @@ unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
  * in the current kernel. We stitch up a pte, similar to kmap_atomic.
  */
 ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-                               size_t csize, unsigned long offset, int userbuf)
+                               size_t csize, unsigned long offset, int userbuf)
 {
-       void *page, *vaddr;
+       void  *vaddr;
 
        if (!csize)
                return 0;
 
-       page = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!page)
-               return -ENOMEM;
-
-       vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
-       copy_page(page, vaddr);
-       kunmap_atomic(vaddr, KM_PTE0);
+       vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
 
        if (userbuf) {
-               if (copy_to_user(buf, (page + offset), csize)) {
-                       kfree(page);
+               if (copy_to_user(buf, (vaddr + offset), csize)) {
+                       iounmap(vaddr);
                        return -EFAULT;
                }
-       } else {
-               memcpy(buf, (page + offset), csize);
-       }
+       } else
+       memcpy(buf, (vaddr + offset), csize);
 
-       kfree(page);
+       iounmap(vaddr);
        return csize;
 }
-#endif
index 17579a1a174bda40da7f3291793ac746b9515cb0..293cd71a266aa221800c6e3246ee768cce5a71cd 100644 (file)
@@ -559,6 +559,27 @@ void __init parse_memopt(char *p, char **from)
        end_user_pfn >>= PAGE_SHIFT;    
 } 
 
+void __init parse_memmapopt(char *p, char **from)
+{
+       unsigned long long start_at, mem_size;
+
+       mem_size = memparse(p, from);
+       p = *from;
+       if (*p == '@') {
+               start_at = memparse(p+1, from);
+               add_memory_region(start_at, mem_size, E820_RAM);
+       } else if (*p == '#') {
+               start_at = memparse(p+1, from);
+               add_memory_region(start_at, mem_size, E820_ACPI);
+       } else if (*p == '$') {
+               start_at = memparse(p+1, from);
+               add_memory_region(start_at, mem_size, E820_RESERVED);
+       } else {
+               end_user_pfn = (mem_size >> PAGE_SHIFT);
+       }
+       p = *from;
+}
+
 unsigned long pci_mem_start = 0xaeedbabe;
 
 /*
index afe11f4fbd1d49d068e7bc3fb64f6d759c342ef1..b7dc1f816d13e616dacced97857994f42000ee47 100644 (file)
@@ -42,8 +42,8 @@
 #include <asm/pgtable.h>
 #include <asm/kdebug.h>
 
-static DECLARE_MUTEX(kprobe_mutex);
 void jprobe_return_end(void);
+static void __kprobes arch_copy_kprobe(struct kprobe *p);
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -69,12 +69,11 @@ static inline int is_IF_modifier(kprobe_opcode_t *insn)
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
        /* insn: must be on special executable page on x86_64. */
-       down(&kprobe_mutex);
        p->ainsn.insn = get_insn_slot();
-       up(&kprobe_mutex);
        if (!p->ainsn.insn) {
                return -ENOMEM;
        }
+       arch_copy_kprobe(p);
        return 0;
 }
 
@@ -181,7 +180,7 @@ static inline s32 *is_riprel(u8 *insn)
        return NULL;
 }
 
-void __kprobes arch_copy_kprobe(struct kprobe *p)
+static void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
        s32 *ripdisp;
        memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
index 64c4534b930c74bc118cf1530a812401456f3d4e..a0e0c9ca8f10c2e2321e9aece952ad1a2602975a 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/processor.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
+#include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
@@ -275,6 +276,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
 {
        char c = ' ', *to = command_line, *from = COMMAND_LINE;
        int len = 0;
+       int userdef = 0;
 
        /* Save unparsed command line copy for /proc/cmdline */
        memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
@@ -357,6 +359,28 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "mem=", 4))
                        parse_memopt(from+4, &from); 
 
+               if (!memcmp(from, "memmap=", 7)) {
+                       /* exactmap option is for used defined memory */
+                       if (!memcmp(from+7, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+                               /* If we are doing a crash dump, we
+                                * still need to know the real mem
+                                * size before original memory map is
+                                * reset.
+                                */
+                               saved_max_pfn = e820_end_of_ram();
+#endif
+                               from += 8+7;
+                               end_pfn_map = 0;
+                               e820.nr_map = 0;
+                               userdef = 1;
+                       }
+                       else {
+                               parse_memmapopt(from+7, &from);
+                               userdef = 1;
+                       }
+               }
+
 #ifdef CONFIG_NUMA
                if (!memcmp(from, "numa=", 5))
                        numa_setup(from+5); 
@@ -395,6 +419,14 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                }
 #endif
 
+#ifdef CONFIG_PROC_VMCORE
+               /* elfcorehdr= specifies the location of elf core header
+                * stored by the crashed kernel. This option will be passed
+                * by kexec loader to the capture kernel.
+                */
+               else if(!memcmp(from, "elfcorehdr=", 11))
+                       elfcorehdr_addr = memparse(from+11, &from);
+#endif
        next_char:
                c = *(from++);
                if (!c)
@@ -403,6 +435,10 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                        break;
                *(to++) = c;
        }
+       if (userdef) {
+               printk(KERN_INFO "user-defined physical RAM map:\n");
+               e820_print_map("user");
+       }
        *to = '\0';
        *cmdline_p = command_line;
 }
index 4a54221e10bc39a0371c35090fe4de72f472a70e..b7fd6681c629f24de029938715ae32fa9bbe1495 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/string.h>
 #include <linux/syscalls.h>
 #include <linux/tty.h>
-#include <linux/ioctl32.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
index 7e841aa2a4aa1259ea9e7367d40f84fd617a5822..7ee4a14ec3b1949d38766b4247bf71d2f2f14159 100644 (file)
@@ -18,10 +18,6 @@ config XTENSA
          with reasonable minimum requirements.  The Xtensa Linux project has
          a home page at <http://xtensa.sourceforge.net/>.
 
-config UID16
-       bool
-       default n
-
 config RWSEM_XCHGADD_ALGORITHM
        bool
        default y
index fd8059920dbfde1a91a472d63480d0293b88236b..6b355bd7816d8fcffea570047396eb28323f6771 100644 (file)
@@ -161,8 +161,8 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-/**
- *     device_subsys - structure to be registered with kobject core.
+/*
+ *     devices_subsys - structure to be registered with kobject core.
  */
 
 decl_subsys(devices, &ktype_device, &device_uevent_ops);
index 281d26784d251107bc6b158ba3ce5f5904a157fd..07a7f97e1de9d95a488f9fea90288052786f6e98 100644 (file)
@@ -83,6 +83,31 @@ static inline void register_cpu_control(struct cpu *cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
+#ifdef CONFIG_KEXEC
+#include <linux/kexec.h>
+
+static ssize_t show_crash_notes(struct sys_device *dev, char *buf)
+{
+       struct cpu *cpu = container_of(dev, struct cpu, sysdev);
+       ssize_t rc;
+       unsigned long long addr;
+       int cpunum;
+
+       cpunum = cpu->sysdev.id;
+
+       /*
+        * Might be reading other cpu's data based on which cpu read thread
+        * has been scheduled. But cpu data (memory) is allocated once during
+        * boot up and this data does not change there after. Hence this
+        * operation should be safe. No locking required.
+        */
+       addr = __pa(per_cpu_ptr(crash_notes, cpunum));
+       rc = sprintf(buf, "%Lx\n", addr);
+       return rc;
+}
+static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
+#endif
+
 /*
  * register_cpu - Setup a driverfs device for a CPU.
  * @cpu - Callers can set the cpu->no_control field to 1, to indicate not to
@@ -108,6 +133,11 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
                register_cpu_control(cpu);
        if (!error)
                cpu_sys_devices[num] = &cpu->sysdev;
+
+#ifdef CONFIG_KEXEC
+       if (!error)
+               error = sysdev_create_file(&cpu->sysdev, &attr_crash_notes);
+#endif
        return error;
 }
 
index 573ff6c1be5f6080362407f17f0785729317025c..613673b12fa6711cb8b749c8aea03cc0fc1c7b01 100644 (file)
@@ -279,6 +279,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
 
        tty->disc_data = hu;
        hu->tty = tty;
+       tty->receive_room = 65536;
 
        spin_lock_init(&hu->rx_lock);
 
@@ -348,20 +349,6 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
                hci_uart_tx_wakeup(hu);
 }
 
-/* hci_uart_tty_room()
- * 
- *    Callback function from tty driver. Return the amount of 
- *    space left in the receiver's buffer to decide if remote
- *    transmitter is to be throttled.
- *
- * Arguments:        tty    pointer to associated tty instance data
- * Return Value:    number of bytes left in receive buffer
- */
-static int hci_uart_tty_room (struct tty_struct *tty)
-{
-       return 65536;
-}
-
 /* hci_uart_tty_receive()
  * 
  *     Called by tty low level driver when receive data is
@@ -544,7 +531,6 @@ static int __init hci_uart_init(void)
        hci_uart_ldisc.write            = hci_uart_tty_write;
        hci_uart_ldisc.ioctl            = hci_uart_tty_ioctl;
        hci_uart_ldisc.poll             = hci_uart_tty_poll;
-       hci_uart_ldisc.receive_room     = hci_uart_tty_room;
        hci_uart_ldisc.receive_buf      = hci_uart_tty_receive;
        hci_uart_ldisc.write_wakeup     = hci_uart_tty_wakeup;
        hci_uart_ldisc.owner            = THIS_MODULE;
index dd7e6901c575b8d0d36dc22b17a820371ed95ec8..d6fcd0a36f9f2239ef025728e7c4ee9e67331af1 100644 (file)
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
 
 config COMPUTONE
        tristate "Computone IntelliPort Plus serial support"
-       depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+       depends on SERIAL_NONSTANDARD
        ---help---
          This driver supports the entire family of Intelliport II/Plus
          controllers with the exception of the MicroChannel controllers and
@@ -153,7 +153,7 @@ config DIGIEPCA
 
 config ESPSERIAL
        tristate "Hayes ESP serial port support"
-       depends on SERIAL_NONSTANDARD && ISA && BROKEN_ON_SMP && ISA_DMA_API
+       depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API
        help
          This is a driver which supports Hayes ESP serial ports.  Both single
          port cards and multiport cards are supported.  Make sure to read
@@ -166,7 +166,7 @@ config ESPSERIAL
 
 config MOXA_INTELLIO
        tristate "Moxa Intellio support"
-       depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+       depends on SERIAL_NONSTANDARD
        help
          Say Y here if you have a Moxa Intellio multiport serial card.
 
@@ -290,7 +290,7 @@ config SX
 
 config RIO
        tristate "Specialix RIO system support"
-       depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+       depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && !64BIT
        help
          This is a driver for the Specialix RIO, a smart serial card which
          drives an outboard box that can support up to 128 ports.  Product
@@ -936,6 +936,15 @@ config SCx200_GPIO
 
          If compiled as a module, it will be called scx200_gpio.
 
+config CS5535_GPIO
+       tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)"
+       depends on X86_32
+       help
+         Give userspace access to the GPIO pins on the AMD CS5535 and
+         CS5536 Geode companion devices.
+
+         If compiled as a module, it will be called cs5535_gpio.
+
 config GPIO_VR41XX
        tristate "NEC VR4100 series General-purpose I/O Unit support"
        depends on CPU_VR41XX
index d973d14d8f7fc998ab88fee69365289f5264502e..503dd901d406bad8e432ce267642926ce325e9c3 100644 (file)
@@ -81,6 +81,7 @@ obj-$(CONFIG_PPDEV) += ppdev.o
 obj-$(CONFIG_NWBUTTON) += nwbutton.o
 obj-$(CONFIG_NWFLASH) += nwflash.o
 obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
+obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
 obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
 obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
 obj-$(CONFIG_TELCLOCK) += tlclk.o
index a124f8c5d062dd65b29775881f9b9c55a0d95a14..869518e4035fab624464b646807980415afa5dc5 100644 (file)
@@ -116,7 +116,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 
 static struct serial_state rs_table[1];
 
-#define NR_PORTS       (sizeof(rs_table)/sizeof(struct serial_state))
+#define NR_PORTS ARRAY_SIZE(rs_table)
 
 /*
  * tmp_buf is used as a temporary buffer by serial_write.  We need to
@@ -265,8 +265,9 @@ static _INLINE_ void receive_chars(struct async_struct *info)
         int status;
        int serdatr;
        struct tty_struct *tty = info->tty;
-       unsigned char ch;
+       unsigned char ch, flag;
        struct  async_icount *icount;
+       int oe = 0;
 
        icount = &info->state->icount;
 
@@ -282,15 +283,12 @@ static _INLINE_ void receive_chars(struct async_struct *info)
            status |= UART_LSR_OE;
 
        ch = serdatr & 0xff;
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-         goto ignore_char;
-       *tty->flip.char_buf_ptr = ch;
        icount->rx++;
 
 #ifdef SERIAL_DEBUG_INTR
        printk("DR%02x:%02x...", ch, status);
 #endif
-       *tty->flip.flag_buf_ptr = 0;
+       flag = TTY_NORMAL;
 
        /*
         * We don't handle parity or frame errors - but I have left
@@ -319,7 +317,7 @@ static _INLINE_ void receive_chars(struct async_struct *info)
           * should be ignored.
           */
          if (status & info->ignore_status_mask)
-           goto ignore_char;
+           goto out;
 
          status &= info->read_status_mask;
 
@@ -327,33 +325,28 @@ static _INLINE_ void receive_chars(struct async_struct *info)
 #ifdef SERIAL_DEBUG_INTR
            printk("handling break....");
 #endif
-           *tty->flip.flag_buf_ptr = TTY_BREAK;
+           flag = TTY_BREAK;
            if (info->flags & ASYNC_SAK)
              do_SAK(tty);
          } else if (status & UART_LSR_PE)
-           *tty->flip.flag_buf_ptr = TTY_PARITY;
+           flag = TTY_PARITY;
          else if (status & UART_LSR_FE)
-           *tty->flip.flag_buf_ptr = TTY_FRAME;
+           flag = TTY_FRAME;
          if (status & UART_LSR_OE) {
            /*
             * Overrun is special, since it's
             * reported immediately, and doesn't
             * affect the current character
             */
-           if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-             tty->flip.count++;
-             tty->flip.flag_buf_ptr++;
-             tty->flip.char_buf_ptr++;
-             *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-           }
+            oe = 1;
          }
        }
-       tty->flip.flag_buf_ptr++;
-       tty->flip.char_buf_ptr++;
-       tty->flip.count++;
- ignore_char:
-
+       tty_insert_flip_char(tty, ch, flag);
+       if (oe == 1)
+               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        tty_flip_buffer_push(tty);
+out:
+       return;
 }
 
 static _INLINE_ void transmit_chars(struct async_struct *info)
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
new file mode 100644 (file)
index 0000000..5d72f50
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * AMD CS5535/CS5536 GPIO driver.
+ * Allows a user space process to play with the GPIO pins.
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the smems of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+
+#define NAME                   "cs5535_gpio"
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO Pin Driver");
+MODULE_LICENSE("GPL");
+
+static int major;
+module_param(major, int, 0);
+MODULE_PARM_DESC(major, "Major device number");
+
+static ulong mask;
+module_param(mask, ulong, 0);
+MODULE_PARM_DESC(mask, "GPIO channel mask");
+
+#define MSR_LBAR_GPIO          0x5140000C
+
+static u32 gpio_base;
+
+static struct pci_device_id divil_pci[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_NS,  PCI_DEVICE_ID_NS_CS5535_ISA) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
+       { } /* NULL entry */
+};
+
+static struct cdev cs5535_gpio_cdev;
+
+/* reserve 32 entries even though some aren't usable */
+#define CS5535_GPIO_COUNT      32
+
+/* IO block size */
+#define CS5535_GPIO_SIZE       256
+
+struct gpio_regmap {
+       u32     rd_offset;
+       u32     wr_offset;
+       char    on;
+       char    off;
+};
+static struct gpio_regmap rm[] =
+{
+       { 0x30, 0x00, '1', '0' },       /* GPIOx_READ_BACK / GPIOx_OUT_VAL */
+       { 0x20, 0x20, 'I', 'i' },       /* GPIOx_IN_EN */
+       { 0x04, 0x04, 'O', 'o' },       /* GPIOx_OUT_EN */
+       { 0x08, 0x08, 't', 'T' },       /* GPIOx_OUT_OD_EN */
+       { 0x18, 0x18, 'P', 'p' },       /* GPIOx_OUT_PU_EN */
+       { 0x1c, 0x1c, 'D', 'd' },       /* GPIOx_OUT_PD_EN */
+};
+
+
+/**
+ * Gets the register offset for the GPIO bank.
+ * Low (0-15) starts at 0x00, high (16-31) starts at 0x80
+ */
+static inline u32 cs5535_lowhigh_base(int reg)
+{
+       return (reg & 0x10) << 3;
+}
+
+static ssize_t cs5535_gpio_write(struct file *file, const char __user *data,
+                                size_t len, loff_t *ppos)
+{
+       u32     m = iminor(file->f_dentry->d_inode);
+       int     i, j;
+       u32     base = gpio_base + cs5535_lowhigh_base(m);
+       u32     m0, m1;
+       char    c;
+
+       /**
+        * Creates the mask for atomic bit programming.
+        * The high 16 bits and the low 16 bits are used to set the mask.
+        * For example, GPIO 15 maps to 31,15: 0,1 => On; 1,0=> Off
+        */
+       m1 = 1 << (m & 0x0F);
+       m0 = m1 << 16;
+
+       for (i = 0; i < len; ++i) {
+               if (get_user(c, data+i))
+                       return -EFAULT;
+
+               for (j = 0; j < ARRAY_SIZE(rm); j++) {
+                       if (c == rm[j].on) {
+                               outl(m1, base + rm[j].wr_offset);
+                               break;
+                       } else if (c == rm[j].off) {
+                               outl(m0, base + rm[j].wr_offset);
+                               break;
+                       }
+               }
+       }
+       *ppos = 0;
+       return len;
+}
+
+static ssize_t cs5535_gpio_read(struct file *file, char __user *buf,
+                               size_t len, loff_t *ppos)
+{
+       u32     m = iminor(file->f_dentry->d_inode);
+       u32     base = gpio_base + cs5535_lowhigh_base(m);
+       int     rd_bit = 1 << (m & 0x0f);
+       int     i;
+       char    ch;
+       ssize_t count = 0;
+
+       if (*ppos >= ARRAY_SIZE(rm))
+               return 0;
+
+       for (i = *ppos; (i < (*ppos + len)) && (i < ARRAY_SIZE(rm)); i++) {
+               ch = (inl(base + rm[i].rd_offset) & rd_bit) ?
+                    rm[i].on : rm[i].off;
+
+               if (put_user(ch, buf+count))
+                       return -EFAULT;
+
+               count++;
+       }
+
+       /* add a line-feed if there is room */
+       if ((i == ARRAY_SIZE(rm)) && (count < len)) {
+               put_user('\n', buf + count);
+               count++;
+       }
+
+       *ppos += count;
+       return count;
+}
+
+static int cs5535_gpio_open(struct inode *inode, struct file *file)
+{
+       u32 m = iminor(inode);
+
+       /* the mask says which pins are usable by this driver */
+       if ((mask & (1 << m)) == 0)
+               return -EINVAL;
+
+       return nonseekable_open(inode, file);
+}
+
+static struct file_operations cs5535_gpio_fops = {
+       .owner  = THIS_MODULE,
+       .write  = cs5535_gpio_write,
+       .read   = cs5535_gpio_read,
+       .open   = cs5535_gpio_open
+};
+
+static int __init cs5535_gpio_init(void)
+{
+       dev_t   dev_id;
+       u32     low, hi;
+       int     retval;
+
+       if (pci_dev_present(divil_pci) == 0) {
+               printk(KERN_WARNING NAME ": DIVIL not found\n");
+               return -ENODEV;
+       }
+
+       /* Grab the GPIO I/O range */
+       rdmsr(MSR_LBAR_GPIO, low, hi);
+
+       /* Check the mask and whether GPIO is enabled (sanity check) */
+       if (hi != 0x0000f001) {
+               printk(KERN_WARNING NAME ": GPIO not enabled\n");
+               return -ENODEV;
+       }
+
+       /* Mask off the IO base address */
+       gpio_base = low & 0x0000ff00;
+
+       /**
+        * Some GPIO pins
+        *  31-29,23 : reserved (always mask out)
+        *  28       : Power Button
+        *  26       : PME#
+        *  22-16    : LPC
+        *  14,15    : SMBus
+        *  9,8      : UART1
+        *  7        : PCI INTB
+        *  3,4      : UART2/DDC
+        *  2        : IDE_IRQ0
+        *  0        : PCI INTA
+        *
+        * If a mask was not specified, be conservative and only allow:
+        *  1,2,5,6,10-13,24,25,27
+        */
+       if (mask != 0)
+               mask &= 0x1f7fffff;
+       else
+               mask = 0x0b003c66;
+
+       if (request_region(gpio_base, CS5535_GPIO_SIZE, NAME) == 0) {
+               printk(KERN_ERR NAME ": can't allocate I/O for GPIO\n");
+               return -ENODEV;
+       }
+
+       if (major) {
+               dev_id = MKDEV(major, 0);
+               retval = register_chrdev_region(dev_id, CS5535_GPIO_COUNT,
+                                               NAME);
+       } else {
+               retval = alloc_chrdev_region(&dev_id, 0, CS5535_GPIO_COUNT,
+                                            NAME);
+               major = MAJOR(dev_id);
+       }
+
+       if (retval) {
+               release_region(gpio_base, CS5535_GPIO_SIZE);
+               return -1;
+       }
+
+       printk(KERN_DEBUG NAME ": base=%#x mask=%#lx major=%d\n",
+              gpio_base, mask, major);
+
+       cdev_init(&cs5535_gpio_cdev, &cs5535_gpio_fops);
+       cdev_add(&cs5535_gpio_cdev, dev_id, CS5535_GPIO_COUNT);
+
+       return 0;
+}
+
+static void __exit cs5535_gpio_cleanup(void)
+{
+       dev_t dev_id = MKDEV(major, 0);
+       unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
+       if (gpio_base != 0)
+               release_region(gpio_base, CS5535_GPIO_SIZE);
+}
+
+module_init(cs5535_gpio_init);
+module_exit(cs5535_gpio_cleanup);
index c7f818cd7b0214b321d9c6d5d7e3b5bf4c34ef03..39c61a71176e0f0eec82a7cb432dba91cd965fdb 100644 (file)
@@ -641,6 +641,7 @@ static char rcsid[] =
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/major.h>
 #include <linux/string.h>
@@ -723,7 +724,7 @@ static unsigned int cy_isa_addresses[] = {
         0xDE000,
         0,0,0,0,0,0,0,0
 };
-#define NR_ISA_ADDRS (sizeof(cy_isa_addresses)/sizeof(unsigned char*))
+#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
 
 #ifdef MODULE
 static long maddr[NR_CARDS] = { 0, };
@@ -1086,7 +1087,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   int had_work;
   int mdm_change;
   int mdm_status;
-
+  int len;
     if((cinfo = (struct cyclades_card *)dev_id) == 0){
 #ifdef CY_DEBUG_INTERRUPTS
        printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
@@ -1163,63 +1164,43 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                info->icount.rx++;
                                 continue;
                             }
-                            if (tty->flip.count < TTY_FLIPBUF_SIZE){
-                                tty->flip.count++;
+                            if (tty_buffer_request_room(tty, 1)) {
                                 if (data & info->read_status_mask){
                                     if(data & CyBREAK){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_BREAK;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK);
                                        info->icount.rx++;
                                         if (info->flags & ASYNC_SAK){
                                             do_SAK(tty);
                                         }
                                     }else if(data & CyFRAME){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_FRAME;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
                                        info->icount.rx++;
                                        info->idle_stats.frame_errs++;
                                     }else if(data & CyPARITY){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_PARITY;
-                                        *tty->flip.char_buf_ptr++ =
-                                         cy_readb(base_addr+(CyRDSR<<index));
+                                       /* Pieces of seven... */
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY);
                                        info->icount.rx++;
                                        info->idle_stats.parity_errs++;
                                     }else if(data & CyOVERRUN){
-                                        *tty->flip.flag_buf_ptr++ =
-                                                           TTY_OVERRUN;
-                                        *tty->flip.char_buf_ptr++ = 0;
+                                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                                        info->icount.rx++;
                                         /* If the flip buffer itself is
                                            overflowing, we still lose
                                            the next incoming character.
                                          */
-                                        if(tty->flip.count
-                                                  < TTY_FLIPBUF_SIZE){
-                                            tty->flip.count++;
-                                            *tty->flip.flag_buf_ptr++ =
-                                                            TTY_NORMAL;
-                                           *tty->flip.char_buf_ptr++ =
-                                           cy_readb(base_addr+(CyRDSR<<index));
-                                           info->icount.rx++;
-                                        }
+                                        tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME);
+                                       info->icount.rx++;
                                        info->idle_stats.overruns++;
                                     /* These two conditions may imply */
                                     /* a normal read should be done. */
                                     /* }else if(data & CyTIMEOUT){ */
                                     /* }else if(data & CySPECHAR){ */
-                                    }else{
-                                        *tty->flip.flag_buf_ptr++ = 0;
-                                        *tty->flip.char_buf_ptr++ = 0;
-                                       info->icount.rx++;
+                                    }else {
+                                       tty_insert_flip_char(tty, 0, TTY_NORMAL);
+                                       info->icount.rx++;
                                     }
                                 }else{
-                                    *tty->flip.flag_buf_ptr++ = 0;
-                                    *tty->flip.char_buf_ptr++ = 0;
+                                   tty_insert_flip_char(tty, 0, TTY_NORMAL);
                                    info->icount.rx++;
                                 }
                             }else{
@@ -1240,14 +1221,10 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                info->mon.char_max = char_count;
                             info->mon.char_last = char_count;
 #endif
-                            while(char_count--){
-                                if (tty->flip.count >= TTY_FLIPBUF_SIZE){
-                                        break;
-                                }
-                                tty->flip.count++;
+                           len = tty_buffer_request_room(tty, char_count);
+                            while(len--){
                                 data = cy_readb(base_addr+(CyRDSR<<index));
-                                *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                                *tty->flip.char_buf_ptr++ = data;
+                               tty_insert_flip_char(tty, data, TTY_NORMAL);
                                info->idle_stats.recv_bytes++;
                                info->icount.rx++;
 #ifdef CY_16Y_HACK
@@ -1256,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                             }
                              info->idle_stats.recv_idle = jiffies;
                         }
-                        schedule_delayed_work(&tty->flip.work, 1);
+                        schedule_delayed_work(&tty->buf.work, 1);
                     }
                     /* end of service */
                     cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f));
@@ -1551,6 +1528,7 @@ cyz_handle_rx(struct cyclades_port *info,
   struct cyclades_card *cinfo = &cy_card[info->card];
   struct tty_struct *tty = info->tty;
   volatile int char_count;
+  int len;
 #ifdef BLOCKMOVE
   int small_count;
 #else
@@ -1606,18 +1584,11 @@ cyz_handle_rx(struct cyclades_port *info,
                tty->flip.count += small_count;
            }
 #else
-           while(char_count--){
-               if (tty->flip.count >= N_TTY_BUF_SIZE - tty->read_cnt)
-                    break;
-
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                   break;
-
+           len = tty_buffer_request_room(tty, char_count);
+           while(len--){
                data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get);
                new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1);
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-               *tty->flip.char_buf_ptr++ = data;
+               tty_insert_flip_char(tty, data, TTY_NORMAL);
                info->idle_stats.recv_bytes++;
                info->icount.rx++;
            }
@@ -1635,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info,
            }
 #endif
            info->idle_stats.recv_idle = jiffies;
-           schedule_delayed_work(&tty->flip.work, 1);
+           schedule_delayed_work(&tty->buf.work, 1);
        }
        /* Update rx_get */
        cy_writel(&buf_ctrl->rx_get, new_rx_get);
@@ -1763,23 +1734,17 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
 
        switch(cmd) {
            case C_CM_PR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_PARITY);
                info->icount.rx++;
                special_count++;
                break;
            case C_CM_FR_ERROR:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_FRAME);
                info->icount.rx++;
                special_count++;
                break;
            case C_CM_RXBRK:
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-               *tty->flip.char_buf_ptr++ = 0;
+               tty_insert_flip_char(tty, 0, TTY_BREAK);
                info->icount.rx++;
                special_count++;
                break;
@@ -1844,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
        if(delta_count)
            cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
        if(special_count)
-           schedule_delayed_work(&tty->flip.work, 1);
+           schedule_delayed_work(&tty->buf.work, 1);
     }
 }
 
index dd91ff6b474cc3045d2aed3004a12db619e30f1e..e9e2db18952dc91e2b88c8283efb6d385ff84dd9 100644 (file)
@@ -28,7 +28,6 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
-#include <linux/ioctl32.h>
 
 #include "drmP.h"
 #include "drm_core.h"
index 2218a946ec872e4041232b01d23a77624349e5b7..296248cdc767e50cc2cdd1c0f40a6deedf4b299e 100644 (file)
@@ -30,7 +30,6 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
-#include <linux/ioctl32.h>
 
 #include "drmP.h"
 #include "drm.h"
index 24a9d4e86af0947e1c1f3d4bafadc71bd32076cf..54a18eb2fc04abb75f7d2f19b6903cb06c3d1ddf 100644 (file)
@@ -31,7 +31,6 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
-#include <linux/ioctl32.h>
 
 #include "drmP.h"
 #include "drm.h"
index 1e2e367b8b82f89749a74059c3890a8e32b1a980..9dd6d4116e4761d9041887cd14d10c27d3016870 100644 (file)
@@ -30,7 +30,6 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
-#include <linux/ioctl32.h>
 
 #include "drmP.h"
 #include "drm.h"
index fef4a2b84c1ec6fdbd72e7df157affbde7dd03b6..0ccfd3618ff1c66a16d6ac261f9f3f2b3bcf1235 100644 (file)
@@ -28,7 +28,6 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
-#include <linux/ioctl32.h>
 
 #include "drmP.h"
 #include "drm.h"
index 407708a001e421ea0322ee908074a09381e2125a..765c5c108bf4f532619724eab156d3bbf3694bda 100644 (file)
@@ -1786,9 +1786,7 @@ static void doevent(int crd)
                if (tty)  { /* Begin if valid tty */
                        if (event & BREAK_IND)  { /* Begin if BREAK_IND */
                                /* A break has been indicated */
-                               tty->flip.count++;
-                               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-                               *tty->flip.char_buf_ptr++ = 0;
+                               tty_insert_flip_char(tty, 0, TTY_BREAK);
                                tty_schedule_flip(tty); 
                        } else if (event & LOWTX_IND)  { /* Begin LOWTX_IND */
                                if (ch->statusflags & LOWWAIT) 
@@ -2124,7 +2122,6 @@ static void receive_data(struct channel *ch)
        int dataToRead, wrapgap, bytesAvailable;
        unsigned int tail, head;
        unsigned int wrapmask;
-       int rc;
 
        /* ---------------------------------------------------------------
                This routine is called by doint when a receive data event 
@@ -2162,16 +2159,15 @@ static void receive_data(struct channel *ch)
                return;
        }
 
-       if (tty->flip.count == TTY_FLIPBUF_SIZE) 
+       if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0)
                return;
 
        if (readb(&bc->orun)) {
                writeb(0, &bc->orun);
                printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n",tty->name);
+               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        }
        rxwinon(ch);
-       rptr = tty->flip.char_buf_ptr;
-       rc = tty->flip.count;
        while (bytesAvailable > 0)  { /* Begin while there is data on the card */
                wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
                /* ---------------------------------------------------------------
@@ -2183,8 +2179,7 @@ static void receive_data(struct channel *ch)
                /* --------------------------------------------------------------
                   Make sure we don't overflow the buffer
                ----------------------------------------------------------------- */
-               if ((rc + dataToRead) > TTY_FLIPBUF_SIZE)
-                       dataToRead = TTY_FLIPBUF_SIZE - rc;
+               dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
                if (dataToRead == 0)
                        break;
                /* ---------------------------------------------------------------
@@ -2192,13 +2187,9 @@ static void receive_data(struct channel *ch)
                        for translation if necessary.
                ------------------------------------------------------------------ */
                memcpy_fromio(rptr, ch->rxptr + tail, dataToRead);
-               rc   += dataToRead;
-               rptr += dataToRead;
                tail = (tail + dataToRead) & wrapmask;
                bytesAvailable -= dataToRead;
        } /* End while there is data on the card */
-       tty->flip.count = rc;
-       tty->flip.char_buf_ptr = rptr;
        globalwinon(ch);
        writew(tail, &bc->rout);
        /* Must be called with global data */
index 9f53d2fcc360deefc94f131e68b590373212b812..e469f641c7289b75439b06e8f31e402eba7cf44c 100644 (file)
@@ -345,26 +345,22 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
 
        for (i = 0; i < num_bytes; i++) {
                if (!(err_buf->data[i] & status_mask)) {
-                       *(tty->flip.char_buf_ptr++) = pio_buf->data[i];
+                       int flag = 0;
 
                        if (err_buf->data[i] & 0x04) {
-                               *(tty->flip.flag_buf_ptr++) = TTY_BREAK;
-
+                               flag = TTY_BREAK;
                                if (info->flags & ASYNC_SAK)
                                        do_SAK(tty);
                        }
                        else if (err_buf->data[i] & 0x02)
-                               *(tty->flip.flag_buf_ptr++) = TTY_FRAME;
+                               flag = TTY_FRAME;
                        else if (err_buf->data[i] & 0x01)
-                               *(tty->flip.flag_buf_ptr++) = TTY_PARITY;
-                       else
-                               *(tty->flip.flag_buf_ptr++) = 0;
-               
-                       tty->flip.count++;
+                               flag = TTY_PARITY;
+                       tty_insert_flip_char(tty, pio_buf->data[i], flag);
                }
        }
 
-       schedule_delayed_work(&tty->flip.work, 1);
+       schedule_delayed_work(&tty->buf.work, 1);
 
        info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
        release_pio_buffer(pio_buf);
@@ -397,7 +393,6 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
        int num_bytes;
        unsigned long flags;
        
-       
        flags=claim_dma_lock();
        disable_dma(dma);
        clear_dma_ff(dma);
@@ -408,38 +403,31 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
        
        info->icount.rx += num_bytes;
 
-       memcpy(tty->flip.char_buf_ptr, dma_buffer, num_bytes);
-       tty->flip.char_buf_ptr += num_bytes;
-       tty->flip.count += num_bytes;
-       memset(tty->flip.flag_buf_ptr, 0, num_bytes);
-       tty->flip.flag_buf_ptr += num_bytes;
-
        if (num_bytes > 0) {
-               tty->flip.flag_buf_ptr--;
+               tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
 
                status &= (0x1c & info->read_status_mask);
+               
+               /* Is the status significant or do we throw the last byte ? */
+               if (!(status & info->ignore_status_mask)) {
+                       int statflag = 0;
 
-               if (status & info->ignore_status_mask) {
-                       tty->flip.count--;
-                       tty->flip.char_buf_ptr--;
-                       tty->flip.flag_buf_ptr--;
-               } else if (status & 0x10) {
-                       *tty->flip.flag_buf_ptr = TTY_BREAK;
-                       (info->icount.brk)++;
-                       if (info->flags & ASYNC_SAK)
-                               do_SAK(tty);
-               } else if (status & 0x08) {
-                       *tty->flip.flag_buf_ptr = TTY_FRAME;
-                       (info->icount.frame)++;
-               }
-               else if (status & 0x04) {
-                       *tty->flip.flag_buf_ptr = TTY_PARITY;
-                       (info->icount.parity)++;
+                       if (status & 0x10) {
+                               statflag = TTY_BREAK;
+                               (info->icount.brk)++;
+                               if (info->flags & ASYNC_SAK)
+                                       do_SAK(tty);
+                       } else if (status & 0x08) {
+                               statflag = TTY_FRAME;
+                               (info->icount.frame)++;
+                       }
+                       else if (status & 0x04) {
+                               statflag = TTY_PARITY;
+                               (info->icount.parity)++;
+                       }
+                       tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag);
                }
-
-               tty->flip.flag_buf_ptr++;
-               
-               schedule_delayed_work(&tty->flip.work, 1);
+               schedule_delayed_work(&tty->buf.work, 1);
        }
 
        if (dma_bytes != num_bytes) {
@@ -693,8 +681,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id,
                num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
                num_bytes |= serial_in(info, UART_ESI_STAT2);
 
-               if (num_bytes > (TTY_FLIPBUF_SIZE - info->tty->flip.count))
-                 num_bytes = TTY_FLIPBUF_SIZE - info->tty->flip.count;
+               num_bytes = tty_buffer_request_room(info->tty, num_bytes);
 
                if (num_bytes) {
                        if (dma_bytes ||
index f921776346779aa8516d7ce861e6c44c6cc50165..1994a92d473390d9b723ecae80406bc27ef548d3 100644 (file)
@@ -597,9 +597,7 @@ static int hvc_poll(struct hvc_struct *hp)
 
        /* Read data if any */
        for (;;) {
-               int count = N_INBUF;
-               if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
-                       count = TTY_FLIPBUF_SIZE - tty->flip.count;
+               int count = tty_buffer_request_room(tty, N_INBUF);
 
                /* If flip is full, just reschedule a later read */
                if (count == 0) {
@@ -635,7 +633,7 @@ static int hvc_poll(struct hvc_struct *hp)
                        tty_insert_flip_char(tty, buf[i], 0);
                }
 
-               if (tty->flip.count)
+               if (count)
                        tty_schedule_flip(tty);
 
                /*
index 53dc77c760fccff12a07665cb9bb0f6d6abdcba7..831eb4e8d9d372afd9e79eec2debb0367d9780e4 100644 (file)
@@ -456,12 +456,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
        /* remove the read masks */
        hvcsd->todo_mask &= ~(HVCS_READ_MASK);
 
-       if ((tty->flip.count + HVCS_BUFF_LEN) < TTY_FLIPBUF_SIZE) {
+       if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) {
                got = hvc_get_chars(unit_address,
                                &buf[0],
                                HVCS_BUFF_LEN);
-               for (i=0;got && i<got;i++)
-                       tty_insert_flip_char(tty, buf[i], TTY_NORMAL);
+               tty_insert_flip_string(tty, buf, got);
        }
 
        /* Give the TTY time to process the data we just sent. */
@@ -469,10 +468,9 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
                hvcsd->todo_mask |= HVCS_QUICK_READ;
 
        spin_unlock_irqrestore(&hvcsd->lock, flags);
-       if (tty->flip.count) {
-               /* This is synch because tty->low_latency == 1 */
+       /* This is synch because tty->low_latency == 1 */
+       if(got)
                tty_flip_buffer_push(tty);
-       }
 
        if (!got) {
                /* Do this _after_ the flip_buffer_push */
index a22aa940e01e15356e81164236853526c16bfb39..a9522189fc9efeaa82dab6d3b479df11d89a8412 100644 (file)
@@ -197,7 +197,7 @@ static inline void print_state(struct hvsi_struct *hp)
        };
        const char *name = state_names[hp->state];
 
-       if (hp->state > (sizeof(state_names)/sizeof(char*)))
+       if (hp->state > ARRAY_SIZE(state_names))
                name = "UNKNOWN";
 
        pr_debug("hvsi%i: state = %s\n", hp->index, name);
index ba85eb1b6ec75bfa56cd10b06b95cd9ff0186ee8..fc944d375be75101429b98e2f160dd41f4e6100e 100644 (file)
@@ -854,7 +854,7 @@ i2Input(i2ChanStrPtr pCh)
                count += IBUF_SIZE;
        }
        // Don't give more than can be taken by the line discipline
-       amountToMove = pCh->pTTY->ldisc.receive_room( pCh->pTTY );
+       amountToMove = pCh->pTTY->receive_room;
        if (count > amountToMove) {
                count = amountToMove;
        }
index d815d197dc3e331daee13bfbfa3e1dd7ba37dddb..56e93a5a1e2413fc8477aa354e436ee0d38df202 100644 (file)
@@ -172,7 +172,7 @@ static int Fip_firmware_size;
 /* Private (static) functions */
 static int  ip2_open(PTTY, struct file *);
 static void ip2_close(PTTY, struct file *);
-static int  ip2_write(PTTY, int, const unsigned char *, int);
+static int  ip2_write(PTTY, const unsigned char *, int);
 static void ip2_putchar(PTTY, unsigned char);
 static void ip2_flush_chars(PTTY);
 static int  ip2_write_room(PTTY);
@@ -1713,7 +1713,7 @@ ip2_hangup ( PTTY tty )
 /*                                                                            */
 /******************************************************************************/
 static int
-ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
+ip2_write( PTTY tty, const unsigned char *pData, int count)
 {
        i2ChanStrPtr  pCh = tty->driver_data;
        int bytesSent = 0;
@@ -1726,7 +1726,7 @@ ip2_write( PTTY tty, int user, const unsigned char *pData, int count)
 
        /* This is the actual move bit. Make sure it does what we need!!!!! */
        WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       bytesSent = i2Output( pCh, pData, count, user );
+       bytesSent = i2Output( pCh, pData, count, 0 );
        WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
 
        ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
@@ -2001,7 +2001,9 @@ ip2_stop ( PTTY tty )
 static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
 {
        i2ChanStrPtr pCh = DevTable[tty->index];
+#ifdef ENABLE_DSSNOW
        wait_queue_t wait;
+#endif
 
        if (pCh == NULL)
                return -ENODEV;
@@ -2089,15 +2091,17 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
 {
        wait_queue_t wait;
        i2ChanStrPtr pCh = DevTable[tty->index];
+       i2eBordStrPtr pB;
        struct async_icount cprev, cnow;        /* kernel counter temps */
        struct serial_icounter_struct __user *p_cuser;
        int rc = 0;
        unsigned long flags;
        void __user *argp = (void __user *)arg;
 
-       if ( pCh == NULL ) {
+       if ( pCh == NULL )
                return -ENODEV;
-       }
+
+       pB = pCh->pMyBord;
 
        ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
 
@@ -2206,9 +2210,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
         * for masking). Caller should use TIOCGICOUNT to see which one it was
         */
        case TIOCMIWAIT:
-               save_flags(flags);cli();
+               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
                cprev = pCh->icount;     /* note the counters on entry */
-               restore_flags(flags);
+               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
                i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, 
                                                CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
                init_waitqueue_entry(&wait, current);
@@ -2228,9 +2232,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
                                rc = -ERESTARTSYS;
                                break;
                        }
-                       save_flags(flags);cli();
+                       WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
                        cnow = pCh->icount; /* atomic copy */
-                       restore_flags(flags);
+                       WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                                cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
                                rc =  -EIO; /* no change => rc */
@@ -2268,9 +2272,9 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
        case TIOCGICOUNT:
                ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
 
-               save_flags(flags);cli();
+               WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
                cnow = pCh->icount;
-               restore_flags(flags);
+               WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
                p_cuser = argp;
                rc = put_user(cnow.cts, &p_cuser->cts);
                rc = put_user(cnow.dsr, &p_cuser->dsr);
index 561430ed94af789d6beb67764660a91222f98c42..0097f06fa67ba0af6852eb033597b7f0f1b08eb1 100644 (file)
@@ -57,6 +57,7 @@ static int initialized = 0;
 
 #ifdef CONFIG_PROC_FS
 struct proc_dir_entry *proc_ipmi_root = NULL;
+EXPORT_SYMBOL(proc_ipmi_root);
 #endif /* CONFIG_PROC_FS */
 
 #define MAX_EVENTS_IN_QUEUE    25
@@ -3295,6 +3296,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
 EXPORT_SYMBOL(ipmi_set_my_LUN);
 EXPORT_SYMBOL(ipmi_get_my_LUN);
 EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
-EXPORT_SYMBOL(proc_ipmi_root);
 EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
 EXPORT_SYMBOL(ipmi_free_recv_msg);
index e053eade0366b070a90772305f91a3f884f5fd38..49c09ae004bffc324162a45710f631552ba1f220 100644 (file)
@@ -612,11 +612,14 @@ static int ipmi_poweroff_init (void)
 #endif
 
        rv = ipmi_smi_watcher_register(&smi_watcher);
+
+#ifdef CONFIG_PROC_FS
        if (rv) {
                unregister_sysctl_table(ipmi_table_header);
                printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
                goto out_err;
        }
+#endif
 
  out_err:
        return rv;
index 1bbf507adda5ee2d43b8d5772dd8e7b273577a93..e9ebabaf8cb03184e9990ea272cc91fa733f6a21 100644 (file)
@@ -20,7 +20,7 @@
  *     3/9/99  sameer                  Added support for ISI4616 cards.
  *
  *     16/9/99 sameer                  We do not force RTS low anymore.
- *                                     This is to prevent the firmware 
+ *                                     This is to prevent the firmware
  *                                     from getting confused.
  *
  *     26/10/99 sameer                 Cosmetic changes:The driver now
  *
  *     10/5/00  sameer                 Fixed isicom_shutdown_board()
  *                                     to not lower DTR on all the ports
- *                                     when the last port on the card is 
+ *                                     when the last port on the card is
  *                                     closed.
  *
  *     10/5/00  sameer                 Signal mask setup command added
- *                                     to  isicom_setup_port and 
+ *                                     to  isicom_setup_port and
  *                                     isicom_shutdown_port.
  *
  *     24/5/00  sameer                 The driver is now SMP aware.
- *                                     
- *     
+ *
+ *
  *     27/11/00 Vinayak P Risbud       Fixed the Driver Crash Problem
- *     
- *     
+ *
+ *
  *     03/01/01  anil .s               Added support for resetting the
  *                                     internal modems on ISI cards.
  *
  *     08/02/01  anil .s               Upgraded the driver for kernel
  *                                     2.4.x
  *
- *      11/04/01  Kevin                        Fixed firmware load problem with
+ *     11/04/01  Kevin                 Fixed firmware load problem with
  *                                     ISIHP-4X card
- *     
+ *
  *     30/04/01  anil .s               Fixed the remote login through
  *                                     ISI port problem. Now the link
  *                                     does not go down before password
@@ -62,9 +62,9 @@
  *                                     among ISI-PCI cards.
  *
  *     03/05/01  anil .s               Added support to display the version
- *                                     info during insmod as well as module 
+ *                                     info during insmod as well as module
  *                                     listing by lsmod.
- *     
+ *
  *     10/05/01  anil .s               Done the modifications to the source
  *                                     file and Install script so that the
  *                                     same installation can be used for
  *     06/06/01  anil .s               Now we drop both dtr and rts during
  *                                     shutdown_port as well as raise them
  *                                     during isicom_config_port.
- *     
+ *
  *     09/06/01 acme@conectiva.com.br  use capable, not suser, do
  *                                     restore_flags on failure in
  *                                     isicom_send_break, verify put_user
  *                                     result
  *
- *     11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
- *                                     Baud index extended to 21
- *     
- *     20/03/03  ranjeeth              Made to work for Linux Advanced server.
- *                                     Taken care of license warning.  
- *      
- *     10/12/03  Ravindra              Made to work for Fedora Core 1 of 
+ *     11/02/03  ranjeeth              Added support for 230 Kbps and 460 Kbps
+ *                                     Baud index extended to 21
+ *
+ *     20/03/03  ranjeeth              Made to work for Linux Advanced server.
+ *                                     Taken care of license warning.
+ *
+ *     10/12/03  Ravindra              Made to work for Fedora Core 1 of
  *                                     Red Hat Distribution
  *
  *     06/01/05  Alan Cox              Merged the ISI and base kernel strands
  *
  *     ***********************************************************
  *
- *     To use this driver you also need the support package. You 
+ *     To use this driver you also need the support package. You
  *     can find this in RPM format on
  *             ftp://ftp.linux.org.uk/pub/linux/alan
- *     
+ *
  *     You can find the original tools for this direct from Multitech
  *             ftp://ftp.multitech.com/ISI-Cards/
  *
  *     Omit those entries for boards you don't have installed.
  *
  *     TODO
- *             Hotplug
  *             Merge testing
  *             64-bit verification
  */
 
 #include <linux/module.h>
+#include <linux/firmware.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/termios.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/serial.h>
 #include <linux/mm.h>
-#include <linux/miscdevice.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/delay.h>
 
 #include <linux/isicom.h>
 
+#define InterruptTheCard(base) outw(0, (base) + 0xc)
+#define ClearInterrupt(base) inw((base) + 0x0a)
+
+#ifdef DEBUG
+#define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str)
+#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
+#else
+#define pr_dbg(str...) do { } while (0)
+#define isicom_paranoia_check(a, b, c) 0
+#endif
+
+static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
+static void __devexit isicom_remove(struct pci_dev *);
+
 static struct pci_device_id isicom_pci_tbl[] = {
-       { VENDOR_ID, 0x2028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-       { VENDOR_ID, 0x2058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_DEVICE(VENDOR_ID, 0x2028) },
+       { PCI_DEVICE(VENDOR_ID, 0x2051) },
+       { PCI_DEVICE(VENDOR_ID, 0x2052) },
+       { PCI_DEVICE(VENDOR_ID, 0x2053) },
+       { PCI_DEVICE(VENDOR_ID, 0x2054) },
+       { PCI_DEVICE(VENDOR_ID, 0x2055) },
+       { PCI_DEVICE(VENDOR_ID, 0x2056) },
+       { PCI_DEVICE(VENDOR_ID, 0x2057) },
+       { PCI_DEVICE(VENDOR_ID, 0x2058) },
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
 
+static struct pci_driver isicom_driver = {
+       .name           = "isicom",
+       .id_table       = isicom_pci_tbl,
+       .probe          = isicom_probe,
+       .remove         = __devexit_p(isicom_remove)
+};
+
 static int prev_card = 3;      /*      start servicing isi_card[0]     */
 static struct tty_driver *isicom_normal;
 
 static struct timer_list tx;
 static char re_schedule = 1;
-#ifdef ISICOM_DEBUG
-static unsigned long tx_count = 0;
-#endif
-
-static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned  int cmd, unsigned long arg);
 
 static void isicom_tx(unsigned long _data);
-static void isicom_start(struct tty_struct * tty);
-
-static unsigned char * tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
+static void isicom_start(struct tty_struct *tty);
 
 /*   baud index mappings from linux defns to isi */
 
 static signed char linuxb_to_isib[] = {
-       -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17,     
-       18, 19
+       -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19
 };
 
 struct isi_board {
-       unsigned short          base;
+       unsigned long           base;
        unsigned char           irq;
        unsigned char           port_count;
        unsigned short          status;
-       unsigned short          port_status; /* each bit represents a single port */
+       unsigned short          port_status; /* each bit for each port */
        unsigned short          shift_count;
        struct isi_port         * ports;
        signed char             count;
@@ -192,9 +204,9 @@ struct      isi_port {
        int                     count;
        int                     blocked_open;
        int                     close_delay;
-       unsigned short          channel;
-       unsigned short          status;
-       unsigned short          closing_wait;
+       u16                     channel;
+       u16                     status;
+       u16                     closing_wait;
        struct isi_board        * card;
        struct tty_struct       * tty;
        wait_queue_head_t       close_wait;
@@ -215,35 +227,37 @@ static struct isi_port  isi_ports[PORT_COUNT];
  *     the kernel lock for the card and have the card in a position that
  *     it wants to talk.
  */
+
 static int lock_card(struct isi_board *card)
 {
        char            retries;
-       unsigned short base = card->base;
+       unsigned long base = card->base;
 
        for (retries = 0; retries < 100; retries++) {
                spin_lock_irqsave(&card->card_lock, card->flags);
                if (inw(base + 0xe) & 0x1) {
-                       return 1; 
+                       return 1;
                } else {
                        spin_unlock_irqrestore(&card->card_lock, card->flags);
                        udelay(1000);   /* 1ms */
                }
        }
-       printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%x)\n", card->base);
+       printk(KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n",
+               card->base);
+
        return 0;       /* Failed to aquire the card! */
 }
 
 static int lock_card_at_interrupt(struct isi_board *card)
 {
        unsigned char           retries;
-       unsigned short          base = card->base;
+       unsigned long base = card->base;
 
        for (retries = 0; retries < 200; retries++) {
                spin_lock_irqsave(&card->card_lock, card->flags);
 
                if (inw(base + 0xe) & 0x1)
-                       return 1; 
+                       return 1;
                else
                        spin_unlock_irqrestore(&card->card_lock, card->flags);
        }
@@ -259,373 +273,141 @@ static void unlock_card(struct isi_board *card)
 /*
  *  ISI Card specific ops ...
  */
-static void raise_dtr(struct isi_port * port)
+
+static void raise_dtr(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0504, base);
        InterruptTheCard(base);
        port->status |= ISI_DTR;
        unlock_card(card);
 }
 
-static inline void drop_dtr(struct isi_port * port)
-{      
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+static inline void drop_dtr(struct isi_port *port)
+{
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0404, base);
-       InterruptTheCard(base); 
+       InterruptTheCard(base);
        port->status &= ~ISI_DTR;
        unlock_card(card);
 }
 
-static inline void raise_rts(struct isi_port * port)
+static inline void raise_rts(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0a04, base);
-       InterruptTheCard(base); 
+       InterruptTheCard(base);
        port->status |= ISI_RTS;
        unlock_card(card);
 }
-static inline void drop_rts(struct isi_port * port)
+static inline void drop_rts(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0804, base);
-       InterruptTheCard(base); 
+       InterruptTheCard(base);
        port->status &= ~ISI_RTS;
        unlock_card(card);
 }
 
-static inline void raise_dtr_rts(struct isi_port * port)
+static inline void raise_dtr_rts(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0f04, base);
        InterruptTheCard(base);
        port->status |= (ISI_DTR | ISI_RTS);
        unlock_card(card);
 }
 
-static void drop_dtr_rts(struct isi_port * port)
+static void drop_dtr_rts(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw(0x0c04, base);
-       InterruptTheCard(base); 
+       InterruptTheCard(base);
        port->status &= ~(ISI_RTS | ISI_DTR);
        unlock_card(card);
 }
 
-static inline void kill_queue(struct isi_port * port, short queue)
+static inline void kill_queue(struct isi_port *port, short queue)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;
-       unsigned char channel = port->channel;
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+       u16 channel = port->channel;
 
        if (!lock_card(card))
                return;
 
-       outw(0x8000 | (channel << card->shift_count) | 0x02 , base);
+       outw(0x8000 | (channel << card->shift_count) | 0x02, base);
        outw((queue << 8) | 0x06, base);
-       InterruptTheCard(base); 
+       InterruptTheCard(base);
        unlock_card(card);
 }
 
-
-/* 
- *  Firmware loader driver specific routines. This needs to mostly die
- *  and be replaced with request_firmware.
- */
-
-static struct file_operations ISILoad_fops = {
-       .owner          = THIS_MODULE,
-       .ioctl          = ISILoad_ioctl,
-};
-
-static struct miscdevice isiloader_device = {
-       ISILOAD_MISC_MINOR, "isictl", &ISILoad_fops
-};
-
-static inline int WaitTillCardIsFree(unsigned short base)
-{
-       unsigned long count=0;
-       while( (!(inw(base+0xe) & 0x1)) && (count++ < 6000000));
-       if (inw(base+0xe)&0x1)  
-               return 0;
-       else
-               return 1;
-}
-
-static int ISILoad_ioctl(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg)
-{
-       unsigned int card, i, j, signature, status, portcount = 0;
-       unsigned long t;
-       unsigned short word_count, base;
-       bin_frame frame;
-       void __user *argp = (void __user *)arg;
-       /* exec_record exec_rec; */
-       
-       if(get_user(card, (int __user *)argp))
-               return -EFAULT;
-               
-       if(card < 0 || card >= BOARD_COUNT)
-               return -ENXIO;
-               
-       base=isi_card[card].base;
-       
-       if(base==0)
-               return -ENXIO;  /* disabled or not used */
-       
-       switch(cmd) {
-               case MIOCTL_RESET_CARD:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       printk(KERN_DEBUG "ISILoad:Resetting Card%d at 0x%x ",card+1,base);
-                                                               
-                       inw(base+0x8);
-                       
-                       for(t=jiffies+HZ/100;time_before(jiffies, t););
-                               
-                       outw(0,base+0x8); /* Reset */
-                       
-                       for(j=1;j<=3;j++) {
-                               for(t=jiffies+HZ;time_before(jiffies, t););
-                               printk(".");
-                       }       
-                       signature=(inw(base+0x4)) & 0xff;       
-                       if (isi_card[card].isa) {
-                                       
-                               if (!(inw(base+0xe) & 0x1) || (inw(base+0x2))) {
-#ifdef ISICOM_DEBUG                            
-                                       printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe));
-#endif                         
-                                       printk("\nISILoad:ISA Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
-                                       return -EIO;                                    
-                               }
-                       }       
-                       else {
-                               portcount = inw(base+0x2);
-                               if (!(inw(base+0xe) & 0x1) || ((portcount!=0) && (portcount!=4) && (portcount!=8))) {   
-#ifdef ISICOM_DEBUG
-                                       printk("\nbase+0x2=0x%x , base+0xe=0x%x",inw(base+0x2),inw(base+0xe));
-#endif
-                                       printk("\nISILoad:PCI Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
-                                       return -EIO;
-                               }
-                       }       
-                       switch(signature) {
-                       case    0xa5:
-                       case    0xbb:
-                       case    0xdd:   
-                                       if (isi_card[card].isa) 
-                                               isi_card[card].port_count = 8;
-                                       else {
-                                               if (portcount == 4)
-                                                       isi_card[card].port_count = 4;
-                                               else
-                                                       isi_card[card].port_count = 8;
-                                       }       
-                                       isi_card[card].shift_count = 12;
-                                       break;
-                                       
-                       case    0xcc:   isi_card[card].port_count = 16;
-                                       isi_card[card].shift_count = 11;
-                                       break;                          
-                                       
-                       default: printk("ISILoad:Card%d reset failure (Possible bad I/O Port Address 0x%x).\n",card+1,base);
-#ifdef ISICOM_DEBUG                    
-                                printk("Sig=0x%x\n",signature);
-#endif                          
-                                return -EIO;
-                       }
-                       printk("-Done\n");
-                       return put_user(signature,(unsigned __user *)argp);
-                                               
-       case    MIOCTL_LOAD_FIRMWARE:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                               
-                       if(copy_from_user(&frame, argp, sizeof(bin_frame)))
-                               return -EFAULT;
-                       
-                       if (WaitTillCardIsFree(base))
-                               return -EIO;
-                       
-                       outw(0xf0,base);        /* start upload sequence */ 
-                       outw(0x00,base);
-                       outw((frame.addr), base);/*      lsb of adderess    */
-                       
-                       word_count=(frame.count >> 1) + frame.count % 2;
-                       outw(word_count, base);
-                       InterruptTheCard(base);
-                       
-                       for(i=0;i<=0x2f;i++);   /* a wee bit of delay */
-                       
-                       if (WaitTillCardIsFree(base)) 
-                               return -EIO;
-                               
-                       if ((status=inw(base+0x4))!=0) {
-                               printk(KERN_WARNING "ISILoad:Card%d rejected load header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n", 
-                               card+1, frame.addr, frame.count, status);
-                               return -EIO;
-                       }
-                       outsw(base, (void *) frame.bin_data, word_count);
-                       
-                       InterruptTheCard(base);
-                       
-                       for(i=0;i<=0x0f;i++);   /* another wee bit of delay */ 
-                       
-                       if (WaitTillCardIsFree(base)) 
-                               return -EIO;
-                               
-                       if ((status=inw(base+0x4))!=0) {
-                               printk(KERN_ERR "ISILoad:Card%d got out of sync.Card Status:0x%x\n",card+1, status);
-                               return -EIO;
-                       }       
-                       return 0;
-                                               
-       case    MIOCTL_READ_FIRMWARE:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                               
-                       if(copy_from_user(&frame, argp, sizeof(bin_header)))
-                               return -EFAULT;
-                       
-                       if (WaitTillCardIsFree(base))
-                               return -EIO;
-                       
-                       outw(0xf1,base);        /* start download sequence */ 
-                       outw(0x00,base);
-                       outw((frame.addr), base);/*      lsb of adderess    */
-                       
-                       word_count=(frame.count >> 1) + frame.count % 2;
-                       outw(word_count+1, base);
-                       InterruptTheCard(base);
-                       
-                       for(i=0;i<=0xf;i++);    /* a wee bit of delay */
-                       
-                       if (WaitTillCardIsFree(base)) 
-                               return -EIO;
-                               
-                       if ((status=inw(base+0x4))!=0) {
-                               printk(KERN_WARNING "ISILoad:Card%d rejected verify header:\nAddress:0x%x \nCount:0x%x \nStatus:0x%x \n", 
-                               card+1, frame.addr, frame.count, status);
-                               return -EIO;
-                       }
-                       
-                       inw(base);
-                       insw(base, frame.bin_data, word_count);
-                       InterruptTheCard(base);
-                       
-                       for(i=0;i<=0x0f;i++);   /* another wee bit of delay */ 
-                       
-                       if (WaitTillCardIsFree(base)) 
-                               return -EIO;
-                               
-                       if ((status=inw(base+0x4))!=0) {
-                               printk(KERN_ERR "ISILoad:Card%d verify got out of sync.Card Status:0x%x\n",card+1, status);
-                               return -EIO;
-                       }       
-                       
-                       if(copy_to_user(argp, &frame, sizeof(bin_frame)))
-                               return -EFAULT;
-                       return 0;
-       
-       case    MIOCTL_XFER_CTRL:
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EPERM;
-                       if (WaitTillCardIsFree(base)) 
-                               return -EIO;
-                                       
-                       outw(0xf2, base);
-                       outw(0x800, base);
-                       outw(0x0, base);
-                       outw(0x0, base);
-                       InterruptTheCard(base);
-                       outw(0x0, base+0x4);    /* for ISI4608 cards */
-                                                       
-                       isi_card[card].status |= FIRMWARE_LOADED;
-                       return 0;       
-                       
-       default:
-#ifdef ISICOM_DEBUG    
-               printk(KERN_DEBUG "ISILoad: Received Ioctl cmd 0x%x.\n", cmd); 
-#endif
-               return -ENOIOCTLCMD;
-       
-       }
-       
-}
-                               
-
 /*
  *     ISICOM Driver specific routines ...
  *
  */
-static inline int isicom_paranoia_check(struct isi_port const * port, char *name, 
-                                       const char * routine)
+
+static inline int __isicom_paranoia_check(struct isi_port const *port,
+       char *name, const char *routine)
 {
-#ifdef ISICOM_DEBUG 
-       static const char * badmagic = 
-                       KERN_WARNING "ISICOM: Warning: bad isicom magic for dev %s in %s.\n";
-       static const char * badport = 
-                       KERN_WARNING "ISICOM: Warning: NULL isicom port for dev %s in %s.\n";           
        if (!port) {
-               printk(badport, name, routine);
+               printk(KERN_WARNING "ISICOM: Warning: bad isicom magic for "
+                       "dev %s in %s.\n", name, routine);
                return 1;
        }
        if (port->magic != ISICOM_MAGIC) {
-               printk(badmagic, name, routine);
+               printk(KERN_WARNING "ISICOM: Warning: NULL isicom port for "
+                       "dev %s in %s.\n", name, routine);
                return 1;
-       }       
-#endif 
+       }
+
        return 0;
 }
-                       
+
 /*
- *     Transmitter. 
+ *     Transmitter.
  *
  *     We shovel data into the card buffers on a regular basis. The card
  *     will do the rest of the work for us.
@@ -635,25 +417,21 @@ static void isicom_tx(unsigned long _data)
 {
        short count = (BOARD_COUNT-1), card, base;
        short txcount, wrd, residue, word_count, cnt;
-       struct isi_port * port;
-       struct tty_struct * tty;
-       
-#ifdef ISICOM_DEBUG
-       ++tx_count;
-#endif 
-       
+       struct isi_port *port;
+       struct tty_struct *tty;
+
        /*      find next active board  */
        card = (prev_card + 1) & 0x0003;
        while(count-- > 0) {
-               if (isi_card[card].status & BOARD_ACTIVE) 
+               if (isi_card[card].status & BOARD_ACTIVE)
                        break;
-               card = (card + 1) & 0x0003;     
+               card = (card + 1) & 0x0003;
        }
        if (!(isi_card[card].status & BOARD_ACTIVE))
                goto sched_again;
-               
+
        prev_card = card;
-       
+
        count = isi_card[card].port_count;
        port = isi_card[card].ports;
        base = isi_card[card].base;
@@ -662,18 +440,18 @@ static void isicom_tx(unsigned long _data)
                        continue;
                /* port not active or tx disabled to force flow control */
                if (!(port->flags & ASYNC_INITIALIZED) ||
-                       !(port->status & ISI_TXOK))
+                               !(port->status & ISI_TXOK))
                        unlock_card(&isi_card[card]);
                        continue;
-               
+
                tty = port->tty;
-               
-               
-               if(tty == NULL) {
+
+
+               if (tty == NULL) {
                        unlock_card(&isi_card[card]);
                        continue;
                }
-               
+
                txcount = min_t(short, TX_SIZE, port->xmit_cnt);
                if (txcount <= 0 || tty->stopped || tty->hw_stopped) {
                        unlock_card(&isi_card[card]);
@@ -681,44 +459,45 @@ static void isicom_tx(unsigned long _data)
                }
                if (!(inw(base + 0x02) & (1 << port->channel))) {
                        unlock_card(&isi_card[card]);
-                       continue;               
+                       continue;
                }
-#ifdef ISICOM_DEBUG
-               printk(KERN_DEBUG "ISICOM: txing %d bytes, port%d.\n", 
-                               txcount, port->channel+1); 
-#endif 
-               outw((port->channel << isi_card[card].shift_count) | txcount
-                                       , base);
+               pr_dbg("txing %d bytes, port%d.\n", txcount,
+                       port->channel + 1);
+               outw((port->channel << isi_card[card].shift_count) | txcount,
+                       base);
                residue = NO;
-               wrd = 0;                        
+               wrd = 0;
                while (1) {
-                       cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE - port->xmit_tail));
+                       cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
+                                       - port->xmit_tail));
                        if (residue == YES) {
                                residue = NO;
                                if (cnt > 0) {
-                                       wrd |= (port->xmit_buf[port->xmit_tail] << 8);
-                                       port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+                                       wrd |= (port->xmit_buf[port->xmit_tail]
+                                                                       << 8);
+                                       port->xmit_tail = (port->xmit_tail + 1)
+                                               & (SERIAL_XMIT_SIZE - 1);
                                        port->xmit_cnt--;
                                        txcount--;
                                        cnt--;
-                                       outw(wrd, base);                        
-                               }
-                               else {
+                                       outw(wrd, base);
+                               } else {
                                        outw(wrd, base);
                                        break;
                                }
-                       }               
+                       }
                        if (cnt <= 0) break;
                        word_count = cnt >> 1;
-                       outsw(base, port->xmit_buf+port->xmit_tail, word_count);
-                       port->xmit_tail = (port->xmit_tail + (word_count << 1)) &
-                                               (SERIAL_XMIT_SIZE - 1);
+                       outsw(base, port->xmit_buf+port->xmit_tail,word_count);
+                       port->xmit_tail = (port->xmit_tail
+                               + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
                        txcount -= (word_count << 1);
                        port->xmit_cnt -= (word_count << 1);
                        if (cnt & 0x0001) {
                                residue = YES;
                                wrd = port->xmit_buf[port->xmit_tail];
-                               port->xmit_tail = (port->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
+                               port->xmit_tail = (port->xmit_tail + 1)
+                                       & (SERIAL_XMIT_SIZE - 1);
                                port->xmit_cnt--;
                                txcount--;
                        }
@@ -730,81 +509,82 @@ static void isicom_tx(unsigned long _data)
                if (port->xmit_cnt <= WAKEUP_CHARS)
                        schedule_work(&port->bh_tqueue);
                unlock_card(&isi_card[card]);
-       }       
+       }
+
+       /*      schedule another tx for hopefully in about 10ms */
+sched_again:
+       if (!re_schedule) {
+               re_schedule = 2;
+               return;
+       }
 
-       /*      schedule another tx for hopefully in about 10ms */      
-sched_again:   
-       if (!re_schedule)       
-               return;
        init_timer(&tx);
        tx.expires = jiffies + HZ/100;
        tx.data = 0;
        tx.function = isicom_tx;
        add_timer(&tx);
-       
-       return; 
-}              
+
+       return;
+}
+
 /*     Interrupt handlers      */
 
-static void isicom_bottomhalf(void * data)
+
+static void isicom_bottomhalf(void *data)
 {
-       struct isi_port * port = (struct isi_port *) data;
-       struct tty_struct * tty = port->tty;
-       
+       struct isi_port *port = (struct isi_port *) data;
+       struct tty_struct *tty = port->tty;
+
        if (!tty)
                return;
 
-       tty_wakeup(tty);        
+       tty_wakeup(tty);
        wake_up_interruptible(&tty->write_wait);
-}              
-               
+}
+
 /*
- *     Main interrupt handler routine 
+ *     Main interrupt handler routine
  */
-static irqreturn_t isicom_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+
+static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-       struct isi_board * card;
-       struct isi_port * port;
-       struct tty_struct * tty;
-       unsigned short base, header, word_count, count;
-       unsigned char channel;
+       struct isi_board *card = dev_id;
+       struct isi_port *port;
+       struct tty_struct *tty;
+       unsigned long base;
+       u16 header, word_count, count, channel;
        short byte_count;
-       
-       card = (struct isi_board *) dev_id;
+       unsigned char *rp;
 
        if (!card || !(card->status & FIRMWARE_LOADED))
                return IRQ_NONE;
-       
+
        base = card->base;
        spin_lock(&card->card_lock);
-       
+
        if (card->isa == NO) {
                /*
-                *      disable any interrupts from the PCI card and lower the
-                *      interrupt line
+                * disable any interrupts from the PCI card and lower the
+                * interrupt line
                 */
                outw(0x8000, base+0x04);
                ClearInterrupt(base);
        }
-       
+
        inw(base);              /* get the dummy word out */
        header = inw(base);
        channel = (header & 0x7800) >> card->shift_count;
        byte_count = header & 0xff;
 
        if (channel + 1 > card->port_count) {
-               printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%x): %d(channel) > port_count.\n",
-                               base, channel+1);
+               printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
+                       "%d(channel) > port_count.\n", base, channel+1);
                if (card->isa)
                        ClearInterrupt(base);
                else
-                       outw(0x0000, base+0x04); /* enable interrupts */                
+                       outw(0x0000, base+0x04); /* enable interrupts */
                spin_unlock(&card->card_lock);
-               return IRQ_HANDLED;                     
+               return IRQ_HANDLED;
        }
        port = card->ports + channel;
        if (!(port->flags & ASYNC_INITIALIZED)) {
@@ -813,8 +593,8 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
                else
                        outw(0x0000, base+0x04); /* enable interrupts */
                return IRQ_HANDLED;
-       }       
-               
+       }
+
        tty = port->tty;
        if (tty == NULL) {
                word_count = byte_count >> 1;
@@ -831,224 +611,204 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id,
                spin_unlock(&card->card_lock);
                return IRQ_HANDLED;
        }
-       
+
        if (header & 0x8000) {          /* Status Packet */
                header = inw(base);
                switch(header & 0xff) {
-                       case 0: /* Change in EIA signals */
-                               
-                               if (port->flags & ASYNC_CHECK_CD) {
-                                       if (port->status & ISI_DCD) {
-                                               if (!(header & ISI_DCD)) {
-                                               /* Carrier has been lost  */
-#ifdef ISICOM_DEBUG                                            
-                                                       printk(KERN_DEBUG "ISICOM: interrupt: DCD->low.\n");
-#endif                                                 
-                                                       port->status &= ~ISI_DCD;
-                                                       schedule_work(&port->hangup_tq);
-                                               }
-                                       }
-                                       else {
-                                               if (header & ISI_DCD) {
-                                               /* Carrier has been detected */
-#ifdef ISICOM_DEBUG
-                                                       printk(KERN_DEBUG "ISICOM: interrupt: DCD->high.\n");
-#endif                                                 
-                                                       port->status |= ISI_DCD;
-                                                       wake_up_interruptible(&port->open_wait);
-                                               }
-                                       }
-                               }
-                               else {
-                                       if (header & ISI_DCD) 
-                                               port->status |= ISI_DCD;
-                                       else
+               case 0: /* Change in EIA signals */
+                       if (port->flags & ASYNC_CHECK_CD) {
+                               if (port->status & ISI_DCD) {
+                                       if (!(header & ISI_DCD)) {
+                                       /* Carrier has been lost  */
+                                               pr_dbg("interrupt: DCD->low.\n"
+                                                       );
                                                port->status &= ~ISI_DCD;
-                               }       
-                               
-                               if (port->flags & ASYNC_CTS_FLOW) {
-                                       if (port->tty->hw_stopped) {
-                                               if (header & ISI_CTS) {
-                                                       port->tty->hw_stopped = 0;
-                                                       /* start tx ing */
-                                                       port->status |= (ISI_TXOK | ISI_CTS);
-                                                       schedule_work(&port->bh_tqueue);
-                                               }
-                                       }
-                                       else {
-                                               if (!(header & ISI_CTS)) {
-                                                       port->tty->hw_stopped = 1;
-                                                       /* stop tx ing */
-                                                       port->status &= ~(ISI_TXOK | ISI_CTS);
-                                               }
+                                               schedule_work(&port->hangup_tq);
                                        }
+                               } else if (header & ISI_DCD) {
+                               /* Carrier has been detected */
+                                       pr_dbg("interrupt: DCD->high.\n");
+                                       port->status |= ISI_DCD;
+                                       wake_up_interruptible(&port->open_wait);
                                }
-                               else {
-                                       if (header & ISI_CTS) 
-                                               port->status |= ISI_CTS;
-                                       else
-                                               port->status &= ~ISI_CTS;
-                               }
-                               
-                               if (header & ISI_DSR) 
-                                       port->status |= ISI_DSR;
+                       } else {
+                               if (header & ISI_DCD)
+                                       port->status |= ISI_DCD;
                                else
-                                       port->status &= ~ISI_DSR;
-                               
-                               if (header & ISI_RI) 
-                                       port->status |= ISI_RI;
+                                       port->status &= ~ISI_DCD;
+                       }
+
+                       if (port->flags & ASYNC_CTS_FLOW) {
+                               if (port->tty->hw_stopped) {
+                                       if (header & ISI_CTS) {
+                                               port->tty->hw_stopped = 0;
+                                               /* start tx ing */
+                                               port->status |= (ISI_TXOK
+                                                       | ISI_CTS);
+                                               schedule_work(&port->bh_tqueue);
+                                       }
+                               } else if (!(header & ISI_CTS)) {
+                                       port->tty->hw_stopped = 1;
+                                       /* stop tx ing */
+                                       port->status &= ~(ISI_TXOK | ISI_CTS);
+                               }
+                       } else {
+                               if (header & ISI_CTS)
+                                       port->status |= ISI_CTS;
                                else
-                                       port->status &= ~ISI_RI;                                                
-                               
-                               break;
-                               
-                       case 1: /* Received Break !!!    */
-                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                                       break;
-                               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-                               *tty->flip.char_buf_ptr++ = 0;
-                               tty->flip.count++;
-                               if (port->flags & ASYNC_SAK)
-                                       do_SAK(tty);
-                               schedule_delayed_work(&tty->flip.work, 1);
-                               break;
-                               
-                       case 2: /* Statistics            */
-                               printk(KERN_DEBUG "ISICOM: isicom_interrupt: stats!!!.\n");                     
-                               break;
-                               
-                       default:
-                               printk(KERN_WARNING "ISICOM: Intr: Unknown code in status packet.\n");
-                               break;
-               }        
-       }
-       else {                          /* Data   Packet */
-               count = min_t(unsigned short, byte_count, (TTY_FLIPBUF_SIZE - tty->flip.count));
-#ifdef ISICOM_DEBUG
-               printk(KERN_DEBUG "ISICOM: Intr: Can rx %d of %d bytes.\n", 
-                                       count, byte_count);
-#endif                 
+                                       port->status &= ~ISI_CTS;
+                       }
+
+                       if (header & ISI_DSR)
+                               port->status |= ISI_DSR;
+                       else
+                               port->status &= ~ISI_DSR;
+
+                       if (header & ISI_RI)
+                               port->status |= ISI_RI;
+                       else
+                               port->status &= ~ISI_RI;
+
+                       break;
+
+               case 1: /* Received Break !!! */
+                       tty_insert_flip_char(tty, 0, TTY_BREAK);
+                       if (port->flags & ASYNC_SAK)
+                               do_SAK(tty);
+                       tty_flip_buffer_push(tty);
+                       break;
+
+               case 2: /* Statistics            */
+                       pr_dbg("isicom_interrupt: stats!!!.\n");
+                       break;
+
+               default:
+                       pr_dbg("Intr: Unknown code in status packet.\n");
+                       break;
+               }
+       } else {                                /* Data   Packet */
+
+               count = tty_prepare_flip_string(tty, &rp, byte_count & ~1);
+               pr_dbg("Intr: Can rx %d of %d bytes.\n", count, byte_count);
                word_count = count >> 1;
-               insw(base, tty->flip.char_buf_ptr, word_count);
-               tty->flip.char_buf_ptr += (word_count << 1);            
+               insw(base, rp, word_count);
                byte_count -= (word_count << 1);
                if (count & 0x0001) {
-                       *tty->flip.char_buf_ptr++ = (char)(inw(base) & 0xff);
+                       tty_insert_flip_char(tty,  inw(base) & 0xff,
+                               TTY_NORMAL);
                        byte_count -= 2;
-               }       
-               memset(tty->flip.flag_buf_ptr, 0, count);
-               tty->flip.flag_buf_ptr += count;
-               tty->flip.count += count;
-               
+               }
                if (byte_count > 0) {
-                       printk(KERN_DEBUG "ISICOM: Intr(0x%x:%d): Flip buffer overflow! dropping bytes...\n",
-                                       base, channel+1);
+                       pr_dbg("Intr(0x%lx:%d): Flip buffer overflow! dropping "
+                               "bytes...\n", base, channel + 1);
                        while(byte_count > 0) { /* drain out unread xtra data */
                                inw(base);
                                byte_count -= 2;
                        }
                }
-               schedule_delayed_work(&tty->flip.work, 1);
+               tty_flip_buffer_push(tty);
        }
        if (card->isa == YES)
                ClearInterrupt(base);
        else
-               outw(0x0000, base+0x04); /* enable interrupts */        
+               outw(0x0000, base+0x04); /* enable interrupts */
+
        return IRQ_HANDLED;
-} 
+}
 
-static void isicom_config_port(struct isi_port * port)
+static void isicom_config_port(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       struct tty_struct * tty;
+       struct isi_board *card = port->card;
+       struct tty_struct *tty;
        unsigned long baud;
-       unsigned short channel_setup, base = card->base;
-       unsigned short channel = port->channel, shift_count = card->shift_count;
+       unsigned long base = card->base;
+       u16 channel_setup, channel = port->channel,
+               shift_count = card->shift_count;
        unsigned char flow_ctrl;
-       
+
        if (!(tty = port->tty) || !tty->termios)
                return;
        baud = C_BAUD(tty);
        if (baud & CBAUDEX) {
                baud &= ~CBAUDEX;
-               
+
                /*  if CBAUDEX bit is on and the baud is set to either 50 or 75
                 *  then the card is programmed for 57.6Kbps or 115Kbps
                 *  respectively.
-                */   
-                
+                */
+
                if (baud < 1 || baud > 2)
                        port->tty->termios->c_cflag &= ~CBAUDEX;
                else
                        baud += 15;
-       }       
+       }
        if (baud == 15) {
-       
-               /*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set 
+
+               /*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
                 *  by the set_serial_info ioctl ... this is done by
                 *  the 'setserial' utility.
-                */  
-                       
+                */
+
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-                       baud++;     /*  57.6 Kbps */
+                       baud++; /*  57.6 Kbps */
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-                       baud +=2;   /*  115  Kbps */     
+                       baud +=2; /*  115  Kbps */
        }
        if (linuxb_to_isib[baud] == -1) {
                /* hang up */
-               drop_dtr(port);
-               return;
-       }       
-       else  
+               drop_dtr(port);
+               return;
+       }
+       else
                raise_dtr(port);
-               
+
        if (lock_card(card)) {
                outw(0x8000 | (channel << shift_count) |0x03, base);
                outw(linuxb_to_isib[baud] << 8 | 0x03, base);
                channel_setup = 0;
                switch(C_CSIZE(tty)) {
-                       case CS5:
-                               channel_setup |= ISICOM_CS5;
-                               break;
-                       case CS6:
-                               channel_setup |= ISICOM_CS6;
-                               break;
-                       case CS7:
-                               channel_setup |= ISICOM_CS7;
-                               break;
-                       case CS8:
-                               channel_setup |= ISICOM_CS8;
-                               break;
+               case CS5:
+                       channel_setup |= ISICOM_CS5;
+                       break;
+               case CS6:
+                       channel_setup |= ISICOM_CS6;
+                       break;
+               case CS7:
+                       channel_setup |= ISICOM_CS7;
+                       break;
+               case CS8:
+                       channel_setup |= ISICOM_CS8;
+                       break;
                }
-                       
+
                if (C_CSTOPB(tty))
                        channel_setup |= ISICOM_2SB;
                if (C_PARENB(tty)) {
                        channel_setup |= ISICOM_EVPAR;
                        if (C_PARODD(tty))
-                               channel_setup |= ISICOM_ODPAR;  
+                               channel_setup |= ISICOM_ODPAR;
                }
-               outw(channel_setup, base);      
+               outw(channel_setup, base);
                InterruptTheCard(base);
-               unlock_card(card);      
-       }       
+               unlock_card(card);
+       }
        if (C_CLOCAL(tty))
                port->flags &= ~ASYNC_CHECK_CD;
        else
-               port->flags |= ASYNC_CHECK_CD;  
-       
+               port->flags |= ASYNC_CHECK_CD;
+
        /* flow control settings ...*/
        flow_ctrl = 0;
        port->flags &= ~ASYNC_CTS_FLOW;
        if (C_CRTSCTS(tty)) {
                port->flags |= ASYNC_CTS_FLOW;
                flow_ctrl |= ISICOM_CTSRTS;
-       }       
-       if (I_IXON(tty))        
+       }
+       if (I_IXON(tty))
                flow_ctrl |= ISICOM_RESPOND_XONXOFF;
        if (I_IXOFF(tty))
-               flow_ctrl |= ISICOM_INITIATE_XONXOFF;   
-               
+               flow_ctrl |= ISICOM_INITIATE_XONXOFF;
+
        if (lock_card(card)) {
                outw(0x8000 | (channel << shift_count) |0x04, base);
                outw(flow_ctrl << 8 | 0x05, base);
@@ -1056,22 +816,22 @@ static void isicom_config_port(struct isi_port * port)
                InterruptTheCard(base);
                unlock_card(card);
        }
-       
+
        /*      rx enabled -> enable port for rx on the card    */
        if (C_CREAD(tty)) {
                card->port_status |= (1 << channel);
                outw(card->port_status, base + 0x02);
        }
 }
-/* open et all */ 
 
-static inline void isicom_setup_board(struct isi_board * bp)
+/* open et all */
+
+static inline void isicom_setup_board(struct isi_board *bp)
 {
        int channel;
-       struct isi_port * port;
+       struct isi_port *port;
        unsigned long flags;
-       
+
        spin_lock_irqsave(&bp->card_lock, flags);
        if (bp->status & BOARD_ACTIVE) {
                spin_unlock_irqrestore(&bp->card_lock, flags);
@@ -1080,53 +840,54 @@ static inline void isicom_setup_board(struct isi_board * bp)
        port = bp->ports;
        bp->status |= BOARD_ACTIVE;
        spin_unlock_irqrestore(&bp->card_lock, flags);
-       for(channel = 0; channel < bp->port_count; channel++, port++)
+       for (channel = 0; channel < bp->port_count; channel++, port++)
                drop_dtr_rts(port);
        return;
 }
-static int isicom_setup_port(struct isi_port * port)
+
+static int isicom_setup_port(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
+       struct isi_board *card = port->card;
        unsigned long flags;
-       
+
        if (port->flags & ASYNC_INITIALIZED) {
                return 0;
        }
        if (!port->xmit_buf) {
                unsigned long page;
-               
+
                if (!(page = get_zeroed_page(GFP_KERNEL)))
                        return -ENOMEM;
-               
+
                if (port->xmit_buf) {
                        free_page(page);
                        return -ERESTARTSYS;
                }
-               port->xmit_buf = (unsigned char *) page;        
-       }       
+               port->xmit_buf = (unsigned char *) page;
+       }
 
        spin_lock_irqsave(&card->card_lock, flags);
        if (port->tty)
                clear_bit(TTY_IO_ERROR, &port->tty->flags);
        if (port->count == 1)
                card->count++;
-               
+
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-       
+
        /*      discard any residual data       */
        kill_queue(port, ISICOM_KILLTX | ISICOM_KILLRX);
-       
+
        isicom_config_port(port);
        port->flags |= ASYNC_INITIALIZED;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
-       return 0;               
-} 
-static int block_til_ready(struct tty_struct * tty, struct file * filp, struct isi_port * port) 
+
+       return 0;
+}
+
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+       struct isi_port *port)
 {
-       struct isi_board * card = port->card;
+       struct isi_board *card = port->card;
        int do_clocal = 0, retval;
        unsigned long flags;
        DECLARE_WAITQUEUE(wait, current);
@@ -1134,30 +895,27 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i
        /* block if port is in the process of being closed */
 
        if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
-#ifdef ISICOM_DEBUG    
-               printk(KERN_DEBUG "ISICOM: block_til_ready: close in progress.\n");
-#endif         
+               pr_dbg("block_til_ready: close in progress.\n");
                interruptible_sleep_on(&port->close_wait);
                if (port->flags & ASYNC_HUP_NOTIFY)
                        return -EAGAIN;
                else
                        return -ERESTARTSYS;
        }
-       
+
        /* if non-blocking mode is set ... */
-       
-       if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
-#ifdef ISICOM_DEBUG    
-               printk(KERN_DEBUG "ISICOM: block_til_ready: non-block mode.\n");
-#endif         
+
+       if ((filp->f_flags & O_NONBLOCK) ||
+                       (tty->flags & (1 << TTY_IO_ERROR))) {
+               pr_dbg("block_til_ready: non-block mode.\n");
                port->flags |= ASYNC_NORMAL_ACTIVE;
-               return 0;       
-       }       
-       
+               return 0;
+       }
+
        if (C_CLOCAL(tty))
                do_clocal = 1;
-       
-       /* block waiting for DCD to be asserted, and while 
+
+       /* block waiting for DCD to be asserted, and while
                                                callout dev is busy */
        retval = 0;
        add_wait_queue(&port->open_wait, &wait);
@@ -1167,27 +925,27 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i
                port->count--;
        port->blocked_open++;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
+
        while (1) {
                raise_dtr_rts(port);
 
                set_current_state(TASK_INTERRUPTIBLE);
-               if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {        
+               if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
                        if (port->flags & ASYNC_HUP_NOTIFY)
                                retval = -EAGAIN;
                        else
                                retval = -ERESTARTSYS;
                        break;
-               }       
+               }
                if (!(port->flags & ASYNC_CLOSING) &&
-                   (do_clocal || (port->status & ISI_DCD))) {
+                               (do_clocal || (port->status & ISI_DCD))) {
                        break;
-               }       
+               }
                if (signal_pending(current)) {
                        retval = -ERESTARTSYS;
                        break;
                }
-               schedule();             
+               schedule();
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&port->open_wait, &wait);
@@ -1201,11 +959,11 @@ static int block_til_ready(struct tty_struct * tty, struct file * filp, struct i
        port->flags |= ASYNC_NORMAL_ACTIVE;
        return 0;
 }
-static int isicom_open(struct tty_struct * tty, struct file * filp)
+
+static int isicom_open(struct tty_struct *tty, struct file *filp)
 {
-       struct isi_port * port;
-       struct isi_board * card;
+       struct isi_port *port;
+       struct isi_board *card;
        unsigned int line, board;
        int error;
 
@@ -1214,20 +972,20 @@ static int isicom_open(struct tty_struct * tty, struct file * filp)
                return -ENODEV;
        board = BOARD(line);
        card = &isi_card[board];
-       
+
        if (!(card->status & FIRMWARE_LOADED))
                return -ENODEV;
-       
+
        /*  open on a port greater than the port count for the card !!! */
        if (line > ((board * 16) + card->port_count - 1))
                return -ENODEV;
 
-       port = &isi_ports[line];        
+       port = &isi_ports[line];
        if (isicom_paranoia_check(port, tty->name, "isicom_open"))
                return -ENODEV;
-               
-       isicom_setup_board(card);               
-       
+
+       isicom_setup_board(card);
+
        port->count++;
        tty->driver_data = port;
        port->tty = tty;
@@ -1236,12 +994,12 @@ static int isicom_open(struct tty_struct * tty, struct file * filp)
        if ((error = block_til_ready(tty, filp, port))!=0)
                return error;
 
-       return 0;               
+       return 0;
 }
+
 /* close et all */
 
-static inline void isicom_shutdown_board(struct isi_board * bp)
+static inline void isicom_shutdown_board(struct isi_board *bp)
 {
        unsigned long flags;
 
@@ -1252,15 +1010,15 @@ static inline void isicom_shutdown_board(struct isi_board * bp)
        spin_unlock_irqrestore(&bp->card_lock, flags);
 }
 
-static void isicom_shutdown_port(struct isi_port * port)
+static void isicom_shutdown_port(struct isi_port *port)
 {
-       struct isi_board * card = port->card;
-       struct tty_struct * tty;        
+       struct isi_board *card = port->card;
+       struct tty_struct *tty;
        unsigned long flags;
-       
+
        tty = port->tty;
 
-       spin_lock_irqsave(&card->card_lock, flags);     
+       spin_lock_irqsave(&card->card_lock, flags);
        if (!(port->flags & ASYNC_INITIALIZED)) {
                spin_unlock_irqrestore(&card->card_lock, flags);
                return;
@@ -1268,93 +1026,91 @@ static void isicom_shutdown_port(struct isi_port * port)
        if (port->xmit_buf) {
                free_page((unsigned long) port->xmit_buf);
                port->xmit_buf = NULL;
-       }       
+       }
        port->flags &= ~ASYNC_INITIALIZED;
        /* 3rd October 2000 : Vinayak P Risbud */
        port->tty = NULL;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
+
        /*Fix done by Anil .S on 30-04-2001
        remote login through isi port has dtr toggle problem
        due to which the carrier drops before the password prompt
-       appears on the remote end. Now we drop the dtr only if the 
+       appears on the remote end. Now we drop the dtr only if the
        HUPCL(Hangup on close) flag is set for the tty*/
-       
-       if (C_HUPCL(tty)) 
+
+       if (C_HUPCL(tty))
                /* drop dtr on this port */
                drop_dtr(port);
-               
-       /* any other port uninits  */ 
+
+       /* any other port uninits  */
        if (tty)
                set_bit(TTY_IO_ERROR, &tty->flags);
-       
+
        if (--card->count < 0) {
-               printk(KERN_DEBUG "ISICOM: isicom_shutdown_port: bad board(0x%x) count %d.\n",
+               pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n",
                        card->base, card->count);
-               card->count = 0;        
+               card->count = 0;
        }
-       
-       /* last port was closed , shutdown that boad too */
-       if(C_HUPCL(tty)) {
+
+       /* last port was closed, shutdown that boad too */
+       if (C_HUPCL(tty)) {
                if (!card->count)
                        isicom_shutdown_board(card);
        }
 }
 
-static void isicom_close(struct tty_struct * tty, struct file * filp)
+static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
        unsigned long flags;
-       
+
        if (!port)
                return;
        if (isicom_paranoia_check(port, tty->name, "isicom_close"))
                return;
-       
-#ifdef ISICOM_DEBUG            
-       printk(KERN_DEBUG "ISICOM: Close start!!!.\n");
-#endif 
-       
+
+       pr_dbg("Close start!!!.\n");
+
        spin_lock_irqsave(&card->card_lock, flags);
        if (tty_hung_up_p(filp)) {
                spin_unlock_irqrestore(&card->card_lock, flags);
                return;
        }
-       
+
        if (tty->count == 1 && port->count != 1) {
-               printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count"
-                       "tty->count = 1 port count = %d.\n",
+               printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
+                       "count tty->count = 1 port count = %d.\n",
                        card->base, port->count);
                port->count = 1;
        }
        if (--port->count < 0) {
-               printk(KERN_WARNING "ISICOM:(0x%x) isicom_close: bad port count for"
-                       "channel%d = %d", card->base, port->channel, 
+               printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
+                       "count for channel%d = %d", card->base, port->channel,
                        port->count);
-               port->count = 0;        
+               port->count = 0;
        }
-       
+
        if (port->count) {
                spin_unlock_irqrestore(&card->card_lock, flags);
                return;
-       }       
+       }
        port->flags |= ASYNC_CLOSING;
        tty->closing = 1;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
+
        if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
                tty_wait_until_sent(tty, port->closing_wait);
-       /* indicate to the card that no more data can be received 
+       /* indicate to the card that no more data can be received
           on this port */
        spin_lock_irqsave(&card->card_lock, flags);
-       if (port->flags & ASYNC_INITIALIZED) {   
+       if (port->flags & ASYNC_INITIALIZED) {
                card->port_status &= ~(1 << port->channel);
                outw(card->port_status, card->base + 0x02);
-       }       
+       }
        isicom_shutdown_port(port);
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
+
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
        tty_ldisc_flush(tty);
@@ -1365,65 +1121,65 @@ static void isicom_close(struct tty_struct * tty, struct file * filp)
        if (port->blocked_open) {
                spin_unlock_irqrestore(&card->card_lock, flags);
                if (port->close_delay) {
-#ifdef ISICOM_DEBUG                    
-                       printk(KERN_DEBUG "ISICOM: scheduling until time out.\n");
-#endif                 
-                       msleep_interruptible(jiffies_to_msecs(port->close_delay));
+                       pr_dbg("scheduling until time out.\n");
+                       msleep_interruptible(
+                               jiffies_to_msecs(port->close_delay));
                }
                spin_lock_irqsave(&card->card_lock, flags);
                wake_up_interruptible(&port->open_wait);
-       }       
+       }
        port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
        wake_up_interruptible(&port->close_wait);
        spin_unlock_irqrestore(&card->card_lock, flags);
 }
 
 /* write et all */
-static int isicom_write(struct tty_struct * tty,
-                       const unsigned char * buf, int count)
+static int isicom_write(struct tty_struct *tty,        const unsigned char *buf,
+       int count)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
        unsigned long flags;
        int cnt, total = 0;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_write"))
                return 0;
-       
-       if (!tty || !port->xmit_buf || !tmp_buf)
+
+       if (!tty || !port->xmit_buf)
                return 0;
-               
+
        spin_lock_irqsave(&card->card_lock, flags);
-       
-       while(1) {      
-               cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-                                           SERIAL_XMIT_SIZE - port->xmit_head));
-               if (cnt <= 0) 
+
+       while(1) {
+               cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
+                               - 1, SERIAL_XMIT_SIZE - port->xmit_head));
+               if (cnt <= 0)
                        break;
-               
+
                memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
-               port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE - 1);
+               port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
+                       - 1);
                port->xmit_cnt += cnt;
                buf += cnt;
                count -= cnt;
                total += cnt;
-       }               
+       }
        if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
                port->status |= ISI_TXOK;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       return total;   
+       return total;
 }
 
 /* put_char et all */
-static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
+static void isicom_put_char(struct tty_struct *tty, unsigned char ch)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
        unsigned long flags;
-       
+
        if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
                return;
-       
+
        if (!tty || !port->xmit_buf)
                return;
 
@@ -1432,7 +1188,7 @@ static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
                spin_unlock_irqrestore(&card->card_lock, flags);
                return;
        }
-       
+
        port->xmit_buf[port->xmit_head++] = ch;
        port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
        port->xmit_cnt++;
@@ -1440,30 +1196,31 @@ static void isicom_put_char(struct tty_struct * tty, unsigned char ch)
 }
 
 /* flush_chars et all */
-static void isicom_flush_chars(struct tty_struct * tty)
+static void isicom_flush_chars(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       
+       struct isi_port *port = tty->driver_data;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
                return;
-       
-       if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !port->xmit_buf)
+
+       if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
+                       !port->xmit_buf)
                return;
-               
+
        /* this tells the transmitter to consider this port for
           data output to the card ... that's the best we can do. */
-       port->status |= ISI_TXOK;       
+       port->status |= ISI_TXOK;
 }
 
 /* write_room et all */
-static int isicom_write_room(struct tty_struct * tty)
+static int isicom_write_room(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
+       struct isi_port *port = tty->driver_data;
        int free;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
                return 0;
-       
+
        free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
        if (free < 0)
                free = 0;
@@ -1471,23 +1228,24 @@ static int isicom_write_room(struct tty_struct * tty)
 }
 
 /* chars_in_buffer et all */
-static int isicom_chars_in_buffer(struct tty_struct * tty)
+static int isicom_chars_in_buffer(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
+       struct isi_port *port = tty->driver_data;
        if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
                return 0;
        return port->xmit_cnt;
 }
 
 /* ioctl et all */
-static inline void isicom_send_break(struct isi_port * port, unsigned long length)
+static inline void isicom_send_break(struct isi_port *port,
+       unsigned long length)
 {
-       struct isi_board * card = port->card;
-       unsigned short base = card->base;       
-       
-       if(!lock_card(card))
+       struct isi_board *card = port->card;
+       unsigned long base = card->base;
+
+       if (!lock_card(card))
                return;
-               
+
        outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
        outw((length & 0xff) << 8 | 0x00, base);
        outw((length & 0xff00), base);
@@ -1498,13 +1256,13 @@ static inline void isicom_send_break(struct isi_port * port, unsigned long lengt
 
 static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
+       struct isi_port *port = tty->driver_data;
        /* just send the port status */
-       unsigned short status = port->status;
+       u16 status = port->status;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
                return -ENODEV;
-       
+
        return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
                ((status & ISI_DTR) ? TIOCM_DTR : 0) |
                ((status & ISI_DCD) ? TIOCM_CAR : 0) |
@@ -1514,13 +1272,13 @@ static int isicom_tiocmget(struct tty_struct *tty, struct file *file)
 }
 
 static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
-                          unsigned int set, unsigned int clear)
+       unsigned int set, unsigned int clear)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       
+       struct isi_port *port = tty->driver_data;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
                return -ENODEV;
-       
+
        if (set & TIOCM_RTS)
                raise_rts(port);
        if (set & TIOCM_DTR)
@@ -1532,46 +1290,46 @@ static int isicom_tiocmset(struct tty_struct *tty, struct file *file,
                drop_dtr(port);
 
        return 0;
-}                      
+}
 
-static int isicom_set_serial_info(struct isi_port * port,
-                                       struct serial_struct __user *info)
+static int isicom_set_serial_info(struct isi_port *port,
+       struct serial_struct __user *info)
 {
        struct serial_struct newinfo;
        int reconfig_port;
 
-       if(copy_from_user(&newinfo, info, sizeof(newinfo)))
+       if (copy_from_user(&newinfo, info, sizeof(newinfo)))
                return -EFAULT;
-               
-       reconfig_port = ((port->flags & ASYNC_SPD_MASK) != 
-                        (newinfo.flags & ASYNC_SPD_MASK));
-       
+
+       reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
+               (newinfo.flags & ASYNC_SPD_MASK));
+
        if (!capable(CAP_SYS_ADMIN)) {
                if ((newinfo.close_delay != port->close_delay) ||
-                   (newinfo.closing_wait != port->closing_wait) ||
-                   ((newinfo.flags & ~ASYNC_USR_MASK) != 
-                    (port->flags & ~ASYNC_USR_MASK)))
+                               (newinfo.closing_wait != port->closing_wait) ||
+                               ((newinfo.flags & ~ASYNC_USR_MASK) !=
+                               (port->flags & ~ASYNC_USR_MASK)))
                        return -EPERM;
                port->flags = ((port->flags & ~ ASYNC_USR_MASK) |
                                (newinfo.flags & ASYNC_USR_MASK));
-       }       
+       }
        else {
                port->close_delay = newinfo.close_delay;
-               port->closing_wait = newinfo.closing_wait; 
-               port->flags = ((port->flags & ~ASYNC_FLAGS) | 
+               port->closing_wait = newinfo.closing_wait;
+               port->flags = ((port->flags & ~ASYNC_FLAGS) |
                                (newinfo.flags & ASYNC_FLAGS));
        }
        if (reconfig_port) {
                isicom_config_port(port);
        }
-       return 0;                
-}              
+       return 0;
+}
 
-static int isicom_get_serial_info(struct isi_port * port, 
-                                       struct serial_struct __user *info)
+static int isicom_get_serial_info(struct isi_port *port,
+       struct serial_struct __user *info)
 {
        struct serial_struct out_info;
-       
+
        memset(&out_info, 0, sizeof(out_info));
 /*     out_info.type = ? */
        out_info.line = port - isi_ports;
@@ -1581,15 +1339,15 @@ static int isicom_get_serial_info(struct isi_port * port,
 /*     out_info.baud_base = ? */
        out_info.close_delay = port->close_delay;
        out_info.closing_wait = port->closing_wait;
-       if(copy_to_user(info, &out_info, sizeof(out_info)))
+       if (copy_to_user(info, &out_info, sizeof(out_info)))
                return -EFAULT;
        return 0;
-}                                      
+}
 
-static int isicom_ioctl(struct tty_struct * tty, struct file * filp,
-                       unsigned int cmd, unsigned long arg) 
+static int isicom_ioctl(struct tty_struct *tty, struct file *filp,
+       unsigned int cmd, unsigned long arg)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
+       struct isi_port *port = tty->driver_data;
        void __user *argp = (void __user *)arg;
        int retval;
 
@@ -1597,139 +1355,141 @@ static int isicom_ioctl(struct tty_struct * tty, struct file * filp,
                return -ENODEV;
 
        switch(cmd) {
-               case TCSBRK:
-                       retval = tty_check_change(tty);
-                       if (retval)
-                               return retval;
-                       tty_wait_until_sent(tty, 0);
-                       if (!arg)
-                               isicom_send_break(port, HZ/4);
-                       return 0;
-                       
-               case TCSBRKP:   
-                       retval = tty_check_change(tty);
-                       if (retval)
-                               return retval;
-                       tty_wait_until_sent(tty, 0);
-                       isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
-                       return 0;
-                       
-               case TIOCGSOFTCAR:
-                       return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
-                       
-               case TIOCSSOFTCAR:
-                       if(get_user(arg, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       tty->termios->c_cflag =
-                               ((tty->termios->c_cflag & ~CLOCAL) |
-                               (arg ? CLOCAL : 0));
-                       return 0;       
-                       
-               case TIOCGSERIAL:
-                       return isicom_get_serial_info(port, argp);
-               
-               case TIOCSSERIAL:
-                       return isicom_set_serial_info(port, argp);
-                                       
-               default:
-                       return -ENOIOCTLCMD;                                            
+       case TCSBRK:
+               retval = tty_check_change(tty);
+               if (retval)
+                       return retval;
+               tty_wait_until_sent(tty, 0);
+               if (!arg)
+                       isicom_send_break(port, HZ/4);
+               return 0;
+
+       case TCSBRKP:
+               retval = tty_check_change(tty);
+               if (retval)
+                       return retval;
+               tty_wait_until_sent(tty, 0);
+               isicom_send_break(port, arg ? arg * (HZ/10) : HZ/4);
+               return 0;
+
+       case TIOCGSOFTCAR:
+               return put_user(C_CLOCAL(tty) ? 1 : 0,
+                               (unsigned long __user *)argp);
+
+       case TIOCSSOFTCAR:
+               if (get_user(arg, (unsigned long __user *) argp))
+                       return -EFAULT;
+               tty->termios->c_cflag =
+                       ((tty->termios->c_cflag & ~CLOCAL) |
+                       (arg ? CLOCAL : 0));
+               return 0;
+
+       case TIOCGSERIAL:
+               return isicom_get_serial_info(port, argp);
+
+       case TIOCSSERIAL:
+               return isicom_set_serial_info(port, argp);
+
+       default:
+               return -ENOIOCTLCMD;
        }
        return 0;
 }
 
 /* set_termios et all */
-static void isicom_set_termios(struct tty_struct * tty, struct termios * old_termios)
+static void isicom_set_termios(struct tty_struct *tty,
+       struct termios *old_termios)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       
+       struct isi_port *port = tty->driver_data;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
                return;
-       
+
        if (tty->termios->c_cflag == old_termios->c_cflag &&
-           tty->termios->c_iflag == old_termios->c_iflag)
+                       tty->termios->c_iflag == old_termios->c_iflag)
                return;
-               
+
        isicom_config_port(port);
-       
+
        if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS)) {       
+                       !(tty->termios->c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
-               isicom_start(tty);   
-       }    
+               isicom_start(tty);
+       }
 }
 
 /* throttle et all */
-static void isicom_throttle(struct tty_struct * tty)
+static void isicom_throttle(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
-       
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
                return;
-       
+
        /* tell the card that this port cannot handle any more data for now */
        card->port_status &= ~(1 << port->channel);
        outw(card->port_status, card->base + 0x02);
 }
 
 /* unthrottle et all */
-static void isicom_unthrottle(struct tty_struct * tty)
+static void isicom_unthrottle(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
-       
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
                return;
-       
+
        /* tell the card that this port is ready to accept more data */
        card->port_status |= (1 << port->channel);
        outw(card->port_status, card->base + 0x02);
 }
 
 /* stop et all */
-static void isicom_stop(struct tty_struct * tty)
+static void isicom_stop(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
+       struct isi_port *port = tty->driver_data;
 
        if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
                return;
-       
+
        /* this tells the transmitter not to consider this port for
           data output to the card. */
        port->status &= ~ISI_TXOK;
 }
 
 /* start et all */
-static void isicom_start(struct tty_struct * tty)
+static void isicom_start(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       
+       struct isi_port *port = tty->driver_data;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_start"))
                return;
-       
+
        /* this tells the transmitter to consider this port for
           data output to the card. */
        port->status |= ISI_TXOK;
 }
 
 /* hangup et all */
-static void do_isicom_hangup(void * data)
+static void do_isicom_hangup(void *data)
 {
-       struct isi_port * port = (struct isi_port *) data;
-       struct tty_struct * tty;
-       
+       struct isi_port *port = data;
+       struct tty_struct *tty;
+
        tty = port->tty;
        if (tty)
                tty_hangup(tty);
 }
 
-static void isicom_hangup(struct tty_struct * tty)
+static void isicom_hangup(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       
+       struct isi_port *port = tty->driver_data;
+
        if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
                return;
-       
+
        isicom_shutdown_port(port);
        port->count = 0;
        port->flags &= ~ASYNC_NORMAL_ACTIVE;
@@ -1738,342 +1498,540 @@ static void isicom_hangup(struct tty_struct * tty)
 }
 
 /* flush_buffer et all */
-static void isicom_flush_buffer(struct tty_struct * tty)
+static void isicom_flush_buffer(struct tty_struct *tty)
 {
-       struct isi_port * port = (struct isi_port *) tty->driver_data;
-       struct isi_board * card = port->card;
+       struct isi_port *port = tty->driver_data;
+       struct isi_board *card = port->card;
        unsigned long flags;
-       
+
        if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
                return;
-       
+
        spin_lock_irqsave(&card->card_lock, flags);
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
        spin_unlock_irqrestore(&card->card_lock, flags);
-       
+
        wake_up_interruptible(&tty->write_wait);
        tty_wakeup(tty);
 }
 
+/*
+ * Driver init and deinit functions
+ */
 
-static int __devinit register_ioregion(void)
+static int __devinit isicom_register_ioregion(struct pci_dev *pdev,
+       const unsigned int index)
 {
-       int count, done=0;
-       for (count=0; count < BOARD_COUNT; count++ ) {
-               if (isi_card[count].base)
-                       if (!request_region(isi_card[count].base,16,ISICOM_NAME)) {
-                               printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x is busy. Card%d will be disabled.\n",
-                                       isi_card[count].base,isi_card[count].base+15,count+1);
-                               isi_card[count].base=0;
-                               done++;
-                       }
-       }
-       return done;
+       struct isi_board *board = pci_get_drvdata(pdev);
+
+       if (!board->base)
+               return -EINVAL;
+
+       if (!request_region(board->base, 16, ISICOM_NAME)) {
+               dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
+                       "will be disabled.\n", board->base, board->base + 15,
+                       index + 1);
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
-static void unregister_ioregion(void)
+static void isicom_unregister_ioregion(struct pci_dev *pdev)
 {
-       int count;
-       for (count=0; count < BOARD_COUNT; count++ ) 
-               if (isi_card[count].base) {
-                       release_region(isi_card[count].base,16);
-#ifdef ISICOM_DEBUG                    
-                       printk(KERN_DEBUG "ISICOM: I/O Region 0x%x-0x%x released for Card%d.\n",isi_card[count].base,isi_card[count].base+15,count+1);
-#endif                 
-               }
+       struct isi_board *board = pci_get_drvdata(pdev);
+
+       if (!board->base)
+               return;
+
+       release_region(board->base, 16);
+       dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n",
+               board->base, board->base + 15);
+       board->base = 0;
 }
 
 static struct tty_operations isicom_ops = {
-       .open   = isicom_open,
-       .close  = isicom_close,
-       .write  = isicom_write,
-       .put_char       = isicom_put_char,
-       .flush_chars    = isicom_flush_chars,
-       .write_room     = isicom_write_room,
+       .open                   = isicom_open,
+       .close                  = isicom_close,
+       .write                  = isicom_write,
+       .put_char               = isicom_put_char,
+       .flush_chars            = isicom_flush_chars,
+       .write_room             = isicom_write_room,
        .chars_in_buffer        = isicom_chars_in_buffer,
-       .ioctl  = isicom_ioctl,
-       .set_termios    = isicom_set_termios,
-       .throttle       = isicom_throttle,
-       .unthrottle     = isicom_unthrottle,
-       .stop   = isicom_stop,
-       .start  = isicom_start,
-       .hangup = isicom_hangup,
-       .flush_buffer   = isicom_flush_buffer,
-       .tiocmget       = isicom_tiocmget,
-       .tiocmset       = isicom_tiocmset,
+       .ioctl                  = isicom_ioctl,
+       .set_termios            = isicom_set_termios,
+       .throttle               = isicom_throttle,
+       .unthrottle             = isicom_unthrottle,
+       .stop                   = isicom_stop,
+       .start                  = isicom_start,
+       .hangup                 = isicom_hangup,
+       .flush_buffer           = isicom_flush_buffer,
+       .tiocmget               = isicom_tiocmget,
+       .tiocmset               = isicom_tiocmset,
 };
 
-static int __devinit register_drivers(void)
+static int __devinit isicom_register_tty_driver(void)
 {
-       int error;
+       int error = -ENOMEM;
 
        /* tty driver structure initialization */
        isicom_normal = alloc_tty_driver(PORT_COUNT);
        if (!isicom_normal)
-               return -ENOMEM;
-
-       isicom_normal->owner    = THIS_MODULE;
-       isicom_normal->name     = "ttyM";
-       isicom_normal->devfs_name = "isicom/";
-       isicom_normal->major    = ISICOM_NMAJOR;
-       isicom_normal->minor_start      = 0;
-       isicom_normal->type     = TTY_DRIVER_TYPE_SERIAL;
-       isicom_normal->subtype  = SERIAL_TYPE_NORMAL;
-       isicom_normal->init_termios     = tty_std_termios;
-       isicom_normal->init_termios.c_cflag     = 
-                               B9600 | CS8 | CREAD | HUPCL |CLOCAL;
-       isicom_normal->flags    = TTY_DRIVER_REAL_RAW;
+               goto end;
+
+       isicom_normal->owner                    = THIS_MODULE;
+       isicom_normal->name                     = "ttyM";
+       isicom_normal->devfs_name               = "isicom/";
+       isicom_normal->major                    = ISICOM_NMAJOR;
+       isicom_normal->minor_start              = 0;
+       isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
+       isicom_normal->subtype                  = SERIAL_TYPE_NORMAL;
+       isicom_normal->init_termios             = tty_std_termios;
+       isicom_normal->init_termios.c_cflag     = B9600 | CS8 | CREAD | HUPCL |
+               CLOCAL;
+       isicom_normal->flags                    = TTY_DRIVER_REAL_RAW;
        tty_set_operations(isicom_normal, &isicom_ops);
-       
-       if ((error=tty_register_driver(isicom_normal))!=0) {
-               printk(KERN_DEBUG "ISICOM: Couldn't register the dialin driver, error=%d\n",
+
+       if ((error = tty_register_driver(isicom_normal))) {
+               pr_dbg("Couldn't register the dialin driver, error=%d\n",
                        error);
                put_tty_driver(isicom_normal);
-               return error;
        }
-       return 0;
+end:
+       return error;
 }
 
-static void unregister_drivers(void)
+static void isicom_unregister_tty_driver(void)
 {
-       int error = tty_unregister_driver(isicom_normal);
-       if (error)
-               printk(KERN_DEBUG "ISICOM: couldn't unregister normal driver error=%d.\n",error);
+       int error;
+
+       if ((error = tty_unregister_driver(isicom_normal)))
+               pr_dbg("couldn't unregister normal driver, error=%d.\n", error);
+
        put_tty_driver(isicom_normal);
 }
 
-static int __devinit register_isr(void)
+static int __devinit isicom_register_isr(struct pci_dev *pdev,
+       const unsigned int index)
 {
-       int count, done=0;
-       unsigned long irqflags;
-
-       for (count=0; count < BOARD_COUNT; count++ ) {
-               if (isi_card[count].base) {
-                       irqflags = (isi_card[count].isa == YES) ? 
-                                       SA_INTERRUPT : 
-                                       (SA_INTERRUPT | SA_SHIRQ);
-
-                       if (request_irq(isi_card[count].irq, 
-                                       isicom_interrupt, 
-                                       irqflags, 
-                                       ISICOM_NAME, &isi_card[count])) {
-
-                               printk(KERN_WARNING "ISICOM: Could not"
-                                       " install handler at Irq %d."
-                                       " Card%d will be disabled.\n",
-                                       isi_card[count].irq, count+1);
-
-                               release_region(isi_card[count].base,16);
-                               isi_card[count].base=0;
-                       }
-                       else
-                               done++;
-               }       
-       }
-       return done;
+       struct isi_board *board = pci_get_drvdata(pdev);
+       unsigned long irqflags = SA_INTERRUPT;
+       int retval = -EINVAL;
+
+       if (!board->base)
+               goto end;
+
+       if (board->isa == NO)
+               irqflags |= SA_SHIRQ;
+
+       retval = request_irq(board->irq, isicom_interrupt, irqflags,
+               ISICOM_NAME, board);
+       if (retval < 0)
+               dev_warn(&pdev->dev, "Could not install handler at Irq %d. "
+                       "Card%d will be disabled.\n", board->irq, index + 1);
+       else
+               retval = 0;
+end:
+       return retval;
 }
 
-static void __exit unregister_isr(void)
+static int __devinit reset_card(struct pci_dev *pdev,
+       const unsigned int card, unsigned int *signature)
 {
-       int count;
+       struct isi_board *board = pci_get_drvdata(pdev);
+       unsigned long base = board->base;
+       unsigned int portcount = 0;
+       int retval = 0;
+
+       dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
+               base);
 
-       for (count=0; count < BOARD_COUNT; count++ ) {
-               if (isi_card[count].base)
-                       free_irq(isi_card[count].irq, &isi_card[count]);
+       inw(base + 0x8);
+
+       mdelay(10);
+
+       outw(0, base + 0x8); /* Reset */
+
+       msleep(3000);
+
+       *signature = inw(base + 0x4) & 0xff;
+
+       if (board->isa == YES) {
+               if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) {
+                       dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
+                               inw(base + 0x2), inw(base + 0xe));
+                       dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure "
+                               "(Possible bad I/O Port Address 0x%lx).\n",
+                               card + 1, base);
+                       retval = -EIO;
+                       goto end;
+               }
+       } else {
+               portcount = inw(base + 0x2);
+               if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
+                               (portcount != 4) && (portcount != 8))) {
+                       dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
+                               inw(base + 0x2), inw(base + 0xe));
+                       dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
+                               "(Possible bad I/O Port Address 0x%lx).\n",
+                               card + 1, base);
+                       retval = -EIO;
+                       goto end;
+               }
        }
+
+       switch (*signature) {
+       case 0xa5:
+       case 0xbb:
+       case 0xdd:
+               board->port_count = (board->isa == NO && portcount == 4) ? 4 :
+                       8;
+               board->shift_count = 12;
+               break;
+       case 0xcc:
+               board->port_count = 16;
+               board->shift_count = 11;
+               break;
+       default:
+               dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
+                       "bad I/O Port Address 0x%lx).\n", card + 1, base);
+               dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
+               retval = -EIO;
+       }
+       dev_info(&pdev->dev, "-Done\n");
+
+end:
+       return retval;
 }
 
-static int __devinit isicom_init(void)
+static inline int WaitTillCardIsFree(u16 base)
 {
-       int card, channel, base;
-       struct isi_port * port;
-       unsigned long page;
-       
-       if (!tmp_buf) { 
-               page = get_zeroed_page(GFP_KERNEL);
-               if (!page) {
-#ifdef ISICOM_DEBUG            
-                       printk(KERN_DEBUG "ISICOM: Couldn't allocate page for tmp_buf.\n");
-#else
-                       printk(KERN_ERR "ISICOM: Not enough memory...\n");
-#endif       
-                       return 0;
-               }       
-               tmp_buf = (unsigned char *) page;
-       }
-       
-       if (!register_ioregion()) 
-       {
-               printk(KERN_ERR "ISICOM: All required I/O space found busy.\n");
-               free_page((unsigned long)tmp_buf);
-               return 0;
-       }
-       if (register_drivers()) 
-       {
-               unregister_ioregion();
-               free_page((unsigned long)tmp_buf);
-               return 0;
-       }
-       if (!register_isr()) 
-       {
-               unregister_drivers();
-               /*  ioports already uregistered in register_isr */
-               free_page((unsigned long)tmp_buf);
-               return 0;               
+       unsigned long count = 0;
+
+       while (!(inw(base + 0xe) & 0x1) && count++ < 100)
+               msleep(5);
+
+       return !(inw(base + 0xe) & 0x1);
+}
+
+static int __devinit load_firmware(struct pci_dev *pdev,
+       const unsigned int index, const unsigned int signature)
+{
+       struct isi_board *board = pci_get_drvdata(pdev);
+       const struct firmware *fw;
+       unsigned long base = board->base;
+       unsigned int a;
+       u16 word_count, status;
+       int retval = -EIO;
+       char *name;
+       u8 *data;
+
+       struct stframe {
+               u16     addr;
+               u16     count;
+               u8      data[0];
+       } *frame;
+
+       switch (signature) {
+       case 0xa5:
+               name = "isi608.bin";
+               break;
+       case 0xbb:
+               name = "isi608em.bin";
+               break;
+       case 0xcc:
+               name = "isi616em.bin";
+               break;
+       case 0xdd:
+               name = "isi4608.bin";
+               break;
+       case 0xee:
+               name = "isi4616.bin";
+               break;
+       default:
+               dev_err(&pdev->dev, "Unknown signature.\n");
+               goto end;
+       }
+
+       retval = request_firmware(&fw, name, &pdev->dev);
+       if (retval)
+               goto end;
+
+       for (frame = (struct stframe *)fw->data;
+                       frame < (struct stframe *)(fw->data + fw->size);
+                       frame++) {
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               outw(0xf0, base);       /* start upload sequence */
+               outw(0x00, base);
+               outw(frame->addr, base); /* lsb of address */
+
+               word_count = frame->count / 2 + frame->count % 2;
+               outw(word_count, base);
+               InterruptTheCard(base);
+
+               udelay(100); /* 0x2f */
+
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               if ((status = inw(base + 0x4)) != 0) {
+                       dev_warn(&pdev->dev, "Card%d rejected load header:\n"
+                               "Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
+                               index + 1, frame->addr, frame->count, status);
+                       goto errrelfw;
+               }
+               outsw(base, frame->data, word_count);
+
+               InterruptTheCard(base);
+
+               udelay(50); /* 0x0f */
+
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               if ((status = inw(base + 0x4)) != 0) {
+                       dev_err(&pdev->dev, "Card%d got out of sync.Card "
+                               "Status:0x%x\n", index + 1, status);
+                       goto errrelfw;
+               }
+       }
+
+       retval = -EIO;
+
+       if (WaitTillCardIsFree(base))
+               goto errrelfw;
+
+       outw(0xf2, base);
+       outw(0x800, base);
+       outw(0x0, base);
+       outw(0x0, base);
+       InterruptTheCard(base);
+       outw(0x0, base + 0x4); /* for ISI4608 cards */
+
+/* XXX: should we test it by reading it back and comparing with original like
+ * in load firmware package? */
+       for (frame = (struct stframe*)fw->data;
+                       frame < (struct stframe*)(fw->data + fw->size);
+                       frame++) {
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               outw(0xf1, base); /* start download sequence */
+               outw(0x00, base);
+               outw(frame->addr, base); /* lsb of address */
+
+               word_count = (frame->count >> 1) + frame->count % 2;
+               outw(word_count + 1, base);
+               InterruptTheCard(base);
+
+               udelay(50); /* 0xf */
+
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               if ((status = inw(base + 0x4)) != 0) {
+                       dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
+                               "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
+                               index + 1, frame->addr, frame->count, status);
+                       goto errrelfw;
+               }
+
+               data = kmalloc(word_count * 2, GFP_KERNEL);
+               inw(base);
+               insw(base, data, word_count);
+               InterruptTheCard(base);
+
+               for (a = 0; a < frame->count; a++)
+                       if (data[a] != frame->data[a]) {
+                               kfree(data);
+                               dev_err(&pdev->dev, "Card%d, firmware upload "
+                                       "failed\n", index + 1);
+                               goto errrelfw;
+                       }
+               kfree(data);
+
+               udelay(50); /* 0xf */
+
+               if (WaitTillCardIsFree(base))
+                       goto errrelfw;
+
+               if ((status = inw(base + 0x4)) != 0) {
+                       dev_err(&pdev->dev, "Card%d verify got out of sync. "
+                               "Card Status:0x%x\n", index + 1, status);
+                       goto errrelfw;
+               }
        }
-       
-       memset(isi_ports, 0, sizeof(isi_ports));
-       for (card = 0; card < BOARD_COUNT; card++) {
-               port = &isi_ports[card * 16];
-               isi_card[card].ports = port;
-               spin_lock_init(&isi_card[card].card_lock);
-               base = isi_card[card].base;
-               for (channel = 0; channel < 16; channel++, port++) {
-                       port->magic = ISICOM_MAGIC;
-                       port->card = &isi_card[card];
-                       port->channel = channel;
-                       port->close_delay = 50 * HZ/100;
-                       port->closing_wait = 3000 * HZ/100;
-                       INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
-                       INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
-                       port->status = 0;
-                       init_waitqueue_head(&port->open_wait);                                  
-                       init_waitqueue_head(&port->close_wait);
-                       /*  . . .  */
-               }
-       } 
-       
-       return 1;       
+
+       board->status |= FIRMWARE_LOADED;
+       retval = 0;
+
+errrelfw:
+       release_firmware(fw);
+end:
+       return retval;
 }
 
 /*
  *     Insmod can set static symbols so keep these static
  */
 static int io[4];
 static int irq[4];
+static int card;
 
-MODULE_AUTHOR("MultiTech");
-MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
-MODULE_LICENSE("GPL");
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O ports for the cards");
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "Interrupts for the cards");
+static int __devinit isicom_probe(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
+{
+       unsigned int ioaddr, signature, index;
+       int retval = -EPERM;
+       u8 pciirq;
+       struct isi_board *board = NULL;
+
+       if (card >= BOARD_COUNT)
+               goto err;
+
+       ioaddr = pci_resource_start(pdev, 3);
+       /* i.e at offset 0x1c in the PCI configuration register space. */
+       pciirq = pdev->irq;
+       dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
+
+       /* allot the first empty slot in the array */
+       for (index = 0; index < BOARD_COUNT; index++)
+               if (isi_card[index].base == 0) {
+                       board = &isi_card[index];
+                       break;
+               }
+
+       board->base = ioaddr;
+       board->irq = pciirq;
+       board->isa = NO;
+       card++;
+
+       pci_set_drvdata(pdev, board);
+
+       retval = isicom_register_ioregion(pdev, index);
+       if (retval < 0)
+               goto err;
+
+       retval = isicom_register_isr(pdev, index);
+       if (retval < 0)
+               goto errunrr;
+
+       retval = reset_card(pdev, index, &signature);
+       if (retval < 0)
+               goto errunri;
+
+       retval = load_firmware(pdev, index, signature);
+       if (retval < 0)
+               goto errunri;
+
+       return 0;
+
+errunri:
+       free_irq(board->irq, board);
+errunrr:
+       isicom_unregister_ioregion(pdev);
+err:
+       board->base = 0;
+       return retval;
+}
+
+static void __devexit isicom_remove(struct pci_dev *pdev)
+{
+       struct isi_board *board = pci_get_drvdata(pdev);
+
+       free_irq(board->irq, board);
+       isicom_unregister_ioregion(pdev);
+}
 
 static int __devinit isicom_setup(void)
 {
-       struct pci_dev *dev = NULL;
-       int retval, card, idx, count;
-       unsigned char pciirq;
-       unsigned int ioaddr;
-                       
+       int retval, idx, channel;
+       struct isi_port *port;
+
        card = 0;
-       for(idx=0; idx < BOARD_COUNT; idx++) {  
-               if (io[idx]) {
-                       isi_card[idx].base=io[idx];
-                       isi_card[idx].irq=irq[idx];
-                       isi_card[idx].isa=YES;
-                       card++;
-               }
-               else {
-                       isi_card[idx].base = 0;
-                       isi_card[idx].irq = 0;
-               }
-       }
-       
-       for (idx=0 ;idx < card; idx++) {
-               if (!((isi_card[idx].irq==2)||(isi_card[idx].irq==3)||
-                   (isi_card[idx].irq==4)||(isi_card[idx].irq==5)||
-                   (isi_card[idx].irq==7)||(isi_card[idx].irq==10)||
-                   (isi_card[idx].irq==11)||(isi_card[idx].irq==12)||
-                   (isi_card[idx].irq==15))) {
-                       
-                       if (isi_card[idx].base) {
-                               printk(KERN_ERR "ISICOM: Irq %d unsupported. Disabling Card%d...\n",
-                                       isi_card[idx].irq, idx+1);
-                               isi_card[idx].base=0;
-                               card--;
-                       }       
-               }
-       }       
-       
-       if (card < BOARD_COUNT) {
-               for (idx=0; idx < DEVID_COUNT; idx++) {
-                       dev = NULL;
-                       for (;;){
-                               if (!(dev = pci_find_device(VENDOR_ID, isicom_pci_tbl[idx].device, dev)))
-                                       break;
-                               if (card >= BOARD_COUNT)
-                                       break;
-                                       
-                               if (pci_enable_device(dev))
-                                       break;
+       memset(isi_ports, 0, sizeof(isi_ports));
 
-                               /* found a PCI ISI card! */
-                               ioaddr = pci_resource_start (dev, 3); /* i.e at offset 0x1c in the
-                                                                      * PCI configuration register
-                                                                      * space.
-                                                                      */
-                               pciirq = dev->irq;
-                               printk(KERN_INFO "ISI PCI Card(Device ID 0x%x)\n", isicom_pci_tbl[idx].device);
-                               /*
-                                * allot the first empty slot in the array
-                                */                             
-                               for (count=0; count < BOARD_COUNT; count++) {                           
-                                       if (isi_card[count].base == 0) {
-                                               isi_card[count].base = ioaddr;
-                                               isi_card[count].irq = pciirq;
-                                               isi_card[count].isa = NO;
-                                               card++;
-                                               break;
-                                       }
-                               }
-                       }                               
-                       if (card >= BOARD_COUNT) break;
-               }
+       for(idx = 0; idx < BOARD_COUNT; idx++) {
+               port = &isi_ports[idx * 16];
+               isi_card[idx].ports = port;
+               spin_lock_init(&isi_card[idx].card_lock);
+               for (channel = 0; channel < 16; channel++, port++) {
+                       port->magic = ISICOM_MAGIC;
+                       port->card = &isi_card[idx];
+                       port->channel = channel;
+                       port->close_delay = 50 * HZ/100;
+                       port->closing_wait = 3000 * HZ/100;
+                       INIT_WORK(&port->hangup_tq, do_isicom_hangup, port);
+                       INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port);
+                       port->status = 0;
+                       init_waitqueue_head(&port->open_wait);
+                       init_waitqueue_head(&port->close_wait);
+                       /*  . . .  */
+               }
+               isi_card[idx].base = 0;
+               isi_card[idx].irq = 0;
+
+               if (!io[idx])
+                       continue;
+
+               if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4     ||
+                               irq[idx] == 5   || irq[idx] == 7        ||
+                               irq[idx] == 10  || irq[idx] == 11       ||
+                               irq[idx] == 12  || irq[idx] == 15) {
+                       printk(KERN_ERR "ISICOM: ISA not supported yet.\n");
+                       retval = -EINVAL;
+                       goto error;
+               } else
+                       printk(KERN_ERR "ISICOM: Irq %d unsupported. "
+                               "Disabling Card%d...\n", irq[idx], idx + 1);
        }
-       
-       if (!(isi_card[0].base || isi_card[1].base || isi_card[2].base || isi_card[3].base)) {
-               printk(KERN_ERR "ISICOM: No valid card configuration. Driver cannot be initialized...\n"); 
-               return -EIO;
-       }       
 
-       retval = misc_register(&isiloader_device);
+       retval = isicom_register_tty_driver();
+       if (retval < 0)
+               goto error;
+
+       retval = pci_register_driver(&isicom_driver);
        if (retval < 0) {
-               printk(KERN_ERR "ISICOM: Unable to register firmware loader driver.\n");
-               return retval;
-       }
-       
-       if (!isicom_init()) {
-               if (misc_deregister(&isiloader_device)) 
-                       printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
-               return -EIO;
+               printk(KERN_ERR "ISICOM: Unable to register pci driver.\n");
+               goto errtty;
        }
-       
+
        init_timer(&tx);
        tx.expires = jiffies + 1;
        tx.data = 0;
        tx.function = isicom_tx;
        re_schedule = 1;
        add_timer(&tx);
-       
+
        return 0;
+errtty:
+       isicom_unregister_tty_driver();
+error:
+       return retval;
 }
 
 static void __exit isicom_exit(void)
 {
+       unsigned int index = 0;
+
        re_schedule = 0;
-       /* FIXME */
-       msleep(1000);
-       unregister_isr();
-       unregister_drivers();
-       unregister_ioregion();  
-       if(tmp_buf)
-               free_page((unsigned long)tmp_buf);
-       if (misc_deregister(&isiloader_device))
-               printk(KERN_ERR "ISICOM: Unable to unregister Firmware Loader driver\n");
+
+       while (re_schedule != 2 && index++ < 100)
+               msleep(10);
+
+       pci_unregister_driver(&isicom_driver);
+       isicom_unregister_tty_driver();
 }
 
 module_init(isicom_setup);
 module_exit(isicom_exit);
+
+MODULE_AUTHOR("MultiTech");
+MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
+MODULE_LICENSE("GPL");
+module_param_array(io, int, NULL, 0);
+MODULE_PARM_DESC(io, "I/O ports for the cards");
+module_param_array(irq, int, NULL, 0);
+MODULE_PARM_DESC(irq, "Interrupts for the cards");
index ce3bc0d45f1f0c8fb2794257e5971078688045ac..28c5a3193b819752024b57941677f1dfe31df818 100644 (file)
@@ -135,7 +135,7 @@ static stlconf_t    stli_brdconf[] = {
        /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/
 };
 
-static int     stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);
+static int     stli_nrbrds = ARRAY_SIZE(stli_brdconf);
 
 /*
  *     There is some experimental EISA board detection code in this driver.
@@ -406,7 +406,7 @@ static unsigned long        stli_eisamemprobeaddrs[] = {
        0xff000000, 0xff010000, 0xff020000, 0xff030000,
 };
 
-static int     stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
+static int     stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs);
 
 /*
  *     Define the Stallion PCI vendor and device IDs.
@@ -899,15 +899,13 @@ static void stli_argbrds(void)
 {
        stlconf_t       conf;
        stlibrd_t       *brdp;
-       int             nrargs, i;
+       int             i;
 
 #ifdef DEBUG
        printk("stli_argbrds()\n");
 #endif
 
-       nrargs = sizeof(stli_brdsp) / sizeof(char **);
-
-       for (i = stli_nrbrds; (i < nrargs); i++) {
+       for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) {
                memset(&conf, 0, sizeof(conf));
                if (stli_parsebrd(&conf, stli_brdsp[i]) == 0)
                        continue;
@@ -967,7 +965,7 @@ static unsigned long stli_atol(char *str)
 static int stli_parsebrd(stlconf_t *confp, char **argp)
 {
        char    *sp;
-       int     nrbrdnames, i;
+       int     i;
 
 #ifdef DEBUG
        printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
@@ -979,14 +977,13 @@ static int stli_parsebrd(stlconf_t *confp, char **argp)
        for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
                *sp = TOLOWER(*sp);
 
-       nrbrdnames = sizeof(stli_brdstr) / sizeof(stlibrdtype_t);
-       for (i = 0; (i < nrbrdnames); i++) {
+       for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) {
                if (strcmp(stli_brdstr[i].name, argp[0]) == 0)
                        break;
        }
-       if (i >= nrbrdnames) {
+       if (i == ARRAY_SIZE(stli_brdstr)) {
                printk("STALLION: unknown board name, %s?\n", argp[0]);
-               return(0);
+               return 0;
        }
 
        confp->brdtype = stli_brdstr[i].type;
@@ -2714,17 +2711,13 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp)
                stlen = size - tail;
        }
 
-       len = MIN(len, (TTY_FLIPBUF_SIZE - tty->flip.count));
+       len = tty_buffer_request_room(tty, len);
+       /* FIXME : iomap ? */
        shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset);
 
        while (len > 0) {
                stlen = MIN(len, stlen);
-               memcpy(tty->flip.char_buf_ptr, (char *) (shbuf + tail), stlen);
-               memset(tty->flip.flag_buf_ptr, 0, stlen);
-               tty->flip.char_buf_ptr += stlen;
-               tty->flip.flag_buf_ptr += stlen;
-               tty->flip.count += stlen;
-
+               tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen);
                len -= stlen;
                tail += stlen;
                if (tail >= size) {
@@ -2909,16 +2902,12 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp)
 
                if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
                        if (tty != (struct tty_struct *) NULL) {
-                               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                       tty->flip.count++;
-                                       *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-                                       *tty->flip.char_buf_ptr++ = 0;
-                                       if (portp->flags & ASYNC_SAK) {
-                                               do_SAK(tty);
-                                               EBRDENABLE(brdp);
-                                       }
-                                       tty_schedule_flip(tty);
+                               tty_insert_flip_char(tty, 0, TTY_BREAK);
+                               if (portp->flags & ASYNC_SAK) {
+                                       do_SAK(tty);
+                                       EBRDENABLE(brdp);
                                }
+                               tty_schedule_flip(tty);
                        }
                }
 
@@ -4943,7 +4932,7 @@ static int stli_portcmdstats(stliport_t *portp)
        if (portp->tty != (struct tty_struct *) NULL) {
                if (portp->tty->driver_data == portp) {
                        stli_comstats.ttystate = portp->tty->flags;
-                       stli_comstats.rxbuffered = portp->tty->flip.count;
+                       stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/;
                        if (portp->tty->termios != (struct termios *) NULL) {
                                stli_comstats.cflags = portp->tty->termios->c_cflag;
                                stli_comstats.iflags = portp->tty->termios->c_iflag;
index 79e490ef2cf2ea352045e2d5a71913bac50158eb..5e3ef5522194d441758c006eb99ff34ef12b1703 100644 (file)
@@ -269,7 +269,7 @@ static int MoxaPortDCDChange(int);
 static int MoxaPortDCDON(int);
 static void MoxaPortFlushData(int, int);
 static int MoxaPortWriteData(int, unsigned char *, int);
-static int MoxaPortReadData(int, unsigned char *, int);
+static int MoxaPortReadData(int, struct tty_struct *tty);
 static int MoxaPortTxQueue(int);
 static int MoxaPortRxQueue(int);
 static int MoxaPortTxFree(int);
@@ -301,6 +301,8 @@ static struct tty_operations moxa_ops = {
        .tiocmset = moxa_tiocmset,
 };
 
+static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED;
+
 #ifdef CONFIG_PCI
 static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
 {
@@ -448,7 +450,7 @@ static int __init moxa_init(void)
 #ifdef CONFIG_PCI
        {
                struct pci_dev *p = NULL;
-               int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
+               int n = ARRAY_SIZE(moxa_pcibrds) - 1;
                i = 0;
                while (i < n) {
                        while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
@@ -645,10 +647,10 @@ static int moxa_write(struct tty_struct *tty,
        if (ch == NULL)
                return (0);
        port = ch->port;
-       save_flags(flags);
-       cli();
+
+       spin_lock_irqsave(&moxa_lock, flags);
        len = MoxaPortWriteData(port, (unsigned char *) buf, count);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&moxa_lock, flags);
 
        /*********************************************
        if ( !(ch->statusflags & LOWWAIT) &&
@@ -723,11 +725,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
        if (ch == NULL)
                return;
        port = ch->port;
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        moxaXmitBuff[0] = c;
        MoxaPortWriteData(port, moxaXmitBuff, 1);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&moxa_lock, flags);
        /************************************************
        if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
        *************************************************/
@@ -1030,12 +1031,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
        printk("block_til_ready before block: ttys%d, count = %d\n",
               ch->line, ch->count);
 #endif
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        if (!tty_hung_up_p(filp))
                ch->count--;
-       restore_flags(flags);
        ch->blocked_open++;
+       spin_unlock_irqrestore(&moxa_lock, flags);
+
        while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (tty_hung_up_p(filp) ||
@@ -1062,17 +1063,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&ch->open_wait, &wait);
+
+       spin_lock_irqsave(&moxa_lock, flags);
        if (!tty_hung_up_p(filp))
                ch->count++;
        ch->blocked_open--;
+       spin_unlock_irqrestore(&moxa_lock, flags);
 #ifdef SERIAL_DEBUG_OPEN
        printk("block_til_ready after blocking: ttys%d, count = %d\n",
               ch->line, ch->count);
 #endif
        if (retval)
                return (retval);
+       /* FIXME: review to see if we need to use set_bit on these */
        ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
-       return (0);
+       return 0;
 }
 
 static void setup_empty_event(struct tty_struct *tty)
@@ -1080,15 +1085,14 @@ static void setup_empty_event(struct tty_struct *tty)
        struct moxa_str *ch = tty->driver_data;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        ch->statusflags |= EMPTYWAIT;
        moxaEmptyTimer_on[ch->port] = 0;
        del_timer(&moxaEmptyTimer[ch->port]);
        moxaEmptyTimer[ch->port].expires = jiffies + HZ;
        moxaEmptyTimer_on[ch->port] = 1;
        add_timer(&moxaEmptyTimer[ch->port]);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&moxa_lock, flags);
 }
 
 static void check_xmit_empty(unsigned long data)
@@ -1135,8 +1139,6 @@ static void receive_data(struct moxa_str *ch)
 {
        struct tty_struct *tp;
        struct termios *ts;
-       int i, count, rc, space;
-       unsigned char *charptr, *flagptr;
        unsigned long flags;
 
        ts = NULL;
@@ -1150,24 +1152,10 @@ static void receive_data(struct moxa_str *ch)
                MoxaPortFlushData(ch->port, 0);
                return;
        }
-       space = TTY_FLIPBUF_SIZE - tp->flip.count;
-       if (space <= 0)
-               return;
-       charptr = tp->flip.char_buf_ptr;
-       flagptr = tp->flip.flag_buf_ptr;
-       rc = tp->flip.count;
-       save_flags(flags);
-       cli();
-       count = MoxaPortReadData(ch->port, charptr, space);
-       restore_flags(flags);
-       for (i = 0; i < count; i++)
-               *flagptr++ = 0;
-       charptr += count;
-       rc += count;
-       tp->flip.count = rc;
-       tp->flip.char_buf_ptr = charptr;
-       tp->flip.flag_buf_ptr = flagptr;
-       tty_schedule_flip(ch->tty);
+       spin_lock_irqsave(&moxa_lock, flags);
+       MoxaPortReadData(ch->port, tp);
+       spin_unlock_irqrestore(&moxa_lock, flags);
+       tty_schedule_flip(tp);
 }
 
 #define Magic_code     0x404
@@ -1774,7 +1762,7 @@ int MoxaPortsOfCard(int cardno)
  *     14. MoxaPortDCDON(int port);                                         *
  *     15. MoxaPortFlushData(int port, int mode);                           *
  *     16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
- *     17. MoxaPortReadData(int port, unsigned char * buffer, int length);  *
+ *     17. MoxaPortReadData(int port, struct tty_struct *tty);              *
  *     18. MoxaPortTxBufSize(int port);                                     *
  *     19. MoxaPortRxBufSize(int port);                                     *
  *     20. MoxaPortTxQueue(int port);                                       *
@@ -2003,10 +1991,9 @@ int MoxaPortsOfCard(int cardno)
  *
  *      Function 21:    Read data.
  *      Syntax:
- *      int  MoxaPortReadData(int port, unsigned char * buffer, int length);
+ *      int  MoxaPortReadData(int port, struct tty_struct *tty);
  *           int port           : port number (0 - 127)
- *           unsigned char * buffer     : pointer to read data buffer.
- *           int length         : read data buffer length
+ *          struct tty_struct *tty : tty for data
  *
  *           return:    0 - length      : real read data length
  *
@@ -2504,7 +2491,7 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len)
        return (total);
 }
 
-int MoxaPortReadData(int port, unsigned char * buffer, int space)
+int MoxaPortReadData(int port, struct tty_struct *tty)
 {
        register ushort head, pageofs;
        int i, count, cnt, len, total, remain;
@@ -2522,9 +2509,9 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
        count = (tail >= head) ? (tail - head)
            : (tail - head + rx_mask + 1);
        if (count == 0)
-               return (0);
+               return 0;
 
-       total = (space > count) ? count : space;
+       total = count;
        remain = count - total;
        moxaLog.rxcnt[port] += total;
        count = total;
@@ -2539,7 +2526,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
                        len = (count > len) ? len : count;
                        ofs = baseAddr + DynPage_addr + bufhead + head;
                        for (i = 0; i < len; i++)
-                               *buffer++ = readb(ofs + i);
+                               tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
                        head = (head + len) & rx_mask;
                        count -= len;
                }
@@ -2556,7 +2543,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
                        writew(pageno, baseAddr + Control_reg);
                        ofs = baseAddr + DynPage_addr + pageofs;
                        for (i = 0; i < cnt; i++)
-                               *buffer++ = readb(ofs + i);
+                               tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
                        if (count == 0) {
                                writew((head + len) & rx_mask, ofsAddr + RXrptr);
                                break;
index 26448f176803e1b551fd21e8689d76911a400b48..ea725a9964e2007075db5e814422ceed52f84ee3 100644 (file)
@@ -813,7 +813,7 @@ static int mxser_init(void)
 
        /* start finding PCI board here */
 #ifdef CONFIG_PCI
-       n = (sizeof(mxser_pcibrds) / sizeof(mxser_pcibrds[0])) - 1;
+       n = ARRAY_SIZE(mxser_pcibrds) - 1;
        index = 0;
        b = 0;
        while (b < n) {
@@ -1982,7 +1982,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status)
 
        spin_lock_irqsave(&info->slock, flags);
 
-       recv_room = tty->ldisc.receive_room(tty);
+       recv_room = tty->receive_room;
        if ((recv_room == 0) && (!info->ldisc_stop_rx)) {
                //mxser_throttle(tty);
                mxser_stoprx(tty);
index a133a62f3d5528a1ad93d6d2ee181cdaaebac295..9f54733f16236e9e5618c91967d1d1434ef824ef 100644 (file)
@@ -191,7 +191,6 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
                                    poll_table *wait);
 static int n_hdlc_tty_open(struct tty_struct *tty);
 static void n_hdlc_tty_close(struct tty_struct *tty);
-static int n_hdlc_tty_room(struct tty_struct *tty);
 static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
                               char *fp, int count);
 static void n_hdlc_tty_wakeup(struct tty_struct *tty);
@@ -212,7 +211,6 @@ static struct tty_ldisc n_hdlc_ldisc = {
        .ioctl          = n_hdlc_tty_ioctl,
        .poll           = n_hdlc_tty_poll,
        .receive_buf    = n_hdlc_tty_receive,
-       .receive_room   = n_hdlc_tty_room,
        .write_wakeup   = n_hdlc_tty_wakeup,
 };
 
@@ -337,6 +335,7 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
                
        tty->disc_data = n_hdlc;
        n_hdlc->tty    = tty;
+       tty->receive_room = 65536;
        
 #if defined(TTY_NO_WRITE_SPLIT)
        /* change tty_io write() to not split large writes into 8K chunks */
@@ -477,22 +476,6 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
                
 }      /* end of n_hdlc_tty_wakeup() */
 
-/**
- * n_hdlc_tty_room - Return the amount of space left in the receiver's buffer
- * @tty        - pointer to associated tty instance data
- *
- * Callback function from tty driver. Return the amount of space left in the
- * receiver's buffer to decide if remote transmitter is to be throttled.
- */
-static int n_hdlc_tty_room(struct tty_struct *tty)
-{
-       if (debuglevel >= DEBUG_LEVEL_INFO)     
-               printk("%s(%d)n_hdlc_tty_room() called\n",__FILE__,__LINE__);
-       /* always return a larger number to prevent */
-       /* throttling of remote transmitter. */
-       return 65536;
-}      /* end of n_hdlc_tty_root() */
-
 /**
  * n_hdlc_tty_receive - Called by tty driver when receive data is available
  * @tty        - pointer to tty instance data
index 853c98cee64fa5c25ee1bced34274f35d2323dda..c48de09d68f0fd1c6b5334744305eb69a650d6d7 100644 (file)
@@ -147,7 +147,6 @@ static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
                      struct poll_table_struct  *wait);
 static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
                               char *fp, int count);
-static int  r3964_receive_room(struct tty_struct *tty);
 
 static struct tty_ldisc tty_ldisc_N_R3964 = {
        .owner   = THIS_MODULE,
@@ -161,7 +160,6 @@ static struct tty_ldisc tty_ldisc_N_R3964 = {
        .set_termios = r3964_set_termios,
        .poll   = r3964_poll,            
        .receive_buf = r3964_receive_buf,
-       .receive_room = r3964_receive_room,
 };
 
 
@@ -1119,6 +1117,7 @@ static int r3964_open(struct tty_struct *tty)
    pInfo->nRetry = 0;
    
    tty->disc_data = pInfo;
+   tty->receive_room = 65536;
 
    init_timer(&pInfo->tmr);
    pInfo->tmr.data = (unsigned long)pInfo;
@@ -1405,12 +1404,5 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
     }
 }
 
-static int r3964_receive_room(struct tty_struct *tty)
-{
-   TRACE_L("receive_room");
-   return -1;
-}
-
-
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_R3964);
index c556f4d3ccd7cda2122fa91098cce56491d3387d..ccad7ae94541111698b08223b844cad43a3128fe 100644 (file)
@@ -78,7 +78,32 @@ static inline void free_buf(unsigned char *buf)
                free_page((unsigned long) buf);
 }
 
-static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
+/**
+ *     n_tty_set__room -       receive space
+ *     @tty: terminal
+ *
+ *     Called by the driver to find out how much data it is
+ *     permitted to feed to the line discipline without any being lost
+ *     and thus to manage flow control. Not serialized. Answers for the
+ *     "instant".
+ */
+
+static void n_tty_set_room(struct tty_struct *tty)
+{
+       int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
+
+       /*
+        * If we are doing input canonicalization, and there are no
+        * pending newlines, let characters through without limit, so
+        * that erase characters will be handled.  Other excess
+        * characters will be beeped.
+        */
+       if (left <= 0)
+               left = tty->icanon && !tty->canon_data;
+       tty->receive_room = left;
+}
+
+static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
 {
        if (tty->read_cnt < N_TTY_BUF_SIZE) {
                tty->read_buf[tty->read_head] = c;
@@ -87,7 +112,7 @@ static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
        }
 }
 
-static inline void put_tty_queue(unsigned char c, struct tty_struct *tty)
+static void put_tty_queue(unsigned char c, struct tty_struct *tty)
 {
        unsigned long flags;
        /*
@@ -136,6 +161,7 @@ static void reset_buffer_flags(struct tty_struct *tty)
        spin_unlock_irqrestore(&tty->read_lock, flags);
        tty->canon_head = tty->canon_data = tty->erasing = 0;
        memset(&tty->read_flags, 0, sizeof tty->read_flags);
+       n_tty_set_room(tty);
        check_unthrottle(tty);
 }
 
@@ -838,30 +864,6 @@ send_signal:
        put_tty_queue(c, tty);
 }      
 
-/**
- *     n_tty_receive_room      -       receive space
- *     @tty: terminal
- *
- *     Called by the driver to find out how much data it is
- *     permitted to feed to the line discipline without any being lost
- *     and thus to manage flow control. Not serialized. Answers for the
- *     "instant".
- */
-static int n_tty_receive_room(struct tty_struct *tty)
-{
-       int     left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
-
-       /*
-        * If we are doing input canonicalization, and there are no
-        * pending newlines, let characters through without limit, so
-        * that erase characters will be handled.  Other excess
-        * characters will be beeped.
-        */
-       if (left <= 0)
-               left = tty->icanon && !tty->canon_data;
-       return left;
-}
 
 /**
  *     n_tty_write_wakeup      -       asynchronous I/O notifier
@@ -953,6 +955,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
                        tty->driver->flush_chars(tty);
        }
 
+       n_tty_set_room(tty);
+
        if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
                kill_fasync(&tty->fasync, SIGIO, POLL_IN);
                if (waitqueue_active(&tty->read_wait))
@@ -964,7 +968,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
         * mode.  We don't want to throttle the driver if we're in
         * canonical mode and don't have a newline yet!
         */
-       if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) {
+       if (tty->receive_room < TTY_THRESHOLD_THROTTLE) {
                /* check TTY_THROTTLED first so it indicates our state */
                if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
                    tty->driver->throttle)
@@ -999,6 +1003,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
        if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
                tty->raw = 1;
                tty->real_raw = 1;
+               n_tty_set_room(tty);
                return;
        }
        if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@@ -1051,6 +1056,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
                else
                        tty->real_raw = 0;
        }
+       n_tty_set_room(tty);
 }
 
 /**
@@ -1130,7 +1136,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
  *
  */
  
-static inline int copy_from_read_buf(struct tty_struct *tty,
+static int copy_from_read_buf(struct tty_struct *tty,
                                      unsigned char __user **b,
                                      size_t *nr)
 
@@ -1308,6 +1314,7 @@ do_it_again:
                                retval = -ERESTARTSYS;
                                break;
                        }
+                       n_tty_set_room(tty);
                        clear_bit(TTY_DONT_FLIP, &tty->flags);
                        timeout = schedule_timeout(timeout);
                        set_bit(TTY_DONT_FLIP, &tty->flags);
@@ -1401,6 +1408,8 @@ do_it_again:
        } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
                 goto do_it_again;
 
+       n_tty_set_room(tty);
+
        return retval;
 }
 
@@ -1553,7 +1562,6 @@ struct tty_ldisc tty_ldisc_N_TTY = {
        normal_poll,            /* poll */
        NULL,                   /* hangup */
        n_tty_receive_buf,      /* receive_buf */
-       n_tty_receive_room,     /* receive_room */
        n_tty_write_wakeup      /* write_wakeup */
 };
 
index 1af733d07321a8f5de4c5412745fd46428ce7332..3556ccd77570b691937ab47bea7ba2af09fe57c2 100644 (file)
@@ -557,13 +557,13 @@ pc_proc_infos(unsigned char *nvram, char *buffer, int *len,
            (nvram[6] & 1) ? (nvram[6] >> 6) + 1 : 0);
        PRINT_PROC("Floppy 0 type  : ");
        type = nvram[2] >> 4;
-       if (type < sizeof (floppy_types) / sizeof (*floppy_types))
+       if (type < ARRAY_SIZE(floppy_types))
                PRINT_PROC("%s\n", floppy_types[type]);
        else
                PRINT_PROC("%d (unknown)\n", type);
        PRINT_PROC("Floppy 1 type  : ");
        type = nvram[2] & 0x0f;
-       if (type < sizeof (floppy_types) / sizeof (*floppy_types))
+       if (type < ARRAY_SIZE(floppy_types))
                PRINT_PROC("%s\n", floppy_types[type]);
        else
                PRINT_PROC("%d (unknown)\n", type);
@@ -843,8 +843,6 @@ static char *colors[] = {
        "2", "4", "16", "256", "65536", "??", "??", "??"
 };
 
-#define fieldsize(a)   (sizeof(a)/sizeof(*a))
-
 static int
 atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
     off_t *begin, off_t offset, int size)
@@ -856,7 +854,7 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
        PRINT_PROC("Checksum status  : %svalid\n", checksum ? "" : "not ");
 
        PRINT_PROC("Boot preference  : ");
-       for (i = fieldsize(boot_prefs) - 1; i >= 0; --i) {
+       for (i = ARRAY_SIZE(boot_prefs) - 1; i >= 0; --i) {
                if (nvram[1] == boot_prefs[i].val) {
                        PRINT_PROC("%s\n", boot_prefs[i].name);
                        break;
@@ -878,12 +876,12 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
                return 1;
 
        PRINT_PROC("OS language      : ");
-       if (nvram[6] < fieldsize(languages))
+       if (nvram[6] < ARRAY_SIZE(languages))
                PRINT_PROC("%s\n", languages[nvram[6]]);
        else
                PRINT_PROC("%u (undefined)\n", nvram[6]);
        PRINT_PROC("Keyboard language: ");
-       if (nvram[7] < fieldsize(languages))
+       if (nvram[7] < ARRAY_SIZE(languages))
                PRINT_PROC("%s\n", languages[nvram[7]]);
        else
                PRINT_PROC("%u (undefined)\n", nvram[7]);
index cf45b100eff1e269f826ae6dbf5a825a3e58677a..8a8ca32822ba4ee800c076ebef798477ce25df5b 100644 (file)
@@ -1007,8 +1007,9 @@ static void rx_ready_hdlc(MGSLPC_INFO *info, int eom)
 
 static void rx_ready_async(MGSLPC_INFO *info, int tcd)
 {
-       unsigned char data, status;
+       unsigned char data, status, flag;
        int fifo_count;
+       int work = 0;
        struct tty_struct *tty = info->tty;
        struct mgsl_icount *icount = &info->icount;
 
@@ -1023,20 +1024,16 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd)
                        fifo_count = 32;
        } else
                fifo_count = 32;
-       
+
+       tty_buffer_request_room(tty, fifo_count);
        /* Flush received async data to receive data buffer. */ 
        while (fifo_count) {
                data   = read_reg(info, CHA + RXFIFO);
                status = read_reg(info, CHA + RXFIFO);
                fifo_count -= 2;
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
-                       
-               *tty->flip.char_buf_ptr = data;
                icount->rx++;
-               
-               *tty->flip.flag_buf_ptr = 0;
+               flag = TTY_NORMAL;
 
                // if no frameing/crc error then save data
                // BIT7:parity error
@@ -1055,26 +1052,23 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd)
                        status &= info->read_status_mask;
 
                        if (status & BIT7)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (status & BIT6)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
-               
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
+               work += tty_insert_flip_char(tty, data, flag);
        }
        issue_command(info, CHA, CMD_RXFIFO);
 
        if (debug_level >= DEBUG_LEVEL_ISR) {
-               printk("%s(%d):rx_ready_async count=%d\n",
-                       __FILE__,__LINE__,tty->flip.count);
+               printk("%s(%d):rx_ready_async",
+                       __FILE__,__LINE__);
                printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
                        __FILE__,__LINE__,icount->rx,icount->brk,
                        icount->parity,icount->frame,icount->overrun);
        }
                        
-       if (tty->flip.count)
+       if (work)
                tty_flip_buffer_push(tty);
 }
 
@@ -4005,7 +3999,7 @@ BOOLEAN register_test(MGSLPC_INFO *info)
 {
        static unsigned char patterns[] = 
            { 0x00, 0xff, 0xaa, 0x55, 0x69, 0x96, 0x0f };
-       static unsigned int count = sizeof(patterns) / sizeof(patterns[0]);
+       static unsigned int count = ARRAY_SIZE(patterns);
        unsigned int i;
        BOOLEAN rc = TRUE;
        unsigned long flags;
@@ -4016,7 +4010,7 @@ BOOLEAN register_test(MGSLPC_INFO *info)
        for (i = 0; i < count; i++) {
                write_reg(info, XAD1, patterns[i]);
                write_reg(info, XAD2, patterns[(i + 1) % count]);
-               if ((read_reg(info, XAD1) != patterns[i]) || 
+               if ((read_reg(info, XAD1) != patterns[i]) ||
                    (read_reg(info, XAD2) != patterns[(i + 1) % count])) {
                        rc = FALSE;
                        break;
index 49f3997fd251d95cfaec443d98f5a15037f52c68..9b5a2c0e7008c82183649e6006784088ceabd220 100644 (file)
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
        if (!to || tty->stopped)
                return 0;
 
-       c = to->ldisc.receive_room(to);
+       c = to->receive_room;
        if (c > count)
                c = count;
        to->ldisc.receive_buf(to, buf, NULL, c);
@@ -126,7 +126,7 @@ static int pty_write_room(struct tty_struct *tty)
        if (!to || tty->stopped)
                return 0;
 
-       return to->ldisc.receive_room(to);
+       return to->receive_room;
 }
 
 /*
index d7d484024e2bf224b6fd3243f85b59bdc299df3b..7085a38532b3ccc9cc1a73fe5f68eb2e3f064c70 100644 (file)
 #include <linux/generic_serial.h>
 #include <asm/uaccess.h>
 
-#if BITS_PER_LONG != 32
-#  error FIXME: this driver only works on 32-bit platforms
-#endif
-
 #include "linux_compat.h"
 #include "typdef.h"
 #include "pkt.h"
@@ -215,7 +211,7 @@ static int rio_poll = 1;
    or less.... */
 static int rio_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000};
 
-#define NR_RIO_ADDRS (sizeof(rio_probe_addrs)/sizeof (int))
+#define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs)
 
 
 /* Set the mask to all-ones. This alas, only supports 32 interrupts. 
index e42e7b50bf6bf50184ca1e16e4588b442ea2add5..ddda9c14e0590277984f5234edfd5291b7ebef5f 100644 (file)
@@ -38,6 +38,7 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c        1.2";
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -560,6 +561,7 @@ struct Port *               PortP;
   struct PKT *PacketP;
   register uint        DataCnt;
   uchar *      ptr;
+  unsigned char *buf;
   int copied =0;
 
   static int intCount, RxIntCnt;
@@ -657,8 +659,7 @@ struct Port *               PortP;
          ** and available space.
          */
                        
-         transCount = min_t(unsigned int, PacketP->len & PKT_LEN_MASK,
-                          TTY_FLIPBUF_SIZE - TtyP->flip.count);
+         transCount = tty_buffer_request_room(TtyP, PacketP->len & PKT_LEN_MASK);
          rio_dprintk (RIO_DEBUG_REC,  "port %d: Copy %d bytes\n", 
                                      PortP->PortNum, transCount);
          /*
@@ -678,9 +679,8 @@ struct Port *               PortP;
 #endif
          ptr = (uchar *) PacketP->data + PortP->RxDataStart;
 
-         rio_memcpy_fromio (TtyP->flip.char_buf_ptr, ptr, transCount);
-         memset(TtyP->flip.flag_buf_ptr, TTY_NORMAL, transCount);
-
+         tty_prepare_flip_string(TtyP, &buf, transCount);
+         rio_memcpy_fromio (buf, ptr, transCount);
 #ifdef STATS
          /*
          ** keep a count for statistical purposes
@@ -690,9 +690,6 @@ struct Port *               PortP;
          PortP->RxDataStart    += transCount;
          PacketP->len          -= transCount;
          copied += transCount;
-         TtyP->flip.count += transCount;
-         TtyP->flip.char_buf_ptr += transCount;
-         TtyP->flip.flag_buf_ptr += transCount;
 
 
 #ifdef ___DEBUG_IT___
index 55a3a0188eda09084f5e1056451162f7d8f85fc5..050e70ee59202f03ff3bee326583d5de4530f534 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/major.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/tty_flip.h>
 
 #include <asm/uaccess.h>
 
@@ -107,15 +108,15 @@ static struct riscom_port rc_port[RC_NBOARD * RC_NPORT];
 
 /* RISCom/8 I/O ports addresses (without address translation) */
 static unsigned short rc_ioport[] =  {
-#if 1  
+#if 1
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c,
-#else  
+#else
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10,
        0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62,
        0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101
-#endif 
+#endif
 };
-#define RC_NIOPORT     (sizeof(rc_ioport) / sizeof(rc_ioport[0]))
+#define RC_NIOPORT     ARRAY_SIZE(rc_ioport)
 
 
 static inline int rc_paranoia_check(struct riscom_port const * port,
@@ -354,28 +355,17 @@ static inline void rc_receive_exc(struct riscom_board const * bp)
        struct riscom_port *port;
        struct tty_struct *tty;
        unsigned char status;
-       unsigned char ch;
+       unsigned char ch, flag;
        
        if (!(port = rc_get_port(bp, "Receive")))
                return;
 
        tty = port->tty;
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-               printk(KERN_WARNING "rc%d: port %d: Working around flip "
-                                   "buffer overflow.\n",
-                      board_No(bp), port_No(port));
-               return;
-       }
        
 #ifdef RC_REPORT_OVERRUN       
        status = rc_in(bp, CD180_RCSR);
-       if (status & RCSR_OE)  {
+       if (status & RCSR_OE)
                port->overrun++;
-#if 0          
-               printk(KERN_ERR "rc%d: port %d: Overrun. Total %ld overruns\n", 
-                      board_No(bp), port_No(port), port->overrun);
-#endif         
-       }
        status &= port->mark_mask;
 #else  
        status = rc_in(bp, CD180_RCSR) & port->mark_mask;
@@ -393,25 +383,24 @@ static inline void rc_receive_exc(struct riscom_board const * bp)
        } else if (status & RCSR_BREAK)  {
                printk(KERN_INFO "rc%d: port %d: Handling break...\n",
                       board_No(bp), port_No(port));
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+               flag = TTY_BREAK;
                if (port->flags & ASYNC_SAK)
                        do_SAK(tty);
                
        } else if (status & RCSR_PE) 
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+               flag = TTY_PARITY;
        
        else if (status & RCSR_FE) 
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+               flag = TTY_FRAME;
        
         else if (status & RCSR_OE)
-               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+               flag = TTY_OVERRUN;
        
        else
-               *tty->flip.flag_buf_ptr++ = 0;
+               flag = TTY_NORMAL;
        
-       *tty->flip.char_buf_ptr++ = ch;
-       tty->flip.count++;
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_insert_flip_char(tty, ch, flag);
+       tty_flip_buffer_push(tty);
 }
 
 static inline void rc_receive(struct riscom_board const * bp)
@@ -432,17 +421,15 @@ static inline void rc_receive(struct riscom_board const * bp)
 #endif 
        
        while (count--)  {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
+               if (tty_buffer_request_room(tty, 1) == 0)  {
                        printk(KERN_WARNING "rc%d: port %d: Working around "
                                            "flip buffer overflow.\n",
                               board_No(bp), port_No(port));
                        break;
                }
-               *tty->flip.char_buf_ptr++ = rc_in(bp, CD180_RDR);
-               *tty->flip.flag_buf_ptr++ = 0;
-               tty->flip.count++;
+               tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
        }
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_flip_buffer_push(tty);
 }
 
 static inline void rc_transmit(struct riscom_board const * bp)
index d3bc731fbb2773cbe6c94c92505781cb63a0bb50..0949dcef06976d8f78a250a0a725f99ce06f8f11 100644 (file)
@@ -325,19 +325,16 @@ static void rp_do_receive(struct r_port *info,
 {
        unsigned int CharNStat;
        int ToRecv, wRecv, space = 0, count;
-       unsigned char *cbuf;
-       char *fbuf;
+       unsigned char *cbuf, *chead;
+       char *fbuf, *fhead;
        struct tty_ldisc *ld;
 
        ld = tty_ldisc_ref(tty);
 
        ToRecv = sGetRxCnt(cp);
-       if (ld)
-               space = ld->receive_room(tty);
+       space = tty->receive_room;
        if (space > 2 * TTY_FLIPBUF_SIZE)
                space = 2 * TTY_FLIPBUF_SIZE;
-       cbuf = tty->flip.char_buf;
-       fbuf = tty->flip.flag_buf;
        count = 0;
 #ifdef ROCKET_DEBUG_INTR
        printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space);
@@ -350,9 +347,13 @@ static void rp_do_receive(struct r_port *info,
        if (ToRecv > space)
                ToRecv = space;
 
+       ToRecv = tty_prepare_flip_string_flags(tty, &chead, &fhead, ToRecv);
        if (ToRecv <= 0)
                goto done;
 
+       cbuf = chead;
+       fbuf = fhead;
+
        /*
         * if status indicates there are errored characters in the
         * FIFO, then enter status mode (a word in FIFO holds
@@ -399,7 +400,7 @@ static void rp_do_receive(struct r_port *info,
                        else if (CharNStat & STMRCVROVRH)
                                *fbuf++ = TTY_OVERRUN;
                        else
-                               *fbuf++ = 0;
+                               *fbuf++ = TTY_NORMAL;
                        *cbuf++ = CharNStat & 0xff;
                        count++;
                        ToRecv--;
@@ -426,13 +427,13 @@ static void rp_do_receive(struct r_port *info,
                        sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
                if (ToRecv & 1)
                        cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
-               memset(fbuf, 0, ToRecv);
+               memset(fbuf, TTY_NORMAL, ToRecv);
                cbuf += ToRecv;
                fbuf += ToRecv;
                count += ToRecv;
        }
        /*  Push the data up to the tty layer */
-       ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+       ld->receive_buf(tty, cbuf, fbuf, count);
 done:
        tty_ldisc_deref(ld);
 }
index 5b187c895c1831fc1bf274aeaa6e7fe35f0c8244..71093a9fc462ac8f562a8c8e980a7d7deceadd89 100644 (file)
@@ -275,7 +275,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
 int paste_selection(struct tty_struct *tty)
 {
        struct vc_data *vc = (struct vc_data *)tty->driver_data;
-       int     pasted = 0, count;
+       int     pasted = 0;
+       unsigned int count;
        struct  tty_ldisc *ld;
        DECLARE_WAITQUEUE(wait, current);
 
@@ -293,7 +294,7 @@ int paste_selection(struct tty_struct *tty)
                        continue;
                }
                count = sel_buffer_lth - pasted;
-               count = min(count, tty->ldisc.receive_room(tty));
+               count = min(count, tty->receive_room);
                tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count);
                pasted += count;
        }
index dda30e42ec79806b8e2de0d79e365c407befb4eb..80a5b840e22f646b432ab17cfe259ebd8f4c96a5 100644 (file)
@@ -194,11 +194,6 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err)
 */
        struct tty_struct *tty = port->gs.tty;
 
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-               return;
-
-       tty->flip.count++;
-
 #if 0
        switch(err) {
        case TTY_BREAK:
@@ -212,8 +207,7 @@ static inline void a2232_receive_char(struct a2232_port *port, int ch, int err)
        }
 #endif
 
-       *tty->flip.flag_buf_ptr++ = err;
-       *tty->flip.char_buf_ptr++ = ch;
+       tty_insert_flip_char(tty, ch, err);
        tty_flip_buffer_push(tty);
 }
 
index c2deac968bdd7c607864a99b72651911d4746e78..f36342ae8e7e91b7121162580d13f39faa176deb 100644 (file)
@@ -117,7 +117,7 @@ struct cyclades_port cy_port[] = {
         {-1 },      /* ttyS2 */
         {-1 },      /* ttyS3 */
 };
-#define NR_PORTS        (sizeof(cy_port)/sizeof(struct cyclades_port))
+#define NR_PORTS        ARRAY_SIZE(cy_port)
 
 /*
  * tmp_buf is used as a temporary buffer by serial_write.  We need to
@@ -422,45 +422,35 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
            base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
            return IRQ_HANDLED;
        }
-       if (tty->flip.count < TTY_FLIPBUF_SIZE){
-           tty->flip.count++;
+       if (tty_buffer_request_room(tty, 1) != 0){
            if (err & info->read_status_mask){
                if(err & CyBREAK){
-                   *tty->flip.flag_buf_ptr++ = TTY_BREAK;
-                   *tty->flip.char_buf_ptr++ = data;
+                   tty_insert_flip_char(tty, data, TTY_BREAK);
                    if (info->flags & ASYNC_SAK){
                        do_SAK(tty);
                    }
                }else if(err & CyFRAME){
-                   *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-                   *tty->flip.char_buf_ptr++ = data;
+                   tty_insert_flip_char(tty, data, TTY_FRAME);
                }else if(err & CyPARITY){
-                   *tty->flip.flag_buf_ptr++ = TTY_PARITY;
-                   *tty->flip.char_buf_ptr++ = data;
+                   tty_insert_flip_char(tty, data, TTY_PARITY);
                }else if(err & CyOVERRUN){
-                   *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-                   *tty->flip.char_buf_ptr++ = 0;
+                   tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                    /*
                       If the flip buffer itself is
                       overflowing, we still loose
                       the next incoming character.
                     */
-                   if(tty->flip.count < TTY_FLIPBUF_SIZE){
-                       tty->flip.count++;
-                       *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                       *tty->flip.char_buf_ptr++ = data;
-                   }
+                   tty_insert_flip_char(tty, data, TTY_NORMAL);
+               }
                /* These two conditions may imply */
                /* a normal read should be done. */
                /* else if(data & CyTIMEOUT) */
                /* else if(data & CySPECHAR) */
                }else{
-                   *tty->flip.flag_buf_ptr++ = 0;
-                   *tty->flip.char_buf_ptr++ = 0;
+                   tty_insert_flip_char(tty, 0, TTY_NORMAL);
                }
            }else{
-               *tty->flip.flag_buf_ptr++ = 0;
-               *tty->flip.char_buf_ptr++ = 0;
+                   tty_insert_flip_char(tty, data, TTY_NORMAL);
            }
        }else{
            /* there was a software buffer overrun
@@ -692,12 +682,7 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 #endif
        while(char_count--){
            data = base_addr[CyRDR];
-           if (tty->flip.count >= TTY_FLIPBUF_SIZE){
-               continue;
-           }
-           tty->flip.count++;
-           *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-           *tty->flip.char_buf_ptr++ = data;
+           tty_insert_flip_char(tty, data, TTY_NORMAL);
 #ifdef CYCLOM_16Y_HACK
            udelay(10L);
 #endif
index 0bbfce43031c9d6be2e4041db9c8fc6f1eea0203..0a574bdbce3695df8ab4e0553753e9e5f2f7a1f7 100644 (file)
@@ -85,6 +85,7 @@
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/serial.h>
 #include <linux/fcntl.h>
@@ -665,7 +666,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
        struct specialix_port *port;
        struct tty_struct *tty;
        unsigned char status;
-       unsigned char ch;
+       unsigned char ch, flag;
 
        func_enter();
 
@@ -676,8 +677,6 @@ static inline void sx_receive_exc(struct specialix_board * bp)
                return;
        }
        tty = port->tty;
-       dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
-                port,  tty->flip.count, TTY_FLIPBUF_SIZE);
 
        status = sx_in(bp, CD186x_RCSR);
 
@@ -691,7 +690,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
 
        /* This flip buffer check needs to be below the reading of the
           status register to reset the chip's IRQ.... */
-       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+       if (tty_buffer_request_room(tty, 1) == 0) {
                dprintk(SX_DEBUG_FIFO, "sx%d: port %d: Working around flip buffer overflow.\n",
                       board_No(bp), port_No(port));
                func_exit();
@@ -712,26 +711,24 @@ static inline void sx_receive_exc(struct specialix_board * bp)
        } else if (status & RCSR_BREAK) {
                dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
                       board_No(bp), port_No(port));
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+               flag = TTY_BREAK;
                if (port->flags & ASYNC_SAK)
                        do_SAK(tty);
 
        } else if (status & RCSR_PE)
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+               flag = TTY_PARITY;
 
        else if (status & RCSR_FE)
-               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+               flag = TTY_FRAME;
 
        else if (status & RCSR_OE)
-               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+               flag = TTY_OVERRUN;
 
        else
-               *tty->flip.flag_buf_ptr++ = 0;
-
-       *tty->flip.char_buf_ptr++ = ch;
-       tty->flip.count++;
-       schedule_delayed_work(&tty->flip.work, 1);
+               flag = TTY_NORMAL;
 
+       if(tty_insert_flip_char(tty, ch, flag))
+               tty_flip_buffer_push(tty);
        func_exit();
 }
 
@@ -755,18 +752,11 @@ static inline void sx_receive(struct specialix_board * bp)
        dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
        port->hits[count > 8 ? 9 : count]++;
 
-       while (count--) {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
-                              board_No(bp), port_No(port));
-                       break;
-               }
-               *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
-               *tty->flip.flag_buf_ptr++ = 0;
-               tty->flip.count++;
-       }
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_buffer_request_room(tty, count);
 
+       while (count--)
+               tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL);
+       tty_flip_buffer_push(tty);
        func_exit();
 }
 
index 95af2a941595517ca0ea30daa4a380a739724475..0e20780d4a29ebac0948abd008757da2cc3c69b3 100644 (file)
@@ -103,7 +103,7 @@ static stlconf_t    stl_brdconf[] = {
        /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
 };
 
-static int     stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t);
+static int     stl_nrbrds = ARRAY_SIZE(stl_brdconf);
 
 /*****************************************************************************/
 
@@ -424,7 +424,7 @@ static stlpcibrd_t  stl_pcibrds[] = {
        { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI },
 };
 
-static int     stl_nrpcibrds = sizeof(stl_pcibrds) / sizeof(stlpcibrd_t);
+static int     stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds);
 
 #endif
 
@@ -704,7 +704,7 @@ static unsigned int sc26198_baudtable[] = {
        230400, 460800, 921600
 };
 
-#define        SC26198_NRBAUDS         (sizeof(sc26198_baudtable) / sizeof(unsigned int))
+#define        SC26198_NRBAUDS         ARRAY_SIZE(sc26198_baudtable)
 
 /*****************************************************************************/
 
@@ -901,7 +901,7 @@ static unsigned long stl_atol(char *str)
 static int stl_parsebrd(stlconf_t *confp, char **argp)
 {
        char    *sp;
-       int     nrbrdnames, i;
+       int     i;
 
 #ifdef DEBUG
        printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp);
@@ -913,14 +913,13 @@ static int stl_parsebrd(stlconf_t *confp, char **argp)
        for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
                *sp = TOLOWER(*sp);
 
-       nrbrdnames = sizeof(stl_brdstr) / sizeof(stlbrdtype_t);
-       for (i = 0; (i < nrbrdnames); i++) {
+       for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) {
                if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
                        break;
        }
-       if (i >= nrbrdnames) {
+       if (i == ARRAY_SIZE(stl_brdstr)) {
                printk("STALLION: unknown board name, %s?\n", argp[0]);
-               return(0);
+               return 0;
        }
 
        confp->brdtype = stl_brdstr[i].type;
@@ -2902,7 +2901,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp)
        if (portp->tty != (struct tty_struct *) NULL) {
                if (portp->tty->driver_data == portp) {
                        portp->stats.ttystate = portp->tty->flags;
-                       portp->stats.rxbuffered = portp->tty->flip.count;
+                       /* No longer available as a statistic */
+                       portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
                        if (portp->tty->termios != (struct termios *) NULL) {
                                portp->stats.cflags = portp->tty->termios->c_cflag;
                                portp->stats.iflags = portp->tty->termios->c_iflag;
@@ -4046,9 +4046,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
        if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
                outb((RDCR + portp->uartaddr), ioaddr);
                len = inb(ioaddr + EREG_DATA);
-               if ((tty == (struct tty_struct *) NULL) ||
-                   (tty->flip.char_buf_ptr == (char *) NULL) ||
-                   ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
+               if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
                        len = MIN(len, sizeof(stl_unwanted));
                        outb((RDSR + portp->uartaddr), ioaddr);
                        insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
@@ -4057,12 +4055,10 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
                } else {
                        len = MIN(len, buflen);
                        if (len > 0) {
+                               unsigned char *ptr;
                                outb((RDSR + portp->uartaddr), ioaddr);
-                               insb((ioaddr + EREG_DATA), tty->flip.char_buf_ptr, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.flag_buf_ptr += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.count += len;
+                               tty_prepare_flip_string(tty, &ptr, len);
+                               insb((ioaddr + EREG_DATA), ptr, len);
                                tty_schedule_flip(tty);
                                portp->stats.rxtotal += len;
                        }
@@ -4086,8 +4082,7 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
                                portp->stats.txxoff++;
                        goto stl_rxalldone;
                }
-               if ((tty != (struct tty_struct *) NULL) &&
-                   ((portp->rxignoremsk & status) == 0)) {
+               if (tty != NULL && (portp->rxignoremsk & status) == 0) {
                        if (portp->rxmarkmsk & status) {
                                if (status & ST_BREAK) {
                                        status = TTY_BREAK;
@@ -4107,14 +4102,8 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr)
                        } else {
                                status = 0;
                        }
-                       if (tty->flip.char_buf_ptr != (char *) NULL) {
-                               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                       *tty->flip.flag_buf_ptr++ = status;
-                                       *tty->flip.char_buf_ptr++ = ch;
-                                       tty->flip.count++;
-                               }
-                               tty_schedule_flip(tty);
-                       }
+                       tty_insert_flip_char(tty, ch, status);
+                       tty_schedule_flip(tty);
                }
        } else {
                printk("STALLION: bad RX interrupt ack value=%x\n", ioack);
@@ -5013,9 +5002,7 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
        len = inb(ioaddr + XP_DATA) + 1;
 
        if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
-               if ((tty == (struct tty_struct *) NULL) ||
-                   (tty->flip.char_buf_ptr == (char *) NULL) ||
-                   ((buflen = TTY_FLIPBUF_SIZE - tty->flip.count) == 0)) {
+               if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
                        len = MIN(len, sizeof(stl_unwanted));
                        outb(GRXFIFO, (ioaddr + XP_ADDR));
                        insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
@@ -5024,12 +5011,10 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack)
                } else {
                        len = MIN(len, buflen);
                        if (len > 0) {
+                               unsigned char *ptr;
                                outb(GRXFIFO, (ioaddr + XP_ADDR));
-                               insb((ioaddr + XP_DATA), tty->flip.char_buf_ptr, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.flag_buf_ptr += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.count += len;
+                               tty_prepare_flip_string(tty, &ptr, len);
+                               insb((ioaddr + XP_DATA), ptr, len);
                                tty_schedule_flip(tty);
                                portp->stats.rxtotal += len;
                        }
@@ -5097,14 +5082,8 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch
                        status = 0;
                }
 
-               if (tty->flip.char_buf_ptr != (char *) NULL) {
-                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                               *tty->flip.flag_buf_ptr++ = status;
-                               *tty->flip.char_buf_ptr++ = ch;
-                               tty->flip.count++;
-                       }
-                       tty_schedule_flip(tty);
-               }
+               tty_insert_flip_char(tty, ch, status);
+               tty_schedule_flip(tty);
 
                if (status == 0)
                        portp->stats.rxtotal++;
index 3ad758a9a1dc104d70b718978e1928f57bc7c274..64bf89cb574f75d105dd4283a8c8c711fc22ae4e 100644 (file)
@@ -345,9 +345,9 @@ static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000,
                               0xc8000, 0xd8000, 0xe8000, 0xa0000};
 static int si1_probe_addrs[]= { 0xd0000};
 
-#define NR_SX_ADDRS (sizeof(sx_probe_addrs)/sizeof (int))
-#define NR_SI_ADDRS (sizeof(si_probe_addrs)/sizeof (int))
-#define NR_SI1_ADDRS (sizeof(si1_probe_addrs)/sizeof (int))
+#define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs)
+#define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs)
+#define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs)
 
 
 /* Set the mask to all-ones. This alas, only supports 32 interrupts. 
@@ -1085,6 +1085,7 @@ static inline void sx_receive_chars (struct sx_port *port)
        int rx_op;
        struct tty_struct *tty;
        int copied=0;
+       unsigned char *rp;
 
        func_enter2 ();
        tty = port->gs.tty;
@@ -1095,8 +1096,8 @@ static inline void sx_receive_chars (struct sx_port *port)
                sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); 
 
                /* Don't copy more bytes than there is room for in the buffer */
-               if (tty->flip.count + c > TTY_FLIPBUF_SIZE) 
-                       c = TTY_FLIPBUF_SIZE - tty->flip.count;
+
+               c = tty_prepare_flip_string(tty, &rp, c);
 
                sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); 
 
@@ -1111,14 +1112,8 @@ static inline void sx_receive_chars (struct sx_port *port)
                sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, 
                            read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op),
                            CHAN_OFFSET(port, hi_rxbuf)); 
-               memcpy_fromio (tty->flip.char_buf_ptr, 
+               memcpy_fromio (rp,
                               port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c);
-               memset(tty->flip.flag_buf_ptr, TTY_NORMAL, c);
-
-               /* Update the kernel buffer end */
-               tty->flip.count += c;
-               tty->flip.char_buf_ptr += c;
-               tty->flip.flag_buf_ptr += c;
 
                /* This one last. ( Not essential.)
                   It allows the card to start putting more data into the buffer! 
index 62aa0e534a6d7dbe30c07b72e338050be2a25225..9f1b466c4f84fcd555c79f92021ce17343c936de 100644 (file)
@@ -1467,6 +1467,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
 {
        int Fifocount;
        u16 status;
+       int work = 0;
        unsigned char DataByte;
        struct tty_struct *tty = info->tty;
        struct  mgsl_icount *icount = &info->icount;
@@ -1487,6 +1488,8 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
        /* flush the receive FIFO */
 
        while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) {
+               int flag;
+
                /* read one byte from RxFIFO */
                outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY),
                      info->io_base + CCAR );
@@ -1498,13 +1501,9 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
                                RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) )
                        usc_UnlatchRxstatusBits(info,RXSTATUS_ALL);
                
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       continue;
-                       
-               *tty->flip.char_buf_ptr = DataByte;
                icount->rx++;
                
-               *tty->flip.flag_buf_ptr = 0;
+               flag = 0;
                if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR +
                                RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) {
                        printk("rxerr=%04X\n",status);                                  
@@ -1530,41 +1529,31 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
                        status &= info->read_status_mask;
                
                        if (status & RXSTATUS_BREAK_RECEIVED) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                                if (info->flags & ASYNC_SAK)
                                        do_SAK(tty);
                        } else if (status & RXSTATUS_PARITY_ERROR)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (status & RXSTATUS_FRAMING_ERROR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-                       if (status & RXSTATUS_OVERRUN) {
-                               /* Overrun is special, since it's
-                                * reported immediately, and doesn't
-                                * affect the current character
-                                */
-                               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                       tty->flip.count++;
-                                       tty->flip.flag_buf_ptr++;
-                                       tty->flip.char_buf_ptr++;
-                                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                               }
-                       }
+                               flag = TTY_FRAME;
                }       /* end of if (error) */
-               
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
+               tty_insert_flip_char(tty, DataByte, flag);
+               if (status & RXSTATUS_OVERRUN) {
+                       /* Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       work += tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               }
        }
 
        if ( debug_level >= DEBUG_LEVEL_ISR ) {
-               printk("%s(%d):mgsl_isr_receive_data flip count=%d\n",
-                       __FILE__,__LINE__,tty->flip.count);
                printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
                        __FILE__,__LINE__,icount->rx,icount->brk,
                        icount->parity,icount->frame,icount->overrun);
        }
                        
-       if ( tty->flip.count )
+       if(work)
                tty_flip_buffer_push(tty);
 }
 
@@ -7058,7 +7047,7 @@ static BOOLEAN mgsl_register_test( struct mgsl_struct *info )
 {
        static unsigned short BitPatterns[] =
                { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f };
-       static unsigned int Patterncount = sizeof(BitPatterns)/sizeof(unsigned short);
+       static unsigned int Patterncount = ARRAY_SIZE(BitPatterns);
        unsigned int i;
        BOOLEAN rc = TRUE;
        unsigned long flags;
@@ -7501,9 +7490,9 @@ static int mgsl_adapter_test( struct mgsl_struct *info )
  */
 static BOOLEAN mgsl_memory_test( struct mgsl_struct *info )
 {
-       static unsigned long BitPatterns[] = { 0x0, 0x55555555, 0xaaaaaaaa,
-                                                                                       0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
-       unsigned long Patterncount = sizeof(BitPatterns)/sizeof(unsigned long);
+       static unsigned long BitPatterns[] =
+               { 0x0, 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
+       unsigned long Patterncount = ARRAY_SIZE(BitPatterns);
        unsigned long i;
        unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long);
        unsigned long * TestAddr;
index 2b9cde94e2f746ad88d1f8a75fb2305270479f95..79c81def4104f207b7a4ff9d7efc21ef1b6720ea 100644 (file)
@@ -75,7 +75,6 @@
 #include <linux/workqueue.h>
 #include <linux/hdlc.h>
 
-#include <asm/serial.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -1750,6 +1749,9 @@ static void rx_async(struct slgt_info *info)
        unsigned char status;
        struct slgt_desc *bufs = info->rbufs;
        int i, count;
+       int chars = 0;
+       int stat;
+       unsigned char ch;
 
        start = end = info->rbuf_current;
 
@@ -1761,16 +1763,15 @@ static void rx_async(struct slgt_info *info)
                DBGDATA(info, p, count, "rx");
 
                for(i=0 ; i < count; i+=2, p+=2) {
-                       if (tty) {
-                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                                       tty_flip_buffer_push(tty);
-                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                                       break;
-                               *tty->flip.char_buf_ptr = *p;
-                               *tty->flip.flag_buf_ptr = 0;
+                       if (tty && chars) {
+                               tty_flip_buffer_push(tty);
+                               chars = 0;
                        }
+                       ch = *p;
                        icount->rx++;
 
+                       stat = 0;
+
                        if ((status = *(p+1) & (BIT9 + BIT8))) {
                                if (status & BIT9)
                                        icount->parity++;
@@ -1779,17 +1780,14 @@ static void rx_async(struct slgt_info *info)
                                /* discard char if tty control flags say so */
                                if (status & info->ignore_status_mask)
                                        continue;
-                               if (tty) {
-                                       if (status & BIT9)
-                                               *tty->flip.flag_buf_ptr = TTY_PARITY;
-                                       else if (status & BIT8)
-                                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-                               }
+                               if (status & BIT9)
+                                       stat = TTY_PARITY;
+                               else if (status & BIT8)
+                                       stat = TTY_FRAME;
                        }
                        if (tty) {
-                               tty->flip.flag_buf_ptr++;
-                               tty->flip.char_buf_ptr++;
-                               tty->flip.count++;
+                               tty_insert_flip_char(tty, ch, stat);
+                               chars++;
                        }
                }
 
@@ -1812,7 +1810,7 @@ static void rx_async(struct slgt_info *info)
                        break;
        }
 
-       if (tty && tty->flip.count)
+       if (tty && chars)
                tty_flip_buffer_push(tty);
 }
 
@@ -2030,7 +2028,7 @@ static void isr_serial(struct slgt_info *info)
                        if (info->tty) {
                                if (!(status & info->ignore_status_mask)) {
                                        if (info->read_status_mask & MASK_BREAK) {
-                                               *info->tty->flip.flag_buf_ptr = TTY_BREAK;
+                                               tty_insert_flip_char(info->tty, 0, TTY_BREAK);
                                                if (info->flags & ASYNC_SAK)
                                                        do_SAK(info->tty);
                                        }
index ee5a40be9f99ef6fbe12f02cadc2beef45bc6f25..960adb256fbb67f3e0e64cfca4a5d9a162169329 100644 (file)
@@ -2196,7 +2196,7 @@ void isr_rxint(SLMP_INFO * info)
                        if ( tty ) {
                                if (!(status & info->ignore_status_mask1)) {
                                        if (info->read_status_mask1 & BRKD) {
-                                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                                               tty_insert_flip_char(tty, 0, TTY_BREAK);
                                                if (info->flags & ASYNC_SAK)
                                                        do_SAK(tty);
                                        }
@@ -2240,16 +2240,10 @@ void isr_rxrdy(SLMP_INFO * info)
 
        while((status = read_reg(info,CST0)) & BIT0)
        {
+               int flag = 0;
+               int over = 0;
                DataByte = read_reg(info,TRB);
 
-               if ( tty ) {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               continue;
-
-                       *tty->flip.char_buf_ptr = DataByte;
-                       *tty->flip.flag_buf_ptr = 0;
-               }
-
                icount->rx++;
 
                if ( status & (PE + FRME + OVRN) ) {
@@ -2272,42 +2266,34 @@ void isr_rxrdy(SLMP_INFO * info)
 
                        if ( tty ) {
                                if (status & PE)
-                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                else if (status & FRME)
-                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
+                                       flag = TTY_FRAME;
                                if (status & OVRN) {
                                        /* Overrun is special, since it's
                                         * reported immediately, and doesn't
                                         * affect the current character
                                         */
-                                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                               tty->flip.count++;
-                                               tty->flip.flag_buf_ptr++;
-                                               tty->flip.char_buf_ptr++;
-                                               *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                                       }
+                                       over = 1;
                                }
                        }
                }       /* end of if (error) */
 
                if ( tty ) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, DataByte, flag);
+                       if (over)
+                               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
        }
 
        if ( debug_level >= DEBUG_LEVEL_ISR ) {
-               printk("%s(%d):%s isr_rxrdy() flip count=%d\n",
-                       __FILE__,__LINE__,info->device_name,
-                       tty ? tty->flip.count : 0);
                printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
                        __FILE__,__LINE__,info->device_name,
                        icount->rx,icount->brk,icount->parity,
                        icount->frame,icount->overrun);
        }
 
-       if ( tty && tty->flip.count )
+       if ( tty )
                tty_flip_buffer_push(tty);
 }
 
@@ -5104,7 +5090,7 @@ void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count)
 int register_test(SLMP_INFO *info)
 {
        static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96};
-       static unsigned int count = sizeof(testval)/sizeof(unsigned char);
+       static unsigned int count = ARRAY_SIZE(testval);
        unsigned int i;
        int rc = TRUE;
        unsigned long flags;
@@ -5422,7 +5408,7 @@ int memory_test(SLMP_INFO *info)
 {
        static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa,
                0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
-       unsigned long count = sizeof(testval)/sizeof(unsigned long);
+       unsigned long count = ARRAY_SIZE(testval);
        unsigned long i;
        unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long);
        unsigned long * addr = (unsigned long *)info->memory_base;
index 4b1eef51ec5926d97918331f20740c3664067375..1eda82b31a61e8d890d551ead0488fdb675993eb 100644 (file)
@@ -166,9 +166,12 @@ static struct tty_struct *alloc_tty_struct(void)
        return tty;
 }
 
+static void tty_buffer_free_all(struct tty_struct *);
+
 static inline void free_tty_struct(struct tty_struct *tty)
 {
        kfree(tty->write_buf);
+       tty_buffer_free_all(tty);
        kfree(tty);
 }
 
@@ -230,6 +233,201 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
        return 0;
 }
 
+/*
+ * Tty buffer allocation management
+ */
+
+static void tty_buffer_free_all(struct tty_struct *tty)
+{
+       struct tty_buffer *thead;
+       while((thead = tty->buf.head) != NULL) {
+               tty->buf.head = thead->next;
+               kfree(thead);
+       }
+       while((thead = tty->buf.free) != NULL) {
+               tty->buf.free = thead->next;
+               kfree(thead);
+       }
+       tty->buf.tail = NULL;
+}
+
+static void tty_buffer_init(struct tty_struct *tty)
+{
+       tty->buf.head = NULL;
+       tty->buf.tail = NULL;
+       tty->buf.free = NULL;
+}
+
+static struct tty_buffer *tty_buffer_alloc(size_t size)
+{
+       struct tty_buffer *p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC);
+       if(p == NULL)
+               return NULL;
+       p->used = 0;
+       p->size = size;
+       p->next = NULL;
+       p->char_buf_ptr = (char *)(p->data);
+       p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size;
+/*     printk("Flip create %p\n", p); */
+       return p;
+}
+
+/* Must be called with the tty_read lock held. This needs to acquire strategy
+   code to decide if we should kfree or relink a given expired buffer */
+
+static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
+{
+       /* Dumb strategy for now - should keep some stats */
+/*     printk("Flip dispose %p\n", b); */
+       if(b->size >= 512)
+               kfree(b);
+       else {
+               b->next = tty->buf.free;
+               tty->buf.free = b;
+       }
+}
+
+static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
+{
+       struct tty_buffer **tbh = &tty->buf.free;
+       while((*tbh) != NULL) {
+               struct tty_buffer *t = *tbh;
+               if(t->size >= size) {
+                       *tbh = t->next;
+                       t->next = NULL;
+                       t->used = 0;
+                       /* DEBUG ONLY */
+                       memset(t->data, '*', size);
+/*                     printk("Flip recycle %p\n", t); */
+                       return t;
+               }
+               tbh = &((*tbh)->next);
+       }
+       /* Round the buffer size out */
+       size = (size + 0xFF) & ~ 0xFF;
+       return tty_buffer_alloc(size);
+       /* Should possibly check if this fails for the largest buffer we
+          have queued and recycle that ? */
+}
+
+int tty_buffer_request_room(struct tty_struct *tty, size_t size)
+{
+       struct tty_buffer *b = tty->buf.head, *n;
+       int left = 0;
+
+       /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
+          remove this conditional if its worth it. This would be invisible
+          to the callers */
+       if(b != NULL)
+               left = b->size - b->used;
+       if(left >= size)
+               return size;
+       /* This is the slow path - looking for new buffers to use */
+       n = tty_buffer_find(tty, size);
+       if(n == NULL)
+               return left;
+       n->next = b;
+       if(b != NULL)
+               b->next = n;
+       else
+               tty->buf.head = n;
+       tty->buf.tail = n;
+       return size;
+}
+
+EXPORT_SYMBOL_GPL(tty_buffer_request_room);
+
+int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size)
+{
+       int copied = 0;
+       do {
+               int space = tty_buffer_request_room(tty, size - copied);
+               struct tty_buffer *tb = tty->buf.tail;
+               /* If there is no space then tb may be NULL */
+               if(unlikely(space == 0))
+                       break;
+               memcpy(tb->char_buf_ptr + tb->used, chars, space);
+               memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+               tb->used += space;
+               copied += space;
+               chars += space;
+/*             printk("Flip insert %d.\n", space); */
+       }
+       /* There is a small chance that we need to split the data over
+          several buffers. If this is the case we must loop */
+       while (unlikely(size > copied));
+       return copied;
+}
+
+EXPORT_SYMBOL_GPL(tty_insert_flip_string);
+
+int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size)
+{
+       int copied = 0;
+       do {
+               int space = tty_buffer_request_room(tty, size - copied);
+               struct tty_buffer *tb = tty->buf.tail;
+               /* If there is no space then tb may be NULL */
+               if(unlikely(space == 0))
+                       break;
+               memcpy(tb->char_buf_ptr + tb->used, chars, space);
+               memcpy(tb->flag_buf_ptr + tb->used, flags, space);
+               tb->used += space;
+               copied += space;
+               chars += space;
+               flags += space;
+       }
+       /* There is a small chance that we need to split the data over
+          several buffers. If this is the case we must loop */
+       while (unlikely(size > copied));
+       return copied;
+}
+
+EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags);
+
+
+/*
+ *     Prepare a block of space in the buffer for data. Returns the length
+ *     available and buffer pointer to the space which is now allocated and
+ *     accounted for as ready for normal characters. This is used for drivers
+ *     that need their own block copy routines into the buffer. There is no
+ *     guarantee the buffer is a DMA target!
+ */
+
+int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size)
+{
+       int space = tty_buffer_request_room(tty, size);
+       struct tty_buffer *tb = tty->buf.tail;
+       *chars = tb->char_buf_ptr + tb->used;
+       memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
+       tb->used += space;
+       return space;
+}
+
+EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
+
+/*
+ *     Prepare a block of space in the buffer for data. Returns the length
+ *     available and buffer pointer to the space which is now allocated and
+ *     accounted for as ready for characters. This is used for drivers
+ *     that need their own block copy routines into the buffer. There is no
+ *     guarantee the buffer is a DMA target!
+ */
+
+int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size)
+{
+       int space = tty_buffer_request_room(tty, size);
+       struct tty_buffer *tb = tty->buf.tail;
+       *chars = tb->char_buf_ptr + tb->used;
+       *flags = tb->flag_buf_ptr + tb->used;
+       tb->used += space;
+       return space;
+}
+
+EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
+
+
+
 /*
  *     This is probably overkill for real world processors but
  *     they are not on hot paths so a little discipline won't do 
@@ -492,6 +690,17 @@ restart:
        if (ld == NULL)
                return -EINVAL;
 
+       /*
+        *      No more input please, we are switching. The new ldisc
+        *      will update this value in the ldisc open function
+        */
+
+       tty->receive_room = 0;
+
+       /*
+        *      Problem: What do we do if this blocks ?
+        */
+
        tty_wait_until_sent(tty, 0);
 
        if (tty->ldisc.num == ldisc) {
@@ -560,9 +769,9 @@ restart:
         *      we say so later on.
         */
 
-       work = cancel_delayed_work(&tty->flip.work);
+       work = cancel_delayed_work(&tty->buf.work);
        /*
-        * Wait for ->hangup_work and ->flip.work handlers to terminate
+        * Wait for ->hangup_work and ->buf.work handlers to terminate
         */
         
        flush_scheduled_work();
@@ -616,7 +825,7 @@ restart:
        /* Restart it in case no characters kick it off. Safe if
           already running */
        if (work)
-               schedule_delayed_work(&tty->flip.work, 1);
+               schedule_delayed_work(&tty->buf.work, 1);
        return retval;
 }
 
@@ -1721,10 +1930,10 @@ static void release_dev(struct file * filp)
         */
        clear_bit(TTY_LDISC, &tty->flags);
        clear_bit(TTY_DONT_FLIP, &tty->flags);
-       cancel_delayed_work(&tty->flip.work);
+       cancel_delayed_work(&tty->buf.work);
 
        /*
-        * Wait for ->hangup_work and ->flip.work handlers to terminate
+        * Wait for ->hangup_work and ->buf.work handlers to terminate
         */
         
        flush_scheduled_work();
@@ -2518,17 +2727,15 @@ EXPORT_SYMBOL(do_SAK);
 
 /*
  * This routine is called out of the software interrupt to flush data
- * from the flip buffer to the line discipline. 
+ * from the buffer chain to the line discipline.
  */
  
 static void flush_to_ldisc(void *private_)
 {
        struct tty_struct *tty = (struct tty_struct *) private_;
-       unsigned char   *cp;
-       char            *fp;
-       int             count;
        unsigned long   flags;
        struct tty_ldisc *disc;
+       struct tty_buffer *tbuf;
 
        disc = tty_ldisc_ref(tty);
        if (disc == NULL)       /*  !TTY_LDISC */
@@ -2538,28 +2745,22 @@ static void flush_to_ldisc(void *private_)
                /*
                 * Do it after the next timer tick:
                 */
-               schedule_delayed_work(&tty->flip.work, 1);
+               schedule_delayed_work(&tty->buf.work, 1);
                goto out;
        }
        spin_lock_irqsave(&tty->read_lock, flags);
-       if (tty->flip.buf_num) {
-               cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
-               fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
-               tty->flip.buf_num = 0;
-               tty->flip.char_buf_ptr = tty->flip.char_buf;
-               tty->flip.flag_buf_ptr = tty->flip.flag_buf;
-       } else {
-               cp = tty->flip.char_buf;
-               fp = tty->flip.flag_buf;
-               tty->flip.buf_num = 1;
-               tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
-               tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
-       }
-       count = tty->flip.count;
-       tty->flip.count = 0;
+       while((tbuf = tty->buf.head) != NULL) {
+               tty->buf.head = tbuf->next;
+               spin_unlock_irqrestore(&tty->read_lock, flags);
+               /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */
+               disc->receive_buf(tty, tbuf->char_buf_ptr,
+                                      tbuf->flag_buf_ptr,
+                                      tbuf->used);
+               spin_lock_irqsave(&tty->read_lock, flags);
+               tty_buffer_free(tty, tbuf);
+       }
+       tty->buf.tail = NULL;
        spin_unlock_irqrestore(&tty->read_lock, flags);
-
-       disc->receive_buf(tty, cp, fp, count);
 out:
        tty_ldisc_deref(disc);
 }
@@ -2654,11 +2855,12 @@ void tty_flip_buffer_push(struct tty_struct *tty)
        if (tty->low_latency)
                flush_to_ldisc((void *) tty);
        else
-               schedule_delayed_work(&tty->flip.work, 1);
+               schedule_delayed_work(&tty->buf.work, 1);
 }
 
 EXPORT_SYMBOL(tty_flip_buffer_push);
 
+
 /*
  * This subroutine initializes a tty structure.
  */
@@ -2669,10 +2871,10 @@ static void initialize_tty_struct(struct tty_struct *tty)
        tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
        tty->pgrp = -1;
        tty->overrun_time = jiffies;
-       tty->flip.char_buf_ptr = tty->flip.char_buf;
-       tty->flip.flag_buf_ptr = tty->flip.flag_buf;
-       INIT_WORK(&tty->flip.work, flush_to_ldisc, tty);
-       init_MUTEX(&tty->flip.pty_sem);
+       tty->buf.head = tty->buf.tail = NULL;
+       tty_buffer_init(tty);
+       INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
+       init_MUTEX(&tty->buf.pty_sem);
        init_MUTEX(&tty->termios_sem);
        init_waitqueue_head(&tty->write_wait);
        init_waitqueue_head(&tty->read_wait);
index 4d75c261f98a8faf2835b382982f235ee116fa23..cb82ebf4cb0787b8fcd7e28e24118b1c334be725 100644 (file)
@@ -993,11 +993,10 @@ static void vioHandleData(struct HvLpEvent *event)
                 * Don't attempt to copy more data into the buffer than we
                 * have room for because it would fail without indication.
                 */
-               if ((tty->flip.count + 1) > TTY_FLIPBUF_SIZE) {
+               if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) {
                        printk(VIOCONS_KERN_WARN "input buffer overflow!\n");
                        break;
                }
-               tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL);
        }
 
        /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */
index 19ba83635dd75d6433cf32c521ed929b679eec33..d9325281e482340697896fec7ae30807f1e91b4f 100644 (file)
@@ -434,13 +434,7 @@ static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp)
                SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
                return IRQ_HANDLED;
        }
-       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = 0;
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
-       }
+       tty_insert_flip_char(tty, ch, 0);
 
        /* Check if another character is already ready; in that case, the
         * spcond_int() function must be used, because this character may have an
@@ -487,13 +481,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp)
                else
                        err = 0;
 
-               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       *tty->flip.char_buf_ptr = ch;
-                       *tty->flip.flag_buf_ptr = err;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
+               tty_insert_flip_char(tty, ch, err);
 
                /* ++TeSche: *All* errors have to be cleared manually,
                 * else the condition persists for the next chars
@@ -875,13 +863,13 @@ static int scc_open (struct tty_struct * tty, struct file * filp)
                local_irq_save(flags);
 #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC)
                if (MACH_IS_MVME147 || MACH_IS_MVME16x) {
-                       for (i=0; i<sizeof(mvme_init_tab)/sizeof(*mvme_init_tab); ++i)
+                       for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i)
                                SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val);
                }
 #endif
 #if defined(CONFIG_BVME6000_SCC)
                if (MACH_IS_BVME6000) {
-                       for (i=0; i<sizeof(bvme_init_tab)/sizeof(*bvme_init_tab); ++i)
+                       for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i)
                                SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val);
                }
 #endif
index 435b30748e231807df780458e47cac52eb700e64..159acd8b77880bf76a6a9be94ce81a937e22e815 100644 (file)
@@ -127,8 +127,6 @@ struct resource rtc_resource[2] = {
                .flags  = IORESOURCE_MEM,       },
 };
 
-#define RTC_NUM_RESOURCES      sizeof(rtc_resource) / sizeof(struct resource)
-
 static inline unsigned long read_elapsed_second(void)
 {
        unsigned long first_low, first_mid, first_high;
@@ -686,7 +684,8 @@ static int __devinit vr41xx_rtc_init(void)
                break;
        }
 
-       rtc_platform_device = platform_device_register_simple("RTC", -1, rtc_resource, RTC_NUM_RESOURCES);
+       rtc_platform_device = platform_device_register_simple("RTC", -1,
+                             rtc_resource, ARRAY_SIZE(rtc_resource));
        if (IS_ERR(rtc_platform_device))
                return PTR_ERR(rtc_platform_device);
 
index e91268e86833bf8322d883e10d69c6bd3ec80089..f1d9cb7feae65c7e54edadec884b1636424608e7 100644 (file)
@@ -2758,29 +2758,6 @@ static void set_vesa_blanking(char __user *p)
     vesa_blank_mode = (mode < 4) ? mode : 0;
 }
 
-/*
- * This is called by a timer handler
- */
-static void vesa_powerdown(void)
-{
-    struct vc_data *c = vc_cons[fg_console].d;
-    /*
-     *  Power down if currently suspended (1 or 2),
-     *  suspend if currently blanked (0),
-     *  else do nothing (i.e. already powered down (3)).
-     *  Called only if powerdown features are allowed.
-     */
-    switch (vesa_blank_mode) {
-    case VESA_NO_BLANKING:
-           c->vc_sw->con_blank(c, VESA_VSYNC_SUSPEND+1, 0);
-           break;
-    case VESA_VSYNC_SUSPEND:
-    case VESA_HSYNC_SUSPEND:
-           c->vc_sw->con_blank(c, VESA_POWERDOWN+1, 0);
-           break;
-    }
-}
-
 void do_blank_screen(int entering_gfx)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
@@ -2791,8 +2768,7 @@ void do_blank_screen(int entering_gfx)
        if (console_blanked) {
                if (blank_state == blank_vesa_wait) {
                        blank_state = blank_off;
-                       vesa_powerdown();
-
+                       vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
                }
                return;
        }
@@ -2822,7 +2798,7 @@ void do_blank_screen(int entering_gfx)
 
        save_screen(vc);
        /* In case we need to reset origin, blanking hook returns 1 */
-       i = vc->vc_sw->con_blank(vc, 1, 0);
+       i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
        console_blanked = fg_console + 1;
        if (i)
                set_origin(vc);
@@ -2830,13 +2806,10 @@ void do_blank_screen(int entering_gfx)
        if (console_blank_hook && console_blank_hook(1))
                return;
 
-       if (vesa_off_interval) {
+       if (vesa_off_interval && vesa_blank_mode) {
                blank_state = blank_vesa_wait;
                mod_timer(&console_timer, jiffies + vesa_off_interval);
        }
-
-       if (vesa_blank_mode)
-               vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
 }
 EXPORT_SYMBOL(do_blank_screen);
 
index 385e52930c02353a396df4009f0a421f2cecf1d5..4b4d7db1ff7bc94dacbdea588904b3a31f084aef 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/ktime.h>
 #include <linux/init.h>
 #include <asm/atomic.h>
 
@@ -56,7 +57,7 @@ void proc_fork_connector(struct task_struct *task)
        msg = (struct cn_msg*)buffer;
        ev = (struct proc_event*)msg->data;
        get_seq(&msg->seq, &ev->cpu);
-       getnstimestamp(&ev->timestamp);
+       ktime_get_ts(&ev->timestamp); /* get high res monotonic timestamp */
        ev->what = PROC_EVENT_FORK;
        ev->event_data.fork.parent_pid = task->real_parent->pid;
        ev->event_data.fork.parent_tgid = task->real_parent->tgid;
@@ -82,7 +83,7 @@ void proc_exec_connector(struct task_struct *task)
        msg = (struct cn_msg*)buffer;
        ev = (struct proc_event*)msg->data;
        get_seq(&msg->seq, &ev->cpu);
-       getnstimestamp(&ev->timestamp);
+       ktime_get_ts(&ev->timestamp);
        ev->what = PROC_EVENT_EXEC;
        ev->event_data.exec.process_pid = task->pid;
        ev->event_data.exec.process_tgid = task->tgid;
@@ -116,7 +117,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
        } else
                return;
        get_seq(&msg->seq, &ev->cpu);
-       getnstimestamp(&ev->timestamp);
+       ktime_get_ts(&ev->timestamp);
 
        memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
        msg->ack = 0; /* not used */
@@ -136,7 +137,7 @@ void proc_exit_connector(struct task_struct *task)
        msg = (struct cn_msg*)buffer;
        ev = (struct proc_event*)msg->data;
        get_seq(&msg->seq, &ev->cpu);
-       getnstimestamp(&ev->timestamp);
+       ktime_get_ts(&ev->timestamp);
        ev->what = PROC_EVENT_EXIT;
        ev->event_data.exit.process_pid = task->pid;
        ev->event_data.exit.process_tgid = task->tgid;
@@ -169,7 +170,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
        msg = (struct cn_msg*)buffer;
        ev = (struct proc_event*)msg->data;
        msg->seq = rcvd_seq;
-       getnstimestamp(&ev->timestamp);
+       ktime_get_ts(&ev->timestamp);
        ev->cpu = -1;
        ev->what = PROC_EVENT_NONE;
        ev->event_data.ack.err = err;
index 211641a5439844c0750c1fa1454c91f57e747f61..fe06ebb0e5bfdd012227f264c636178d30ed8569 100644 (file)
@@ -39,7 +39,7 @@
 
 #define PDC202_DEBUG_CABLE     0
 
-const static char *pdc_quirk_drives[] = {
+static const char *pdc_quirk_drives[] = {
        "QUANTUM FIREBALLlct08 08",
        "QUANTUM FIREBALLP KA6.4",
        "QUANTUM FIREBALLP KA9.1",
index 86fb1e0286d38b704cd8f8ebf327c4aeb3673e11..c85b87cb59d11763100d0f74630a2f30b7bc6dc3 100644 (file)
@@ -439,7 +439,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
        hwif->speedproc = &via_set_drive;
 
 
-#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_PPC32)
+#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
        if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) {
                hwif->irq = hwif->channel ? 15 : 14;
        }
index 75897509c4017c3a2f8175b79181cfae4c87bab8..17390d762cf70b7af4281e4deaccd62591afaf2e 100644 (file)
@@ -80,7 +80,6 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
-#include <linux/ioctl32.h>
 #include <linux/compat.h>
 #include <linux/cdev.h>
 #include <asm/uaccess.h>
index 196db74392726e6645a33fae7c23962bc1736f7e..efeaa944bd0a9ba3bd8e413f1f9fca6e569a39b2 100644 (file)
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/string.h>
-#include <linux/ioctl32.h>
 #include <linux/compat.h>
 #include <linux/cdev.h>
 
index 608479b2df1405ee87567765992bef1f15a4faf8..39fb88309e8e804cfeabe00e7f90b249fa2e0e32 100644 (file)
@@ -48,7 +48,6 @@
 #include <linux/vmalloc.h>
 #include <linux/timex.h>
 #include <linux/mm.h>
-#include <linux/ioctl32.h>
 #include <linux/compat.h>
 #include <linux/cdev.h>
 
index 1bd88fca05425a9d6ddfb9f52c36d296f832fad2..54a680cc704d29bebdf3135f75d02c2069f2f1cf 100644 (file)
@@ -96,6 +96,7 @@ static int serport_ldisc_open(struct tty_struct *tty)
        init_waitqueue_head(&serport->wait);
 
        tty->disc_data = serport;
+       tty->receive_room = 256;
        set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 
        return 0;
@@ -139,17 +140,6 @@ out:
        spin_unlock_irqrestore(&serport->lock, flags);
 }
 
-/*
- * serport_ldisc_room() reports how much room we do have for receiving data.
- * Although we in fact have infinite room, we need to specify some value
- * here, and 256 seems to be reasonable.
- */
-
-static int serport_ldisc_room(struct tty_struct *tty)
-{
-       return 256;
-}
-
 /*
  * serport_ldisc_read() just waits indefinitely if everything goes well.
  * However, when the serio driver closes the serio port, it finishes,
@@ -237,7 +227,6 @@ static struct tty_ldisc serport_ldisc = {
        .read =         serport_ldisc_read,
        .ioctl =        serport_ldisc_ioctl,
        .receive_buf =  serport_ldisc_receive,
-       .receive_room = serport_ldisc_room,
        .write_wakeup = serport_ldisc_write_wakeup
 };
 
index 11ae0fddea04bd87bda30e034a67dc8a03978406..623adbb0d13abe8098912f0203c9218211967019 100644 (file)
@@ -463,8 +463,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
 #endif
                goto bad;
        }
-       if (ld->receive_room &&
-           ld->receive_room(mp->tty) < datalen) {
+       if (mp->tty->receive_room < datalen) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
                printk(KERN_DEBUG "capi: no room in tty\n");
 #endif
index 4643df097bfebe62d80358c18ba7f87f6ee8ff6c..22759c01746af5d71a1c016d79716d4ec3406c91 100644 (file)
@@ -857,6 +857,118 @@ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_que
        return count;
 }
 
+/*
+ * isdn_readbchan_tty() tries to get data from the read-queue.
+ * It MUST be called with interrupts off.
+ *
+ * Be aware that this is not an atomic operation when sleep != 0, even though
+ * interrupts are turned off! Well, like that we are currently only called
+ * on behalf of a read system call on raw device files (which are documented
+ * to be dangerous and for for debugging purpose only). The inode semaphore
+ * takes care that this is not called for the same minor device number while
+ * we are sleeping, but access is not serialized against simultaneous read()
+ * from the corresponding ttyI device. Can other ugly events, like changes
+ * of the mapping (di,ch)<->minor, happen during the sleep? --he
+ */
+int
+isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
+{
+       int count;
+       int count_pull;
+       int count_put;
+       int dflag;
+       struct sk_buff *skb;
+       char last = 0;
+       int len;
+
+       if (!dev->drv[di])
+               return 0;
+       if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
+                       return 0;
+
+       len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]);
+       if(len == 0)
+               return len;
+
+       count = 0;
+       while (len) {
+               if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
+                       break;
+#ifdef CONFIG_ISDN_AUDIO
+               if (ISDN_AUDIO_SKB_LOCK(skb))
+                       break;
+               ISDN_AUDIO_SKB_LOCK(skb) = 1;
+               if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) {
+                       char *p = skb->data;
+                       unsigned long DLEmask = (1 << channel);
+
+                       dflag = 0;
+                       count_pull = count_put = 0;
+                       while ((count_pull < skb->len) && (len > 0)) {
+                               len--;
+                               if (dev->drv[di]->DLEflag & DLEmask) {
+                                       last = DLE;
+                                       dev->drv[di]->DLEflag &= ~DLEmask;
+                               } else {
+                                       last = *p;
+                                       if (last == DLE) {
+                                               dev->drv[di]->DLEflag |= DLEmask;
+                                               (ISDN_AUDIO_SKB_DLECOUNT(skb))--;
+                                       }
+                                       p++;
+                                       count_pull++;
+                               }
+                               count_put++;
+                       }
+                       if (count_pull >= skb->len)
+                               dflag = 1;
+               } else {
+#endif
+                       /* No DLE's in buff, so simply copy it */
+                       dflag = 1;
+                       if ((count_pull = skb->len) > len) {
+                               count_pull = len;
+                               dflag = 0;
+                       }
+                       count_put = count_pull;
+                       if(count_put > 1)
+                               tty_insert_flip_string(tty, skb->data, count_put - 1);
+                       last = skb->data[count_put] - 1;
+                       len -= count_put;
+#ifdef CONFIG_ISDN_AUDIO
+               }
+#endif
+               count += count_put;
+               if (dflag) {
+                       /* We got all the data in this buff.
+                        * Now we can dequeue it.
+                        */
+                       if(cisco_hack)
+                               tty_insert_flip_char(tty, last, 0xFF);
+                       else
+                               tty_insert_flip_char(tty, last, TTY_NORMAL);
+#ifdef CONFIG_ISDN_AUDIO
+                       ISDN_AUDIO_SKB_LOCK(skb) = 0;
+#endif
+                       skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]);
+                       dev_kfree_skb(skb);
+               } else {
+                       tty_insert_flip_char(tty, last, TTY_NORMAL);
+                       /* Not yet emptied this buff, so it
+                        * must stay in the queue, for further calls
+                        * but we pull off the data we got until now.
+                        */
+                       skb_pull(skb, count_pull);
+#ifdef CONFIG_ISDN_AUDIO
+                       ISDN_AUDIO_SKB_LOCK(skb) = 0;
+#endif
+               }
+               dev->drv[di]->rcvcount[channel] -= count_put;
+       }
+       return count;
+}
+
+
 static __inline int
 isdn_minor2drv(int minor)
 {
index e27e9c3a81ed6622641bf853d9e99411c6759183..082735dbb4129a9eebef1706a38979c364ddf59f 100644 (file)
@@ -37,6 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff);
 extern void isdn_unexclusive_channel(int di, int ch);
 extern int  isdn_getnum(char **);
 extern int  isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *);
+extern int  isdn_readbchan_tty(int, int, struct tty_struct *, int);
 extern int  isdn_get_free_channel(int, int, int, int, int, char *);
 extern int  isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
 extern int  register_isdn(isdn_if * i);
index 8c404b4e2482d4769a263514faa9b68eb05ca4e6..f190a99604f0c3821c9e97e865819e4d89dfc144 100644 (file)
@@ -64,37 +64,42 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb)
        int c;
        int len;
        struct tty_struct *tty;
+       char last;
 
        if (info->online) {
                if ((tty = info->tty)) {
                        if (info->mcr & UART_MCR_RTS) {
-                               c = TTY_FLIPBUF_SIZE - tty->flip.count;
                                len = skb->len
 #ifdef CONFIG_ISDN_AUDIO
                                        + ISDN_AUDIO_SKB_DLECOUNT(skb)
 #endif
                                        ;
+
+                               c = tty_buffer_request_room(tty, len);
                                if (c >= len) {
 #ifdef CONFIG_ISDN_AUDIO
-                                       if (ISDN_AUDIO_SKB_DLECOUNT(skb))
-                                               while (skb->len--) {
+                                       if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
+                                               int l = skb->len;
+                                               unsigned char *dp = skb->data;
+                                               while (--l) {
                                                        if (*skb->data == DLE)
                                                                tty_insert_flip_char(tty, DLE, 0);
-                                                       tty_insert_flip_char(tty, *skb->data++, 0);
+                                                       tty_insert_flip_char(tty, *dp++, 0);
+                                               }
+                                               last = *dp;
                                        } else {
 #endif
-                                               memcpy(tty->flip.char_buf_ptr,
-                                                      skb->data, len);
-                                               tty->flip.count += len;
-                                               tty->flip.char_buf_ptr += len;
-                                               memset(tty->flip.flag_buf_ptr, 0, len);
-                                               tty->flip.flag_buf_ptr += len;
+                                               if(len > 1)
+                                                       tty_insert_flip_string(tty, skb->data, len - 1);
+                                               last = skb->data[len - 1];
 #ifdef CONFIG_ISDN_AUDIO
                                        }
 #endif
                                        if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
-                                               tty->flip.flag_buf_ptr[len - 1] = 0xff;
-                                       schedule_delayed_work(&tty->flip.work, 1);
+                                               tty_insert_flip_char(tty, last, 0xFF);
+                                       else
+                                               tty_insert_flip_char(tty, last, TTY_NORMAL);
+                                       tty_flip_buffer_push(tty);
                                        kfree_skb(skb);
                                        return 1;
                                }
@@ -114,7 +119,6 @@ isdn_tty_readmodem(void)
        int resched = 0;
        int midx;
        int i;
-       int c;
        int r;
        struct tty_struct *tty;
        modem_info *info;
@@ -131,20 +135,13 @@ isdn_tty_readmodem(void)
 #endif
                                if ((tty = info->tty)) {
                                        if (info->mcr & UART_MCR_RTS) {
-                                               c = TTY_FLIPBUF_SIZE - tty->flip.count;
-                                               if (c > 0) {
-                                                       r = isdn_readbchan(info->isdn_driver, info->isdn_channel,
-                                                                          tty->flip.char_buf_ptr,
-                                                                          tty->flip.flag_buf_ptr, c, NULL);
-                                                       /* CISCO AsyncPPP Hack */
-                                                       if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
-                                                               memset(tty->flip.flag_buf_ptr, 0, r);
-                                                       tty->flip.count += r;
-                                                       tty->flip.flag_buf_ptr += r;
-                                                       tty->flip.char_buf_ptr += r;
-                                                       if (r)
-                                                               schedule_delayed_work(&tty->flip.work, 1);
-                                               }
+                                               /* CISCO AsyncPPP Hack */
+                                               if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
+                                                       r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
+                                               else
+                                                       r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
+                                               if (r)
+                                                       tty_flip_buffer_push(tty);
                                        } else
                                                r = 1;
                                } else
@@ -249,7 +246,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
        }
 #endif
 #endif
-       /* Try to deliver directly via tty-flip-buf if queue is empty */
+       /* Try to deliver directly via tty-buf if queue is empty */
        spin_lock_irqsave(&info->readlock, flags);
        if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
                if (isdn_tty_try_read(info, skb)) {
@@ -534,7 +531,7 @@ isdn_tty_senddown(modem_info * info)
 /* The next routine is called once from within timer-interrupt
  * triggered within isdn_tty_modem_ncarrier(). It calls
  * isdn_tty_modem_result() to stuff a "NO CARRIER" Message
- * into the tty's flip-buffer.
+ * into the tty's buffer.
  */
 static void
 isdn_tty_modem_do_ncarrier(unsigned long data)
@@ -2347,6 +2344,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
        u_long flags;
        struct sk_buff *skb = NULL;
        char *sp = NULL;
+       int l = strlen(msg);
 
        if (!msg) {
                printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n");
@@ -2359,16 +2357,16 @@ isdn_tty_at_cout(char *msg, modem_info * info)
                return;
        }
 
-       /* use queue instead of direct flip, if online and */
-       /* data is in queue or flip buffer is full */
-       if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) ||
-           (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) {
-               skb = alloc_skb(strlen(msg), GFP_ATOMIC);
+       /* use queue instead of direct, if online and */
+       /* data is in queue or buffer is full */
+       if ((info->online && tty_buffer_request_room(tty, l) < l) ||
+           (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) {
+               skb = alloc_skb(l, GFP_ATOMIC);
                if (!skb) {
                        spin_unlock_irqrestore(&info->readlock, flags);
                        return;
                }
-               sp = skb_put(skb, strlen(msg));
+               sp = skb_put(skb, l);
 #ifdef CONFIG_ISDN_AUDIO
                ISDN_AUDIO_SKB_DLECOUNT(skb) = 0;
                ISDN_AUDIO_SKB_LOCK(skb) = 0;
@@ -2392,9 +2390,8 @@ isdn_tty_at_cout(char *msg, modem_info * info)
                if (skb) {
                        *sp++ = c;
                } else {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+                       if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0)
                                break;
-                       tty_insert_flip_char(tty, c, 0);
                }
        }
        if (skb) {
@@ -2402,12 +2399,12 @@ isdn_tty_at_cout(char *msg, modem_info * info)
                dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len;
                spin_unlock_irqrestore(&info->readlock, flags);
                /* Schedule dequeuing */
-               if ((dev->modempoll) && (info->rcvsched))
+               if (dev->modempoll && info->rcvsched)
                        isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
 
        } else {
                spin_unlock_irqrestore(&info->readlock, flags);
-               schedule_delayed_work(&tty->flip.work, 1);
+               tty_flip_buffer_push(tty);
        }
 }
 
index e6aa309a66d7b7a4d71525702706f1bae99a8461..96f7af4ae400ad4eaa2dd7d47d9e1a1ce1ca3efa 100644 (file)
@@ -303,6 +303,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
 static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 {
        multipath_conf_t *conf = mddev->private;
+       struct request_queue *q;
        int found = 0;
        int path;
        struct multipath_info *p;
@@ -311,8 +312,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
 
        for (path=0; path<mddev->raid_disks; path++) 
                if ((p=conf->multipaths+path)->rdev == NULL) {
-                       blk_queue_stack_limits(mddev->queue,
-                                              rdev->bdev->bd_disk->queue);
+                       q = rdev->bdev->bd_disk->queue;
+                       blk_queue_stack_limits(mddev->queue, q);
 
                /* as we don't honour merge_bvec_fn, we must never risk
                 * violating it, so limit ->max_sector to one PAGE, as
@@ -320,7 +321,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
                 * (Note: it is very unlikely that a device with
                 * merge_bvec_fn will be involved in multipath.)
                 */
-                       if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
+                       if (q->merge_bvec_fn &&
                            mddev->queue->max_sectors > (PAGE_SIZE>>9))
                                blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
index c30effdf711feb6ba8e5457b5c908ca472abeb52..36c9f5bf8cdd09a0931b863aa770e7454276fdf2 100644 (file)
 #include <linux/pci.h>
 #include <linux/videodev.h>
 
-#define DRIVER_VERSION "0.04"
+#define DRIVER_VERSION "0.05"
 
-#define PCI_VENDOR_ESS                  0x125D
-#define PCI_DEVICE_ID_ESS_ESS1968       0x1968          /* Maestro 2    */
-#define PCI_DEVICE_ID_ESS_ESS1978       0x1978          /* Maestro 2E   */
-
-#define GPIO_DATA       0x60   /* port offset from ESS_IO_BASE */
+#define GPIO_DATA      0x60   /* port offset from ESS_IO_BASE */
 
 #define IO_MASK                4      /* mask      register offset from GPIO_DATA
                                bits 1=unmask write to given bit */
 #define IO_DIR         8      /* direction register offset from GPIO_DATA
                                bits 0/1=read/write direction */
 
-#define GPIO6           0x0040 /* mask bits for GPIO lines */
-#define GPIO7           0x0080
-#define GPIO8           0x0100
-#define GPIO9           0x0200
+#define GPIO6          0x0040 /* mask bits for GPIO lines */
+#define GPIO7          0x0080
+#define GPIO8          0x0100
+#define GPIO9          0x0200
 
-#define STR_DATA        GPIO6  /* radio TEA5757 pins and GPIO bits */
-#define STR_CLK         GPIO7
-#define STR_WREN        GPIO8
-#define STR_MOST        GPIO9
+#define STR_DATA       GPIO6  /* radio TEA5757 pins and GPIO bits */
+#define STR_CLK                GPIO7
+#define STR_WREN       GPIO8
+#define STR_MOST       GPIO9
 
 #define FREQ_LO                 50*16000
 #define FREQ_HI                150*16000
 
-#define FREQ_IF         171200 /* 10.7*16000   */
-#define FREQ_STEP       200    /* 12.5*16      */
+#define FREQ_IF                171200 /* 10.7*16000   */
+#define FREQ_STEP      200    /* 12.5*16      */
 
 #define FREQ2BITS(x)   ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
                        /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
@@ -65,7 +61,27 @@ static int radio_nr = -1;
 module_param(radio_nr, int, 0);
 
 static int radio_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg);
+       unsigned int cmd, unsigned long arg);
+static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void maestro_remove(struct pci_dev *pdev);
+
+static struct pci_device_id maestro_r_pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
+               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+               .class_mask = 0xffff00 },
+       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
+               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+               .class_mask = 0xffff00 },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
+
+static struct pci_driver maestro_r_driver = {
+       .name           = "maestro_radio",
+       .id_table       = maestro_r_pci_tbl,
+       .probe          = maestro_probe,
+       .remove         = __devexit_p(maestro_remove),
+};
 
 static struct file_operations maestro_fops = {
        .owner          = THIS_MODULE,
@@ -76,29 +92,27 @@ static struct file_operations maestro_fops = {
        .llseek         = no_llseek,
 };
 
-static struct video_device maestro_radio=
-{
-       .owner          = THIS_MODULE,
+static struct video_device maestro_radio = {
        .name           = "Maestro radio",
        .type           = VID_TYPE_TUNER,
        .hardware       = VID_HARDWARE_SF16MI,
-       .fops           = &maestro_fops,
+       .fops           = &maestro_fops,
 };
 
-static struct radio_device
-{
-       __u16   io,     /* base of Maestro card radio io (GPIO_DATA)*/
+struct radio_device {
+       u16     io,     /* base of Maestro card radio io (GPIO_DATA)*/
                muted,  /* VIDEO_AUDIO_MUTE */
                stereo, /* VIDEO_TUNER_STEREO_ON */     
                tuned;  /* signal strength (0 or 0xffff) */
-       struct  semaphore lock;
-} radio_unit = {0, 0, 0, 0, };
+       struct  semaphore lock;
+};
 
-static __u32 radio_bits_get(struct radio_device *dev)
+static u32 radio_bits_get(struct radio_device *dev)
 {
-       register __u16 io=dev->io, l, rdata;
-       register __u32 data=0;
-       __u16 omask;
+       register u16 io=dev->io, l, rdata;
+       register u32 data=0;
+       u16 omask;
+
        omask = inw(io + IO_MASK);
        outw(~(STR_CLK | STR_WREN), io + IO_MASK);
        outw(0, io);
@@ -121,17 +135,21 @@ static __u32 radio_bits_get(struct radio_device *dev)
                                data++;
                udelay(2);
        }
+
        if(dev->muted)
                outw(STR_WREN, io);
+
        udelay(4);
        outw(omask, io + IO_MASK);
+
        return data & 0x3ffe;
 }
 
-static void radio_bits_set(struct radio_device *dev, __u32 data)
+static void radio_bits_set(struct radio_device *dev, u32 data)
 {
-       register __u16 io=dev->io, l, bits;
-       __u16 omask, odir;
+       register u16 io=dev->io, l, bits;
+       u16 omask, odir;
+
        omask = inw(io + IO_MASK);
        odir  = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
        outw(odir | STR_DATA, io + IO_DIR);
@@ -147,8 +165,10 @@ static void radio_bits_set(struct radio_device *dev, __u32 data)
                outw(bits, io);                 /* LO level */
                udelay(4);
        }
+
        if(!dev->muted)
                outw(0, io);
+
        udelay(4);
        outw(omask, io + IO_MASK);
        outw(odir, io + IO_DIR);
@@ -156,141 +176,103 @@ static void radio_bits_set(struct radio_device *dev, __u32 data)
 }
 
 static inline int radio_function(struct inode *inode, struct file *file,
-                                unsigned int cmd, void *arg)
+       unsigned int cmd, void *arg)
 {
        struct video_device *dev = video_devdata(file);
-       struct radio_device *card=dev->priv;
-       
-       switch(cmd) {
-               case VIDIOCGCAP: {
-                       struct video_capability *v = arg;
-                       memset(v,0,sizeof(*v));
-                       strcpy(v->name, "Maestro radio");
-                       v->type=VID_TYPE_TUNER;
-                       v->channels=v->audios=1;
-                       return 0;
-               }
-               case VIDIOCGTUNER: {
-                       struct video_tuner *v = arg;
-                       if(v->tuner)
-                               return -EINVAL;
-                       (void)radio_bits_get(card);
-                       v->flags = VIDEO_TUNER_LOW | card->stereo;
-                       v->signal = card->tuned;
-                       strcpy(v->name, "FM");
-                       v->rangelow = FREQ_LO;
-                       v->rangehigh = FREQ_HI;
-                       v->mode = VIDEO_MODE_AUTO;
-                       return 0;
-               }
-               case VIDIOCSTUNER: {
-                       struct video_tuner *v = arg;
-                       if(v->tuner!=0)
-                               return -EINVAL;
-                       return 0;
-               }
-               case VIDIOCGFREQ: {
-                       unsigned long *freq = arg;
-                       *freq = BITS2FREQ(radio_bits_get(card));
-                       return 0;
-               }
-               case VIDIOCSFREQ: {
-                       unsigned long *freq = arg;
-                       if (*freq<FREQ_LO || *freq>FREQ_HI )
-                               return -EINVAL;
-                       radio_bits_set(card, FREQ2BITS(*freq));
+       struct radio_device *card = video_get_drvdata(dev);
+
+       switch (cmd) {
+       case VIDIOCGCAP: {
+               struct video_capability *v = arg;
+               memset(v, 0, sizeof(*v));
+               strcpy(v->name, "Maestro radio");
+               v->type = VID_TYPE_TUNER;
+               v->channels = v->audios = 1;
+               return 0;
+       } case VIDIOCGTUNER: {
+               struct video_tuner *v = arg;
+               if (v->tuner)
+                       return -EINVAL;
+               (void)radio_bits_get(card);
+               v->flags = VIDEO_TUNER_LOW | card->stereo;
+               v->signal = card->tuned;
+               strcpy(v->name, "FM");
+               v->rangelow = FREQ_LO;
+               v->rangehigh = FREQ_HI;
+               v->mode = VIDEO_MODE_AUTO;
+               return 0;
+       } case VIDIOCSTUNER: {
+               struct video_tuner *v = arg;
+               if (v->tuner != 0)
+                       return -EINVAL;
+               return 0;
+       } case VIDIOCGFREQ: {
+               unsigned long *freq = arg;
+               *freq = BITS2FREQ(radio_bits_get(card));
+               return 0;
+       } case VIDIOCSFREQ: {
+               unsigned long *freq = arg;
+               if (*freq < FREQ_LO || *freq > FREQ_HI)
+                       return -EINVAL;
+               radio_bits_set(card, FREQ2BITS(*freq));
+               return 0;
+       } case VIDIOCGAUDIO: {
+               struct video_audio *v = arg;
+               memset(v, 0, sizeof(*v));
+               strcpy(v->name, "Radio");
+               v->flags = VIDEO_AUDIO_MUTABLE | card->muted;
+               v->mode = VIDEO_SOUND_STEREO;
+               return 0;
+       } case VIDIOCSAUDIO: {
+               struct video_audio *v = arg;
+               if (v->audio)
+                       return -EINVAL;
+               {
+                       register u16 io = card->io;
+                       register u16 omask = inw(io + IO_MASK);
+                       outw(~STR_WREN, io + IO_MASK);
+                       outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) ?
+                               STR_WREN : 0, io);
+                       udelay(4);
+                       outw(omask, io + IO_MASK);
+                       msleep(125);
                        return 0;
                }
-               case VIDIOCGAUDIO: {    
-                       struct video_audio *v = arg;
-                       memset(v,0,sizeof(*v));
-                       strcpy(v->name, "Radio");
-                       v->flags=VIDEO_AUDIO_MUTABLE | card->muted;
-                       v->mode=VIDEO_SOUND_STEREO;
-                       return 0;               
-               }
-               case VIDIOCSAUDIO: {
-                       struct video_audio *v = arg;
-                       if(v->audio)
-                               return -EINVAL;
-                       {
-                               register __u16 io=card->io;
-                               register __u16 omask = inw(io + IO_MASK);
-                               outw(~STR_WREN, io + IO_MASK);
-                               outw((card->muted = v->flags & VIDEO_AUDIO_MUTE)
-                                    ? STR_WREN : 0, io);
-                               udelay(4);
-                               outw(omask, io + IO_MASK);
-                               msleep(125);
-                               return 0;
-                       }
-               }
-               case VIDIOCGUNIT: {
-                       struct video_unit *v = arg;
-                       v->video=VIDEO_NO_UNIT;
-                       v->vbi=VIDEO_NO_UNIT;
-                       v->radio=dev->minor;
-                       v->audio=0;
-                       v->teletext=VIDEO_NO_UNIT;
-                       return 0;               
-               }
-               default: return -ENOIOCTLCMD;
+       } case VIDIOCGUNIT: {
+               struct video_unit *v = arg;
+               v->video = VIDEO_NO_UNIT;
+               v->vbi = VIDEO_NO_UNIT;
+               v->radio = dev->minor;
+               v->audio = 0;
+               v->teletext = VIDEO_NO_UNIT;
+               return 0;
+       } default:
+               return -ENOIOCTLCMD;
        }
 }
 
 static int radio_ioctl(struct inode *inode, struct file *file,
-                      unsigned int cmd, unsigned long arg)
+       unsigned int cmd, unsigned long arg)
 {
        struct video_device *dev = video_devdata(file);
-       struct radio_device *card=dev->priv;
+       struct radio_device *card = video_get_drvdata(dev);
        int ret;
 
        down(&card->lock);
        ret = video_usercopy(inode, file, cmd, arg, radio_function);
        up(&card->lock);
-       return ret;
-}
 
-static __u16 radio_install(struct pci_dev *pcidev);
-
-MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
-
-static void __exit maestro_radio_exit(void)
-{
-       video_unregister_device(&maestro_radio);
+       return ret;
 }
 
-static int __init maestro_radio_init(void)
+static u16 __devinit radio_power_on(struct radio_device *dev)
 {
-       register __u16 found=0;
-       struct pci_dev *pcidev = NULL;
-       while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS, 
-                                                 PCI_DEVICE_ID_ESS_ESS1968,
-                                                 pcidev)))
-               found |= radio_install(pcidev);
-       while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
-                                                 PCI_DEVICE_ID_ESS_ESS1978, 
-                                                 pcidev)))
-               found |= radio_install(pcidev);
-       if(!found) {
-               printk(KERN_INFO "radio-maestro: no devices found.\n");
-               return -ENODEV;
-       }
-       return 0;
-}
+       register u16 io = dev->io;
+       register u32 ofreq;
+       u16 omask, odir;
 
-module_init(maestro_radio_init);
-module_exit(maestro_radio_exit);
-
-static inline __u16 radio_power_on(struct radio_device *dev)
-{
-       register __u16 io=dev->io;
-       register __u32 ofreq;
-       __u16 omask, odir;
        omask = inw(io + IO_MASK);
-       odir  = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+       odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
        outw(odir & ~STR_WREN, io + IO_DIR);
        dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE;
        outw(odir, io + IO_DIR);
@@ -299,35 +281,101 @@ static inline __u16 radio_power_on(struct radio_device *dev)
        udelay(16);
        outw(omask, io + IO_MASK);
        ofreq = radio_bits_get(dev);
-       if((ofreq<FREQ2BITS(FREQ_LO)) || (ofreq>FREQ2BITS(FREQ_HI)))
+
+       if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
                ofreq = FREQ2BITS(FREQ_LO);
        radio_bits_set(dev, ofreq);
+
        return (ofreq == radio_bits_get(dev));
 }
 
-static __u16 radio_install(struct pci_dev *pcidev)
+static int __devinit maestro_probe(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
 {
-       if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-               return 0;
-       
-       radio_unit.io = pcidev->resource[0].start + GPIO_DATA;
-       maestro_radio.priv = &radio_unit;
-       init_MUTEX(&radio_unit.lock);
-       
-       if(radio_power_on(&radio_unit)) {
-               if(video_register_device(&maestro_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
-                       printk("radio-maestro: can't register device!");
-                       return 0;
-               }
-               printk(KERN_INFO "radio-maestro: version "
-                      DRIVER_VERSION 
-                      " time " 
-                      __TIME__ "  "
-                      __DATE__
-                      "\n");
-               printk(KERN_INFO "radio-maestro: radio chip initialized\n");
-               return 1;
-       } else
-               return 0;   
+       struct radio_device *radio_unit;
+       struct video_device *maestro_radio_inst;
+       int retval;
+
+       retval = pci_enable_device(pdev);
+       if (retval) {
+               dev_err(&pdev->dev, "enabling pci device failed!\n");
+               goto err;
+       }
+
+       retval = -ENOMEM;
+
+       radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
+       if (radio_unit == NULL) {
+               dev_err(&pdev->dev, "not enough memory\n");
+               goto err;
+       }
+
+       radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
+       init_MUTEX(&radio_unit->lock);
+
+       maestro_radio_inst = video_device_alloc();
+       if (maestro_radio_inst == NULL) {
+               dev_err(&pdev->dev, "not enough memory\n");
+               goto errfr;
+       }
+
+       memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
+       video_set_drvdata(maestro_radio_inst, radio_unit);
+       pci_set_drvdata(pdev, maestro_radio_inst);
+
+       retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO,
+               radio_nr);
+       if (retval) {
+               printk(KERN_ERR "can't register video device!\n");
+               goto errfr1;
+       }
+
+       if (!radio_power_on(radio_unit)) {
+               retval = -EIO;
+               goto errunr;
+       }
+
+       dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ "  "
+                __DATE__ "\n");
+       dev_info(&pdev->dev, "radio chip initialized\n");
+
+       return 0;
+errunr:
+       video_unregister_device(maestro_radio_inst);
+errfr1:
+       kfree(maestro_radio_inst);
+errfr:
+       kfree(radio_unit);
+err:
+       return retval;
+
+}
+
+static void __devexit maestro_remove(struct pci_dev *pdev)
+{
+       struct video_device *vdev = pci_get_drvdata(pdev);
+
+       video_unregister_device(vdev);
 }
 
+static int __init maestro_radio_init(void)
+{
+       int retval = pci_register_driver(&maestro_r_driver);
+
+       if (retval)
+               printk(KERN_ERR "error during registration pci driver\n");
+
+       return retval;
+}
+
+static void __exit maestro_radio_exit(void)
+{
+       pci_unregister_driver(&maestro_r_driver);
+}
+
+module_init(maestro_radio_init);
+module_exit(maestro_radio_exit);
+
+MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
index 959d2c5951b8beb072b4c00b0fbc34ac836c6acc..7c340240a50e94f1258fd3c2b5d19c3f079740d0 100644 (file)
@@ -2585,8 +2585,6 @@ static struct miscdevice mptctl_miscdev = {
 
 #ifdef CONFIG_COMPAT
 
-#include <linux/ioctl32.h>
-
 static int
 compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
                        unsigned long arg)
index 9c5945d6df882eecbe1bce15f6b62e0f22a4fbd4..201e1362da14748a493dea2acd719c72fd750e83 100644 (file)
@@ -43,7 +43,7 @@ static int nand_width = 1; /* default x8*/
 /*
  * Define partitions for flash device
  */
-const static struct mtd_partition partition_info[] = {
+static const struct mtd_partition partition_info[] = {
        {
                .name   = "NAND FS 0",
                .offset = 0,
index 3a5841c9d950edd00f05b21767fa15bf23edec03..4129c03dfd9090b4962212e5a03207f598da1f8e 100644 (file)
@@ -96,7 +96,7 @@ static struct mtd_info *rtc_from4_mtd = NULL;
  */
 static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
 
-const static struct mtd_partition partition_info[] = {
+static const struct mtd_partition partition_info[] = {
         {
                 .name   = "Renesas flash partition 1",
                 .offset = 0,
index 32541cbb0103284669c6fc91c62aa58501132e2f..9cf1ce718ec150c2bb47b89f1efb3d36b7fad850 100644 (file)
@@ -67,7 +67,7 @@ module_param(spia_peddr, int, 0);
 /*
  * Define partitions for flash device
  */
-const static struct mtd_partition partition_info[] = {
+static const struct mtd_partition partition_info[] = {
        {
                .name   = "SPIA flash partition 1",
                .offset = 0,
index d2102a27d3071492dd4c3cd686e286c6dffaf8f4..adfba44dac5a009a484894fc3d36c71ae9dd6502 100644 (file)
@@ -505,7 +505,7 @@ enum chip_flags {
 #define HW_REVID_MASK  HW_REVID(1, 1, 1, 1, 1, 1, 1)
 
 /* directly indexed by chip_t, above */
-const static struct {
+static const struct {
        const char *name;
        u32 version; /* from RTL8139C/RTL8139D docs */
        u32 flags;
index 90999867a32c56fd6819acee43ef1934984b061d..102c1f0b90dac7a941902322dbc33cfd295c1799 100644 (file)
@@ -456,11 +456,6 @@ out:
 
 /* ----------------------------------------------------------------------- */
 
-static int sixpack_receive_room(struct tty_struct *tty)
-{
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -671,6 +666,7 @@ static int sixpack_open(struct tty_struct *tty)
 
        /* Done.  We have linked the TTY line to a channel. */
        tty->disc_data = sp;
+       tty->receive_room = 65536;
 
        /* Now we're ready to register. */
        if (register_netdev(dev))
@@ -802,7 +798,6 @@ static struct tty_ldisc sp_ldisc = {
        .close          = sixpack_close,
        .ioctl          = sixpack_ioctl,
        .receive_buf    = sixpack_receive_buf,
-       .receive_room   = sixpack_receive_room,
        .write_wakeup   = sixpack_write_wakeup,
 };
 
index f4424cf886c563a3a5c4955336f7c3c2c8f52f04..dc5e9d59deede332e84caa2241c22c255cf2b7a3 100644 (file)
@@ -753,6 +753,7 @@ static int mkiss_open(struct tty_struct *tty)
 
        ax->tty = tty;
        tty->disc_data = ax;
+       tty->receive_room = 65535;
 
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
@@ -940,11 +941,6 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
                tty->driver->unthrottle(tty);
 }
 
-static int mkiss_receive_room(struct tty_struct *tty)
-{
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Called by the driver when there's room for more data.  If we have
  * more packets to send, we send them here.
@@ -983,7 +979,6 @@ static struct tty_ldisc ax_ldisc = {
        .close          = mkiss_close,
        .ioctl          = mkiss_ioctl,
        .receive_buf    = mkiss_receive_buf,
-       .receive_room   = mkiss_receive_room,
        .write_wakeup   = mkiss_write_wakeup
 };
 
index 3d016a498e1d928418c1bb02855e37e50cbba49d..6070195b87bd711645840acc3536241277e69341 100644 (file)
@@ -284,19 +284,6 @@ static void irport_start(struct irport_cb *self)
        outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
 }
 
-/*
- * Function irport_probe (void)
- *
- *    Start IO port 
- *
- */
-int irport_probe(int iobase)
-{
-       IRDA_DEBUG(4, "%s(), iobase=%#x\n", __FUNCTION__, iobase);
-
-       return 0;
-}
-
 /*
  * Function irport_get_fcr (speed)
  *
@@ -382,7 +369,7 @@ static void irport_change_speed(void *priv, __u32 speed)
  *    we cannot use schedule_timeout() when we are in interrupt context
  *
  */
-int __irport_change_speed(struct irda_task *task)
+static int __irport_change_speed(struct irda_task *task)
 {
        struct irport_cb *self;
        __u32 speed = (__u32) task->param;
index b8d112348ba40a01f00811402a8d7a525931b313..101750bf210f1c2381bf6f5b54df9850eacefe7d 100644 (file)
@@ -288,22 +288,6 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
        sirdev_receive(dev, cp, count);
 }
 
-/*
- * Function irtty_receive_room (tty)
- *
- *    Used by the TTY to find out how much data we can receive at a time
- * 
-*/
-static int irtty_receive_room(struct tty_struct *tty) 
-{
-       struct sirtty_cb *priv = tty->disc_data;
-
-       IRDA_ASSERT(priv != NULL, return 0;);
-       IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return 0;);
-
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Function irtty_write_wakeup (tty)
  *
@@ -534,6 +518,7 @@ static int irtty_open(struct tty_struct *tty)
 
        dev->priv = priv;
        tty->disc_data = priv;
+       tty->receive_room = 65536;
 
        up(&irtty_sem);
 
@@ -605,7 +590,6 @@ static struct tty_ldisc irda_ldisc = {
        .ioctl          = irtty_ioctl,
        .poll           = NULL,
        .receive_buf    = irtty_receive_buf,
-       .receive_room   = irtty_receive_room,
        .write_wakeup   = irtty_write_wakeup,
        .owner          = THIS_MODULE,
 };
index a1ac4bd1696eae7d909729aaca014edbf919cedf..a7bb54df75a89e3bb5d2b0bf9fa348ae3a352f34 100644 (file)
@@ -415,7 +415,7 @@ typedef enum {
 
 
 /* directly indexed by chip_t, above */
-const static struct {
+static const struct {
        const char *name;
        u8 version; /* from RTL8139C docs */
        u32 RxConfigMask; /* should clear the bits supported by this chip */
index 400f652282d76f4fe7c0d003ca0ec1f22d3da27f..aa6540b39466d464f0c70f497469b90820458ac8 100644 (file)
@@ -189,7 +189,7 @@ ppp_asynctty_open(struct tty_struct *tty)
                goto out_free;
 
        tty->disc_data = ap;
-
+       tty->receive_room = 65536;
        return 0;
 
  out_free:
@@ -343,12 +343,6 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
        return 0;
 }
 
-static int
-ppp_asynctty_room(struct tty_struct *tty)
-{
-       return 65535;
-}
-
 /*
  * This can now be called from hard interrupt level as well
  * as soft interrupt level or mainline.
@@ -398,7 +392,6 @@ static struct tty_ldisc ppp_ldisc = {
        .write  = ppp_asynctty_write,
        .ioctl  = ppp_asynctty_ioctl,
        .poll   = ppp_asynctty_poll,
-       .receive_room = ppp_asynctty_room,
        .receive_buf = ppp_asynctty_receive,
        .write_wakeup = ppp_asynctty_wakeup,
 };
index 4d51c0c8023d160b5d82c3d09e37e440fe0e16bf..33cb8254e79dac71b1d7e9d676f3c70b8a00f97e 100644 (file)
@@ -237,7 +237,7 @@ ppp_sync_open(struct tty_struct *tty)
                goto out_free;
 
        tty->disc_data = ap;
-
+       tty->receive_room = 65536;
        return 0;
 
  out_free:
@@ -384,12 +384,6 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
        return 0;
 }
 
-static int
-ppp_sync_room(struct tty_struct *tty)
-{
-       return 65535;
-}
-
 /*
  * This can now be called from hard interrupt level as well
  * as soft interrupt level or mainline.
@@ -439,7 +433,6 @@ static struct tty_ldisc ppp_sync_ldisc = {
        .write  = ppp_sync_write,
        .ioctl  = ppp_synctty_ioctl,
        .poll   = ppp_sync_poll,
-       .receive_room = ppp_sync_room,
        .receive_buf = ppp_sync_receive,
        .write_wakeup = ppp_sync_wakeup,
 };
index 14a76f7cf900fa86493ba745bf9fe1bbabb23c6c..2e1bed153c39c00827e2ef986bca3db3129c807d 100644 (file)
@@ -170,7 +170,7 @@ enum phy_version {
 #define _R(NAME,MAC,MASK) \
        { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
 
-const static struct {
+static const struct {
        const char *name;
        u8 mac_version;
        u32 RxConfigMask;       /* Clears the bits supported by this chip */
index 478791e09bf772f416f1f3dd97873e937ebeb182..b420182eec4be6441c4b31b75f7763bb50610593 100644 (file)
@@ -329,7 +329,7 @@ static struct mii_chip_info {
        { NULL, }
 };
 
-const static struct {
+static const struct {
        const char *name;
 } sis_chip_info[] = {
        { "SiS 190 PCI Fast Ethernet adapter" },
index 404ea4297e32796e28a8fbb8a5e5a49fc203e6fc..b2e18d28850d6b45e27916553408ff5b23c580a9 100644 (file)
@@ -651,11 +651,6 @@ static void sl_setup(struct net_device *dev)
  ******************************************/
 
 
-static int slip_receive_room(struct tty_struct *tty)
-{
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -869,10 +864,6 @@ static int slip_open(struct tty_struct *tty)
        sl->line = tty_devnum(tty);
        sl->pid = current->pid;
        
-       /* FIXME: already done before we were called - seems this can go */
-       if (tty->driver->flush_buffer)
-               tty->driver->flush_buffer(tty);
-               
        if (!test_bit(SLF_INUSE, &sl->flags)) {
                /* Perform the low-level SLIP initialization. */
                if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0)
@@ -897,6 +888,7 @@ static int slip_open(struct tty_struct *tty)
 
        /* Done.  We have linked the TTY line to a channel. */
        rtnl_unlock();
+       tty->receive_room = 65536;      /* We don't flow control */
        return sl->dev->base_addr;
 
 err_free_bufs:
@@ -1329,7 +1321,6 @@ static struct tty_ldisc   sl_ldisc = {
        .close          = slip_close,
        .ioctl          = slip_ioctl,
        .receive_buf    = slip_receive_buf,
-       .receive_room   = slip_receive_room,
        .write_wakeup   = slip_write_wakeup,
 };
 
index 52f26b9c69d245e9aa090e374964f04d5895f7b0..931cbdf6d79165648e0a383235af4221c71581c6 100644 (file)
@@ -689,7 +689,7 @@ static void cpc_tty_rx_work(void * data)
                                        }
                                }       
                                cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
-                               kfree(buf);
+                               kfree((void *)buf);
                                buf = cpc_tty->buf_rx.first;
                                flg_rx = 1;
                        }
index bdf672c48182a148dd5420f4aee505f340d2114e..9c3ccc6691435b7b5ac96a266566fa8d6f93e8bb 100644 (file)
@@ -515,11 +515,6 @@ static int x25_asy_close(struct net_device *dev)
        return 0;
 }
 
-static int x25_asy_receive_room(struct tty_struct *tty)
-{
-       return 65536;  /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
@@ -573,6 +568,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
 
        sl->tty = tty;
        tty->disc_data = sl;
+       tty->receive_room = 65536;
        if (tty->driver->flush_buffer)  {
                tty->driver->flush_buffer(tty);
        }
@@ -779,7 +775,6 @@ static struct tty_ldisc x25_ldisc = {
        .close          = x25_asy_close_tty,
        .ioctl          = x25_asy_ioctl,
        .receive_buf    = x25_asy_receive_buf,
-       .receive_room   = x25_asy_receive_room,
        .write_wakeup   = x25_asy_write_wakeup,
 };
 
index d25264ba0c0e12000780a223c426002dd49d0ea6..18baacfc5a2cc3cb04cbf2e336ac79550624a714 100644 (file)
@@ -1675,11 +1675,6 @@ static int strip_rebuild_header(struct sk_buff *skb)
 /************************************************************************/
 /* Receiving routines                                                  */
 
-static int strip_receive_room(struct tty_struct *tty)
-{
-       return 0x10000;         /* We can handle an infinite amount of data. :-) */
-}
-
 /*
  * This function parses the response to the ATS300? command,
  * extracting the radio version and serial number.
@@ -2424,7 +2419,7 @@ static struct net_device_stats *strip_get_stats(struct net_device *dev)
 /*
  * Here's the order things happen:
  * When the user runs "slattach -p strip ..."
- *  1. The TTY module calls strip_open
+ *  1. The TTY module calls strip_open;;
  *  2. strip_open calls strip_alloc
  *  3.                  strip_alloc calls register_netdev
  *  4.                  register_netdev calls strip_dev_init
@@ -2652,6 +2647,8 @@ static int strip_open(struct tty_struct *tty)
 
        strip_info->tty = tty;
        tty->disc_data = strip_info;
+       tty->receive_room = 65536;
+
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
 
@@ -2762,7 +2759,6 @@ static struct tty_ldisc strip_ldisc = {
        .close = strip_close,
        .ioctl = strip_ioctl,
        .receive_buf = strip_receive_buf,
-       .receive_room = strip_receive_room,
        .write_wakeup = strip_write_some_more,
 };
 
index 2472fa1a1be14c72a6e324ec28e42070ea4fb253..9c25654b1e75f5da0eabebc7c6f203b4e49691a8 100644 (file)
@@ -1751,6 +1751,7 @@ dasd_device_operations = {
        .open           = dasd_open,
        .release        = dasd_release,
        .ioctl          = dasd_ioctl,
+       .compat_ioctl   = dasd_compat_ioctl,
        .getgeo         = dasd_getgeo,
 };
 
index 2fb05c4a528cb47c64ebbce23e068bfdf5ada51a..e4b401500b019e61b03ec8e5cf30694a8d42923f 100644 (file)
@@ -527,6 +527,7 @@ void dasd_ioctl_exit(void);
 int  dasd_ioctl_no_register(struct module *, int, dasd_ioctl_fn_t);
 int  dasd_ioctl_no_unregister(struct module *, int, dasd_ioctl_fn_t);
 int  dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+long dasd_compat_ioctl(struct file *, unsigned int, unsigned long);
 
 /* externals in dasd_proc.c */
 int dasd_proc_init(void);
index 8e4dcd58599eb7ba4db58377865fa0eef8684296..9396fcacb8f8900338b7479daa807735dea6246b 100644 (file)
@@ -118,6 +118,18 @@ dasd_ioctl(struct inode *inp, struct file *filp,
        return -EINVAL;
 }
 
+long
+dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int rval;
+
+       lock_kernel();
+       rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+       unlock_kernel();
+
+       return (rval == -EINVAL) ? -ENOIOCTLCMD : rval;
+}
+
 static int
 dasd_ioctl_api_version(struct block_device *bdev, int no, long args)
 {
index 75419cf9d35351b0b2c2a3cb1c3296046d1d7e51..1f060914cfa429275333377b21dcae3d27937135 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/vt_kern.h>
 #include <linux/init.h>
 #include <linux/console.h>
@@ -432,8 +433,6 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                                if (count > slen)
                                        count = slen;
                        } else
-                       if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
-                               count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
                        EBCASC(raw->inbuf, count);
                        cchar = ctrlchar_handle(raw->inbuf, count, tty);
                        switch (cchar & CTRLCHAR_MASK) {
@@ -441,28 +440,20 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                                break;
 
                        case CTRLCHAR_CTRL:
-                               tty->flip.count++;
-                               *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-                               *tty->flip.char_buf_ptr++ = cchar;
+                               tty_insert_flip_char(tty, cchar, TTY_NORMAL);
                                tty_flip_buffer_push(raw->tty);
                                break;
 
                        case CTRLCHAR_NONE:
-                               memcpy(tty->flip.char_buf_ptr,
-                                      raw->inbuf, count);
                                if (count < 2 ||
-                                   (strncmp(raw->inbuf+count-2, "^n", 2) &&
-                                   strncmp(raw->inbuf+count-2, "\252n", 2)) ) {
-                                       /* don't add the auto \n */
-                                       tty->flip.char_buf_ptr[count] = '\n';
-                                       memset(tty->flip.flag_buf_ptr,
-                                              TTY_NORMAL, count + 1);
+                                   (strncmp(raw->inbuf+count-2, "\252n", 2) &&
+                                    strncmp(raw->inbuf+count-2, "^n", 2)) ) {
+                                       /* add the auto \n */
+                                       raw->inbuf[count] = '\n';
                                        count++;
                                } else
-                                       count-=2;
-                               tty->flip.char_buf_ptr += count;
-                               tty->flip.flag_buf_ptr += count;
-                               tty->flip.count += count;
+                                       count -= 2;
+                               tty_insert_flip_string(tty, raw->inbuf, count);
                                tty_flip_buffer_push(raw->tty);
                                break;
                        }
index 735a7fcdeff51dd1616a0481a0ebaa68b57217bc..5f6fa4c67843e07f1e9b3f28281026792e093353 100644 (file)
@@ -319,9 +319,8 @@ fs3270_write(struct file *filp, const char *data, size_t count, loff_t *off)
 /*
  * process ioctl commands for the tube driver
  */
-static int
-fs3270_ioctl(struct inode *inode, struct file *filp,
-            unsigned int cmd, unsigned long arg)
+static long
+fs3270_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct fs3270 *fp;
        struct raw3270_iocb iocb;
@@ -331,6 +330,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp,
        if (!fp)
                return -ENODEV;
        rc = 0;
+       lock_kernel();
        switch (cmd) {
        case TUBICMD:
                fp->read_command = arg;
@@ -356,6 +356,7 @@ fs3270_ioctl(struct inode *inode, struct file *filp,
                        rc = -EFAULT;
                break;
        }
+       unlock_kernel();
        return rc;
 }
 
@@ -491,12 +492,13 @@ fs3270_close(struct inode *inode, struct file *filp)
 }
 
 static struct file_operations fs3270_fops = {
-       .owner   = THIS_MODULE,         /* owner */
-       .read    = fs3270_read,         /* read */
-       .write   = fs3270_write,        /* write */
-       .ioctl   = fs3270_ioctl,        /* ioctl */
-       .open    = fs3270_open,         /* open */
-       .release = fs3270_close,        /* release */
+       .owner           = THIS_MODULE,         /* owner */
+       .read            = fs3270_read,         /* read */
+       .write           = fs3270_write,        /* write */
+       .unlocked_ioctl  = fs3270_ioctl,        /* ioctl */
+       .compat_ioctl    = fs3270_ioctl,        /* ioctl */
+       .open           = fs3270_open,          /* open */
+       .release        = fs3270_close,         /* release */
 };
 
 /*
index a20d7c89341dabf3d36d07024eb7d78e8b656cd4..6cbf067f1a8f8b4720686d22f3c15a3fea94f848 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kmod.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
@@ -496,25 +497,19 @@ sclp_tty_input(unsigned char* buf, unsigned int count)
        case CTRLCHAR_SYSRQ:
                break;
        case CTRLCHAR_CTRL:
-               sclp_tty->flip.count++;
-               *sclp_tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-               *sclp_tty->flip.char_buf_ptr++ = cchar;
+               tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL);
                tty_flip_buffer_push(sclp_tty);
                break;
        case CTRLCHAR_NONE:
                /* send (normal) input to line discipline */
-               memcpy(sclp_tty->flip.char_buf_ptr, buf, count);
                if (count < 2 ||
-                   (strncmp ((const char *) buf + count - 2, "^n", 2) &&
-                    strncmp ((const char *) buf + count - 2, "\0252n", 2))) {
-                       sclp_tty->flip.char_buf_ptr[count] = '\n';
-                       count++;
+                   (strncmp((const char *) buf + count - 2, "^n", 2) &&
+                    strncmp((const char *) buf + count - 2, "\252n", 2))) {
+                       /* add the auto \n */
+                       tty_insert_flip_string(sclp_tty, buf, count);
+                       tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL);
                } else
-                       count -= 2;
-               memset(sclp_tty->flip.flag_buf_ptr, TTY_NORMAL, count);
-               sclp_tty->flip.char_buf_ptr += count;
-               sclp_tty->flip.flag_buf_ptr += count;
-               sclp_tty->flip.count += count;
+                       tty_insert_flip_string(sclp_tty, buf, count - 2);
                tty_flip_buffer_push(sclp_tty);
                break;
        }
index 06bd85824d7bcf822ddd91b614f49ee70e5d0247..9e02625c82cfc2853b3fa5be86fb883ddb82c8c2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -482,16 +483,7 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
                /* Send input to line discipline */
                buffer++;
                count--;
-               /* Prevent buffer overrun by discarding input. Note that
-                * because buffer_push works asynchronously, we cannot wait
-                * for the buffer to be emptied. */
-               if (count + sclp_vt220_tty->flip.count > TTY_FLIPBUF_SIZE)
-                       count = TTY_FLIPBUF_SIZE - sclp_vt220_tty->flip.count;
-               memcpy(sclp_vt220_tty->flip.char_buf_ptr, buffer, count);
-               memset(sclp_vt220_tty->flip.flag_buf_ptr, TTY_NORMAL, count);
-               sclp_vt220_tty->flip.char_buf_ptr += count;
-               sclp_vt220_tty->flip.flag_buf_ptr += count;
-               sclp_vt220_tty->flip.count += count;
+               tty_insert_flip_string(sclp_vt220_tty, buffer, count);
                tty_flip_buffer_push(sclp_vt220_tty);
                break;
        }
index 86262a13f7c60d0d4040492bea19295155cb360a..5ce7ca38ace0d54db704191c1a295ce3e81514e5 100644 (file)
@@ -37,6 +37,8 @@ static int tapechar_open(struct inode *,struct file *);
 static int tapechar_release(struct inode *,struct file *);
 static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
                          unsigned long);
+static long tapechar_compat_ioctl(struct file *, unsigned int,
+                         unsigned long);
 
 static struct file_operations tape_fops =
 {
@@ -44,6 +46,7 @@ static struct file_operations tape_fops =
        .read = tapechar_read,
        .write = tapechar_write,
        .ioctl = tapechar_ioctl,
+       .compat_ioctl = tapechar_compat_ioctl,
        .open = tapechar_open,
        .release = tapechar_release,
 };
@@ -463,6 +466,23 @@ tapechar_ioctl(struct inode *inp, struct file *filp,
        return device->discipline->ioctl_fn(device, no, data);
 }
 
+static long
+tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data)
+{
+       struct tape_device *device = filp->private_data;
+       int rval = -ENOIOCTLCMD;
+
+       if (device->discipline->ioctl_fn) {
+               lock_kernel();
+               rval = device->discipline->ioctl_fn(device, no, data);
+               unlock_kernel();
+               if (rval == -EINVAL)
+                       rval = -ENOIOCTLCMD;
+       }
+
+       return rval;
+}
+
 /*
  * Initialize character device frontend.
  */
index 135ae04e6e75d8f3e283dc09f74e93597b330da0..2f54d033d7cf8925502ba7a3f09c81c7599777d9 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/delay.h>       // mdelay
 #include <linux/init.h>
 #include <linux/interrupt.h>   // for tasklets
-#include <linux/ioctl32.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 968f2c113efeefa2bf627f39bc711c32e4dbfff3..93d1725eb79b988db630d07da7cb9e605eee5c2c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial_reg.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -101,25 +102,17 @@ static spinlock_t ctc_tty_lock;
 static int
 ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
 {
-       int c;
        int len;
        struct tty_struct *tty;
 
        DBF_TEXT(trace, 5, __FUNCTION__);
        if ((tty = info->tty)) {
                if (info->mcr & UART_MCR_RTS) {
-                       c = TTY_FLIPBUF_SIZE - tty->flip.count;
                        len = skb->len;
-                       if (c >= len) {
-                               memcpy(tty->flip.char_buf_ptr, skb->data, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.count += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.flag_buf_ptr += len;
-                               tty_flip_buffer_push(tty);
-                               kfree_skb(skb);
-                               return 1;
-                       }
+                       tty_insert_flip_string(tty, skb->data, len);
+                       tty_flip_buffer_push(tty);
+                       kfree_skb(skb);
+                       return 1;
                }
        }
        return 0;
@@ -138,19 +131,12 @@ ctc_tty_readmodem(ctc_tty_info *info)
        DBF_TEXT(trace, 5, __FUNCTION__);
        if ((tty = info->tty)) {
                if (info->mcr & UART_MCR_RTS) {
-                       int c = TTY_FLIPBUF_SIZE - tty->flip.count;
                        struct sk_buff *skb;
                        
-                       if ((c > 0) && (skb = skb_dequeue(&info->rx_queue))) {
+                       if ((skb = skb_dequeue(&info->rx_queue))) {
                                int len = skb->len;
-                               if (len > c)
-                                       len = c;
-                               memcpy(tty->flip.char_buf_ptr, skb->data, len);
+                               tty_insert_flip_string(tty, skb->data, len);
                                skb_pull(skb, len);
-                               memset(tty->flip.flag_buf_ptr, 0, len);
-                               tty->flip.count += len;
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.flag_buf_ptr += len;
                                tty_flip_buffer_push(tty);
                                if (skb->len > 0)
                                        skb_queue_head(&info->rx_queue, skb);
index 3cb68af904561ddeafac166a2b10fb053b3b8398..9b9062f02462534a216e2099ae7fa93d5ea0d3c0 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/syscalls.h>
-#include <linux/ioctl32.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
 #include <asm/semaphore.h>
index 0920220f331394a147337c1a14ba0007535961aa..4299fabca5547469dc9fe59aee9f04c4c48fd529 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/interrupt.h>
 #include <linux/blkdev.h>
 #include <linux/completion.h>
-#include <linux/ioctl32.h>
 #include <linux/compat.h>
 #include <linux/chio.h>                        /* here are all the ioctls */
 
index eb8c390a0fa3f67f25de61a1c1c1c8b13237f763..3d9e67d6849d6431c0c6842d1e0f2c70b32be964 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/list.h>
-#include <linux/ioctl32.h>
 
 #include "mbox_defs.h"
 #include "megaraid_ioctl.h"
index b5cf39468d18bf66fdee5ff2fe87601698f0152d..221999bcf8fe3809b943e4f11c53ba4529810f52 100644 (file)
@@ -94,15 +94,6 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r
 
        status = *CSR_UARTFLG;
        while (!(status & 0x10) && max_count--) {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
-
                ch = *CSR_UARTDR;
                flag = TTY_NORMAL;
                port->icount.rx++;
index 67e9afa000c135bdcd8b621dc39677e36e575945..4dd5c3f98167a143b2e29ea17b991540e618843d 100644 (file)
@@ -294,7 +294,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
 {
        struct tty_struct *tty = info->tty;
        m68328_uart *uart = &uart_addr[info->line];
-       unsigned char ch;
+       unsigned char ch, flag;
 
        /*
         * This do { } while() loop will get ALL chars out of Rx FIFO 
@@ -332,26 +332,24 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
                /*
                 * Make sure that we do not overflow the buffer
                 */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+               if (tty_request_buffer_room(tty, 1) == 0) {
                        schedule_work(&tty->flip.work);
                        return;
                }
 
+               flag = TTY_NORMAL;
+
                if(rx & URX_PARITY_ERROR) {
-                       *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+                       flag = TTY_PARITY;
                        status_handle(info, rx);
                } else if(rx & URX_OVRUN) {
-                       *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+                       flag = TTY_OVERRUN;
                        status_handle(info, rx);
                } else if(rx & URX_FRAME_ERROR) {
-                       *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+                       flag = TTY_FRAME;
                        status_handle(info, rx);
-               } else {
-                       *tty->flip.flag_buf_ptr++ = 0; /* XXX */
                }
-                *tty->flip.char_buf_ptr++ = ch;
-               tty->flip.count++;
-
+               tty_insert_flip_char(tty, ch, flag);
 #ifndef CONFIG_XCOPILOT_BUGS
        } while((rx = uart->urx.w) & URX_DATA_READY);
 #endif
index 170c9d2a749cc1ce8f2c3820dd603435bbcbf7ad..60f5a5dc17f1cf1cf4e10c38127690872d1df1bc 100644 (file)
@@ -394,7 +394,7 @@ static void rs_360_start(struct tty_struct *tty)
 static _INLINE_ void receive_chars(ser_info_t *info)
 {
        struct tty_struct *tty = info->tty;
-       unsigned char ch, *cp;
+       unsigned char ch, flag, *cp;
        /*int   ignored = 0;*/
        int     i;
        ushort  status;
@@ -438,24 +438,15 @@ static _INLINE_ void receive_chars(ser_info_t *info)
                cp = (char *)bdp->buf;
                status = bdp->status;
 
-               /* Check to see if there is room in the tty buffer for
-                * the characters in our BD buffer.  If not, we exit
-                * now, leaving the BD with the characters.  We'll pick
-                * them up again on the next receive interrupt (which could
-                * be a timeout).
-                */
-               if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE)
-                       break;
-
                while (i-- > 0) {
                        ch = *cp++;
-                       *tty->flip.char_buf_ptr = ch;
                        icount->rx++;
 
 #ifdef SERIAL_DEBUG_INTR
                        printk("DR%02x:%02x...", ch, status);
 #endif
-                       *tty->flip.flag_buf_ptr = 0;
+                       flag = TTY_NORMAL;
+
                        if (status & (BD_SC_BR | BD_SC_FR |
                                       BD_SC_PR | BD_SC_OV)) {
                                /*
@@ -490,30 +481,18 @@ static _INLINE_ void receive_chars(ser_info_t *info)
                                        if (info->flags & ASYNC_SAK)
                                                do_SAK(tty);
                                } else if (status & BD_SC_PR)
-                                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                else if (status & BD_SC_FR)
-                                       *tty->flip.flag_buf_ptr = TTY_FRAME;
-                               if (status & BD_SC_OV) {
-                                       /*
-                                        * Overrun is special, since it's
-                                        * reported immediately, and doesn't
-                                        * affect the current character
-                                        */
-                                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                               tty->flip.count++;
-                                               tty->flip.flag_buf_ptr++;
-                                               tty->flip.char_buf_ptr++;
-                                               *tty->flip.flag_buf_ptr =
-                                                               TTY_OVERRUN;
-                                       }
-                               }
+                                       flag = TTY_FRAME;
                        }
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               break;
-
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flag);
+                       if (status & BD_SC_OV)
+                               /*
+                                * Overrun is special, since it's
+                                * reported immediately, and doesn't
+                                * affect the current character
+                                */
+                               tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
 
                /* This BD is ready to be used again.  Clear status.
@@ -541,12 +520,7 @@ static _INLINE_ void receive_break(ser_info_t *info)
        /* Check to see if there is room in the tty buffer for
         * the break.  If not, we exit now, losing the break.  FIXME
         */
-       if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE)
-               return;
-       *(tty->flip.flag_buf_ptr++) = TTY_BREAK;
-       *(tty->flip.char_buf_ptr++) = 0;
-       tty->flip.count++;
-
+       tty_insert_flip_char(tty, 0, TTY_BREAK);
        schedule_work(&tty->flip.work);
 }
 
index e8454611cb652b48151daceebf41c1cc800d53bf..54e5cc0dd5f8c323134531f6671c559754d10b5d 100644 (file)
@@ -1142,19 +1142,6 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
        char flag;
 
        do {
-               /* The following is not allowed by the tty layer and
-                  unsafe. It should be fixed ASAP */
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       if (tty->low_latency) {
-                               spin_unlock(&up->port.lock);
-                               tty_flip_buffer_push(tty);
-                               spin_lock(&up->port.lock);
-                       }
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
                ch = serial_inp(up, UART_RX);
                flag = TTY_NORMAL;
                up->port.icount.rx++;
index 1bae26a8a503c74e17de2543542d8541027f4008..698cb76819d95d1a3851f6fc70613de38421931d 100644 (file)
@@ -860,7 +860,7 @@ config SERIAL_VR41XX_CONSOLE
 
 config SERIAL_JSM
         tristate "Digi International NEO PCI Support"
-       depends on PCI
+       depends on PCI && BROKEN
         select SERIAL_CORE
         help
           This is a driver for Digi International's Neo series
index 48f6e872314bb2a1acf12efc7b003739707d2c9e..3490022e9fdc7e923d265eb06e635f4dc32e5026 100644 (file)
@@ -154,15 +154,6 @@ pl010_rx_chars(struct uart_port *port)
 
        status = UART_GET_FR(port);
        while (UART_RX_DATA(status) && max_count--) {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts.
-                        */
-               }
-
                ch = UART_GET_CHAR(port);
                flag = TTY_NORMAL;
 
index 129670556162a460f4f5f1b494446cb14db93887..034a029e356edfe3e8f48d1749b03450e2196c26 100644 (file)
@@ -120,15 +120,6 @@ pl011_rx_chars(struct uart_amba_port *uap)
 
        status = readw(uap->port.membase + UART01x_FR);
        while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
-
                ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
                flag = TTY_NORMAL;
                uap->port.icount.rx++;
index a274ebf256a190fb6de6e94883a8807bbf31f752..ceb5d7f37bbd26920b27813b29daf812ec33926e 100644 (file)
@@ -241,18 +241,12 @@ static _INLINE_ void
 receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
 {
        struct tty_struct *tty = up->port.info->tty;
-       unsigned char ch;
+       unsigned char ch, flag;
        int max_count = 256;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return; // if TTY_DONT_FLIP is set
-               }
                ch = serial_inp(up, UART_RX);
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
 
                if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
@@ -292,30 +286,23 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
 #endif
                        if (*status & UART_LSR_BI) {
                                DEBUG_INTR("handling break....");
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (*status & UART_LSR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (*status & UART_LSR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((*status & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((*status & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
+               if ((*status & up->port.ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+               if (*status & UART_LSR_OE)
                        /*
                         * Overrun is special, since it's reported
                         * immediately, and doesn't affect the current
                         * character.
                         */
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
        ignore_char:
                *status = serial_inp(up, UART_LSR);
index 87ef368384fb31d9d055f169e1c1986e43db8659..8ef999481f9386fe351e77e0a7cd9b98d6250d73 100644 (file)
@@ -104,8 +104,6 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
        while (!(status & SYSFLG_URXFE)) {
                ch = clps_readl(UARTDR(port));
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       goto ignore_char;
                port->icount.rx++;
 
                flg = TTY_NORMAL;
index 4d8516d1bb71692d217e50ab5934c8862643b3ab..a64ba26a94e8b317a0e6ef1b31e778a892986231 100644 (file)
@@ -216,8 +216,6 @@ static inline void dz_receive_chars(struct dz_port *dport)
 
                if (!tty)
                        break;
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
 
                icount->rx++;
 
index eb31125c6a30f84de2416f80c939bc1eae412fc8..144a7a352b28c4fb2328a3b0857d90fc72da4e90 100644 (file)
@@ -729,19 +729,20 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
        unsigned short int status;
        struct uart_icount *icount;
        unsigned long offset;
+       unsigned char flag;
 
        trace(icom_port, "RCV_COMPLETE", 0);
        rcv_buff = icom_port->next_rcv;
 
        status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
        while (status & SA_FL_RCV_DONE) {
+               int first = -1;
 
                trace(icom_port, "FID_STATUS", status);
                count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
 
+                count = tty_buffer_request_room(tty, count);
                trace(icom_port, "RCV_COUNT", count);
-               if (count > (TTY_FLIPBUF_SIZE - tty->flip.count))
-                       count = TTY_FLIPBUF_SIZE - tty->flip.count;
 
                trace(icom_port, "REAL_COUNT", count);
 
@@ -749,15 +750,10 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
                        cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
                        icom_port->recv_buf_pci;
 
-               memcpy(tty->flip.char_buf_ptr,(unsigned char *)
-                      ((unsigned long)icom_port->recv_buf + offset), count);
-
+               /* Block copy all but the last byte as this may have status */
                if (count > 0) {
-                       tty->flip.count += count - 1;
-                       tty->flip.char_buf_ptr += count - 1;
-
-                       memset(tty->flip.flag_buf_ptr, 0, count);
-                       tty->flip.flag_buf_ptr += count - 1;
+                       first = icom_port->recv_buf[offset];
+                       tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
                }
 
                icount = &icom_port->uart_port.icount;
@@ -765,12 +761,14 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 
                /* Break detect logic */
                if ((status & SA_FLAGS_FRAME_ERROR)
-                   && (tty->flip.char_buf_ptr[0] == 0x00)) {
+                   && first == 0) {
                        status &= ~SA_FLAGS_FRAME_ERROR;
                        status |= SA_FLAGS_BREAK_DET;
                        trace(icom_port, "BREAK_DET", 0);
                }
 
+               flag = TTY_NORMAL;
+
                if (status &
                    (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
                     SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
@@ -797,33 +795,26 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
                        status &= icom_port->read_status_mask;
 
                        if (status & SA_FLAGS_BREAK_DET) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (status & SA_FLAGS_PARITY_ERROR) {
                                trace(icom_port, "PARITY_ERROR", 0);
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        } else if (status & SA_FLAGS_FRAME_ERROR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-
-                       if (status & SA_FLAGS_OVERRUN) {
-                               /*
-                                * Overrun is special, since it's
-                                * reported immediately, and doesn't
-                                * affect the current character
-                                */
-                               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-                                       tty->flip.count++;
-                                       tty->flip.flag_buf_ptr++;
-                                       tty->flip.char_buf_ptr++;
-                                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                               }
-                       }
+                               flag = TTY_FRAME;
+
                }
 
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
-               ignore_char:
-                       icom_port->statStg->rcv[rcv_buff].flags = 0;
+               tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
+
+               if (status & SA_FLAGS_OVERRUN)
+                       /*
+                        * Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ignore_char:
+               icom_port->statStg->rcv[rcv_buff].flags = 0;
                icom_port->statStg->rcv[rcv_buff].leLength = 0;
                icom_port->statStg->rcv[rcv_buff].WorkingLength =
                        (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
index 83c4c12165877c4e02b2449a63969dbdba05ab04..5c098be9346b35de2b8ed58b0b6648df8c7c160a 100644 (file)
@@ -256,9 +256,6 @@ static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs)
        error_return:
                tty_insert_flip_char(tty, rx, flg);
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       goto out;
-
        ignore_char:
                rx = URXD0((u32)sport->port.membase);
        } while(rx & URXD_CHARRDY);
index 771676abee60195dc07eeabe652719e9cbbc02c4..1d85533d46d2170caecdb44779fd06e4885e90a0 100644 (file)
@@ -2327,19 +2327,13 @@ static void receive_chars(struct uart_port *the_port)
        spin_lock_irqsave(&the_port->lock, pflags);
        tty = info->tty;
 
-       if (request_count > TTY_FLIPBUF_SIZE - tty->flip.count)
-               request_count = TTY_FLIPBUF_SIZE - tty->flip.count;
+       request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS - 2);
 
        if (request_count > 0) {
                icount = &the_port->icount;
                read_count = do_read(the_port, ch, request_count);
                if (read_count > 0) {
-                       flip = 1;
-                       memcpy(tty->flip.char_buf_ptr, ch, read_count);
-                       memset(tty->flip.flag_buf_ptr, TTY_NORMAL, read_count);
-                       tty->flip.char_buf_ptr += read_count;
-                       tty->flip.flag_buf_ptr += read_count;
-                       tty->flip.count += read_count;
+                       tty_insert_flip_string(tty, ch, read_count);
                        icount->rx += read_count;
                }
        }
index ef132349f310d8325122458bea12b52b039d696e..66f117d150650294db0c88fa04308e67e83e37e1 100644 (file)
@@ -259,13 +259,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
        struct tty_struct *tty = up->port.info->tty;    /* XXX info==NULL? */
 
        while (1) {
-               unsigned char ch, r1;
-
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return;         /* XXX Ignores SysRq when we need it most. Fix. */
-               }
+               unsigned char ch, r1, flag;
 
                r1 = read_zsreg(channel, R1);
                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
@@ -303,8 +297,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
                }
 
                /* A real serial line, record the character and status.  */
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
                if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
                        if (r1 & BRK_ABRT) {
@@ -321,28 +314,21 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
                                up->port.icount.overrun++;
                        r1 &= up->port.read_status_mask;
                        if (r1 & BRK_ABRT)
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        else if (r1 & PAR_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (r1 & CRC_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto next_char;
 
                if (up->port.ignore_status_mask == 0xff ||
-                   (r1 & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((r1 & Rx_OVR) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
+                   (r1 & up->port.ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+
+               if (r1 & Rx_OVR)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        next_char:
                ch = readb(&channel->control);
                ZSDELAY();
index b0ecc7537ce5de9bbd3328a8cd44dc53453690e7..b48066a64a7df59b88f29e83aa28a6570e78300b 100644 (file)
@@ -331,17 +331,12 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status,
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch;
+       unsigned char flag;
        int max_count = 256;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return; // if TTY_DONT_FLIP is set
-               }
                ch = sio_in(up, SIORXB);
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
 
                if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
@@ -380,30 +375,24 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status,
 
                        if (*status & UART_LSR_BI) {
                                DEBUG_INTR("handling break....");
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (*status & UART_LSR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (*status & UART_LSR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((*status & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((*status & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
+               if ((*status & up->port.ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+
+               if (*status & UART_LSR_OE) {
                        /*
                         * Overrun is special, since it's reported
                         * immediately, and doesn't affect the current
                         * character.
                         */
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
                }
        ignore_char:
                *status = serial_in(up, UART_LSR);
index 47f7404cb04542a80408254685b3d57451eaea06..f2a51e61eec7f55f9c8e6dbc431778655622b345 100644 (file)
@@ -313,7 +313,7 @@ static inline void receive_chars(struct mcf_serial *info)
 {
        volatile unsigned char  *uartp;
        struct tty_struct       *tty = info->tty;
-       unsigned char           status, ch;
+       unsigned char           status, ch, flag;
 
        if (!tty)
                return;
@@ -321,10 +321,6 @@ static inline void receive_chars(struct mcf_serial *info)
        uartp = info->addr;
 
        while ((status = uartp[MCFUART_USR]) & MCFUART_USR_RXREADY) {
-
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
-
                ch = uartp[MCFUART_URB];
                info->stats.rx++;
 
@@ -335,29 +331,24 @@ static inline void receive_chars(struct mcf_serial *info)
                }
 #endif
 
-               tty->flip.count++;
+               flag = TTY_NORMAL;
                if (status & MCFUART_USR_RXERR) {
                        uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR;
                        if (status & MCFUART_USR_RXBREAK) {
                                info->stats.rxbreak++;
-                               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (status & MCFUART_USR_RXPARITY) {
                                info->stats.rxparity++;
-                               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+                               flag = TTY_PARITY;
                        } else if (status & MCFUART_USR_RXOVERRUN) {
                                info->stats.rxoverrun++;
-                               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+                               flag = TTY_OVERRUN;
                        } else if (status & MCFUART_USR_RXFRAMING) {
                                info->stats.rxframing++;
-                               *tty->flip.flag_buf_ptr++ = TTY_FRAME;
-                       } else {
-                               /* This should never happen... */
-                               *tty->flip.flag_buf_ptr++ = 0;
+                               flag = TTY_FRAME;
                        }
-               } else {
-                       *tty->flip.flag_buf_ptr++ = 0;
                }
-               *tty->flip.char_buf_ptr++ = ch;
+               tty_insert_flip_char(tty, ch, flag);
        }
 
        schedule_work(&tty->flip.work);
index 1288d6203e948983bb36bdc13025375ad4b0787c..61dd17d7bacefd0a777ad107dd75869c71b3a319 100644 (file)
@@ -405,17 +405,13 @@ static inline int
 mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
 {
        struct tty_struct *tty = port->info->tty;
-       unsigned char ch;
+       unsigned char ch, flag;
        unsigned short status;
 
        /* While we can read, do so ! */
        while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) &
                MPC52xx_PSC_SR_RXRDY) {
 
-               /* If we are full, just stop reading */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       break;
-               
                /* Get the char */
                ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8);
 
@@ -428,45 +424,35 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
 #endif
 
                /* Store it */
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = 0;
+
+               flag = TTY_NORMAL;
                port->icount.rx++;
        
                if ( status & (MPC52xx_PSC_SR_PE |
                               MPC52xx_PSC_SR_FE |
-                              MPC52xx_PSC_SR_RB |
-                              MPC52xx_PSC_SR_OE) ) {
+                              MPC52xx_PSC_SR_RB) ) {
                        
                        if (status & MPC52xx_PSC_SR_RB) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                                uart_handle_break(port);
                        } else if (status & MPC52xx_PSC_SR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (status & MPC52xx_PSC_SR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
-                       if (status & MPC52xx_PSC_SR_OE) {
-                               /*
-                                * Overrun is special, since it's
-                                * reported immediately, and doesn't
-                                * affect the current character
-                                */
-                               if (tty->flip.count < (TTY_FLIPBUF_SIZE-1)) {
-                                       tty->flip.flag_buf_ptr++;
-                                       tty->flip.char_buf_ptr++;
-                                       tty->flip.count++;
-                               }
-                               *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       }
+                               flag = TTY_FRAME;
 
                        /* Clear error condition */
                        out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT);
 
                }
-
-               tty->flip.char_buf_ptr++;
-               tty->flip.flag_buf_ptr++;
-               tty->flip.count++;
-
+               tty_insert_flip_char(tty, ch, flag);
+               if (status & MPC52xx_PSC_SR_OE) {
+                       /*
+                        * Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               }
        }
 
        tty_flip_buffer_push(tty);
index 8f83e4007ecdf787fa9d890c37571afe41e2a43f..0ca83ac31d07a379eb95727ff8718392dd073c37 100644 (file)
@@ -769,12 +769,12 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
                bytes_in = be16_to_cpu(rxre->bytecnt);
 
                /* Following use of tty struct directly is deprecated */
-               if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){
+               if (unlikely(tty_buffer_request_room(tty, bytes_in) < bytes_in)) {
                        if (tty->low_latency)
                                tty_flip_buffer_push(tty);
                        /*
-                        * If this failed then we will throw awa the bytes
-                        * but mst do so to clear interrupts.
+                        * If this failed then we will throw away the bytes
+                        * but must do so to clear interrupts.
                         */
                }
 
index 7633132a10aab7d553f96f156d2af34affb5ceda..4e49168c31761a976588c35fee2a0d446644cd4a 100644 (file)
@@ -223,11 +223,6 @@ static void mux_read(struct uart_port *port)
                if (MUX_EOFIFO(data))
                        break;
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       continue;
-
-               *tty->flip.char_buf_ptr = data & 0xffu;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
                port->icount.rx++;
 
                if (MUX_BREAK(data)) {
@@ -239,9 +234,7 @@ static void mux_read(struct uart_port *port)
                if (uart_handle_sysrq_char(port, data & 0xffu, NULL))
                        continue;
 
-               tty->flip.flag_buf_ptr++;
-               tty->flip.char_buf_ptr++;
-               tty->flip.count++;
+               tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL);
        }
        
        if (start_count != port->icount.rx) {
index ea24129eb6b9f50911c960524af4650dc023202a..f330d6c0e0dfa0ca0878316a8c41337acc524c83 100644 (file)
@@ -210,10 +210,9 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                                            struct pt_regs *regs)
 {
        struct tty_struct *tty = NULL;
-       unsigned char ch, r1, drop, error;
+       unsigned char ch, r1, drop, error, flag;
        int loops = 0;
 
- retry:
        /* The interrupt can be enabled when the port isn't open, typically
         * that happens when using one port is open and the other closed (stale
         * interrupt) or when one port is used as a console.
@@ -246,20 +245,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                error = 0;
                drop = 0;
 
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       /* Have to drop the lock here */
-                       pmz_debug("pmz: flip overflow\n");
-                       spin_unlock(&uap->port.lock);
-                       tty->flip.work.func((void *)tty);
-                       spin_lock(&uap->port.lock);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               drop = 1;
-                       if (ZS_IS_ASLEEP(uap))
-                               return NULL;
-                       if (!ZS_IS_OPEN(uap))
-                               goto retry;
-               }
-
                r1 = read_zsreg(uap, R1);
                ch = read_zsdata(uap);
 
@@ -295,8 +280,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                if (drop)
                        goto next_char;
 
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                uap->port.icount.rx++;
 
                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) {
@@ -316,26 +300,19 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                                uap->port.icount.overrun++;
                        r1 &= uap->port.read_status_mask;
                        if (r1 & BRK_ABRT)
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        else if (r1 & PAR_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (r1 & CRC_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
 
                if (uap->port.ignore_status_mask == 0xff ||
                    (r1 & uap->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((r1 & Rx_OVR) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flag);
                }
+               if (r1 & Rx_OVR)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        next_char:
                /* We can get stuck in an infinite loop getting char 0 when the
                 * line is in a wrong HW state, we break that here.
index cc998b99a19f816e4aae59295ee7e3c40ce7c502..10535f00301f2e375c7a68ddf9a0d80662ffcb06 100644 (file)
@@ -107,14 +107,6 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs)
        int max_count = 256;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
                ch = serial_in(up, UART_RX);
                flag = TTY_NORMAL;
                up->port.icount.rx++;
index fe83ce6fef52a5ad3a64fb0df9154fe337c2d50e..eb4883efb7c65953534797dc913752d5dbcefddf 100644 (file)
@@ -323,16 +323,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
                if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
                        break;
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
-
                uerstat = rd_regl(port, S3C2410_UERSTAT);
                ch = rd_regb(port, S3C2410_URXH);
 
index 25a086458ab9bcb431d06eb6a7d92e71d3e7f405..1bd93168f504117440acf790f2e0bfbe384d6c5c 100644 (file)
@@ -201,8 +201,6 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
        while (status & UTSR1_TO_SM(UTSR1_RNE)) {
                ch = UART_GET_CHAR(sport);
 
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                       goto ignore_char;
                sport->port.icount.rx++;
 
                flg = TTY_NORMAL;
index d01dbe5da3b96d395caf8c83a9b923d1325833a8..d4a1f0e798c1bc461f737ec343e92d196608183f 100644 (file)
@@ -148,15 +148,6 @@ lh7a40xuart_rx_chars (struct uart_port* port)
        unsigned int data, flag;/* Received data and status */
 
        while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-                       /*
-                        * If this failed then we will throw away the
-                        * bytes but must do so to clear interrupts
-                        */
-               }
-
                data = UR (port, UART_R_DATA);
                flag = TTY_NORMAL;
                ++port->icount.rx;
index 995d9dd9ddd59c721b2ee85c708cb0c111f918f3..fdd1f1915a427d4104574b8d3deeebf6b8bffa56 100644 (file)
@@ -303,17 +303,6 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
        char flag;
 
        do {
-               /* The following is not allowed by the tty layer and
-                  unsafe. It should be fixed ASAP */
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       if (tty->low_latency) {
-                               spin_unlock(&up->port.lock);
-                               tty_flip_buffer_push(tty);
-                               spin_lock(&up->port.lock);
-                       }
-                       /* If this failed then we will throw away the
-                          bytes but must do so to clear interrupts */
-               }
                ch = sio_in(up, TXX9_SIRFIFO);
                flag = TTY_NORMAL;
                up->port.icount.rx++;
index 430754ebac8a69af20f716e82d2342cfb32ea32b..a9e070759628558c970487fa48209d40139aa4ef 100644 (file)
@@ -482,6 +482,7 @@ static inline void sci_receive_chars(struct uart_port *port,
        struct tty_struct *tty = port->info->tty;
        int i, count, copied = 0;
        unsigned short status;
+       unsigned char flag;
 
        status = sci_in(port, SCxSR);
        if (!(status & SCxSR_RDxF(port)))
@@ -499,8 +500,7 @@ static inline void sci_receive_chars(struct uart_port *port,
 #endif
 
                /* Don't copy more bytes than there is room for in the buffer */
-               if (tty->flip.count + count > TTY_FLIPBUF_SIZE)
-                       count = TTY_FLIPBUF_SIZE - tty->flip.count;
+               count = tty_buffer_request_room(tty, count);
 
                /* If for any reason we can't copy more data, we're done! */
                if (count == 0)
@@ -512,8 +512,7 @@ static inline void sci_receive_chars(struct uart_port *port,
                            || uart_handle_sysrq_char(port, c, regs)) {
                                count = 0;
                        } else {
-                           tty->flip.char_buf_ptr[0] = c;
-                           tty->flip.flag_buf_ptr[0] = TTY_NORMAL;
+                           tty_insert_flip_char(tty, c, TTY_NORMAL);
                        }
                } else {
                        for (i=0; i<count; i++) {
@@ -542,26 +541,21 @@ static inline void sci_receive_chars(struct uart_port *port,
                                }
 
                                /* Store data and status */
-                               tty->flip.char_buf_ptr[i] = c;
                                if (status&SCxSR_FER(port)) {
-                                       tty->flip.flag_buf_ptr[i] = TTY_FRAME;
+                                       flag = TTY_FRAME;
                                        pr_debug("sci: frame error\n");
                                } else if (status&SCxSR_PER(port)) {
-                                       tty->flip.flag_buf_ptr[i] = TTY_PARITY;
+                                       flag = TTY_PARITY;
                                        pr_debug("sci: parity error\n");
-                               } else {
-                                       tty->flip.flag_buf_ptr[i] = TTY_NORMAL;
-                               }
+                               } else
+                                       flag = TTY_NORMAL;
+                               tty_insert_flip_char(tty, c, flag);
                        }
                }
 
                sci_in(port, SCxSR); /* dummy read */
                sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 
-               /* Update the kernel buffer end */
-               tty->flip.count += count;
-               tty->flip.char_buf_ptr += count;
-               tty->flip.flag_buf_ptr += count;
                copied += count;
                port->icount.rx += count;
        }
@@ -608,48 +602,45 @@ static inline int sci_handle_errors(struct uart_port *port)
        unsigned short status = sci_in(port, SCxSR);
        struct tty_struct *tty = port->info->tty;
 
-       if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+       if (status&SCxSR_ORER(port)) {
                /* overrun error */
-               copied++;
-               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+               if(tty_insert_flip_char(tty, 0, TTY_OVERRUN))
+                       copied++;
                pr_debug("sci: overrun error\n");
        }
 
-       if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+       if (status&SCxSR_FER(port)) {
                if (sci_rxd_in(port) == 0) {
                        /* Notify of BREAK */
                        struct sci_port * sci_port = (struct sci_port *)port;
-                       if(!sci_port->break_flag) {
-                               sci_port->break_flag = 1;
-                               sci_schedule_break_timer((struct sci_port *)port);
+                       if(!sci_port->break_flag) {
+                               sci_port->break_flag = 1;
+                               sci_schedule_break_timer((struct sci_port *)port);
                                /* Do sysrq handling. */
-                               if(uart_handle_break(port)) {
+                               if(uart_handle_break(port))
                                        return 0;
-                               }
                                pr_debug("sci: BREAK detected\n");
-                               copied++;
-                               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+                               if(tty_insert_flip_char(tty, 0, TTY_BREAK))
+                                       copied++;
                        }
                }
                else {
                        /* frame error */
-                       copied++;
-                       *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+                       if(tty_insert_flip_char(tty, 0, TTY_FRAME))
+                               copied++;
                        pr_debug("sci: frame error\n");
                }
        }
 
-       if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+       if (status&SCxSR_PER(port)) {
+               if(tty_insert_flip_char(tty, 0, TTY_PARITY))
+                       copied++;
                /* parity error */
-               copied++;
-               *tty->flip.flag_buf_ptr++ = TTY_PARITY;
                pr_debug("sci: parity error\n");
        }
 
-       if (copied) {
-               tty->flip.count += copied;
+       if (copied)
                tty_flip_buffer_push(tty);
-       }
 
        return copied;
 }
@@ -661,15 +652,14 @@ static inline int sci_handle_breaks(struct uart_port *port)
        struct tty_struct *tty = port->info->tty;
        struct sci_port *s = &sci_ports[port->line];
 
-       if (!s->break_flag && status & SCxSR_BRK(port) &&
-           tty->flip.count < TTY_FLIPBUF_SIZE) {
+       if (!s->break_flag && status & SCxSR_BRK(port))
 #if defined(CONFIG_CPU_SH3)
                /* Debounce break */
                s->break_flag = 1;
 #endif
                /* Notify of BREAK */
-               copied++;
-               *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+               if(tty_insert_flip_char(tty, 0, TTY_BREAK))
+                       copied++;
                pr_debug("sci: BREAK detected\n");
        }
 
@@ -677,19 +667,15 @@ static inline int sci_handle_breaks(struct uart_port *port)
        /* XXX: Handle SCIF overrun error */
        if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
                sci_out(port, SCLSR, 0);
-               if(tty->flip.count<TTY_FLIPBUF_SIZE) {
+               if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) {
                        copied++;
-                       *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
                        pr_debug("sci: overrun error\n");
                }
        }
 #endif
 
-       if (copied) {
-               tty->flip.count += copied;
+       if (copied)
                tty_flip_buffer_push(tty);
-       }
-
        return copied;
 }
 
@@ -732,12 +718,9 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
                        struct tty_struct *tty = port->info->tty;
 
                        sci_out(port, SCLSR, 0);
-                       if(tty->flip.count<TTY_FLIPBUF_SIZE) {
-                               *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-                               tty->flip.count++;
-                               tty_flip_buffer_push(tty);
-                               pr_debug("scif: overrun error\n");
-                       }
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+                       tty_flip_buffer_push(tty);
+                       pr_debug("scif: overrun error\n");
                }
 #endif
                sci_rx_interrupt(irq, ptr, regs);
index 313f9df24a2de97426df92de3c439af9d07dda91..5468e5a767e21bf9bcbf951f21b05dbbdb17b3b7 100644 (file)
@@ -519,11 +519,7 @@ sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs,
 
                /* record the character to pass up to the tty layer */
                if (tty) {
-                       *tty->flip.char_buf_ptr = ch;
-                       *tty->flip.flag_buf_ptr = TTY_NORMAL;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-                       if (tty->flip.count == TTY_FLIPBUF_SIZE)
+                       if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0)
                                break;
                }
                port->sc_port.icount.rx++;
index ba9381fd3f2da3916e309cc41ad535a448d566ac..7e773ff76c6106721f42b0dce9aa5cd1f43c123c 100644 (file)
@@ -159,21 +159,14 @@ receive_chars(struct uart_sunsab_port *up,
                saw_console_brk = 1;
 
        for (i = 0; i < count; i++) {
-               unsigned char ch = buf[i];
+               unsigned char ch = buf[i], flag;
 
                if (tty == NULL) {
                        uart_handle_sysrq_char(&up->port, ch, regs);
                        continue;
                }
 
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return tty; // if TTY_DONT_FLIP is set
-               }
-
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
 
                if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR |
@@ -209,34 +202,21 @@ receive_chars(struct uart_sunsab_port *up,
                        stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff);
 
                        if (stat->sreg.isr1 & SAB82532_ISR1_BRK) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (stat->sreg.isr0 & SAB82532_ISR0_PERR)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (stat->sreg.isr0 & SAB82532_ISR0_FERR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
 
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        continue;
 
                if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 &&
-                   (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0){
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((stat->sreg.isr0 & SAB82532_ISR0_RFO) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       /*
-                        * Overrun is special, since it's reported
-                        * immediately, and doesn't affect the current
-                        * character.
-                        */
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
+                   (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+               if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        }
 
        if (saw_console_brk)
index f0738533f39a7f5adddb1a24737155851eed43de..9a3665b34d97218dca97b18bbf60740bb45dece7 100644 (file)
@@ -323,19 +323,13 @@ static _INLINE_ struct tty_struct *
 receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs)
 {
        struct tty_struct *tty = up->port.info->tty;
-       unsigned char ch;
+       unsigned char ch, flag;
        int max_count = 256;
        int saw_console_brk = 0;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return tty; // if TTY_DONT_FLIP is set
-               }
                ch = serial_inp(up, UART_RX);
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
 
                if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
@@ -377,31 +371,23 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
                        }
 
                        if (*status & UART_LSR_BI) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (*status & UART_LSR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (*status & UART_LSR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((*status & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((*status & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
+               if ((*status & up->port.ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+               if (*status & UART_LSR_OE)
                        /*
                         * Overrun is special, since it's reported
                         * immediately, and doesn't affect the current
                         * character.
                         */
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
+                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        ignore_char:
                *status = serial_inp(up, UART_LSR);
        } while ((*status & UART_LSR_DR) && (max_count-- > 0));
index 7653d6cf05aff66a697e3c057682cfafeab0b177..3c72484adea7593c85169e894fe5bf14cfe2674c 100644 (file)
@@ -319,7 +319,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                       struct pt_regs *regs)
 {
        struct tty_struct *tty;
-       unsigned char ch, r1;
+       unsigned char ch, r1, flag;
 
        tty = NULL;
        if (up->port.info != NULL &&            /* Unopened serial console */
@@ -362,19 +362,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                        continue;
                }
 
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       /*
-                        * The 8250 bails out of the loop here,
-                        * but we need to read everything, or die.
-                        */
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               continue;
-               }
-
                /* A real serial line, record the character and status.  */
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
                if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
                        if (r1 & BRK_ABRT) {
@@ -391,28 +380,21 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                                up->port.icount.overrun++;
                        r1 &= up->port.read_status_mask;
                        if (r1 & BRK_ABRT)
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        else if (r1 & PAR_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (r1 & CRC_ERR)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        continue;
 
                if (up->port.ignore_status_mask == 0xff ||
                    (r1 & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((r1 & Rx_OVR) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flag);
                }
+               if (r1 & Rx_OVR)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        }
 
        return tty;
index 865d4dea65df9b4d131bac4f50fe496246c9b535..0a28deeb098d6f0cf254a703196b2202dfcb824a 100644 (file)
@@ -371,11 +371,6 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status,
        lsr = *status;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       if (tty->low_latency)
-                               tty_flip_buffer_push(tty);
-               }
-
                ch = siu_read(port, UART_RX);
                port->icount.rx++;
                flag = TTY_NORMAL;
index b28336148658f6ba453b0b6454876bfe1d064323..c1b47d74e206a468fdc9c2bce7792d19740256e1 100644 (file)
@@ -532,9 +532,9 @@ static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs)
        int ret = int_urb->status;
 
        /* The magic interrupt for "up state" */
-       const static unsigned char up_int[6]   = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
+       static const unsigned char up_int[6]   = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
        /* The magic interrupt for "down state" */
-       const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       static const unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
        atm_dbg(usbatm, "%s entered\n", __func__);
 
index 248279e44c99d57c969a8ef03057b850da0cfb57..b9fd39fd1b5b3c37c9a8dc6c729a20bfc6b39fba 100644 (file)
@@ -335,14 +335,9 @@ next_buffer:
 
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
 
-       for (i = 0; i < buf->size && !acm->throttle; i++) {
-               /* if we insert more than TTY_FLIPBUF_SIZE characters,
-                  we drop them. */
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-               }
-               tty_insert_flip_char(tty, buf->base[i], 0);
-       }
+       tty_buffer_request_room(tty, buf->size);
+       if (!acm->throttle)
+               tty_insert_flip_string(tty, buf->base, buf->size);
        tty_flip_buffer_push(tty);
 
        spin_lock(&acm->throttle_lock);
index 65e084a2c87e13804d4a83c16bf8c0564bd26743..2e6926b33455b0197bb58179c922acd42dadf76c 100644 (file)
@@ -1271,6 +1271,7 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
        unsigned int len;
        struct gs_port *port;
        int ret;
+       struct tty_struct *tty;
 
        /* TEMPORARY -- only port 0 is supported right now */
        port = dev->dev_port[0];
@@ -1290,7 +1291,10 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
                goto exit;
        }
 
-       if (port->port_tty == NULL) {
+
+       tty = port->port_tty;
+
+       if (tty == NULL) {
                printk(KERN_ERR "gs_recv_packet: port=%d, NULL tty pointer\n",
                        port->port_num);
                ret = -EIO;
@@ -1304,20 +1308,13 @@ static int gs_recv_packet(struct gs_dev *dev, char *packet, unsigned int size)
                goto exit;
        }
 
-       len = (unsigned int)(TTY_FLIPBUF_SIZE - port->port_tty->flip.count);
-       if (len < size)
-               size = len;
-
-       if (size > 0) {
-               memcpy(port->port_tty->flip.char_buf_ptr, packet, size);
-               port->port_tty->flip.char_buf_ptr += size;
-               port->port_tty->flip.count += size;
+       len = tty_buffer_request_room(tty, size);
+       if (len > 0) {
+               tty_insert_flip_string(tty, packet, len);
                tty_flip_buffer_push(port->port_tty);
                wake_up_interruptible(&port->port_tty->read_wait);
        }
-
        ret = 0;
-
 exit:
        spin_unlock(&port->port_lock);
        return ret;
index 458f2acdeb0a5695a2754edb45a8e3a28c9ae32d..28538db9eaf3920eb5e565058882c069ecf6ddde 100644 (file)
@@ -674,7 +674,7 @@ struct vendor_product
 
 
 /* These are taken from the msmUSB.inf file on the Windows driver CD */
-const static struct vendor_product mts_supported_products[] =
+static const struct vendor_product mts_supported_products[] =
 {
        { "Phantom 336CX",      mts_sup_unknown},
        { "Phantom 336CX",      mts_sup_unknown},
index 14f55fd26a64b06f49b4da4bea56128df8227874..be5dc80836c303b506b47e92484f3c2356bffaa4 100644 (file)
@@ -84,7 +84,7 @@ config USB_SERIAL_BELKIN
 
 config USB_SERIAL_WHITEHEAT
        tristate "USB ConnectTech WhiteHEAT Serial Driver"
-       depends on USB_SERIAL && BROKEN_ON_SMP
+       depends on USB_SERIAL
        help
          Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
          USB to serial converter device.
index 6d18d4eaba358b94e3f73e75fd2bfc8f1963fc96..2357b1d102d7e5fef562be87c47ca703d35d678c 100644 (file)
@@ -364,7 +364,6 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        short todo;
-       int i;
        int result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -381,14 +380,8 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                return;
        }
        if (urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
 
index 4e9637eb6137836b3e62a0b7eb2e39aee099cf32..68067fe117a46ab25d0ce71695643095eea2fdc3 100644 (file)
@@ -1263,12 +1263,10 @@ static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
 
        /* process read if there is data other than line status */
        if (tty && (bytes > i)) {
+               bytes = tty_buffer_request_room(tty, bytes);
                for (; i < bytes ; ++i) {
                        dbg("pushing byte number %d - %d - %c", i, data[i],
                                        data[i]);
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
                        tty_insert_flip_char(tty, data[i], tty_flag);
                }
                tty_flip_buffer_push(port->tty);
index 8fc414bd5b24ba1bc7c6db856df06f8704470853..b3f776a90c932c8ea1c249adb19c0aa8e2720bb2 100644 (file)
@@ -946,13 +946,10 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num );
        spin_lock_irqsave( &priv->dp_port_lock, flags );
 
        /* send any buffered chars from throttle time on to tty subsystem */
-       len = min(priv->dp_in_buf_len, TTY_FLIPBUF_SIZE - tty->flip.count );
+
+       len = tty_buffer_request_room(tty, priv->dp_in_buf_len);
        if( len > 0 ) {
-               memcpy( tty->flip.char_buf_ptr, priv->dp_in_buf, len );
-               memcpy( tty->flip.flag_buf_ptr, priv->dp_in_flag_buf, len );
-               tty->flip.char_buf_ptr += len;
-               tty->flip.flag_buf_ptr += len;
-               tty->flip.count += len;
+               tty_insert_flip_string_flags(tty, priv->dp_in_buf, priv->dp_in_flag_buf, len);
                tty_flip_buffer_push( tty );
        }
 
@@ -1827,6 +1824,7 @@ static int digi_read_inb_callback( struct urb *urb )
        int status = ((unsigned char *)urb->transfer_buffer)[2];
        unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3;
        int flag,throttled;
+       int i;
 
        /* do not process callbacks on closed ports */
        /* but do continue the read chain */
@@ -1885,20 +1883,18 @@ static int digi_read_inb_callback( struct urb *urb )
                        }
 
                } else {
-
-                       len = min( len, TTY_FLIPBUF_SIZE - tty->flip.count );
-
+                       len = tty_buffer_request_room(tty, len);
                        if( len > 0 ) {
-                               memcpy( tty->flip.char_buf_ptr, data, len );
-                               memset( tty->flip.flag_buf_ptr, flag, len );
-                               tty->flip.char_buf_ptr += len;
-                               tty->flip.flag_buf_ptr += len;
-                               tty->flip.count += len;
+                               /* Hot path */
+                               if(flag == TTY_NORMAL)
+                                       tty_insert_flip_string(tty, data, len);
+                               else {
+                                       for(i = 0; i < len; i++)
+                                               tty_insert_flip_char(tty, data[i], flag);
+                               }
                                tty_flip_buffer_push( tty );
                        }
-
                }
-
        }
 
        spin_unlock( &priv->dp_port_lock );
index 79a766e9ca23170160c69f182f1cd69e28d313c2..63f7c78a1152d05924711628be6c2e93b70ef555 100644 (file)
@@ -344,7 +344,6 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
-       int i;
        int result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -359,19 +358,8 @@ static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        tty = port->tty;
 
        if (urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* gb - 2000/11/13
-                        * If we insert too many characters we'll overflow the buffer.
-                        * This means we'll lose bytes - Decidedly bad.
-                        */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                               }
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
-               /* gb - 2000/11/13
-                * Goes straight through instead of scheduling - if tty->low_latency is set.
-                */
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
                bytes_in += urb->actual_length;
        }
index eb863b3f2d7950d3880ed78472328631ffda9bcd..10bc1bf23b3514cb9bc50acad7c47f3dc3998583 100644 (file)
@@ -1610,24 +1610,11 @@ static void ftdi_process_read (void *param)
                        length = 0;
                }
 
-               /* have to make sure we don't overflow the buffer
-                  with tty_insert_flip_char's */
-               if (tty->flip.count+length > TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-                       need_flip = 0;
-
-                       if (tty->flip.count != 0) {
-                               /* flip didn't work, this happens when ftdi_process_read() is
-                                * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */
-                               dbg("%s - flip buffer push failed", __FUNCTION__);
-                               break;
-                       }
-               }
                if (priv->rx_flags & THROTTLED) {
                        dbg("%s - throttled", __FUNCTION__);
                        break;
                }
-               if (tty->ldisc.receive_room(tty)-tty->flip.count < length) {
+               if (tty_buffer_request_room(tty, length) < length) {
                        /* break out & wait for throttling/unthrottling to happen */
                        dbg("%s - receive room low", __FUNCTION__);
                        break;
index 452efce72714aae72aedc2426d6a50a4b9dfabe5..d6f55e9dccae26433fc066273c1a0858943c27fb 100644 (file)
@@ -275,23 +275,14 @@ static void send_to_tty(struct usb_serial_port *port,
                         char *data, unsigned int actual_length)
 {
        struct tty_struct *tty = port->tty;
-       int i;
 
        if (tty && actual_length) {
 
                usb_serial_debug_data(debug, &port->dev, 
                                        __FUNCTION__, actual_length, data);
 
-               for (i = 0; i < actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters,
-                          we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless
-                          tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, actual_length);
+               tty_insert_flip_string(tty, data, actual_length);
                tty_flip_buffer_push(tty);
        }
 }
index 4ddac620fc0cbc23c8b8c44c5fcf4f11e8f114dc..476cda107f4fa8bcf0ef2fe53a04d9f37f4a698d 100644 (file)
@@ -254,7 +254,6 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg
        struct usb_serial *serial = port->serial;
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
-       int i;
        int result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -268,14 +267,8 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
 
index faedbeb6ba49a1a958f03cb182cb3780b7d71296..3f29e6b0fd196ca95e7c47537d3f3c23e856db2c 100644 (file)
@@ -1965,20 +1965,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c
        int cnt;
 
        do {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               dev_err(dev, "%s - dropping data, %d bytes lost\n",
-                                       __FUNCTION__, length);
-                               return;
-                       }
+               cnt = tty_buffer_request_room(tty, length);
+               if (cnt < length) {
+                       dev_err(dev, "%s - dropping data, %d bytes lost\n",
+                                       __FUNCTION__, length - cnt);
+                       if(cnt == 0)
+                               break;
                }
-               cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);
-               memcpy(tty->flip.char_buf_ptr, data, cnt);
-               memset(tty->flip.flag_buf_ptr, 0, cnt);
-               tty->flip.char_buf_ptr += cnt;
-               tty->flip.flag_buf_ptr += cnt;
-               tty->flip.count += cnt;
+               tty_insert_flip_string(tty, data, cnt);
                data += cnt;
                length -= cnt;
        } while (length > 0);
index 2edf9cabad201d739e1209130af7c4df60e6e2dc..afc0f34b3a4695cc0ead14ad98368035d08da6a7 100644 (file)
@@ -1865,20 +1865,14 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c
        int cnt;
 
        do {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               dev_err(dev, "%s - dropping data, %d bytes lost\n",
-                                       __FUNCTION__, length);
-                               return;
-                       }
+               cnt = tty_buffer_request_room(tty, length);
+               if (cnt < length) {
+                       dev_err(dev, "%s - dropping data, %d bytes lost\n",
+                               __FUNCTION__, length - cnt);
+                       if(cnt == 0)
+                               break;
                }
-               cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);
-               memcpy(tty->flip.char_buf_ptr, data, cnt);
-               memset(tty->flip.flag_buf_ptr, 0, cnt);
-               tty->flip.char_buf_ptr += cnt;
-               tty->flip.flag_buf_ptr += cnt;
-               tty->flip.count += cnt;
+               tty_insert_flip_string(tty, data, cnt);
                data += cnt;
                length -= cnt;
        } while (length > 0);
index 06d07cea0b70a3a4a0a09f6265a247b4550e8013..9a5c979895629c727fdef8d377261b30efa21944 100644 (file)
@@ -711,7 +711,7 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
        struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;
        struct tty_struct       *tty;
        unsigned char           *data = urb->transfer_buffer;
-       int                     i, result;
+       int                     result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -724,14 +724,8 @@ static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
                bytes_in += urb->actual_length;
        }
index 2dd191f5fe766962e37e9a0a5971334b216e7d1c..e760a70242c1ccace3664f1b2e46d72e67bb6386 100644 (file)
@@ -166,7 +166,6 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
-       int i;
        int result;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -180,14 +179,8 @@ static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
 
index 4e2f7dfb58b260960c9fd8658cca09a4459d39e0..78335a5f77430e18a1d97e7b22e177f79ee07147 100644 (file)
@@ -648,7 +648,6 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                usb_serial_debug_data(debug, &port->dev, __FUNCTION__,
                                      urb->actual_length, data);
        } else {
-               int i;
                int bytes_sent = ((__u8 *) data)[0] +
                                 ((unsigned int) ((__u8 *) data)[1] << 8);
                tty = port->tty;
@@ -669,16 +668,8 @@ static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
                        bytes_sent = urb->actual_length - 2;
                }
 
-               for (i = 2; i < 2+bytes_sent; i++) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters,
-                        * we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless 
-                        * tty->low_latency is set */
-                       tty_insert_flip_char(tty, ((__u8*) data)[i], 0);
-               }
+               tty_buffer_request_room(tty, bytes_sent);
+               tty_insert_flip_string(tty, data + 2, bytes_sent);
                tty_flip_buffer_push(tty);
 
                /* again lockless, but debug info only */
index d9c21e275130a59a76bdc89a9de7ae3bf35280c9..b8b213185d0f05ea6fc3d6a142962e039fea75ea 100644 (file)
@@ -365,7 +365,6 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
 
 static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
 {
-       int i;
        int result;
        struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
        struct tty_struct *tty;
@@ -397,14 +396,8 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
                */
                // END DEBUG
 
-               for (i = 0; i < purb->actual_length; ++i) {
-                       // if we insert more than TTY_FLIPBUF_SIZE characters, we drop them.
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       // this doesn't actually push the data through unless tty->low_latency is set
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, purb->actual_length);
+               tty_insert_flip_string(tty, data, purb->actual_length);
                tty_flip_buffer_push(tty);
        }
 
index 3fd2405304fdc156c588772b692962057f849d29..52bdf6fe46f27b59df7f69ac35fb6e6bb06c7e48 100644 (file)
@@ -321,7 +321,7 @@ static int option_write(struct usb_serial_port *port,
 
 static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
 {
-       int i, err;
+       int err;
        int endpoint;
        struct usb_serial_port *port;
        struct tty_struct *tty;
@@ -338,11 +338,8 @@ static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
        } else {
                tty = port->tty;
                if (urb->actual_length) {
-                       for (i = 0; i < urb->actual_length ; ++i) {
-                               if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                                       tty_flip_buffer_push(tty);
-                               tty_insert_flip_char(tty, data[i], 0);
-                       }
+                       tty_buffer_request_room(tty, urb->actual_length);
+                       tty_insert_flip_string(tty, data, urb->actual_length);
                        tty_flip_buffer_push(tty);
                } else {
                        dbg("%s: empty read urb received", __FUNCTION__);
index f037210561905ecd1149e31570a98a112f26dc27..9ffff1938239c97bc878160c73f3e890a28d2d36 100644 (file)
@@ -924,16 +924,12 @@ static void pl2303_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
+               tty_buffer_request_room(tty, urb->actual_length + 1);
                /* overrun is special, not associated with a char */
                if (status & UART_OVERRUN_ERROR)
                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-
-               for (i = 0; i < urb->actual_length; ++i) {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
+               for (i = 0; i < urb->actual_length; ++i)
                        tty_insert_flip_char (tty, data[i], tty_flag);
-               }
                tty_flip_buffer_push (tty);
        }
 
index abb830cb77bd926365d20c67ed5516b2d11d0b49..c18db325707311ca29fd7e0a9dc516027932fc1e 100644 (file)
@@ -1280,24 +1280,18 @@ static void ti_recv(struct device *dev, struct tty_struct *tty,
        int cnt;
 
        do {
-               if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                       tty_flip_buffer_push(tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length);
-                               return;
-                       }
+               cnt = tty_buffer_request_room(tty, length);
+               if (cnt < length) {
+                       dev_err(dev, "%s - dropping data, %d bytes lost\n", __FUNCTION__, length - cnt);
+                       if(cnt == 0)
+                               break;
                }
-               cnt = min(length, TTY_FLIPBUF_SIZE - tty->flip.count);
-               memcpy(tty->flip.char_buf_ptr, data, cnt);
-               memset(tty->flip.flag_buf_ptr, 0, cnt);
-               tty->flip.char_buf_ptr += cnt;
-               tty->flip.flag_buf_ptr += cnt;
-               tty->flip.count += cnt;
+               tty_insert_flip_string(tty, data, cnt);
+               tty_flip_buffer_push(tty);
                data += cnt;
                length -= cnt;
        } while (length > 0);
 
-       tty_flip_buffer_push(tty);
 }
 
 
index 49b1fbe61f25e446a60b8ecf8a8bc09780aeeb5d..bce3d55affd8d1d410647191d754f1752ea4849d 100644 (file)
@@ -488,7 +488,6 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        unsigned char *data = urb->transfer_buffer;
        struct tty_struct *tty;
        unsigned long flags;
-       int i;
        int throttled;
        int result;
 
@@ -503,14 +502,8 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 
        tty = port->tty;
        if (tty && urb->actual_length) {
-               for (i = 0; i < urb->actual_length ; ++i) {
-                       /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
-                       if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               tty_flip_buffer_push(tty);
-                       }
-                       /* this doesn't actually push the data through unless tty->low_latency is set */
-                       tty_insert_flip_char(tty, data[i], 0);
-               }
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
                tty_flip_buffer_push(tty);
        }
        spin_lock_irqsave(&priv->lock, flags);
index a7c3c4734d839ea83d8195374f81361e71ced15b..557411c6e7c7031f60cdbde3ddfb4102cc9e91c3 100644 (file)
@@ -1434,7 +1434,9 @@ static void rx_data_softint(void *private)
                urb = wrap->urb;
 
                if (tty && urb->actual_length) {
-                       if (urb->actual_length > TTY_FLIPBUF_SIZE - tty->flip.count) {
+                       int len = tty_buffer_request_room(tty, urb->actual_length);
+                       /* This stuff can go away now I suspect */
+                       if (unlikely(len < urb->actual_length)) {
                                spin_lock_irqsave(&info->lock, flags);
                                list_add(tmp, &info->rx_urb_q);
                                spin_unlock_irqrestore(&info->lock, flags);
@@ -1442,11 +1444,8 @@ static void rx_data_softint(void *private)
                                schedule_work(&info->rx_work);
                                return;
                        }
-
-                       memcpy(tty->flip.char_buf_ptr, urb->transfer_buffer, urb->actual_length);
-                       tty->flip.char_buf_ptr += urb->actual_length;
-                       tty->flip.count += urb->actual_length;
-                       sent += urb->actual_length;
+                       tty_insert_flip_string(tty, urb->transfer_buffer, len);
+                       sent += len;
                }
 
                urb->dev = port->serial->dev;
index 3f04427c9026ed6b741bae3de1883cb313b689d4..3e153d313bb01457cc54401925f78aad88da734c 100644 (file)
@@ -993,12 +993,6 @@ config FB_ATY_GENERIC_LCD
          Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
          Rage XC, or Rage XL chipset.
 
-config FB_ATY_XL_INIT
-       bool "Rage XL No-BIOS Init support"
-       depends on FB_ATY_CT
-       help
-         Say Y here to support booting a Rage XL without BIOS support.
-
 config FB_ATY_GX
        bool "Mach64 GX support" if PCI
        depends on FB_ATY
@@ -1376,7 +1370,7 @@ config FB_PXA
 
          This driver is also available as a module ( = code which can be
          inserted and removed from the running kernel whenever you want). The
-         module will be called vfb. If you want to compile it as a module,
+         module will be called pxafb. If you want to compile it as a module,
          say M here and read <file:Documentation/modules.txt>.
 
          If unsure, say N.
@@ -1409,7 +1403,7 @@ config FB_W100
 
          This driver is also available as a module ( = code which can be
          inserted and removed from the running kernel whenever you want). The
-         module will be called vfb. If you want to compile it as a module,
+         module will be called w100fb. If you want to compile it as a module,
          say M here and read <file:Documentation/modules.txt>.
 
          If unsure, say N.
index 2784f0a9d693a20144d260468da19c8468003324..89060b2db8e5f1bf5c6aae4d10eb0f8899927a7a 100644 (file)
@@ -366,7 +366,8 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx,
        }
 }
 
-void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void arcfb_fillrect(struct fb_info *info,
+                          const struct fb_fillrect *rect)
 {
        struct arcfb_par *par = info->par;
 
@@ -376,7 +377,8 @@ void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
        arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
 }
 
-void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void arcfb_copyarea(struct fb_info *info,
+                          const struct fb_copyarea *area)
 {
        struct arcfb_par *par = info->par;
 
@@ -386,7 +388,7 @@ void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
 }
 
-void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct arcfb_par *par = info->par;
 
index c64de59398f499e80507a3e3d582f90d8515bf19..69f75547865df1c799cf427d796672aa73c3ab48 100644 (file)
@@ -549,7 +549,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
        if (!request_mem_region(addr, size, "asiliantfb"))
                return -EBUSY;
 
-       p = framebuffer_alloc(sizeof(u32) * 256, &dp->dev);
+       p = framebuffer_alloc(sizeof(u32) * 16, &dp->dev);
        if (!p) {
                release_mem_region(addr, size);
                return -ENOMEM;
index 9dec96249ffb94fff24d773ee667e32a75b89df6..18521397a6e3d6ad19ddd9f258ffa656f7bf5f44 100644 (file)
@@ -5,7 +5,6 @@ obj-$(CONFIG_FB_RADEON) += radeonfb.o
 atyfb-y                                := atyfb_base.o mach64_accel.o mach64_cursor.o
 atyfb-$(CONFIG_FB_ATY_GX)      += mach64_gx.o
 atyfb-$(CONFIG_FB_ATY_CT)      += mach64_ct.o
-atyfb-$(CONFIG_FB_ATY_XL_INIT)  += xlinit.o
 
 atyfb-objs                     := $(atyfb-y)
 
index 09de173c1164bc7f6835b67d51f4e0a5c525be2d..e9b7a64c1ac4009fee66247bcf2e5697a327e5d3 100644 (file)
@@ -50,6 +50,7 @@ struct pll_info {
        int sclk, mclk, mclk_pm, xclk;
        int ref_div;
        int ref_clk;
+       int ecp_max;
 };
 
 typedef struct {
@@ -354,6 +355,5 @@ static inline void wait_for_idle(struct atyfb_par *par)
 
 extern void aty_reset_engine(const struct atyfb_par *par);
 extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info);
-extern int  atyfb_xl_init(struct fb_info *info);
 extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par);
 extern u8   aty_ld_pll_ct(int offset, const struct atyfb_par *par);
index 3fefdb0cbf07be5b5da584b5a1c2df870d5229dd..e370125e4fbc8ebe5a1cf192544d902bdda1e2a6 100644 (file)
 #define GUI_RESERVE    (1 * PAGE_SIZE)
 
 /* FIXME: remove the FAIL definition */
-#define FAIL(msg) do { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0)
-#define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0)
-
+#define FAIL(msg) do { \
+       if (!(var->activate & FB_ACTIVATE_TEST)) \
+               printk(KERN_CRIT "atyfb: " msg "\n"); \
+       return -EINVAL; \
+} while (0)
+#define FAIL_MAX(msg, x, _max_) do { \
+       if (x > _max_) { \
+               if (!(var->activate & FB_ACTIVATE_TEST)) \
+                       printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \
+               return -EINVAL; \
+       } \
+} while (0)
 #ifdef DEBUG
 #define DPRINTK(fmt, args...)  printk(KERN_DEBUG "atyfb: " fmt, ## args)
 #else
@@ -340,6 +349,7 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
 #define ATI_CHIP_264VT3    (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL)
 #define ATI_CHIP_264VT4    (M64F_VT | M64F_INTEGRATED               | M64F_GTB_DSP)
 
+/* FIXME what is this chip? */
 #define ATI_CHIP_264LT     (M64F_GT | M64F_INTEGRATED               | M64F_GTB_DSP)
 
 /* make sets shorter */
@@ -359,58 +369,60 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
 static struct {
        u16 pci_id;
        const char *name;
-       int pll, mclk, xclk;
+       int pll, mclk, xclk, ecp_max;
        u32 features;
 } aty_chips[] __devinitdata = {
 #ifdef CONFIG_FB_ATY_GX
        /* Mach64 GX */
-       { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX },
-       { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX },
+       { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX },
+       { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX },
 #endif /* CONFIG_FB_ATY_GX */
 
 #ifdef CONFIG_FB_ATY_CT
-       { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT },
-       { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET },
-       { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT },
-       { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT },
-       /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */
-       { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB  },
-       { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 },
-
-       { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT },
-        /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */
-       { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
-
-       { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 },
-
-       { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
-       { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
-       { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C },
-       { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C },
-
-       { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO },
-       { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO },
-       { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
-       { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO },
-       { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO },
-
-       { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO },
-       { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO },
-       { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
-       { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
-       { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO },
-
-       { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
-       { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
-       { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
-       { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
-       { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
-       { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
-
-       { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
-       { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY },
-       { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
-       { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY },
+       { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT },
+       { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET },
+
+       /* FIXME what is this chip? */
+       { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT },
+
+       { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT },
+       { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT },
+
+       { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 },
+       { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB },
+
+       { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 },
+
+       { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 },
+
+       { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
+       { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
+       { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
+       { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C },
+
+       { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
+       { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
+       { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE },
+       { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
+       { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO },
+
+       { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
+       { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
+       { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
+       { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
+       { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
+
+       { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
+       { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
+       { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
+       { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL },
+       { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
+       { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL },
+
+       { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
+       { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
+       { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
+       { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY },
 #endif /* CONFIG_FB_ATY_CT */
 };
 
@@ -431,6 +443,7 @@ static int __devinit correct_chipset(struct atyfb_par *par)
        par->pll_limits.pll_max = aty_chips[i].pll;
        par->pll_limits.mclk = aty_chips[i].mclk;
        par->pll_limits.xclk = aty_chips[i].xclk;
+       par->pll_limits.ecp_max = aty_chips[i].ecp_max;
        par->features = aty_chips[i].features;
 
        chip_id = aty_ld_le32(CONFIG_CHIP_ID, par);
@@ -450,39 +463,63 @@ static int __devinit correct_chipset(struct atyfb_par *par)
 #endif
 #ifdef CONFIG_FB_ATY_CT
        case PCI_CHIP_MACH64VT:
-               rev &= 0xc7;
-               if(rev == 0x00) {
-                       name = "ATI264VTA3 (Mach64 VT)";
-                       par->pll_limits.pll_max = 170;
-                       par->pll_limits.mclk = 67;
-                       par->pll_limits.xclk = 67;
-                       par->features = ATI_CHIP_264VT;
-               } else if(rev == 0x40) {
-                       name = "ATI264VTA4 (Mach64 VT)";
+               switch (rev & 0x07) {
+               case 0x00:
+                       switch (rev & 0xc0) {
+                       case 0x00:
+                               name = "ATI264VT (A3) (Mach64 VT)";
+                               par->pll_limits.pll_max = 170;
+                               par->pll_limits.mclk = 67;
+                               par->pll_limits.xclk = 67;
+                               par->pll_limits.ecp_max = 80;
+                               par->features = ATI_CHIP_264VT;
+                               break;
+                       case 0x40:
+                               name = "ATI264VT2 (A4) (Mach64 VT)";
+                               par->pll_limits.pll_max = 200;
+                               par->pll_limits.mclk = 67;
+                               par->pll_limits.xclk = 67;
+                               par->pll_limits.ecp_max = 80;
+                               par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
+                               break;
+                       }
+                       break;
+               case 0x01:
+                       name = "ATI264VT3 (B1) (Mach64 VT)";
                        par->pll_limits.pll_max = 200;
                        par->pll_limits.mclk = 67;
                        par->pll_limits.xclk = 67;
-                       par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV;
-               } else {
-                       name = "ATI264VTB (Mach64 VT)";
+                       par->pll_limits.ecp_max = 80;
+                       par->features = ATI_CHIP_264VTB;
+                       break;
+               case 0x02:
+                       name = "ATI264VT3 (B2) (Mach64 VT)";
                        par->pll_limits.pll_max = 200;
                        par->pll_limits.mclk = 67;
                        par->pll_limits.xclk = 67;
-                       par->features = ATI_CHIP_264VTB;
+                       par->pll_limits.ecp_max = 80;
+                       par->features = ATI_CHIP_264VT3;
+                       break;
                }
                break;
        case PCI_CHIP_MACH64GT:
-               rev &= 0x07;
-               if(rev == 0x01) {
+               switch (rev & 0x07) {
+               case 0x01:
+                       name = "3D RAGE II (Mach64 GT)";
                        par->pll_limits.pll_max = 170;
                        par->pll_limits.mclk = 67;
                        par->pll_limits.xclk = 67;
+                       par->pll_limits.ecp_max = 80;
                        par->features = ATI_CHIP_264GTB;
-               } else if(rev == 0x02) {
+                       break;
+               case 0x02:
+                       name = "3D RAGE II+ (Mach64 GT)";
                        par->pll_limits.pll_max = 200;
                        par->pll_limits.mclk = 67;
                        par->pll_limits.xclk = 67;
+                       par->pll_limits.ecp_max = 100;
                        par->features = ATI_CHIP_264GTB;
+                       break;
                }
                break;
 #endif
@@ -692,7 +729,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
                aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) |
                        (SHADOW_EN | SHADOW_RW_EN), par);
 
-               DPRINTK("set secondary CRT to %ix%i %c%c\n",
+               DPRINTK("set shadow CRT to %ix%i %c%c\n",
                    ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1),
                    (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P');
 
@@ -840,11 +877,14 @@ static int aty_var_to_crtc(const struct fb_info *info,
                           know if one is connected. So it's better to fail then.
                         */
                        if (crtc->lcd_gen_cntl & CRT_ON) {
-                               PRINTKI("Disable lcd panel, because video mode does not fit.\n");
+                               if (!(var->activate & FB_ACTIVATE_TEST))
+                                       PRINTKI("Disable LCD panel, because video mode does not fit.\n");
                                crtc->lcd_gen_cntl &= ~LCD_ON;
                                /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/
                        } else {
-                               FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode.");
+                               if (!(var->activate & FB_ACTIVATE_TEST))
+                                       PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n");
+                               return -EINVAL;
                        }
                }
        }
@@ -858,9 +898,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
                vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED);
 
                /* This is horror! When we simulate, say 640x480 on an 800x600
-                  lcd monitor, the CRTC should be programmed 800x600 values for
+                  LCD monitor, the CRTC should be programmed 800x600 values for
                   the non visible part, but 640x480 for the visible part.
-                  This code has been tested on a laptop with it's 1400x1050 lcd
+                  This code has been tested on a laptop with it's 1400x1050 LCD
                   monitor and a conventional monitor both switched on.
                   Tested modes: 1280x1024, 1152x864, 1024x768, 800x600,
                    works with little glitches also with DOUBLESCAN modes
@@ -955,16 +995,6 @@ static int aty_var_to_crtc(const struct fb_info *info,
                vdisplay = yres;
                if(vmode & FB_VMODE_DOUBLE)
                        vdisplay <<= 1;
-               if(vmode & FB_VMODE_INTERLACED) {
-                       vdisplay >>= 1;
-
-                       /* The prefered mode for the lcd is not interlaced, so disable it if
-                          it was enabled. For doublescan there is no problem, because we can
-                          compensate for it in the hardware stretching (we stretch half as much)
-                        */
-                       vmode &= ~FB_VMODE_INTERLACED;
-                       /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/
-               }
                crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH);
                crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
                        /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/
@@ -980,7 +1010,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
                crtc->horz_stretching &=
                        ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO |
                        HORZ_STRETCH_MODE | HORZ_STRETCH_EN);
-               if (xres < par->lcd_width) {
+               if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) {
                        do {
                                /*
                                * The horizontal blender misbehaves when HDisplay is less than a
@@ -1042,7 +1072,7 @@ static int aty_var_to_crtc(const struct fb_info *info,
                        } while (0);
                }
 
-               if (vdisplay < par->lcd_height) {
+               if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) {
                        crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN |
                                (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0));
 
@@ -1065,9 +1095,8 @@ static int aty_var_to_crtc(const struct fb_info *info,
 #endif /* CONFIG_FB_ATY_GENERIC_LCD */
 
        if (M64_HAS(MAGIC_FIFO)) {
-               /* Not VTB/GTB */
-               /* FIXME: magic FIFO values */
-               crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH);
+               /* FIXME: display FIFO low watermark values */
+               crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM);
        }
        crtc->dp_pix_width = dp_pix_width;
        crtc->dp_chain_mask = dp_chain_mask;
@@ -1184,7 +1213,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va
                var->transp.length = 8;
                break;
        default:
-               FAIL("Invalid pixel width");
+               PRINTKE("Invalid pixel width\n");
+               return -EINVAL;
        }
 
        /* output */
@@ -1241,7 +1271,8 @@ static int atyfb_set_par(struct fb_info *info)
        pixclock = atyfb_get_pixclock(var, par);
 
        if (pixclock == 0) {
-               FAIL("Invalid pixclock");
+               PRINTKE("Invalid pixclock\n");
+               return -EINVAL;
        } else {
                if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll)))
                        return err;
@@ -1446,7 +1477,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        pixclock = atyfb_get_pixclock(var, par);
 
        if (pixclock == 0) {
-               FAIL("Invalid pixclock");
+               if (!(var->activate & FB_ACTIVATE_TEST))
+                       PRINTKE("Invalid pixclock\n");
+               return -EINVAL;
        } else {
                if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll)))
                        return err;
@@ -2291,10 +2324,6 @@ static int __init aty_init(struct fb_info *info, const char *name)
                par->dac_ops = &aty_dac_ct;
                par->pll_ops = &aty_pll_ct;
                par->bus_type = PCI;
-#ifdef CONFIG_FB_ATY_XL_INIT
-               if (IS_XL(par->pci_id))
-                       atyfb_xl_init(info);
-#endif
                par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07);
                ramname = aty_ct_ram[par->ram_type];
                /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
@@ -2638,16 +2667,16 @@ static int __init store_video_par(char *video_str, unsigned char m64_num)
 static int atyfb_blank(int blank, struct fb_info *info)
 {
        struct atyfb_par *par = (struct atyfb_par *) info->par;
-       u8 gen_cntl;
+       u32 gen_cntl;
 
        if (par->lock_blank || par->asleep)
                return 0;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-       if ((_machine == _MACH_Pmac) && blank)
+       if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL)
                set_backlight_enable(0);
 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
-       if (par->lcd_table && blank &&
+       if (par->lcd_table && blank > FB_BLANK_NORMAL &&
            (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
                u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
                pm &= ~PWR_BLON;
@@ -2655,31 +2684,31 @@ static int atyfb_blank(int blank, struct fb_info *info)
        }
 #endif
 
-       gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par);
+       gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
        switch (blank) {
                case FB_BLANK_UNBLANK:
-                       gen_cntl &= ~(0x4c);
+                       gen_cntl &= ~0x400004c;
                        break;
                case FB_BLANK_NORMAL:
-                       gen_cntl |= 0x40;
+                       gen_cntl |= 0x4000040;
                        break;
                case FB_BLANK_VSYNC_SUSPEND:
-                       gen_cntl |= 0x8;
+                       gen_cntl |= 0x4000048;
                        break;
                case FB_BLANK_HSYNC_SUSPEND:
-                       gen_cntl |= 0x4;
+                       gen_cntl |= 0x4000044;
                        break;
                case FB_BLANK_POWERDOWN:
-                       gen_cntl |= 0x4c;
+                       gen_cntl |= 0x400004c;
                        break;
        }
-       aty_st_8(CRTC_GEN_CNTL, gen_cntl, par);
+       aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-       if ((_machine == _MACH_Pmac) && !blank)
+       if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL)
                set_backlight_enable(1);
 #elif defined(CONFIG_FB_ATY_GENERIC_LCD)
-       if (par->lcd_table && !blank &&
+       if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
            (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
                u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
                pm |= PWR_BLON;
@@ -3157,15 +3186,15 @@ static void aty_init_lcd(struct atyfb_par *par, u32 bios_base)
                        refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]);
                par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate];
                /* We now need to determine the crtc parameters for the
-                * lcd monitor. This is tricky, because they are not stored
+                * LCD monitor. This is tricky, because they are not stored
                 * individually in the BIOS. Instead, the BIOS contains a
                 * table of display modes that work for this monitor.
                 *
                 * The idea is that we search for a mode of the same dimensions
-                * as the dimensions of the lcd monitor. Say our lcd monitor
+                * as the dimensions of the LCD monitor. Say our LCD monitor
                 * is 800x600 pixels, we search for a 800x600 monitor.
                 * The CRTC parameters we find here are the ones that we need
-                * to use to simulate other resolutions on the lcd screen.
+                * to use to simulate other resolutions on the LCD screen.
                 */
                lcdmodeptr = (u16 *)(par->lcd_table + 64);
                while (*lcdmodeptr != 0) {
@@ -3692,9 +3721,7 @@ static int __init atyfb_init(void)
     atyfb_setup(option);
 #endif
 
-#ifdef CONFIG_PCI
     pci_register_driver(&atyfb_driver);
-#endif
 #ifdef CONFIG_ATARI
     atyfb_atari_probe();
 #endif
@@ -3703,9 +3730,7 @@ static int __init atyfb_init(void)
 
 static void __exit atyfb_exit(void)
 {
-#ifdef CONFIG_PCI
        pci_unregister_driver(&atyfb_driver);
-#endif
 }
 
 module_init(atyfb_init);
index 9bdb2aab01aa2f29242f07ad70ac9f5efe4de307..e7056934c6a831c06620fd6ea1a45d1b689c3ead 100644 (file)
@@ -206,9 +206,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll
 {
        u32 q;
        struct atyfb_par *par = (struct atyfb_par *) info->par;
-#ifdef DEBUG
        int pllvclk;
-#endif
 
        /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
        q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per;
@@ -223,13 +221,26 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll
        pll->vclk_post_div_real = postdividers[pll->vclk_post_div];
        //    pll->vclk_post_div <<= 6;
        pll->vclk_fb_div = q * pll->vclk_post_div_real / 8;
-#ifdef DEBUG
        pllvclk = (1000000 * 2 * pll->vclk_fb_div) /
                (par->ref_clk_per * pll->pll_ref_div);
+#ifdef DEBUG
        printk("atyfb(%s): pllvclk=%d MHz, vclk=%d MHz\n",
                __FUNCTION__, pllvclk, pllvclk / pll->vclk_post_div_real);
 #endif
        pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
+
+       /* Set ECP (scaler/overlay clock) divider */
+       if (par->pll_limits.ecp_max) {
+               int ecp = pllvclk / pll->vclk_post_div_real;
+               int ecp_div = 0;
+
+               while (ecp > par->pll_limits.ecp_max && ecp_div < 2) {
+                       ecp >>= 1;
+                       ecp_div++;
+               }
+               pll->pll_vclk_cntl |= ecp_div << 4;
+       }
+
        return 0;
 }
 
diff --git a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c
deleted file mode 100644 (file)
index a085cbf..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- *  ATI Rage XL Initialization. Support for Xpert98 and Victoria
- *  PCI cards.
- *
- *  Copyright (C) 2002 MontaVista Software Inc.
- *  Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF 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.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h> 
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <video/mach64.h>
-#include "atyfb.h"
-
-#define MPLL_GAIN       0xad
-#define VPLL_GAIN       0xd5
-
-enum {
-       VICTORIA = 0,
-       XPERT98,
-       NUM_XL_CARDS
-};
-
-extern const struct aty_pll_ops aty_pll_ct;
-
-#define DEFAULT_CARD XPERT98
-static int xl_card = DEFAULT_CARD;
-
-static const struct xl_card_cfg_t {
-       int ref_crystal; // 10^4 Hz
-       int mem_type;
-       int mem_size;
-       u32 mem_cntl;
-       u32 ext_mem_cntl;
-       u32 mem_addr_config;
-       u32 bus_cntl;
-       u32 dac_cntl;
-       u32 hw_debug;
-       u32 custom_macro_cntl;
-       u8  dll2_cntl;
-       u8  pll_yclk_cntl;
-} card_cfg[NUM_XL_CARDS] = {
-       // VICTORIA
-       {       2700, SDRAM, 0x800000,
-               0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040,
-               0x82010102, 0x48803800, 0x005E0179,
-               0x50, 0x25
-       },
-       // XPERT98
-       {       1432,  WRAM, 0x800000,
-               0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001,
-               0x8000000A, 0x48833800, 0x007F0779,
-               0x10, 0x19
-       }
-};
-         
-typedef struct {
-       u8 lcd_reg;
-       u32 val;
-} lcd_tbl_t;
-
-static const lcd_tbl_t lcd_tbl[] = {
-       { 0x01, 0x000520C0 },
-       { 0x08, 0x02000408 },
-       { 0x03, 0x00000F00 },
-       { 0x00, 0x00000000 },
-       { 0x02, 0x00000000 },
-       { 0x04, 0x00000000 },
-       { 0x05, 0x00000000 },
-       { 0x06, 0x00000000 },
-       { 0x33, 0x00000000 },
-       { 0x34, 0x00000000 },
-       { 0x35, 0x00000000 },
-       { 0x36, 0x00000000 },
-       { 0x37, 0x00000000 }
-};
-
-static void reset_gui(struct atyfb_par *par)
-{
-       aty_st_8(GEN_TEST_CNTL+1, 0x01, par);
-       aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
-       aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
-       mdelay(5);
-}
-
-static void reset_sdram(struct atyfb_par *par)
-{
-       u8 temp;
-
-       temp = aty_ld_8(EXT_MEM_CNTL, par);
-       temp |= 0x02;
-       aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_RESET = 1b
-       temp |= 0x08;
-       aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 10b
-       temp |= 0x0c;
-       aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 11b
-       mdelay(5);
-       temp &= 0xf3;
-       aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST    = 00b
-       temp &= 0xfd;
-       aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_REST  = 0b
-       mdelay(5);
-}
-
-static void init_dll(struct atyfb_par *par)
-{
-       // enable DLL
-       aty_st_pll_ct(PLL_GEN_CNTL,
-                  aty_ld_pll_ct(PLL_GEN_CNTL, par) & 0x7f,
-                  par);
-
-       // reset DLL
-       aty_st_pll_ct(DLL_CNTL, 0x82, par);
-       aty_st_pll_ct(DLL_CNTL, 0xE2, par);
-       mdelay(5);
-       aty_st_pll_ct(DLL_CNTL, 0x82, par);
-       mdelay(6);
-}
-
-static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll,
-                        int hsync_enb)
-{
-       reset_gui(par);
-       aty_st_pll_ct(MCLK_FB_DIV, pll->mclk_fb_div, par);
-       aty_st_pll_ct(SCLK_FB_DIV, pll->sclk_fb_div, par);
-
-       mdelay(15);
-       init_dll(par);
-       aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
-       mdelay(5);
-       aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
-       mdelay(6);
-       reset_sdram(par);
-       aty_st_8(CRTC_GEN_CNTL+3,
-                hsync_enb ? 0x00 : 0x04, par);
-
-       aty_st_pll_ct(SPLL_CNTL2, pll->spll_cntl2, par);
-       aty_st_pll_ct(PLL_GEN_CNTL, pll->pll_gen_cntl, par);
-       aty_st_pll_ct(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par);
-}
-
-int atyfb_xl_init(struct fb_info *info)
-{
-       const struct xl_card_cfg_t * card = &card_cfg[xl_card];
-       struct atyfb_par *par = (struct atyfb_par *) info->par;
-       union aty_pll pll;
-       int err;
-       u32 temp;
-       
-       aty_st_8(CONFIG_STAT0, 0x85, par);
-       mdelay(10);
-
-       /*
-        * The following needs to be set before the call
-        * to var_to_pll() below. They'll be re-set again
-        * to the same values in aty_init().
-        */
-       par->ref_clk_per = 100000000UL/card->ref_crystal;
-       par->ram_type = card->mem_type;
-       info->fix.smem_len = card->mem_size;
-       if (xl_card == VICTORIA) {
-               // the MCLK, XCLK are 120MHz on victoria card
-               par->mclk_per = 1000000/120;
-               par->xclk_per = 1000000/120;
-               par->features &= ~M64F_MFB_FORCE_4;
-       }
-       
-       /*
-        * Calculate mclk and xclk dividers, etc. The passed
-        * pixclock and bpp values don't matter yet, the vclk
-        * isn't programmed until later.
-        */
-       if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll)))
-               return err;
-
-       aty_st_pll_ct(LVDS_CNTL0, 0x00, par);
-       aty_st_pll_ct(DLL2_CNTL, card->dll2_cntl, par);
-       aty_st_pll_ct(V2PLL_CNTL, 0x10, par);
-       aty_st_pll_ct(MPLL_CNTL, MPLL_GAIN, par);
-       aty_st_pll_ct(VPLL_CNTL, VPLL_GAIN, par);
-       aty_st_pll_ct(PLL_VCLK_CNTL, 0x00, par);
-       aty_st_pll_ct(VFC_CNTL, 0x1B, par);
-       aty_st_pll_ct(PLL_REF_DIV, pll.ct.pll_ref_div, par);
-       aty_st_pll_ct(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par);
-       aty_st_pll_ct(SPLL_CNTL2, 0x03, par);
-       aty_st_pll_ct(PLL_GEN_CNTL, 0x44, par);
-
-       reset_clocks(par, &pll.ct, 0);
-       mdelay(10);
-
-       aty_st_pll_ct(VCLK_POST_DIV, 0x03, par);
-       aty_st_pll_ct(VCLK0_FB_DIV, 0xDA, par);
-       aty_st_pll_ct(VCLK_POST_DIV, 0x0F, par);
-       aty_st_pll_ct(VCLK1_FB_DIV, 0xF5, par);
-       aty_st_pll_ct(VCLK_POST_DIV, 0x3F, par);
-       aty_st_pll_ct(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par);
-       aty_st_pll_ct(VCLK2_FB_DIV, 0x00, par);
-       aty_st_pll_ct(VCLK_POST_DIV, 0xFF, par);
-       aty_st_pll_ct(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par);
-       aty_st_pll_ct(VCLK3_FB_DIV, 0x00, par);
-
-       aty_st_8(BUS_CNTL, 0x01, par);
-       aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par);
-
-       aty_st_le32(CRTC_GEN_CNTL, 0x04000200, par);
-       aty_st_le16(CONFIG_STAT0, 0x0020, par);
-       aty_st_le32(MEM_CNTL, 0x10151A33, par);
-       aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, par);
-       aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, par);
-       aty_st_le32(DAC_CNTL, card->dac_cntl, par);
-       aty_st_le16(GEN_TEST_CNTL, 0x0100, par);
-       aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, par);
-       aty_st_le32(MEM_BUF_CNTL, 0x00382848, par);
-
-       aty_st_le32(HW_DEBUG, card->hw_debug, par);
-       aty_st_le16(MEM_ADDR_CONFIG, 0x0000, par);
-       aty_st_le16(GP_IO+2, 0x0000, par);
-       aty_st_le16(GEN_TEST_CNTL, 0x0000, par);
-       aty_st_le16(EXT_DAC_REGS+2, 0x0000, par);
-       aty_st_le32(CRTC_INT_CNTL, 0x00000000, par);
-       aty_st_le32(TIMER_CONFIG, 0x00000000, par);
-       aty_st_le32(0xEC, 0x00000000, par);
-       aty_st_le32(0xFC, 0x00000000, par);
-
-#if defined (CONFIG_FB_ATY_GENERIC_LCD)
-       {
-               int i;
-
-               for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++)
-                       aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);
-       }
-#endif
-
-       aty_st_le16(CONFIG_STAT0, 0x00A4, par);
-       mdelay(10);
-
-       aty_st_8(BUS_CNTL+1, 0xA0, par);
-       mdelay(10);
-       
-       reset_clocks(par, &pll.ct, 1);
-       mdelay(10);
-
-       // something about power management
-       aty_st_8(LCD_INDEX, 0x08, par);
-       aty_st_8(LCD_DATA, 0x0A, par);
-       aty_st_8(LCD_INDEX, 0x08, par);
-       aty_st_8(LCD_DATA+3, 0x02, par);
-       aty_st_8(LCD_INDEX, 0x08, par);
-       aty_st_8(LCD_DATA, 0x0B, par);
-       mdelay(2);
-       
-       // enable display requests, enable CRTC
-       aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);
-       // disable display
-       aty_st_8(CRTC_GEN_CNTL, 0x40, par);
-       // disable display requests, disable CRTC
-       aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
-       mdelay(10);
-
-       aty_st_pll_ct(PLL_YCLK_CNTL, 0x25, par);
-
-       aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par);
-       aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par);
-       aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, par);
-       aty_st_8(CUSTOM_MACRO_CNTL+1,
-                (card->custom_macro_cntl>>8) & 0xff, par);
-
-       aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, par);
-       aty_st_le32(MEM_CNTL, card->mem_cntl, par);
-       aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, par);
-
-       aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par);
-
-       aty_st_pll_ct(PLL_YCLK_CNTL, 0x01, par);
-       mdelay(15);
-       aty_st_pll_ct(PLL_YCLK_CNTL, card->pll_yclk_cntl, par);
-       mdelay(1);
-       
-       reset_clocks(par, &pll.ct, 0);
-       mdelay(50);
-       reset_clocks(par, &pll.ct, 0);
-       mdelay(50);
-
-       // enable extended register block
-       aty_st_8(BUS_CNTL+3, 0x7B, par);
-       mdelay(1);
-       // disable extended register block
-       aty_st_8(BUS_CNTL+3, 0x73, par);
-
-       aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, par);
-
-       // disable display requests, disable CRTC
-       aty_st_8(CRTC_GEN_CNTL+3, 0x04, par);
-       // disable mapping registers in VGA aperture
-       aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, par) & ~0x04, par);
-       mdelay(50);
-       // enable display requests, enable CRTC
-       aty_st_8(CRTC_GEN_CNTL+3, 0x02, par);
-
-       // make GPIO's 14,15,16 all inputs
-       aty_st_8(LCD_INDEX, 0x07, par);
-       aty_st_8(LCD_DATA+3, 0x00, par);
-
-       // enable the display
-       aty_st_8(CRTC_GEN_CNTL, 0x00, par);
-       mdelay(17);
-       // reset the memory controller
-       aty_st_8(GEN_TEST_CNTL+1, 0x02, par);
-       mdelay(15);
-       aty_st_8(GEN_TEST_CNTL+1, 0x00, par);
-       mdelay(30);
-
-       // enable extended register block
-       aty_st_8(BUS_CNTL+3,
-                (u8)(aty_ld_8(BUS_CNTL+3, par) | 0x08),
-                par);
-       // set FIFO size to 512 (PIO)
-       aty_st_le32(GUI_CNTL,
-                   aty_ld_le32(GUI_CNTL, par) & ~0x3,
-                   par);
-
-       // enable CRT and disable lcd
-       aty_st_8(LCD_INDEX, 0x01, par);
-       temp = aty_ld_le32(LCD_DATA, par);
-       temp = (temp | 0x01) & ~0x02;
-       aty_st_le32(LCD_DATA, temp, par);
-       return 0;
-}
-
index e65fc3ef7630ad5ac117843871d0fd9ad04476b3..eea422eb1ab56b8bf83bcae1083e51066beeca98 100644 (file)
@@ -234,14 +234,14 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
        }
 }
 
-static void bit_cursor(struct vc_data *vc, struct fb_info *info,
-                      struct display *p, int mode, int softback_lines, int fg, int bg)
+static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+                      int softback_lines, int fg, int bg)
 {
        struct fb_cursor cursor;
-       struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+       struct fbcon_ops *ops = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
        int w = (vc->vc_font.width + 7) >> 3, c;
-       int y = real_y(p, vc->vc_y);
+       int y = real_y(ops->p, vc->vc_y);
        int attribute, use_sw = (vc->vc_cursor_type & 0x10);
        int err = 1;
        char *src;
@@ -310,7 +310,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
        }
 
        if (cursor.set & FB_CUR_SETSIZE ||
-           vc->vc_cursor_type != p->cursor_shape ||
+           vc->vc_cursor_type != ops->p->cursor_shape ||
            ops->cursor_state.mask == NULL ||
            ops->cursor_reset) {
                char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
@@ -323,10 +323,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
                kfree(ops->cursor_state.mask);
                ops->cursor_state.mask = mask;
 
-               p->cursor_shape = vc->vc_cursor_type;
+               ops->p->cursor_shape = vc->vc_cursor_type;
                cursor.set |= FB_CUR_SETSHAPE;
 
-               switch (p->cursor_shape & CUR_HWMASK) {
+               switch (ops->p->cursor_shape & CUR_HWMASK) {
                case CUR_NONE:
                        cur_height = 0;
                        break;
index 50e4c4eb491fbb2e457c482bc92ee14ec8a51d56..041d069878612052cddc875fba3094ed28d1c32c 100644 (file)
@@ -209,13 +209,13 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
 #endif
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
-static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+static inline void fbcon_set_rotation(struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
 
        if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
-           p->con_rotate < 4)
-               ops->rotate = p->con_rotate;
+           ops->p->con_rotate < 4)
+               ops->rotate = ops->p->con_rotate;
        else
                ops->rotate = 0;
 }
@@ -265,7 +265,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
        fbcon_set_all_vcs(info);
 }
 #else
-static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+static inline void fbcon_set_rotation(struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
 
@@ -402,7 +402,7 @@ static void fb_flashcursor(void *private)
        c = scr_readw((u16 *) vc->vc_pos);
        mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
                CM_ERASE : CM_DRAW;
-       ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1),
+       ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
                    get_color(vc, info, c, 0));
        release_console_sem();
 }
@@ -647,29 +647,27 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
 }
 
 #ifdef CONFIG_FB_TILEBLITTING
-static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
-                             struct display *p)
+static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
 
-       ops->p = (p) ? p : &fb_display[vc->vc_num];
+       ops->p = &fb_display[vc->vc_num];
 
        if ((info->flags & FBINFO_MISC_TILEBLITTING))
-               fbcon_set_tileops(vc, info, p, ops);
+               fbcon_set_tileops(vc, info);
        else {
-               fbcon_set_rotation(info, ops->p);
+               fbcon_set_rotation(info);
                fbcon_set_bitops(ops);
        }
 }
 #else
-static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
-                             struct display *p)
+static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
 {
        struct fbcon_ops *ops = info->fbcon_par;
 
        info->flags &= ~FBINFO_MISC_TILEBLITTING;
-       ops->p = (p) ? p : &fb_display[vc->vc_num];
-       fbcon_set_rotation(info, ops->p);
+       ops->p = &fb_display[vc->vc_num];
+       fbcon_set_rotation(info);
        fbcon_set_bitops(ops);
 }
 #endif /* CONFIG_MISC_TILEBLITTING */
@@ -689,15 +687,14 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
                err = -ENODEV;
 
        if (!err) {
-               ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
+               ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
                if (!ops)
                        err = -ENOMEM;
        }
 
        if (!err) {
-               memset(ops, 0, sizeof(struct fbcon_ops));
                info->fbcon_par = ops;
-               set_blitting_type(vc, info, NULL);
+               set_blitting_type(vc, info);
        }
 
        if (err) {
@@ -921,19 +918,18 @@ static const char *fbcon_startup(void)
                return NULL;
        }
 
-       ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
+       ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
        if (!ops) {
                module_put(owner);
                return NULL;
        }
 
-       memset(ops, 0, sizeof(struct fbcon_ops));
        ops->currcon = -1;
        ops->graphics = 1;
        ops->cur_rotate = -1;
        info->fbcon_par = ops;
        p->con_rotate = rotate;
-       set_blitting_type(vc, info, NULL);
+       set_blitting_type(vc, info);
 
        if (info->fix.type != FB_TYPE_TEXT) {
                if (fbcon_softback_size) {
@@ -1093,7 +1089,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 
        ops = info->fbcon_par;
        p->con_rotate = rotate;
-       set_blitting_type(vc, info, NULL);
+       set_blitting_type(vc, info);
 
        cols = vc->vc_cols;
        rows = vc->vc_rows;
@@ -1141,9 +1137,9 @@ static void fbcon_init(struct vc_data *vc, int init)
        if (vc == svc && softback_buf)
                fbcon_update_softback(vc);
 
-       if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+       if (ops->rotate_font && ops->rotate_font(info, vc)) {
                ops->rotate = FB_ROTATE_UR;
-               set_blitting_type(vc, info, p);
+               set_blitting_type(vc, info);
        }
 
 }
@@ -1243,7 +1239,6 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
 {
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct fbcon_ops *ops = info->fbcon_par;
-       struct display *p = &fb_display[vc->vc_num];
        int y;
        int c = scr_readw((u16 *) vc->vc_pos);
 
@@ -1260,7 +1255,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
                y = 0;
        }
 
-       ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1),
+       ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
                    get_color(vc, info, c, 0));
        vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
@@ -1411,16 +1406,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct fbcon_ops *ops = info->fbcon_par;
        struct display *p = &fb_display[vc->vc_num];
-       int redraw = 0;
 
        p->yscroll += count;
+
        if (p->yscroll > p->vrows - vc->vc_rows) {
                p->yscroll -= p->vrows - vc->vc_rows;
-               redraw = 1;
-       }
-
-       if (redraw)
                fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
+       }
 
        ops->var.xoffset = 0;
        ops->var.yoffset = p->yscroll * vc->vc_font.height;
@@ -1462,16 +1454,13 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
        struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
        struct fbcon_ops *ops = info->fbcon_par;
        struct display *p = &fb_display[vc->vc_num];
-       int redraw = 0;
 
        p->yscroll -= count;
+
        if (p->yscroll < 0) {
                p->yscroll += p->vrows - vc->vc_rows;
-               redraw = 1;
-       }
-
-       if (redraw)
                fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
+       }
 
        ops->var.xoffset = 0;
        ops->var.yoffset = p->yscroll * vc->vc_font.height;
@@ -1968,7 +1957,8 @@ static __inline__ void updatescrollmode(struct display *p,
                divides(ypan, vc->vc_font.height) && vyres > yres;
        int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
                divides(ywrap, vc->vc_font.height) &&
-               divides(vc->vc_font.height, vyres);
+               divides(vc->vc_font.height, vyres) &&
+               divides(vc->vc_font.height, yres);
        int reading_fast = cap & FBINFO_READS_FAST;
        int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
                !(cap & FBINFO_HWACCEL_DISABLED);
@@ -2107,16 +2097,19 @@ static int fbcon_switch(struct vc_data *vc)
                                 info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
                if (info->fbops->fb_set_par)
                        info->fbops->fb_set_par(info);
-               fbcon_del_cursor_timer(old_info);
-               fbcon_add_cursor_timer(info);
+
+               if (old_info != info) {
+                       fbcon_del_cursor_timer(old_info);
+                       fbcon_add_cursor_timer(info);
+               }
        }
 
-       set_blitting_type(vc, info, p);
+       set_blitting_type(vc, info);
        ops->cursor_reset = 1;
 
-       if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+       if (ops->rotate_font && ops->rotate_font(info, vc)) {
                ops->rotate = FB_ROTATE_UR;
-               set_blitting_type(vc, info, p);
+               set_blitting_type(vc, info);
        }
 
        vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
@@ -2739,7 +2732,7 @@ static void fbcon_modechanged(struct fb_info *info)
                return;
 
        p = &fb_display[vc->vc_num];
-       set_blitting_type(vc, info, p);
+       set_blitting_type(vc, info);
 
        if (CON_IS_VISIBLE(vc)) {
                var_to_display(p, &info->var, info);
@@ -2781,7 +2774,7 @@ static void fbcon_set_all_vcs(struct fb_info *info)
                        continue;
 
                p = &fb_display[vc->vc_num];
-               set_blitting_type(vc, info, p);
+               set_blitting_type(vc, info);
                var_to_display(p, &info->var, info);
                cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
                rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
@@ -2806,6 +2799,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
                                fbcon_update_softback(vc);
                }
        }
+
+       ops->p = &fb_display[ops->currcon];
 }
 
 static int fbcon_mode_deleted(struct fb_info *info,
index 6892e7ff34de87233268b528297cbfa4a8005bdc..c38c3d8e7a7421ee4e84b6dc942f29d85e9281f3 100644 (file)
@@ -62,12 +62,10 @@ struct fbcon_ops {
                      int fg, int bg);
        void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
                              int bottom_only);
-       void (*cursor)(struct vc_data *vc, struct fb_info *info,
-                      struct display *p, int mode, int softback_lines,
-                      int fg, int bg);
+       void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode,
+                      int softback_lines, int fg, int bg);
        int  (*update_start)(struct fb_info *info);
-       int  (*rotate_font)(struct fb_info *info, struct vc_data *vc,
-                           struct display *p);
+       int  (*rotate_font)(struct fb_info *info, struct vc_data *vc);
        struct fb_var_screeninfo var;  /* copy of the current fb_var_screeninfo */
        struct timer_list cursor_timer; /* Cursor timer */
        struct fb_cursor cursor_state;
@@ -173,8 +171,7 @@ struct fbcon_ops {
 #define SCROLL_PAN_REDRAW  0x005
 
 #ifdef CONFIG_FB_TILEBLITTING
-extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
-                             struct display *p, struct fbcon_ops *ops);
+extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
 extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
index 4952b66ae2062996d13ce6efcbb0b7df29c68470..990289a69b785163ac95b3dfb28dde61e03d3b0b 100644 (file)
@@ -219,19 +219,18 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
        }
 }
 
-static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
-                     struct display *p, int mode, int softback_lines,
-                     int fg, int bg)
+static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+                      int softback_lines, int fg, int bg)
 {
        struct fb_cursor cursor;
-       struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+       struct fbcon_ops *ops = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
        int w = (vc->vc_font.height + 7) >> 3, c;
-       int y = real_y(p, vc->vc_y);
+       int y = real_y(ops->p, vc->vc_y);
        int attribute, use_sw = (vc->vc_cursor_type & 0x10);
        int err = 1, dx, dy;
        char *src;
-       u32 vyres = GETVYRES(p->scrollmode, info);
+       u32 vyres = GETVYRES(ops->p->scrollmode, info);
 
        if (!ops->fontbuffer)
                return;
@@ -303,7 +302,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
        }
 
        if (cursor.set & FB_CUR_SETSIZE ||
-           vc->vc_cursor_type != p->cursor_shape ||
+           vc->vc_cursor_type != ops->p->cursor_shape ||
            ops->cursor_state.mask == NULL ||
            ops->cursor_reset) {
                char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
@@ -323,10 +322,10 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
                kfree(ops->cursor_state.mask);
                ops->cursor_state.mask = mask;
 
-               p->cursor_shape = vc->vc_cursor_type;
+               ops->p->cursor_shape = vc->vc_cursor_type;
                cursor.set |= FB_CUR_SETSHAPE;
 
-               switch (p->cursor_shape & CUR_HWMASK) {
+               switch (ops->p->cursor_shape & CUR_HWMASK) {
                case CUR_NONE:
                        cur_height = 0;
                        break;
index 6d92b845620629fbfe7b9353b449ac741fa7b420..d44c5fa515fb3e9156d93d0e057c17d01d238e7d 100644 (file)
@@ -203,19 +203,18 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
        }
 }
 
-static void cw_cursor(struct vc_data *vc, struct fb_info *info,
-                     struct display *p, int mode, int softback_lines,
-                     int fg, int bg)
+static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+                     int softback_lines, int fg, int bg)
 {
        struct fb_cursor cursor;
-       struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+       struct fbcon_ops *ops = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
        int w = (vc->vc_font.height + 7) >> 3, c;
-       int y = real_y(p, vc->vc_y);
+       int y = real_y(ops->p, vc->vc_y);
        int attribute, use_sw = (vc->vc_cursor_type & 0x10);
        int err = 1, dx, dy;
        char *src;
-       u32 vxres = GETVXRES(p->scrollmode, info);
+       u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
        if (!ops->fontbuffer)
                return;
@@ -287,7 +286,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info,
        }
 
        if (cursor.set & FB_CUR_SETSIZE ||
-           vc->vc_cursor_type != p->cursor_shape ||
+           vc->vc_cursor_type != ops->p->cursor_shape ||
            ops->cursor_state.mask == NULL ||
            ops->cursor_reset) {
                char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
@@ -307,10 +306,10 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info,
                kfree(ops->cursor_state.mask);
                ops->cursor_state.mask = mask;
 
-               p->cursor_shape = vc->vc_cursor_type;
+               ops->p->cursor_shape = vc->vc_cursor_type;
                cursor.set |= FB_CUR_SETSHAPE;
 
-               switch (p->cursor_shape & CUR_HWMASK) {
+               switch (ops->p->cursor_shape & CUR_HWMASK) {
                case CUR_NONE:
                        cur_height = 0;
                        break;
index ec0dd8fe241c2fdcab9981890b439532b1e99ec3..2dc091fbd5c9c0d29066817b1c0c4ae436ef2178 100644 (file)
@@ -18,8 +18,7 @@
 #include "fbcon.h"
 #include "fbcon_rotate.h"
 
-static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
-                            struct display *p)
+static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
 {
        struct fbcon_ops *ops = info->fbcon_par;
        int len, err = 0;
@@ -28,12 +27,12 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
        u8 *dst;
 
        if (vc->vc_font.data == ops->fontdata &&
-           p->con_rotate == ops->cur_rotate)
+           ops->p->con_rotate == ops->cur_rotate)
                goto finished;
 
        src = ops->fontdata = vc->vc_font.data;
-       ops->cur_rotate = p->con_rotate;
-       len = (!p->userfont) ? 256 : FNTCHARCNT(src);
+       ops->cur_rotate = ops->p->con_rotate;
+       len = (!ops->p->userfont) ? 256 : FNTCHARCNT(src);
        s_cellsize = ((vc->vc_font.width + 7)/8) *
                vc->vc_font.height;
        d_cellsize = s_cellsize;
index 1b8f92fdc6a82f3c02b8c02096832d053ba6e1d9..75be5ce53dc541f74b15d014b2e652d6a627664c 100644 (file)
@@ -11,8 +11,6 @@
 #ifndef _FBCON_ROTATE_H
 #define _FBCON_ROTATE_H
 
-#define FNTCHARCNT(fd) (((int *)(fd))[-3])
-
 #define GETVYRES(s,i) ({                           \
         (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
         (i)->var.yres : (i)->var.yres_virtual; })
index 9dd059e8b64515f16f2b162adf91d465a1400b42..f56ed068a5bc753f3b54a52da1f8941ad60e0a34 100644 (file)
@@ -249,20 +249,19 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
        }
 }
 
-static void ud_cursor(struct vc_data *vc, struct fb_info *info,
-                     struct display *p, int mode, int softback_lines,
-                     int fg, int bg)
+static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+                     int softback_lines, int fg, int bg)
 {
        struct fb_cursor cursor;
-       struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
+       struct fbcon_ops *ops = info->fbcon_par;
        unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
        int w = (vc->vc_font.width + 7) >> 3, c;
-       int y = real_y(p, vc->vc_y);
+       int y = real_y(ops->p, vc->vc_y);
        int attribute, use_sw = (vc->vc_cursor_type & 0x10);
        int err = 1, dx, dy;
        char *src;
-       u32 vyres = GETVYRES(p->scrollmode, info);
-       u32 vxres = GETVXRES(p->scrollmode, info);
+       u32 vyres = GETVYRES(ops->p->scrollmode, info);
+       u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
        if (!ops->fontbuffer)
                return;
@@ -334,7 +333,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info,
        }
 
        if (cursor.set & FB_CUR_SETSIZE ||
-           vc->vc_cursor_type != p->cursor_shape ||
+           vc->vc_cursor_type != ops->p->cursor_shape ||
            ops->cursor_state.mask == NULL ||
            ops->cursor_reset) {
                char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
@@ -347,10 +346,10 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info,
                kfree(ops->cursor_state.mask);
                ops->cursor_state.mask = mask;
 
-               p->cursor_shape = vc->vc_cursor_type;
+               ops->p->cursor_shape = vc->vc_cursor_type;
                cursor.set |= FB_CUR_SETSHAPE;
 
-               switch (p->cursor_shape & CUR_HWMASK) {
+               switch (ops->p->cursor_shape & CUR_HWMASK) {
                case CUR_NONE:
                        cur_height = 0;
                        break;
index 8529bf08db28a92807b4e2f5d404be56917ff412..3957fc7523e2495ab397696e21dc8129eb3e39ff 100644 (file)
@@ -17,6 +17,8 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#include "fbcon.h"
+
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
        unsigned int scan_align = info->pixmap.scan_align - 1;
index cb25324a56357bfbdb0c7a9fe8619153441799ba..153352ca9461c030515c755e8867f465cf0fff1a 100644 (file)
@@ -80,9 +80,8 @@ static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
        return;
 }
 
-static void tile_cursor(struct vc_data *vc, struct fb_info *info,
-                       struct display *p, int mode, int softback_lines,
-                       int fg, int bg)
+static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+                       int softback_lines, int fg, int bg)
 {
        struct fb_tilecursor cursor;
        int use_sw = (vc->vc_cursor_type & 0x01);
@@ -130,10 +129,10 @@ static int tile_update_start(struct fb_info *info)
        return err;
 }
 
-void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
-                      struct display *p, struct fbcon_ops *ops)
+void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info)
 {
        struct fb_tilemap map;
+       struct fbcon_ops *ops = info->fbcon_par;
 
        ops->bmove = tile_bmove;
        ops->clear = tile_clear;
@@ -142,13 +141,13 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
        ops->cursor = tile_cursor;
        ops->update_start = tile_update_start;
 
-       if (p) {
+       if (ops->p) {
                map.width = vc->vc_font.width;
                map.height = vc->vc_font.height;
                map.depth = 1;
-               map.length = (p->userfont) ?
-                       FNTCHARCNT(p->fontdata) : 256;
-               map.data = p->fontdata;
+               map.length = (ops->p->userfont) ?
+                       FNTCHARCNT(ops->p->fontdata) : 256;
+               map.data = ops->p->fontdata;
                info->tileops->fb_settile(info, &map);
        }
 }
index 0b6af00d197e058af63663fad76fe84d6c802d57..ac90883dc3aa310ea23016ba9cf01f95165f91ba 100644 (file)
@@ -214,12 +214,11 @@ static void fb_cvt_print_name(struct fb_cvt_data *cvt)
 {
        u32 pixcount, pixcount_mod;
        int cnt = 255, offset = 0, read = 0;
-       u8 *buf = kmalloc(256, GFP_KERNEL);
+       u8 *buf = kzalloc(256, GFP_KERNEL);
 
        if (!buf)
                return;
 
-       memset(buf, 0, 256);
        pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000;
        pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000;
        pixcount_mod /= 1000;
index 10dfdf0352644d296247f3a18f17c3302f615189..32a9b69becc51d32764b6a75cbdfdad471dc5af7 100644 (file)
@@ -589,17 +589,19 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                return info->fbops->fb_read(file, buf, count, ppos);
        
        total_size = info->screen_size;
+
        if (total_size == 0)
                total_size = info->fix.smem_len;
 
        if (p >= total_size)
-           return 0;
+               return 0;
+
        if (count >= total_size)
-           count = total_size;
+               count = total_size;
+
        if (count + p > total_size)
                count = total_size - p;
 
-       cnt = 0;
        buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
                         GFP_KERNEL);
        if (!buffer)
@@ -636,6 +638,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        }
 
        kfree(buffer);
+
        return (err) ? err : cnt;
 }
 
@@ -648,7 +651,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        struct fb_info *info = registered_fb[fbidx];
        u32 *buffer, *src;
        u32 __iomem *dst;
-       int c, i, cnt = 0, err;
+       int c, i, cnt = 0, err = 0;
        unsigned long total_size;
 
        if (!info || !info->screen_base)
@@ -661,19 +664,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                return info->fbops->fb_write(file, buf, count, ppos);
        
        total_size = info->screen_size;
+
        if (total_size == 0)
                total_size = info->fix.smem_len;
 
        if (p > total_size)
-           return -ENOSPC;
+               return 0;
+
        if (count >= total_size)
-           count = total_size;
-       err = 0;
-       if (count + p > total_size) {
-           count = total_size - p;
-           err = -ENOSPC;
-       }
-       cnt = 0;
+               count = total_size;
+
+       if (count + p > total_size)
+               count = total_size - p;
+
        buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
                         GFP_KERNEL);
        if (!buffer)
@@ -687,12 +690,15 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        while (count) {
                c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
                src = buffer;
+
                if (copy_from_user(src, buf, c)) {
                        err = -EFAULT;
                        break;
                }
+
                for (i = c >> 2; i--; )
                        fb_writel(*src++, dst++);
+
                if (c & 3) {
                        u8 *src8 = (u8 *) src;
                        u8 __iomem *dst8 = (u8 __iomem *) dst;
@@ -702,11 +708,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
                        dst = (u32 __iomem *) dst8;
                }
+
                *ppos += c;
                buf += c;
                cnt += c;
                count -= c;
        }
+
        kfree(buffer);
 
        return (err) ? err : cnt;
@@ -1226,6 +1234,7 @@ fb_open(struct inode *inode, struct file *file)
                return -ENODEV;
        if (!try_module_get(info->fbops->owner))
                return -ENODEV;
+       file->private_data = info;
        if (info->fbops->fb_open) {
                res = info->fbops->fb_open(info,1);
                if (res)
@@ -1237,11 +1246,9 @@ fb_open(struct inode *inode, struct file *file)
 static int 
 fb_release(struct inode *inode, struct file *file)
 {
-       int fbidx = iminor(inode);
-       struct fb_info *info;
+       struct fb_info * const info = file->private_data;
 
        lock_kernel();
-       info = registered_fb[fbidx];
        if (info->fbops->fb_release)
                info->fbops->fb_release(info,1);
        module_put(info->fbops->owner);
index fc7965b66775983a97d62d10ab7805c475e0eb73..7c74e7325d95a1830ef0d36aac0680462ff62fac 100644 (file)
@@ -317,26 +317,29 @@ static int edid_is_monitor_block(unsigned char *block)
 static void calc_mode_timings(int xres, int yres, int refresh,
                              struct fb_videomode *mode)
 {
-       struct fb_var_screeninfo var;
-       struct fb_info info;
+       struct fb_var_screeninfo *var;
        
-       memset(&var, 0, sizeof(struct fb_var_screeninfo));
-       var.xres = xres;
-       var.yres = yres;
-       fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 
-                   refresh, &var, &info);
-       mode->xres = xres;
-       mode->yres = yres;
-       mode->pixclock = var.pixclock;
-       mode->refresh = refresh;
-       mode->left_margin = var.left_margin;
-       mode->right_margin = var.right_margin;
-       mode->upper_margin = var.upper_margin;
-       mode->lower_margin = var.lower_margin;
-       mode->hsync_len = var.hsync_len;
-       mode->vsync_len = var.vsync_len;
-       mode->vmode = 0;
-       mode->sync = 0;
+       var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
+
+       if (var) {
+               var->xres = xres;
+               var->yres = yres;
+               fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON,
+                           refresh, var, NULL);
+               mode->xres = xres;
+               mode->yres = yres;
+               mode->pixclock = var->pixclock;
+               mode->refresh = refresh;
+               mode->left_margin = var->left_margin;
+               mode->right_margin = var->right_margin;
+               mode->upper_margin = var->upper_margin;
+               mode->lower_margin = var->lower_margin;
+               mode->hsync_len = var->hsync_len;
+               mode->vsync_len = var->vsync_len;
+               mode->vmode = 0;
+               mode->sync = 0;
+               kfree(var);
+       }
 }
 
 static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
@@ -525,10 +528,9 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
        unsigned char *block;
        int num = 0, i;
 
-       mode = kmalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
+       mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
        if (mode == NULL)
                return NULL;
-       memset(mode, 0, 50 * sizeof(struct fb_videomode));
 
        if (edid == NULL || !edid_checksum(edid) || 
            !edid_check_header(edid)) {
@@ -1105,15 +1107,21 @@ static void fb_timings_dclk(struct __fb_timings *timings)
  */ 
 int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct __fb_timings timings;
+       struct __fb_timings *timings;
        u32 interlace = 1, dscan = 1;
-       u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
+       u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0;
+
+
+       timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL);
+
+       if (!timings)
+               return -ENOMEM;
 
        /* 
         * If monspecs are invalid, use values that are enough
         * for 640x480@60
         */
-       if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
+       if (!info || !info->monspecs.hfmax || !info->monspecs.vfmax ||
            !info->monspecs.dclkmax ||
            info->monspecs.hfmax < info->monspecs.hfmin ||
            info->monspecs.vfmax < info->monspecs.vfmin ||
@@ -1130,65 +1138,66 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
                dclkmax = info->monspecs.dclkmax;
        }
 
-       memset(&timings, 0, sizeof(struct __fb_timings));
-       timings.hactive = var->xres;
-       timings.vactive = var->yres;
+       timings->hactive = var->xres;
+       timings->vactive = var->yres;
        if (var->vmode & FB_VMODE_INTERLACED) { 
-               timings.vactive /= 2;
+               timings->vactive /= 2;
                interlace = 2;
        }
        if (var->vmode & FB_VMODE_DOUBLE) {
-               timings.vactive *= 2;
+               timings->vactive *= 2;
                dscan = 2;
        }
 
        switch (flags & ~FB_IGNOREMON) {
        case FB_MAXTIMINGS: /* maximize refresh rate */
-               timings.hfreq = hfmax;
-               fb_timings_hfreq(&timings);
-               if (timings.vfreq > vfmax) {
-                       timings.vfreq = vfmax;
-                       fb_timings_vfreq(&timings);
+               timings->hfreq = hfmax;
+               fb_timings_hfreq(timings);
+               if (timings->vfreq > vfmax) {
+                       timings->vfreq = vfmax;
+                       fb_timings_vfreq(timings);
                }
-               if (timings.dclk > dclkmax) {
-                       timings.dclk = dclkmax;
-                       fb_timings_dclk(&timings);
+               if (timings->dclk > dclkmax) {
+                       timings->dclk = dclkmax;
+                       fb_timings_dclk(timings);
                }
                break;
        case FB_VSYNCTIMINGS: /* vrefresh driven */
-               timings.vfreq = val;
-               fb_timings_vfreq(&timings);
+               timings->vfreq = val;
+               fb_timings_vfreq(timings);
                break;
        case FB_HSYNCTIMINGS: /* hsync driven */
-               timings.hfreq = val;
-               fb_timings_hfreq(&timings);
+               timings->hfreq = val;
+               fb_timings_hfreq(timings);
                break;
        case FB_DCLKTIMINGS: /* pixelclock driven */
-               timings.dclk = PICOS2KHZ(val) * 1000;
-               fb_timings_dclk(&timings);
+               timings->dclk = PICOS2KHZ(val) * 1000;
+               fb_timings_dclk(timings);
                break;
        default:
-               return -EINVAL;
+               err = -EINVAL;
                
        } 
        
-       if (!(flags & FB_IGNOREMON) && 
-           (timings.vfreq < vfmin || timings.vfreq > vfmax || 
-            timings.hfreq < hfmin || timings.hfreq > hfmax ||
-            timings.dclk < dclkmin || timings.dclk > dclkmax))
-               return -EINVAL;
-
-       var->pixclock = KHZ2PICOS(timings.dclk/1000);
-       var->hsync_len = (timings.htotal * 8)/100;
-       var->right_margin = (timings.hblank/2) - var->hsync_len;
-       var->left_margin = timings.hblank - var->right_margin - var->hsync_len;
-       
-       var->vsync_len = (3 * interlace)/dscan;
-       var->lower_margin = (1 * interlace)/dscan;
-       var->upper_margin = (timings.vblank * interlace)/dscan - 
-               (var->vsync_len + var->lower_margin);
+       if (err || (!(flags & FB_IGNOREMON) &&
+           (timings->vfreq < vfmin || timings->vfreq > vfmax ||
+            timings->hfreq < hfmin || timings->hfreq > hfmax ||
+            timings->dclk < dclkmin || timings->dclk > dclkmax))) {
+               err = -EINVAL;
+       } else {
+               var->pixclock = KHZ2PICOS(timings->dclk/1000);
+               var->hsync_len = (timings->htotal * 8)/100;
+               var->right_margin = (timings->hblank/2) - var->hsync_len;
+               var->left_margin = timings->hblank - var->right_margin -
+                       var->hsync_len;
+               var->vsync_len = (3 * interlace)/dscan;
+               var->lower_margin = (1 * interlace)/dscan;
+               var->upper_margin = (timings->vblank * interlace)/dscan -
+                       (var->vsync_len + var->lower_margin);
+       }
        
-       return 0;
+       kfree(timings);
+       return err;
 }
 #else
 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
index 08dac9580d15440728d5c6374ec7c2de20a8e86c..6d26057337e262e1c762ae2de279a02a9054273d 100644 (file)
@@ -43,10 +43,11 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
        if (size)
                fb_info_size += PADDING;
 
-       p = kmalloc(fb_info_size + size, GFP_KERNEL);
+       p = kzalloc(fb_info_size + size, GFP_KERNEL);
+
        if (!p)
                return NULL;
-       memset(p, 0, fb_info_size + size);
+
        info = (struct fb_info *) p;
 
        if (size)
@@ -106,8 +107,7 @@ static int mode_string(char *buf, unsigned int offset,
 static ssize_t store_mode(struct class_device *class_device, const char * buf,
                          size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        char mstr[100];
        struct fb_var_screeninfo var;
        struct fb_modelist *modelist;
@@ -137,8 +137,7 @@ static ssize_t store_mode(struct class_device *class_device, const char * buf,
 
 static ssize_t show_mode(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
 
        if (!fb_info->mode)
                return 0;
@@ -149,8 +148,7 @@ static ssize_t show_mode(struct class_device *class_device, char *buf)
 static ssize_t store_modes(struct class_device *class_device, const char * buf,
                           size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        LIST_HEAD(old_list);
        int i = count / sizeof(struct fb_videomode);
 
@@ -174,8 +172,7 @@ static ssize_t store_modes(struct class_device *class_device, const char * buf,
 
 static ssize_t show_modes(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        unsigned int i;
        struct list_head *pos;
        struct fb_modelist *modelist;
@@ -193,8 +190,7 @@ static ssize_t show_modes(struct class_device *class_device, char *buf)
 static ssize_t store_bpp(struct class_device *class_device, const char * buf,
                         size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        struct fb_var_screeninfo var;
        char ** last = NULL;
        int err;
@@ -208,8 +204,7 @@ static ssize_t store_bpp(struct class_device *class_device, const char * buf,
 
 static ssize_t show_bpp(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
 }
 
@@ -280,8 +275,7 @@ static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
 static ssize_t store_virtual(struct class_device *class_device,
                             const char * buf, size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        struct fb_var_screeninfo var;
        char *last = NULL;
        int err;
@@ -300,16 +294,14 @@ static ssize_t store_virtual(struct class_device *class_device,
 
 static ssize_t show_virtual(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual,
                        fb_info->var.yres_virtual);
 }
 
 static ssize_t show_stride(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length);
 }
 
@@ -320,7 +312,7 @@ static ssize_t show_stride(struct class_device *class_device, char *buf)
 static ssize_t store_cmap(struct class_device *class_device, const char *buf,
                          size_t count)
 {
-       struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        int rc, i, start, length, transp = 0;
 
        if ((count > PAGE_SIZE) || ((count % 16) != 0))
@@ -380,8 +372,7 @@ static ssize_t store_cmap(struct class_device *class_device, const char *buf,
 
 static ssize_t show_cmap(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        unsigned int i;
 
        if (!fb_info->cmap.red || !fb_info->cmap.blue ||
@@ -405,8 +396,7 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
 static ssize_t store_blank(struct class_device *class_device, const char * buf,
                           size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        char *last = NULL;
        int err;
 
@@ -422,41 +412,40 @@ static ssize_t store_blank(struct class_device *class_device, const char * buf,
 
 static ssize_t show_blank(struct class_device *class_device, char *buf)
 {
-//     struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+//     struct fb_info *fb_info = class_get_devdata(class_device);
        return 0;
 }
 
 static ssize_t store_console(struct class_device *class_device,
                             const char * buf, size_t count)
 {
-//     struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+//     struct fb_info *fb_info = class_get_devdata(class_device);
        return 0;
 }
 
 static ssize_t show_console(struct class_device *class_device, char *buf)
 {
-//     struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+//     struct fb_info *fb_info = class_get_devdata(class_device);
        return 0;
 }
 
 static ssize_t store_cursor(struct class_device *class_device,
                            const char * buf, size_t count)
 {
-//     struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+//     struct fb_info *fb_info = class_get_devdata(class_device);
        return 0;
 }
 
 static ssize_t show_cursor(struct class_device *class_device, char *buf)
 {
-//     struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+//     struct fb_info *fb_info = class_get_devdata(class_device);
        return 0;
 }
 
 static ssize_t store_pan(struct class_device *class_device, const char * buf,
                         size_t count)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        struct fb_var_screeninfo var;
        char *last = NULL;
        int err;
@@ -479,19 +468,40 @@ static ssize_t store_pan(struct class_device *class_device, const char * buf,
 
 static ssize_t show_pan(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info =
-               (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
        return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
                        fb_info->var.xoffset);
 }
 
 static ssize_t show_name(struct class_device *class_device, char *buf)
 {
-       struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+       struct fb_info *fb_info = class_get_devdata(class_device);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
 }
 
+static ssize_t store_fbstate(struct class_device *class_device,
+                       const char *buf, size_t count)
+{
+       struct fb_info *fb_info = class_get_devdata(class_device);
+       u32 state;
+       char *last = NULL;
+
+       state = simple_strtoul(buf, &last, 0);
+
+       acquire_console_sem();
+       fb_set_suspend(fb_info, (int)state);
+       release_console_sem();
+
+       return count;
+}
+
+static ssize_t show_fbstate(struct class_device *class_device, char *buf)
+{
+       struct fb_info *fb_info = class_get_devdata(class_device);
+       return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
+}
+
 static struct class_device_attribute class_device_attrs[] = {
        __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
        __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
@@ -507,6 +517,7 @@ static struct class_device_attribute class_device_attrs[] = {
        __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
        __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
        __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
+       __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate),
 };
 
 int fb_init_class_device(struct fb_info *fb_info)
index b37cea7d1094be96aea39340368d88cc7368b24d..4e39035cf335621481966593d7797ea77e4df965 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/vga.h>
 
@@ -107,7 +108,7 @@ static DEFINE_SPINLOCK(hga_reg_lock);
 
 /* Framebuffer driver structures */
 
-static struct fb_var_screeninfo hga_default_var = {
+static struct fb_var_screeninfo __initdata hga_default_var = {
        .xres           = 720,
        .yres           = 348,
        .xres_virtual   = 720,
@@ -121,7 +122,7 @@ static struct fb_var_screeninfo hga_default_var = {
        .width          = -1,
 };
 
-static struct fb_fix_screeninfo hga_fix = {
+static struct fb_fix_screeninfo __initdata hga_fix = {
        .id             = "HGA",
        .type           = FB_TYPE_PACKED_PIXELS,        /* (not sure) */
        .visual         = FB_VISUAL_MONO10,
@@ -131,8 +132,6 @@ static struct fb_fix_screeninfo hga_fix = {
        .accel          = FB_ACCEL_NONE
 };
 
-static struct fb_info fb_info;
-
 /* Don't assume that tty1 will be the initial current console. */
 static int release_io_port = 0;
 static int release_io_ports = 0;
@@ -549,10 +548,9 @@ static struct fb_ops hgafb_ops = {
         *  Initialization
         */
 
-static int __init hgafb_init(void)
+static int __init hgafb_probe(struct device *device)
 {
-       if (fb_get_options("hgafb", NULL))
-               return -ENODEV;
+       struct fb_info *info;
 
        if (! hga_card_detect()) {
                printk(KERN_INFO "hgafb: HGA card not detected.\n");
@@ -564,41 +562,95 @@ static int __init hgafb_init(void)
        printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
                hga_type_name, hga_vram_len/1024);
 
+       info = framebuffer_alloc(0, NULL);
+       if (!info) {
+               iounmap(hga_vram);
+               return -ENOMEM;
+       }
+
        hga_fix.smem_start = (unsigned long)hga_vram;
        hga_fix.smem_len = hga_vram_len;
 
-       fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
-       fb_info.var = hga_default_var;
-       fb_info.fix = hga_fix;
-       fb_info.monspecs.hfmin = 0;
-       fb_info.monspecs.hfmax = 0;
-       fb_info.monspecs.vfmin = 10000;
-       fb_info.monspecs.vfmax = 10000;
-       fb_info.monspecs.dpms = 0;
-       fb_info.fbops = &hgafb_ops;
-       fb_info.screen_base = hga_vram;
-
-        if (register_framebuffer(&fb_info) < 0) {
+       info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+       info->var = hga_default_var;
+       info->fix = hga_fix;
+       info->monspecs.hfmin = 0;
+       info->monspecs.hfmax = 0;
+       info->monspecs.vfmin = 10000;
+       info->monspecs.vfmax = 10000;
+       info->monspecs.dpms = 0;
+       info->fbops = &hgafb_ops;
+       info->screen_base = hga_vram;
+
+        if (register_framebuffer(info) < 0) {
+               framebuffer_release(info);
                iounmap(hga_vram);
                return -EINVAL;
        }
 
         printk(KERN_INFO "fb%d: %s frame buffer device\n",
-               fb_info.node, fb_info.fix.id);
+               info->node, info->fix.id);
+       dev_set_drvdata(device, info);
        return 0;
 }
 
-#ifdef MODULE
-static void __exit hgafb_exit(void)
+static int hgafb_remove(struct device *device)
 {
+       struct fb_info *info = dev_get_drvdata(device);
+
        hga_txt_mode();
        hga_clear_screen();
-       unregister_framebuffer(&fb_info);
+
+       if (info) {
+               unregister_framebuffer(info);
+               framebuffer_release(info);
+       }
+
        iounmap(hga_vram);
-       if (release_io_ports) release_region(0x3b0, 12);
-       if (release_io_port) release_region(0x3bf, 1);
+
+       if (release_io_ports)
+               release_region(0x3b0, 12);
+
+       if (release_io_port)
+               release_region(0x3bf, 1);
+
+       return 0;
+}
+
+static struct device_driver hgafb_driver = {
+       .name = "hgafb",
+       .bus  = &platform_bus_type,
+       .probe = hgafb_probe,
+       .remove = hgafb_remove,
+};
+
+static struct platform_device hgafb_device = {
+       .name = "hgafb",
+};
+
+static int __init hgafb_init(void)
+{
+       int ret;
+
+       if (fb_get_options("hgafb", NULL))
+               return -ENODEV;
+
+       ret = driver_register(&hgafb_driver);
+
+       if (!ret) {
+               ret = platform_device_register(&hgafb_device);
+               if (ret)
+                       driver_unregister(&hgafb_driver);
+       }
+
+       return ret;
+}
+
+static void __exit hgafb_exit(void)
+{
+       platform_device_unregister(&hgafb_device);
+       driver_unregister(&hgafb_driver);
 }
-#endif
 
 /* -------------------------------------------------------------------------
  *
@@ -613,7 +665,4 @@ MODULE_LICENSE("GPL");
 module_param(nologo, bool, 0);
 MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)");
 module_init(hgafb_init);
-
-#ifdef MODULE
 module_exit(hgafb_exit);
-#endif
index c61bad0da20f942c46c537a7107f27074467f8f8..bd410e06db73f1f267071450eba64d23a605a053 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/fb.h>
 #include "i810.h"
 #include "i810_regs.h"
+#include "i810_main.h"
 #include "../edid.h"
 
 #define I810_DDC 0x50
@@ -42,7 +43,7 @@
 
 static void i810i2c_setscl(void *data, int state)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
        u8                        __iomem *mmio = par->mmio_start_virtual;
 
index 64cd1c827cf00bbd241fe59f2efbc57929ecf71d..76764ea3486a7d31a77e0887548ea17696819672 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "i810_regs.h"
 #include "i810.h"
+#include "i810_main.h"
 
 static u32 i810fb_rop[] = {
        COLOR_COPY_ROP, /* ROP_COPY */
@@ -57,7 +58,7 @@ static inline void i810_report_error(u8 __iomem *mmio)
  */    
 static inline int wait_for_space(struct fb_info *info, u32 space)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 head, count = WAIT_COUNT, tail;
        u8 __iomem *mmio = par->mmio_start_virtual;
 
@@ -88,7 +89,7 @@ static inline int wait_for_space(struct fb_info *info, u32 space)
  */
 static inline int wait_for_engine_idle(struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
        int count = WAIT_COUNT;
 
@@ -116,7 +117,7 @@ static inline int wait_for_engine_idle(struct fb_info *info)
  */ 
 static inline u32 begin_iring(struct fb_info *info, u32 space)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        if (par->dev_flags & ALWAYS_SYNC) 
                wait_for_engine_idle(info);
@@ -161,7 +162,7 @@ static inline void source_copy_blit(int dwidth, int dheight, int dpitch,
                                    int xdir, int src, int dest, int rop, 
                                    int blit_bpp, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        if (begin_iring(info, 24 + IRING_PAD)) return;
 
@@ -195,7 +196,7 @@ static inline void color_blit(int width, int height, int pitch,  int dest,
                              int rop, int what, int blit_bpp, 
                              struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        if (begin_iring(info, 24 + IRING_PAD)) return;
 
@@ -236,7 +237,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch,
                                          int dest, const u32 *src, int bg,
                                          int fg, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        if (begin_iring(info, 24 + (dsize << 2) + IRING_PAD)) return;
 
@@ -254,7 +255,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch,
 
 static inline void load_front(int offset, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        if (begin_iring(info, 8 + IRING_PAD)) return;
 
@@ -296,7 +297,7 @@ static inline void i810fb_iring_enable(struct i810fb_par *par, u32 mode)
 
 void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 dx, dy, width, height, dest, rop = 0, color = 0;
 
        if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
@@ -322,7 +323,7 @@ void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
        
 void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir;
 
        if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
@@ -361,7 +362,7 @@ void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 
 void i810fb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 fg = 0, bg = 0, size, dst;
        
        if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
@@ -397,7 +398,7 @@ void i810fb_imageblit(struct fb_info *info, const struct fb_image *image)
 
 int i810fb_sync(struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        
        if (!info->var.accel_flags || par->dev_flags & LOCKUP)
                return 0;
@@ -407,7 +408,7 @@ int i810fb_sync(struct fb_info *info)
 
 void i810fb_load_front(u32 offset, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
 
        if (!info->var.accel_flags || par->dev_flags & LOCKUP)
@@ -427,7 +428,7 @@ void i810fb_load_front(u32 offset, struct fb_info *info)
  */
 void i810fb_init_ringbuffer(struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 tmp1, tmp2;
        u8 __iomem *mmio = par->mmio_start_virtual;
        
index 64f087a4466bc31a8dbaf572660b9832f3fed44b..9743d51e7f8ca35cd1325dcc4d5c3503dff1a156 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "i810_regs.h"
 #include "i810.h"
+#include "i810_main.h"
 
 /*
  * FIFO and Watermark tables - based almost wholly on i810_wmark.c in 
index c0c974b1afaa0285fd1cc753affc90f71c96e6f0..266d0ab926635fe760f646b00dbe8fe974d8124b 100644 (file)
 #include <linux/pci_ids.h>
 #include <linux/resource.h>
 #include <linux/unistd.h>
+#include <linux/console.h>
 
 #include <asm/io.h>
 #include <asm/div64.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif 
-
 #include <asm/page.h>
 
 #include "i810_regs.h"
 #include "i810.h"
 #include "i810_main.h"
 
+/*
+ * voffset - framebuffer offset in MiB from aperture start address.  In order for
+ * the driver to work with X, we must try to use memory holes left untouched by X. The
+ * following table lists where X's different surfaces start at.
+ *
+ * ---------------------------------------------
+ * :                :  64 MiB     : 32 MiB      :
+ * ----------------------------------------------
+ * : FrontBuffer    :   0         :  0          :
+ * : DepthBuffer    :   48        :  16         :
+ * : BackBuffer     :   56        :  24         :
+ * ----------------------------------------------
+ *
+ * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to
+ * 15 + 1 MiB of Framebuffer memory.  For 32 MiB Aperture sizes, a v_offset of 8 MiB should
+ * work, allowing 7 + 1 MiB of Framebuffer memory.
+ * Note, the size of the hole may change depending on how much memory you allocate to X,
+ * and how the memory is split up between these surfaces.
+ *
+ * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with
+ * DRI disabled.  But if the Frontbuffer is overlapped, X will fail to load.
+ *
+ * Experiment with v_offset to find out which works best for you.
+ */
+static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */
+static u32 voffset          __initdata = 0;
+
+static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
+static int  __devinit i810fb_init_pci (struct pci_dev *dev,
+                                      const struct pci_device_id *entry);
+static void __exit i810fb_remove_pci(struct pci_dev *dev);
+static int i810fb_resume(struct pci_dev *dev);
+static int i810fb_suspend(struct pci_dev *dev, pm_message_t state);
+
+/* Chipset Specific Functions */
+static int i810fb_set_par    (struct fb_info *info);
+static int i810fb_getcolreg  (u8 regno, u8 *red, u8 *green, u8 *blue,
+                             u8 *transp, struct fb_info *info);
+static int i810fb_setcolreg  (unsigned regno, unsigned red, unsigned green, unsigned blue,
+                             unsigned transp, struct fb_info *info);
+static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
+static int i810fb_blank      (int blank_mode, struct fb_info *info);
+
+/* Initialization */
+static void i810fb_release_resource       (struct fb_info *info, struct i810fb_par *par);
+
 /* PCI */
 static const char *i810_pci_list[] __devinitdata = {
        "Intel(R) 810 Framebuffer Device"                                 ,
@@ -776,7 +818,7 @@ static void i810_load_cursor_image(int width, int height, u8 *data,
 
 static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
        u8 red, green, blue, trans, temp;
 
@@ -949,7 +991,7 @@ static void set_color_bitfields(struct fb_var_screeninfo *var)
 static int i810_check_params(struct fb_var_screeninfo *var, 
                             struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        int line_length, vidmem, mode_valid = 0, retval = 0;
        u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
        /*
@@ -1043,7 +1085,7 @@ static int i810_check_params(struct fb_var_screeninfo *var,
  */
 static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
@@ -1154,7 +1196,7 @@ static void decode_var(const struct fb_var_screeninfo *var,
 static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, 
                            u8 *transp, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
        u8 temp;
 
@@ -1193,7 +1235,7 @@ static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue,
 
 static int i810fb_open(struct fb_info *info, int user)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 count = atomic_read(&par->use_count);
        
        if (count == 0) {
@@ -1212,7 +1254,7 @@ static int i810fb_open(struct fb_info *info, int user)
 
 static int i810fb_release(struct fb_info *info, int user)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 count;
        
        count = atomic_read(&par->use_count);
@@ -1234,7 +1276,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green,
                            unsigned blue, unsigned transp, 
                            struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
        u8 temp;
        int i;
@@ -1328,7 +1370,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int i810fb_pan_display(struct fb_var_screeninfo *var, 
                              struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u32 total;
        
        total = var->xoffset * par->depth + 
@@ -1340,7 +1382,7 @@ static int i810fb_pan_display(struct fb_var_screeninfo *var,
 
 static int i810fb_blank (int blank_mode, struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
        int mode = 0, pwr, scr_off = 0;
        
@@ -1385,7 +1427,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info)
 
 static int i810fb_set_par(struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        decode_var(&info->var, par);
        i810_load_regs(par);
@@ -1429,7 +1471,7 @@ static int i810fb_check_var(struct fb_var_screeninfo *var,
 
 static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       struct i810fb_par *par = (struct i810fb_par *)info->par;
+       struct i810fb_par *par = info->par;
        u8 __iomem *mmio = par->mmio_start_virtual;
 
        if (!par->dev_flags & LOCKUP)
@@ -1516,36 +1558,29 @@ static struct fb_ops i810fb_ops __devinitdata = {
 static int i810fb_suspend(struct pci_dev *dev, pm_message_t state)
 {
        struct fb_info *info = pci_get_drvdata(dev);
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
-       int blank = 0, prev_state = par->cur_state;
-
-       if (state.event == prev_state)
-               return 0;
+       struct i810fb_par *par = info->par;
 
        par->cur_state = state.event;
 
-       switch (state.event) {
-       case 1:
-               blank = VESA_VSYNC_SUSPEND;
-               break;
-       case 2:
-               blank = VESA_HSYNC_SUSPEND;
-               break;
-       case 3:
-               blank = VESA_POWERDOWN;
-               break;
-       default:
-               return -EINVAL;
+       if (state.event == PM_EVENT_FREEZE) {
+               dev->dev.power.power_state = state;
+               return 0;
        }
-       info->fbops->fb_blank(blank, info);
 
-       if (!prev_state) { 
-               agp_unbind_memory(par->i810_gtt.i810_fb_memory);
-               agp_unbind_memory(par->i810_gtt.i810_cursor_memory);
-               pci_disable_device(dev);
-       }
+       acquire_console_sem();
+       fb_set_suspend(info, 1);
+
+       if (info->fbops->fb_sync)
+               info->fbops->fb_sync(info);
+
+       i810fb_blank(FB_BLANK_POWERDOWN, info);
+       agp_unbind_memory(par->i810_gtt.i810_fb_memory);
+       agp_unbind_memory(par->i810_gtt.i810_cursor_memory);
+
        pci_save_state(dev);
+       pci_disable_device(dev);
        pci_set_power_state(dev, pci_choose_state(dev, state));
+       release_console_sem();
 
        return 0;
 }
@@ -1553,23 +1588,29 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t state)
 static int i810fb_resume(struct pci_dev *dev) 
 {
        struct fb_info *info = pci_get_drvdata(dev);
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
+       int cur_state = par->cur_state;
+
+       par->cur_state = PM_EVENT_ON;
 
-       if (par->cur_state == 0)
+       if (cur_state == PM_EVENT_FREEZE) {
+               pci_set_power_state(dev, PCI_D0);
                return 0;
+       }
 
-       pci_restore_state(dev);
+       acquire_console_sem();
        pci_set_power_state(dev, PCI_D0);
+       pci_restore_state(dev);
        pci_enable_device(dev);
+       pci_set_master(dev);
        agp_bind_memory(par->i810_gtt.i810_fb_memory,
                        par->fb.offset);
        agp_bind_memory(par->i810_gtt.i810_cursor_memory,
                        par->cursor_heap.offset);
-
+       i810fb_set_par(info);
+       fb_set_suspend (info, 0);
        info->fbops->fb_blank(VESA_NO_BLANKING, info);
-
-       par->cur_state = 0;
-
+       release_console_sem();
        return 0;
 }
 /***********************************************************************
@@ -1610,7 +1651,7 @@ static void __devinit i810_fix_offsets(struct i810fb_par *par)
 
 static int __devinit i810_alloc_agp_mem(struct fb_info *info)
 {
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
        int size;
        struct agp_bridge_data *bridge;
        
@@ -2074,7 +2115,7 @@ static void i810fb_release_resource(struct fb_info *info,
 static void __exit i810fb_remove_pci(struct pci_dev *dev)
 {
        struct fb_info *info = pci_get_drvdata(dev);
-       struct i810fb_par *par = (struct i810fb_par *) info->par;
+       struct i810fb_par *par = info->par;
 
        unregister_framebuffer(info);  
        i810fb_release_resource(info, par);
index 06072a6466f2cee0fc46be91e9e11b9fc716bea3..51d4f3d4116dda55e130360b89cc02e06cdfa984 100644 (file)
 #ifndef __I810_MAIN_H__
 #define __I810_MAIN_H__
 
-static int  __devinit i810fb_init_pci (struct pci_dev *dev, 
-                                      const struct pci_device_id *entry);
-static void __exit i810fb_remove_pci(struct pci_dev *dev);
-static int i810fb_resume(struct pci_dev *dev);
-static int i810fb_suspend(struct pci_dev *dev, pm_message_t state);
-
-/*
- * voffset - framebuffer offset in MiB from aperture start address.  In order for
- * the driver to work with X, we must try to use memory holes left untouched by X. The 
- * following table lists where X's different surfaces start at.  
- * 
- * ---------------------------------------------
- * :                :  64 MiB     : 32 MiB      :
- * ----------------------------------------------
- * : FrontBuffer    :   0         :  0          :
- * : DepthBuffer    :   48        :  16         :
- * : BackBuffer     :   56        :  24         :
- * ----------------------------------------------
- *
- * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to
- * 15 + 1 MiB of Framebuffer memory.  For 32 MiB Aperture sizes, a v_offset of 8 MiB should
- * work, allowing 7 + 1 MiB of Framebuffer memory.
- * Note, the size of the hole may change depending on how much memory you allocate to X,
- * and how the memory is split up between these surfaces.  
- *
- * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with
- * DRI disabled.  But if the Frontbuffer is overlapped, X will fail to load.
- * 
- * Experiment with v_offset to find out which works best for you.
- */
-static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */
-static u32 voffset          __initdata = 0;
-
-static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
-
-/* Chipset Specific Functions */
-static int i810fb_set_par    (struct fb_info *info);
-static int i810fb_getcolreg  (u8 regno, u8 *red, u8 *green, u8 *blue,
-                             u8 *transp, struct fb_info *info);
-static int i810fb_setcolreg  (unsigned regno, unsigned red, unsigned green, unsigned blue,
-                             unsigned transp, struct fb_info *info);
-static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static int i810fb_blank      (int blank_mode, struct fb_info *info);
-
-/* Initialization */
-static void i810fb_release_resource       (struct fb_info *info, struct i810fb_par *par);
-extern int __init agp_intel_init(void);
-
-
 /* Video Timings */
 extern void round_off_xres         (u32 *xres);
 extern void round_off_yres         (u32 *xres, u32 *yres);
@@ -101,7 +52,7 @@ static inline void i810_delete_i2c_busses(struct i810fb_par *par) { }
 
 /* Conditionals */
 #ifdef CONFIG_X86
-inline void flush_cache(void)
+static inline void flush_cache(void)
 {
        asm volatile ("wbinvd":::"memory");
 }
@@ -110,7 +61,9 @@ inline void flush_cache(void)
 #endif 
 
 #ifdef CONFIG_MTRR
-#define KERNEL_HAS_MTRR 1
+
+#include <asm/mtrr.h>
+
 static inline void __devinit set_mtrr(struct i810fb_par *par)
 {
        par->mtrr_reg = mtrr_add((u32) par->aperture.physical, 
@@ -128,7 +81,6 @@ static inline void unset_mtrr(struct i810fb_par *par)
                         par->aperture.size); 
 }
 #else
-#define KERNEL_HAS_MTRR 0
 #define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n")
 
 #define unset_mtrr(x) do { } while (0)
index 7fbe24206b190458b8b9aeb89e123cb47b8b6aa2..a5d813050db574ed36548ee82d848fcf46fd03de 100644 (file)
@@ -323,6 +323,7 @@ struct imstt_par {
        unsigned long cmap_regs_phys;
        __u8 *cmap_regs;
        __u32 ramdac;
+       __u32 palette[16];
 };
  
 enum {
@@ -657,7 +658,7 @@ set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp)
 static void
 set_imstt_regvals (struct fb_info *info, u_int bpp)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        struct imstt_regvals *init = &par->init;
        __u32 ctl, pitch, byteswap, scr;
 
@@ -749,7 +750,7 @@ set_imstt_regvals (struct fb_info *info, u_int bpp)
 static inline void
 set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 off = var->yoffset * (info->fix.line_length >> 3)
                    + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
        write_reg_le32(par->dc_regs, SSR, off);
@@ -863,7 +864,7 @@ imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 static int
 imsttfb_set_par(struct fb_info *info) 
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
                
        if (!compute_imstt_regvals(par, info->var.xres, info->var.yres))
                return -EINVAL;
@@ -881,7 +882,7 @@ static int
 imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
                   u_int transp, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        u_int bpp = info->var.bits_per_pixel;
 
        if (regno > 255)
@@ -905,14 +906,17 @@ imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
        if (regno < 16)
                switch (bpp) {
                        case 16:
-                               ((u16 *)info->pseudo_palette)[regno] = (regno << (info->var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno;
+                               par->palette[regno] =
+                                       (regno << (info->var.green.length ==
+                                       5 ? 10 : 11)) | (regno << 5) | regno;
                                break;
                        case 24:
-                               ((u32 *)info->pseudo_palette)[regno] = (regno << 16) | (regno << 8) | regno;
+                               par->palette[regno] =
+                                       (regno << 16) | (regno << 8) | regno;
                                break;
                        case 32: {
                                int i = (regno << 8) | regno;
-                               ((u32 *)info->pseudo_palette)[regno] = (i << 16) | i;
+                               par->palette[regno] = (i << 16) |i;
                                break;
                        }
                }
@@ -935,7 +939,7 @@ imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 static int 
 imsttfb_blank(int blank, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 ctrl;
 
        ctrl = read_reg_le32(par->dc_regs, STGCTL);
@@ -989,7 +993,7 @@ imsttfb_blank(int blank, struct fb_info *info)
 static void
 imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 { 
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 Bpp, line_pitch, bgc, dx, dy, width, height;
 
        bgc = rect->color;
@@ -1033,7 +1037,7 @@ imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 static void
 imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl;
        __u32 cnt, bltctl, sx, sy, dx, dy, height, width;
 
@@ -1195,7 +1199,7 @@ imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on)
 static int 
 imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
         u32 flags = cursor->set, fg, bg, xx, yy;
 
        if (cursor->dest == NULL && cursor->rop == ROP_XOR)
@@ -1266,7 +1270,7 @@ static int
 imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
              u_long arg, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        void __user *argp = (void __user *)arg;
        __u32 reg[2];
        __u8 idx[2];
@@ -1350,7 +1354,7 @@ static struct fb_ops imsttfb_ops = {
 static void __devinit
 init_imstt(struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 i, tmp, *ip, *end;
 
        tmp = read_reg_le32(par->dc_regs, PRC);
@@ -1413,7 +1417,7 @@ init_imstt(struct fb_info *info)
        if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len
            || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
                printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
-               kfree(info);
+               framebuffer_release(info);
                return;
        }
 
@@ -1449,7 +1453,7 @@ init_imstt(struct fb_info *info)
        fb_alloc_cmap(&info->cmap, 0, 0);
 
        if (register_framebuffer(info) < 0) {
-               kfree(info);
+               framebuffer_release(info);
                return;
        }
 
@@ -1474,26 +1478,21 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_ERR "imsttfb: no OF node for pci device\n");
 #endif /* CONFIG_PPC_OF */
 
-       size = sizeof(struct fb_info) + sizeof(struct imstt_par) +
-               sizeof(u32) * 16;
-
-       info = kmalloc(size, GFP_KERNEL);
+       info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);
 
        if (!info) {
                printk(KERN_ERR "imsttfb: Can't allocate memory\n");
                return -ENOMEM;
        }
 
-       memset(info, 0, size);
-
-       par = (struct imstt_par *) (info + 1);
+       par = info->par;
 
        addr = pci_resource_start (pdev, 0);
        size = pci_resource_len (pdev, 0);
 
        if (!request_mem_region(addr, size, "imsttfb")) {
                printk(KERN_ERR "imsttfb: Can't reserve memory region\n");
-               kfree(info);
+               framebuffer_release(info);
                return -ENODEV;
        }
 
@@ -1516,14 +1515,13 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        info->fix.smem_start = addr;
-       info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000);
+       info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
+                                           0x400000 : 0x800000);
        info->fix.mmio_start = addr + 0x800000;
        par->dc_regs = ioremap(addr + 0x800000, 0x1000);
        par->cmap_regs_phys = addr + 0x840000;
        par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
-       info->par = par;
-       info->pseudo_palette = (void *) (par + 1);
-       info->device = &pdev->dev;
+       info->pseudo_palette = par->palette;
        init_imstt(info);
 
        pci_set_drvdata(pdev, info);
@@ -1534,7 +1532,7 @@ static void __devexit
 imsttfb_remove(struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        int size = pci_resource_len(pdev, 0);
 
        unregister_framebuffer(info);
@@ -1542,7 +1540,7 @@ imsttfb_remove(struct pci_dev *pdev)
        iounmap(par->dc_regs);
        iounmap(info->screen_base);
        release_mem_region(info->fix.smem_start, size);
-       kfree(info);
+       framebuffer_release(info);
 }
 
 #ifndef MODULE
index 7e33cd307d47fe03b8315c9f3f105ad31b59cb3d..ab5285a7f1d6b1de4beff23674b8e93981dc28d7 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/pci.h>
 
 #include "STG4000Reg.h"
+#include "STG4000Interface.h"
 
 /* SDRAM fixed settings */
 #define SDRAM_CFG_0   0x49A1
index e75b3b4a4aa1adf3c1c525464e37c89e1f70f844..b7c83d5dfb139fb8d80e17703d9a573cbcda33f9 100644 (file)
@@ -11,7 +11,8 @@
 #ifndef _STG4000INTERFACE_H
 #define _STG4000INTERFACE_H
 
-struct pci_dev;
+#include <linux/pci.h>
+#include <video/kyro.h>
 
 /*
  * Ramdac Setup
index 2ae9bafacdd0cb0cc20f27756421249c54f4bcf0..a8c9713413e66938e4cc432a5d738e0adc54449b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 
 #include "STG4000Reg.h"
+#include "STG4000Interface.h"
 
 /* HW Defines */
 
index 5eb4d5c177bd1899a5caeea3d536a7d4ec414e2b..bcd359b6d4ff5a86dd31b48e1d9008c4e0f254bc 100644 (file)
@@ -73,8 +73,6 @@ static struct fb_var_screeninfo kyro_var __devinitdata = {
        .vmode          = FB_VMODE_NONINTERLACED,
 };
 
-static struct kyrofb_info *currentpar;
-
 typedef struct {
        STG4000REG __iomem *pSTGReg;    /* Virtual address of PCI register region */
        u32 ulNextFreeVidMem;   /* Offset from start of vid mem to next free region */
@@ -309,7 +307,7 @@ enum {
 /* Accessors */
 static int kyro_dev_video_mode_set(struct fb_info *info)
 {
-       struct kyrofb_info *par = (struct kyrofb_info *)info->par;
+       struct kyrofb_info *par = info->par;
 
        /* Turn off display */
        StopVTG(deviceInfo.pSTGReg);
@@ -402,7 +400,7 @@ static inline unsigned long get_line_length(int x, int bpp)
 
 static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct kyrofb_info *par = (struct kyrofb_info *)info->par;
+       struct kyrofb_info *par = info->par;
 
        if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) {
                printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel);
@@ -478,7 +476,7 @@ static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 static int kyrofb_set_par(struct fb_info *info)
 {
-       struct kyrofb_info *par = (struct kyrofb_info *)info->par;
+       struct kyrofb_info *par = info->par;
        unsigned long lineclock;
        unsigned long frameclock;
 
@@ -536,20 +534,22 @@ static int kyrofb_set_par(struct fb_info *info)
 static int kyrofb_setcolreg(u_int regno, u_int red, u_int green,
                            u_int blue, u_int transp, struct fb_info *info)
 {
+       struct kyrofb_info *par = info->par;
+
        if (regno > 255)
                return 1;       /* Invalid register */
 
        if (regno < 16) {
                switch (info->var.bits_per_pixel) {
                case 16:
-                       ((u16*)(info->pseudo_palette))[regno] =
+                       par->palette[regno] =
                             (red   & 0xf800) |
                            ((green & 0xfc00) >> 5) |
                            ((blue  & 0xf800) >> 11);
                        break;
                case 32:
                        red >>= 8; green >>= 8; blue >>= 8; transp >>= 8;
-                       ((u32*)(info->pseudo_palette))[regno] =
+                       par->palette[regno] =
                            (transp << 24) | (red << 16) | (green << 8) | blue;
                        break;
                }
@@ -675,6 +675,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        struct fb_info *info;
+       struct kyrofb_info *currentpar;
        unsigned long size;
        int err;
 
@@ -683,14 +684,11 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev,
                return err;
        }
 
-       size = sizeof(struct fb_info) + sizeof(struct kyrofb_info) + 16 * sizeof(u32);
-       info = kmalloc(size, GFP_KERNEL);
+       info = framebuffer_alloc(sizeof(struct kyrofb_info), &pdev->dev);
        if (!info)
                return -ENOMEM;
 
-       memset(info, 0, size);
-
-       currentpar = (struct kyrofb_info *)(info + 1);
+       currentpar = info->par;
 
        kyro_fix.smem_start = pci_resource_start(pdev, 0);
        kyro_fix.smem_len   = pci_resource_len(pdev, 0);
@@ -716,8 +714,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev,
 
        info->fbops             = &kyrofb_ops;
        info->fix               = kyro_fix;
-       info->par               = currentpar;
-       info->pseudo_palette    = (void *)(currentpar + 1);
+       info->pseudo_palette    = currentpar->palette;
        info->flags             = FBINFO_DEFAULT;
 
        SetCoreClockPLL(deviceInfo.pSTGReg, pdev);
@@ -741,7 +738,6 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev,
 
        fb_memset(info->screen_base, 0, size);
 
-       info->device = &pdev->dev;
        if (register_framebuffer(info) < 0)
                goto out_unmap;
 
@@ -757,7 +753,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev,
 out_unmap:
        iounmap(currentpar->regbase);
        iounmap(info->screen_base);
-       kfree(info);
+       framebuffer_release(info);
 
        return -EINVAL;
 }
@@ -765,7 +761,7 @@ out_unmap:
 static void __devexit kyrofb_remove(struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
-       struct kyrofb_info *par = (struct kyrofb_info *)info->par;
+       struct kyrofb_info *par = info->par;
 
        /* Reset the board */
        StopVTG(deviceInfo.pSTGReg);
@@ -789,7 +785,7 @@ static void __devexit kyrofb_remove(struct pci_dev *pdev)
 
        unregister_framebuffer(info);
        pci_set_drvdata(pdev, NULL);
-       kfree(info);
+       framebuffer_release(info);
 }
 
 static int __init kyrofb_init(void)
index a8c47ad2cdb6059d63671a685247018415b8632a..3a3e1804c56a507a23b320527d9c7373e4ca1266 100644 (file)
@@ -50,8 +50,6 @@
 #include <asm/mtrr.h>
 #endif
 
-#include "../console/fbcon.h"
-
 #if defined(CONFIG_PPC_PMAC)
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
@@ -351,8 +349,6 @@ struct matrox_bios {
                      } output;
 };
 
-extern struct display fb_display[];
-
 struct matrox_switch;
 struct matroxfb_driver;
 struct matroxfb_dh_fb_info;
index 35008af7db75771d007d64715238eba18219f1d4..c122d8743dd2ced2344027cce6c82b3bc651298f 100644 (file)
@@ -20,6 +20,8 @@
 #include <asm/uaccess.h>
 #include <asm/div64.h>
 
+#include "matroxfb_g450.h"
+
 /* Definition of the various controls */
 struct mctl {
        struct v4l2_queryctrl desc;
index d9d3e9f6c08e245d54c8cf0621b340e03708fcc3..455a46ce840c3360d93d33ddbc56b16b493b138a 100644 (file)
@@ -192,11 +192,8 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
        unsigned int wd;
        unsigned int divider;
        int i;
-       int fwidth;
        struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw);
 
-       fwidth = 8;
-
        DBG(__FUNCTION__)
 
        hw->SEQ[0] = 0x00;
@@ -235,10 +232,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
        hw->ATTR[16] = 0x41;
        hw->ATTR[17] = 0xFF;
        hw->ATTR[18] = 0x0F;
-       if (fwidth == 9)
-               hw->ATTR[19] = 0x08;
-       else
-               hw->ATTR[19] = 0x00;
+       hw->ATTR[19] = 0x00;
        hw->ATTR[20] = 0x00;
 
        hd = m->HDisplay >> 3;
index 8486e77872dc0a6c1789f230ed85dc9717d1ee6d..e18c9f98a40188f1deccea933f7f4607371a33a1 100644 (file)
@@ -485,7 +485,7 @@ static void vgaHWRestore(const struct fb_info *info,
  */
 static inline int neo2200_sync(struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        int waitcycles;
 
        while (readl(&par->neo2200->bltStat) & 1)
@@ -525,7 +525,7 @@ static inline void neo2200_wait_fifo(struct fb_info *info,
 static inline void neo2200_accel_init(struct fb_info *info,
                                      struct fb_var_screeninfo *var)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        Neo2200 __iomem *neo2200 = par->neo2200;
        u32 bltMod, pitch;
 
@@ -560,7 +560,7 @@ static inline void neo2200_accel_init(struct fb_info *info,
 static int
 neofb_open(struct fb_info *info, int user)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        int cnt = atomic_read(&par->ref_count);
 
        if (!cnt) {
@@ -575,7 +575,7 @@ neofb_open(struct fb_info *info, int user)
 static int
 neofb_release(struct fb_info *info, int user)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        int cnt = atomic_read(&par->ref_count);
 
        if (!cnt)
@@ -590,7 +590,7 @@ neofb_release(struct fb_info *info, int user)
 static int
 neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        unsigned int pixclock = var->pixclock;
        struct xtimings timings;
        int memlen, vramlen;
@@ -757,7 +757,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 static int neofb_set_par(struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        struct xtimings timings;
        unsigned char temp;
        int i, clock_hi = 0;
@@ -1216,7 +1216,7 @@ static int neofb_set_par(struct fb_info *info)
 static void neofb_update_start(struct fb_info *info,
                               struct fb_var_screeninfo *var)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        struct vgastate *state = &par->state;
        int oldExtCRTDispAddr;
        int Base;
@@ -1331,7 +1331,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info)
         *  wms...Enable VESA DPMS compatible powerdown mode
         *  run "setterm -powersave powerdown" to take advantage
         */
-       struct neofb_par *par = (struct neofb_par *)info->par;
+       struct neofb_par *par = info->par;
        int seqflags, lcdflags, dpmsflags, reg;
 
        switch (blank_mode) {
@@ -1404,7 +1404,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info)
 static void
 neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        u_long dst, rop;
 
        dst = rect->dx + rect->dy * info->var.xres_virtual;
@@ -1440,7 +1440,7 @@ static void
 neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
        u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        u_long src, dst, bltCntl;
 
        bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
@@ -1472,7 +1472,7 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 static void
 neo2200_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        int s_pitch = (image->width * image->depth + 7) >> 3;
        int scan_align = info->pixmap.scan_align - 1;
        int buf_align = info->pixmap.buf_align - 1;
@@ -1686,7 +1686,7 @@ static struct fb_videomode __devinitdata mode800x480 = {
 static int __devinit neo_map_mmio(struct fb_info *info,
                                  struct pci_dev *dev)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
 
        DBG("neo_map_mmio");
 
@@ -1733,7 +1733,7 @@ static int __devinit neo_map_mmio(struct fb_info *info,
 
 static void neo_unmap_mmio(struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
 
        DBG("neo_unmap_mmio");
 
@@ -1796,7 +1796,7 @@ static void neo_unmap_video(struct fb_info *info)
 
 #ifdef CONFIG_MTRR
        {
-               struct neofb_par *par = (struct neofb_par *) info->par;
+               struct neofb_par *par = info->par;
 
                mtrr_del(par->mtrr, info->fix.smem_start,
                         info->fix.smem_len);
@@ -1811,7 +1811,7 @@ static void neo_unmap_video(struct fb_info *info)
 
 static int __devinit neo_scan_monitor(struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        unsigned char type, display;
        int w;
 
@@ -1890,7 +1890,7 @@ static int __devinit neo_scan_monitor(struct fb_info *info)
 
 static int __devinit neo_init_hw(struct fb_info *info)
 {
-       struct neofb_par *par = (struct neofb_par *) info->par;
+       struct neofb_par *par = info->par;
        int videoRam = 896;
        int maxClock = 65000;
        int CursorMem = 1024;
@@ -2014,7 +2014,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
        struct fb_info *info;
        struct neofb_par *par;
 
-       info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 256, &dev->dev);
+       info = framebuffer_alloc(sizeof(struct neofb_par), &dev->dev);
 
        if (!info)
                return NULL;
@@ -2081,7 +2081,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
        info->fix.accel = id->driver_data;
 
        info->fbops = &neofb_ops;
-       info->pseudo_palette = (void *) (par + 1);
+       info->pseudo_palette = par->palette;
        return info;
 }
 
index b989358437b3723e4e26dddb4b597b85c411fccb..99c3a8e6a2375eac0e51f3c74d34630da465c324 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/pci.h>
 #include "nv_type.h"
 #include "nv_local.h"
+#include "nv_proto.h"
 
 void NVLockUnlock(struct nvidia_par *par, int Lock)
 {
@@ -848,7 +849,7 @@ void NVCalcStateExt(struct nvidia_par *par,
                    int width,
                    int hDisplaySize, int height, int dotClock, int flags)
 {
-       int pixelDepth, VClk;
+       int pixelDepth, VClk = 0;
        /*
         * Save mode parameters.
         */
@@ -938,15 +939,24 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
 
        if (par->Architecture == NV_ARCH_04) {
                NV_WR32(par->PFB, 0x0200, state->config);
-       } else if ((par->Chipset & 0xfff0) == 0x0090) {
-               for (i = 0; i < 15; i++) {
-                       NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
-                       NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1);
-               }
-       } else {
+       } else if ((par->Architecture < NV_ARCH_40) ||
+                  (par->Chipset & 0xfff0) == 0x0040) {
                for (i = 0; i < 8; i++) {
                        NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
-                       NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1);
+                       NV_WR32(par->PFB, 0x0244 + (i * 0x10),
+                               par->FbMapSize - 1);
+               }
+       } else {
+               int regions = 12;
+
+               if (((par->Chipset & 0xfff0) == 0x0090) ||
+                   ((par->Chipset & 0xfff0) == 0x01D0) ||
+                   ((par->Chipset & 0xfff0) == 0x0290))
+                       regions = 15;
+               for(i = 0; i < regions; i++) {
+                       NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
+                       NV_WR32(par->PFB, 0x0604 + (i * 0x10),
+                               par->FbMapSize - 1);
                }
        }
 
@@ -1182,11 +1192,17 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                        NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF);
                } else {
                        if (par->Architecture >= NV_ARCH_40) {
+                               u32 tmp;
+
                                NV_WR32(par->PGRAPH, 0x0084, 0x401287c0);
                                NV_WR32(par->PGRAPH, 0x008C, 0x60de8051);
                                NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
                                NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);
 
+                               tmp = NV_RD32(par->REGS, 0x1540) & 0xff;
+                               for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++);
+                               NV_WR32(par->PGRAPH, 0x5000, i);
+
                                if ((par->Chipset & 0xfff0) == 0x0040) {
                                        NV_WR32(par->PGRAPH, 0x09b0,
                                                0x83280fff);
@@ -1211,6 +1227,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                                0xffff7fff);
                                        break;
                                case 0x00C0:
+                               case 0x0120:
                                        NV_WR32(par->PGRAPH, 0x0828,
                                                0x007596ff);
                                        NV_WR32(par->PGRAPH, 0x082C,
@@ -1245,6 +1262,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                                0x00100000);
                                        break;
                                case 0x0090:
+                               case 0x0290:
                                        NV_WR32(par->PRAMDAC, 0x0608,
                                                NV_RD32(par->PRAMDAC, 0x0608) |
                                                0x00100000);
@@ -1310,14 +1328,44 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                }
                        }
 
-                       if ((par->Chipset & 0xfff0) == 0x0090) {
-                               for (i = 0; i < 60; i++)
-                                       NV_WR32(par->PGRAPH, 0x0D00 + i,
-                                               NV_RD32(par->PFB, 0x0600 + i));
+                       if ((par->Architecture < NV_ARCH_40) ||
+                           ((par->Chipset & 0xfff0) == 0x0040)) {
+                               for (i = 0; i < 32; i++) {
+                                       NV_WR32(par->PGRAPH, 0x0900 + i*4,
+                                               NV_RD32(par->PFB, 0x0240 +i*4));
+                                       NV_WR32(par->PGRAPH, 0x6900 + i*4,
+                                               NV_RD32(par->PFB, 0x0240 +i*4));
+                               }
                        } else {
-                               for (i = 0; i < 32; i++)
-                                       NV_WR32(par->PGRAPH, 0x0900 + i,
-                                               NV_RD32(par->PFB, 0x0240 + i));
+                               if (((par->Chipset & 0xfff0) == 0x0090) ||
+                                   ((par->Chipset & 0xfff0) == 0x01D0) ||
+                                   ((par->Chipset & 0xfff0) == 0x0290)) {
+                                       for (i = 0; i < 60; i++) {
+                                               NV_WR32(par->PGRAPH,
+                                                       0x0D00 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                               NV_WR32(par->PGRAPH,
+                                                       0x6900 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                       }
+                               } else {
+                                       for (i = 0; i < 48; i++) {
+                                               NV_WR32(par->PGRAPH,
+                                                       0x0900 + i*4,
+                                                       NV_RD32(par->PFB,
+                                                               0x0600 + i*4));
+                                               if(((par->Chipset & 0xfff0)
+                                                   != 0x0160) &&
+                                                  ((par->Chipset & 0xfff0)
+                                                   != 0x0220))
+                                                       NV_WR32(par->PGRAPH,
+                                                               0x6900 + i*4,
+                                                               NV_RD32(par->PFB,
+                                                                       0x0600 + i*4));
+                                       }
+                               }
                        }
 
                        if (par->Architecture >= NV_ARCH_40) {
@@ -1338,7 +1386,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
                                        NV_WR32(par->PGRAPH, 0x0868,
                                                par->FbMapSize - 1);
                                } else {
-                                       if((par->Chipset & 0xfff0) == 0x0090) {
+                                       if ((par->Chipset & 0xfff0) == 0x0090 ||
+                                           (par->Chipset & 0xfff0) == 0x01D0 ||
+                                           (par->Chipset & 0xfff0) == 0x0290) {
                                                NV_WR32(par->PGRAPH, 0x0DF0,
                                                        NV_RD32(par->PFB, 0x0200));
                                                NV_WR32(par->PGRAPH, 0x0DF4,
index 12f2884d3f0bd7da64b6fc37e2042fee4f05f5a6..bd9eca05e146d515a06d1c2c3e8e814d48c71ff8 100644 (file)
@@ -46,7 +46,7 @@ static void nvidia_gpio_setscl(void *data, int state)
 
 static void nvidia_gpio_setsda(void *data, int state)
 {
-       struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data;
+       struct nvidia_i2c_chan *chan = data;
        struct nvidia_par *par = chan->par;
        u32 val;
 
@@ -64,7 +64,7 @@ static void nvidia_gpio_setsda(void *data, int state)
 
 static int nvidia_gpio_getscl(void *data)
 {
-       struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data;
+       struct nvidia_i2c_chan *chan = data;
        struct nvidia_par *par = chan->par;
        u32 val = 0;
 
@@ -79,7 +79,7 @@ static int nvidia_gpio_getscl(void *data)
 
 static int nvidia_gpio_getsda(void *data)
 {
-       struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data;
+       struct nvidia_i2c_chan *chan = data;
        struct nvidia_par *par = chan->par;
        u32 val = 0;
 
@@ -136,13 +136,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
        par->chan[2].par = par;
 
        par->chan[0].ddc_base = 0x3e;
-       nvidia_setup_i2c_bus(&par->chan[0], "BUS1");
+       nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0");
 
        par->chan[1].ddc_base = 0x36;
-       nvidia_setup_i2c_bus(&par->chan[1], "BUS2");
+       nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1");
 
        par->chan[2].ddc_base = 0x50;
-       nvidia_setup_i2c_bus(&par->chan[2], "BUS3");
+       nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2");
 }
 
 void nvidia_delete_i2c_busses(struct nvidia_par *par)
index 3353103e8b0bd7416bb2ba05dbfb4ac21f52ec5c..b149a690ee0f854321717b0ec7a75e5e55ccbf02 100644 (file)
@@ -4,7 +4,7 @@
 #define __NV_PROTO_H__
 
 /* in nv_setup.c */
-void NVCommonSetup(struct fb_info *info);
+int NVCommonSetup(struct fb_info *info);
 void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value);
 u8 NVReadCrtc(struct nvidia_par *par, u8 index);
 void NVWriteGr(struct nvidia_par *par, u8 index, u8 value);
index 1f06a9f1bd0f52d893e4233111174281a23f130e..a18a9aebf05fb2f7ea9c428ee7171068b9bfd5c5 100644 (file)
@@ -285,28 +285,34 @@ static void nv10GetConfig(struct nvidia_par *par)
                        par->CrystalFreqKHz = 27000;
        }
 
-       par->CursorStart = (par->RamAmountKBytes - 96) * 1024;
        par->CURSOR = NULL;     /* can't set this here */
        par->MinVClockFreqKHz = 12000;
        par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000;
 }
 
-void NVCommonSetup(struct fb_info *info)
+int NVCommonSetup(struct fb_info *info)
 {
        struct nvidia_par *par = info->par;
-       struct fb_var_screeninfo var;
+       struct fb_var_screeninfo *var;
        u16 implementation = par->Chipset & 0x0ff0;
        u8 *edidA = NULL, *edidB = NULL;
-       struct fb_monspecs monitorA, monitorB;
+       struct fb_monspecs *monitorA, *monitorB;
        struct fb_monspecs *monA = NULL, *monB = NULL;
        int mobile = 0;
        int tvA = 0;
        int tvB = 0;
        int FlatPanel = -1;     /* really means the CRTC is slaved */
        int Television = 0;
+       int err = 0;
 
-       memset(&monitorA, 0, sizeof(struct fb_monspecs));
-       memset(&monitorB, 0, sizeof(struct fb_monspecs));
+       var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
+       monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL);
+       monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL);
+
+       if (!var || !monitorA || !monitorB) {
+               err = -ENOMEM;
+               goto done;
+       }
 
        par->PRAMIN = par->REGS + (0x00710000 / 4);
        par->PCRTC0 = par->REGS + (0x00600000 / 4);
@@ -382,6 +388,8 @@ void NVCommonSetup(struct fb_info *info)
        case 0x0146:
        case 0x0147:
        case 0x0148:
+       case 0x0098:
+       case 0x0099:
                mobile = 1;
                break;
        default:
@@ -406,9 +414,9 @@ void NVCommonSetup(struct fb_info *info)
                par->CRTCnumber = 0;
                if (nvidia_probe_i2c_connector(info, 1, &edidA))
                        nvidia_probe_of_connector(info, 1, &edidA);
-               if (edidA && !fb_parse_edid(edidA, &var)) {
+               if (edidA && !fb_parse_edid(edidA, var)) {
                        printk("nvidiafb: EDID found from BUS1\n");
-                       monA = &monitorA;
+                       monA = monitorA;
                        fb_edid_to_monspecs(edidA, monA);
                        FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0;
 
@@ -494,17 +502,17 @@ void NVCommonSetup(struct fb_info *info)
 
                if (nvidia_probe_i2c_connector(info, 1, &edidA))
                        nvidia_probe_of_connector(info, 1, &edidA);
-               if (edidA && !fb_parse_edid(edidA, &var)) {
+               if (edidA && !fb_parse_edid(edidA, var)) {
                        printk("nvidiafb: EDID found from BUS1\n");
-                       monA = &monitorA;
+                       monA = monitorA;
                        fb_edid_to_monspecs(edidA, monA);
                }
 
                if (nvidia_probe_i2c_connector(info, 2, &edidB))
                        nvidia_probe_of_connector(info, 2, &edidB);
-               if (edidB && !fb_parse_edid(edidB, &var)) {
+               if (edidB && !fb_parse_edid(edidB, var)) {
                        printk("nvidiafb: EDID found from BUS2\n");
-                       monB = &monitorB;
+                       monB = monitorB;
                        fb_edid_to_monspecs(edidB, monB);
                }
 
@@ -639,4 +647,9 @@ void NVCommonSetup(struct fb_info *info)
 
        kfree(edidA);
        kfree(edidB);
+done:
+       kfree(var);
+       kfree(monitorA);
+       kfree(monitorB);
+       return err;
 }
index bee09c6e48f61ce28224fa2282f6bd8f113f114a..dbcb8962e57dd790e9bf9e0dafc2363e805e7007 100644 (file)
@@ -284,6 +284,16 @@ static struct pci_device_id nvidiafb_pci_tbl[] = {
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200,
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT,
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_NVIDIA, 0x0252,
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {PCI_VENDOR_ID_NVIDIA, 0x0313,
@@ -418,6 +428,7 @@ static int noaccel __devinitdata = 0;
 static int noscale __devinitdata = 0;
 static int paneltweak __devinitdata = 0;
 static int vram __devinitdata = 0;
+static int bpp __devinitdata = 8;
 #ifdef CONFIG_MTRR
 static int nomtrr __devinitdata = 0;
 #endif
@@ -485,7 +496,7 @@ static int nvidia_backlight_levels[] = {
 
 static int nvidia_set_backlight_enable(int on, int level, void *data)
 {
-       struct nvidia_par *par = (struct nvidia_par *)data;
+       struct nvidia_par *par = data;
        u32 tmp_pcrt, tmp_pmc, fpcontrol;
 
        tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF;
@@ -1382,24 +1393,36 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
                                 info->monspecs.modedb_len, &info->modelist);
        fb_var_to_videomode(&modedb, &nvidiafb_default_var);
 
+       switch (bpp) {
+       case 0 ... 8:
+               bpp = 8;
+               break;
+       case 9 ... 16:
+               bpp = 16;
+               break;
+       default:
+               bpp = 32;
+               break;
+       }
+
        if (specs->modedb != NULL) {
                struct fb_videomode *modedb;
 
                modedb = fb_find_best_display(specs, &info->modelist);
                fb_videomode_to_var(&nvidiafb_default_var, modedb);
-               nvidiafb_default_var.bits_per_pixel = 8;
+               nvidiafb_default_var.bits_per_pixel = bpp;
        } else if (par->fpWidth && par->fpHeight) {
                char buf[16];
 
                memset(buf, 0, 16);
                snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight);
                fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
-                            specs->modedb_len, &modedb, 8);
+                            specs->modedb_len, &modedb, bpp);
        }
 
        if (mode_option)
                fb_find_mode(&nvidiafb_default_var, info, mode_option,
-                            specs->modedb, specs->modedb_len, &modedb, 8);
+                            specs->modedb, specs->modedb_len, &modedb, bpp);
 
        info->var = nvidiafb_default_var;
        info->fix.visual = (info->var.bits_per_pixel == 8) ?
@@ -1448,11 +1471,34 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
        return nvidiafb_check_var(&info->var, info);
 }
 
-static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
+static u32 __devinit nvidia_get_chipset(struct fb_info *info)
 {
+       struct nvidia_par *par = info->par;
+       u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
+
+       printk("nvidiafb: PCI id - %x\n", id);
+       if ((id & 0xfff0) == 0x00f0) {
+               /* pci-e */
+               printk("nvidiafb: PCI-E card\n");
+               id = NV_RD32(par->REGS, 0x1800);
+
+               if ((id & 0x0000ffff) == 0x000010DE)
+                       id = 0x10DE0000 | (id >> 16);
+               else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
+                       id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
+                            ((id >> 8) & 0x000000ff);
+       }
+
+       printk("nvidiafb: Actual id - %x\n", id);
+       return id;
+}
+
+static u32 __devinit nvidia_get_arch(struct fb_info *info)
+{
+       struct nvidia_par *par = info->par;
        u32 arch = 0;
 
-       switch (pd->device & 0x0ff0) {
+       switch (par->Chipset & 0x0ff0) {
        case 0x0100:            /* GeForce 256 */
        case 0x0110:            /* GeForce2 MX */
        case 0x0150:            /* GeForce2 */
@@ -1485,6 +1531,8 @@ static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
        case 0x0210:
        case 0x0220:
        case 0x0230:
+       case 0x0290:
+       case 0x0390:
                arch = NV_ARCH_40;
                break;
        case 0x0020:            /* TNT, TNT2 */
@@ -1513,7 +1561,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        if (!info)
                goto err_out;
 
-       par = (struct nvidia_par *)info->par;
+       par = info->par;
        par->pci_dev = pd;
 
        info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
@@ -1533,18 +1581,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
                goto err_out_request;
        }
 
-       par->Architecture = nvidia_get_arch(pd);
-
-       par->Chipset = (pd->vendor << 16) | pd->device;
-       printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
-
-       if (par->Architecture == 0) {
-               printk(KERN_ERR PFX "unknown NV_ARCH\n");
-               goto err_out_free_base0;
-       }
-
-       sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
-
        par->FlatPanel = flatpanel;
        if (flatpanel == 1)
                printk(KERN_INFO PFX "flatpanel support enabled\n");
@@ -1570,7 +1606,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
                goto err_out_free_base0;
        }
 
-       NVCommonSetup(info);
+       par->Chipset = nvidia_get_chipset(info);
+       printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);
+       par->Architecture = nvidia_get_arch(info);
+
+       if (par->Architecture == 0) {
+               printk(KERN_ERR PFX "unknown NV_ARCH\n");
+               goto err_out_arch;
+       }
+
+       sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
+
+       if (NVCommonSetup(info))
+               goto err_out_arch;
 
        par->FbAddress = nvidiafb_fix.smem_start;
        par->FbMapSize = par->RamAmountKBytes * 1024;
@@ -1581,10 +1629,15 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        if (par->FbMapSize > 64 * 1024 * 1024)
                par->FbMapSize = 64 * 1024 * 1024;
 
-       par->FbUsableSize = par->FbMapSize - (128 * 1024);
+       if(par->Architecture >= NV_ARCH_40)
+               par->FbUsableSize = par->FbMapSize - (560 * 1024);
+       else
+               par->FbUsableSize = par->FbMapSize - (128 * 1024);
        par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
            16 * 1024;
        par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
+       par->CursorStart = par->FbUsableSize + (32 * 1024);
+
        info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
        info->screen_size = par->FbUsableSize;
        nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
@@ -1640,21 +1693,22 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        NVTRACE_LEAVE();
        return 0;
 
-      err_out_iounmap_fb:
+err_out_iounmap_fb:
        iounmap(info->screen_base);
-      err_out_free_base1:
+err_out_free_base1:
        fb_destroy_modedb(info->monspecs.modedb);
        nvidia_delete_i2c_busses(par);
+err_out_arch:
        iounmap(par->REGS);
-      err_out_free_base0:
+err_out_free_base0:
        pci_release_regions(pd);
-      err_out_request:
+err_out_request:
        pci_disable_device(pd);
-      err_out_enable:
+err_out_enable:
        kfree(info->pixmap.addr);
-      err_out_kfree:
+err_out_kfree:
        framebuffer_release(info);
-      err_out:
+err_out:
        return -ENODEV;
 }
 
@@ -1729,6 +1783,8 @@ static int __devinit nvidiafb_setup(char *options)
 #endif
                } else if (!strncmp(this_opt, "fpdither:", 9)) {
                        fpdither = simple_strtol(this_opt+9, NULL, 0);
+               } else if (!strncmp(this_opt, "bpp:", 4)) {
+                       bpp = simple_strtoul(this_opt+4, NULL, 0);
                } else
                        mode_option = this_opt;
        }
@@ -1804,6 +1860,11 @@ module_param(vram, int, 0);
 MODULE_PARM_DESC(vram,
                 "amount of framebuffer memory to remap in MiB"
                 "(default=0 - remap entire memory)");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Specify initial video mode");
+module_param(bpp, int, 0);
+MODULE_PARM_DESC(bpp, "pixel width in bits"
+                "(default=8)");
 #ifdef CONFIG_MTRR
 module_param(nomtrr, bool, 0);
 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
index 0277ce031e5e0e3b5e941c71f6d4836ac8c2de3d..5fe197943deb4a1c1deea3fa3b71e716a93265b0 100644 (file)
@@ -91,6 +91,7 @@ struct pm2fb_par
        u32             mem_config;     /* MemConfig reg at probe */
        u32             mem_control;    /* MemControl reg at probe */
        u32             boot_address;   /* BootAddress reg at probe */
+       u32             palette[16];
 };
 
 /*
@@ -674,7 +675,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  */
 static int pm2fb_set_par(struct fb_info *info)
 {
-       struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+       struct pm2fb_par *par = info->par;
        u32 pixclock;
        u32 width, height, depth;
        u32 hsstart, hsend, hbend, htotal;
@@ -854,7 +855,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
                           unsigned blue, unsigned transp,
                           struct fb_info *info)
 {
-       struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+       struct pm2fb_par *par = info->par;
 
        if (regno >= info->cmap.len)  /* no. of hw registers */
                return 1;
@@ -929,7 +930,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
                case 16:
                case 24:
                case 32:        
-                       ((u32*)(info->pseudo_palette))[regno] = v;
+                       par->palette[regno] = v;
                        break;
                }
                return 0;
@@ -955,7 +956,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int pm2fb_pan_display(struct fb_var_screeninfo *var,
                             struct fb_info *info)
 {
-       struct pm2fb_par *p = (struct pm2fb_par *) info->par;
+       struct pm2fb_par *p = info->par;
        u32 base;
        u32 depth;
        u32 xres;
@@ -987,7 +988,7 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
  */
 static int pm2fb_blank(int blank_mode, struct fb_info *info)
 {
-       struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+       struct pm2fb_par *par = info->par;
        u32 video = par->video;
 
        DPRINTK("blank_mode %d\n", blank_mode);
@@ -1054,8 +1055,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
 {
        struct pm2fb_par *default_par;
        struct fb_info *info;
-       int size, err;
-       int err_retval = -ENXIO;
+       int err, err_retval = -ENXIO;
 
        err = pci_enable_device(pdev);
        if ( err ) {
@@ -1063,11 +1063,10 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
                return err;
        }
 
-       size = sizeof(struct pm2fb_par) + 256 * sizeof(u32);
-       info = framebuffer_alloc(size, &pdev->dev);
+       info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
        if ( !info )
                return -ENOMEM;
-       default_par = (struct pm2fb_par *) info->par;
+       default_par = info->par;
 
        switch (pdev->device) {
        case  PCI_DEVICE_ID_TI_TVP4020:
@@ -1171,7 +1170,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
 
        info->fbops             = &pm2fb_ops;
        info->fix               = pm2fb_fix;    
-       info->pseudo_palette    = (void *)(default_par + 1); 
+       info->pseudo_palette    = default_par->palette;
        info->flags             = FBINFO_DEFAULT |
                                   FBINFO_HWACCEL_YPAN;
 
index 3e9f96e9237d8cd3fc45080c0aa5b83219a79a7d..6c19ab6afb015f8dc371689c1c91f7d1b0f4ba73 100644 (file)
@@ -630,7 +630,7 @@ static void riva_load_video_mode(struct fb_info *info)
        int bpp, width, hDisplaySize, hDisplay, hStart,
            hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
        int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        struct riva_regs newmode;
        
        NVTRACE_ENTER();
@@ -925,7 +925,7 @@ riva_set_rop_solid(struct riva_par *par, int rop)
 
 static void riva_setup_accel(struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
 
        RIVA_FIFO_FREE(par->riva, Clip, 2);
        NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0);
@@ -979,7 +979,7 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
 #ifdef CONFIG_PMAC_BACKLIGHT
 static int riva_set_backlight_enable(int on, int level, void *data)
 {
-       struct riva_par *par = (struct riva_par *)data;
+       struct riva_par *par = data;
        U032 tmp_pcrt, tmp_pmc;
 
        tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
@@ -1008,7 +1008,7 @@ static int riva_set_backlight_level(int level, void *data)
 
 static int rivafb_open(struct fb_info *info, int user)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        int cnt = atomic_read(&par->ref_count);
 
        NVTRACE_ENTER();
@@ -1034,7 +1034,7 @@ static int rivafb_open(struct fb_info *info, int user)
 
 static int rivafb_release(struct fb_info *info, int user)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        int cnt = atomic_read(&par->ref_count);
 
        NVTRACE_ENTER();
@@ -1057,7 +1057,7 @@ static int rivafb_release(struct fb_info *info, int user)
 static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        struct fb_videomode *mode;
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        int nom, den;           /* translating from pixels->bytes */
        int mode_valid = 0;
        
@@ -1166,7 +1166,7 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 static int rivafb_set_par(struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
 
        NVTRACE_ENTER();
        /* vgaHWunlock() + riva unlock (0x7F) */
@@ -1205,43 +1205,19 @@ static int rivafb_set_par(struct fb_info *info)
 static int rivafb_pan_display(struct fb_var_screeninfo *var,
                              struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *)info->par;
+       struct riva_par *par = info->par;
        unsigned int base;
 
        NVTRACE_ENTER();
-       if (var->xoffset > (var->xres_virtual - var->xres))
-               return -EINVAL;
-       if (var->yoffset > (var->yres_virtual - var->yres))
-               return -EINVAL;
-
-       if (var->vmode & FB_VMODE_YWRAP) {
-               if (var->yoffset < 0
-                   || var->yoffset >= info->var.yres_virtual
-                   || var->xoffset) return -EINVAL;
-       } else {
-               if (var->xoffset + info->var.xres > info->var.xres_virtual ||
-                   var->yoffset + info->var.yres > info->var.yres_virtual)
-                       return -EINVAL;
-       }
-
        base = var->yoffset * info->fix.line_length + var->xoffset;
-
        par->riva.SetStartAddress(&par->riva, base);
-
-       info->var.xoffset = var->xoffset;
-       info->var.yoffset = var->yoffset;
-
-       if (var->vmode & FB_VMODE_YWRAP)
-               info->var.vmode |= FB_VMODE_YWRAP;
-       else
-               info->var.vmode &= ~FB_VMODE_YWRAP;
        NVTRACE_LEAVE();
        return 0;
 }
 
 static int rivafb_blank(int blank, struct fb_info *info)
 {
-       struct riva_par *par= (struct riva_par *)info->par;
+       struct riva_par *par= info->par;
        unsigned char tmp, vesa;
 
        tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
@@ -1304,7 +1280,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                          unsigned blue, unsigned transp,
                          struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *)info->par;
+       struct riva_par *par = info->par;
        RIVA_HW_INST *chip = &par->riva;
        int i;
 
@@ -1393,7 +1369,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
  */
 static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        u_int color, rop = 0;
 
        if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
@@ -1449,7 +1425,7 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect
  */
 static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
 
        if ((info->flags & FBINFO_HWACCEL_DISABLED)) {
                cfb_copyarea(info, region);
@@ -1495,7 +1471,7 @@ static inline void convert_bgcolor_16(u32 *col)
 static void rivafb_imageblit(struct fb_info *info, 
                             const struct fb_image *image)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        u32 fgx = 0, bgx = 0, width, tmp;
        u8 *cdat = (u8 *) image->data;
        volatile u32 __iomem *d;
@@ -1580,7 +1556,7 @@ static void rivafb_imageblit(struct fb_info *info,
  */
 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        u8 data[MAX_CURS * MAX_CURS/8];
        int i, set = cursor->set;
        u16 fg, bg;
@@ -1664,7 +1640,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 
 static int rivafb_sync(struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *)info->par;
+       struct riva_par *par = info->par;
 
        wait_for_idle(par);
        return 0;
@@ -1696,7 +1672,7 @@ static struct fb_ops riva_fb_ops = {
 static int __devinit riva_set_fbinfo(struct fb_info *info)
 {
        unsigned int cmap_len;
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
 
        NVTRACE_ENTER();
        info->flags = FBINFO_DEFAULT
@@ -1733,7 +1709,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info)
 #ifdef CONFIG_PPC_OF
 static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        struct device_node *dp;
        unsigned char *pedid = NULL;
        unsigned char *disptype = NULL;
@@ -1767,7 +1743,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
 #if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF)
 static int __devinit riva_get_EDID_i2c(struct fb_info *info)
 {
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        struct fb_var_screeninfo var;
        int i;
 
@@ -1837,7 +1813,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
 static void __devinit riva_get_edidinfo(struct fb_info *info)
 {
        struct fb_var_screeninfo *var = &rivafb_default_var;
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
 
        fb_edid_to_monspecs(par->EDID, &info->monspecs);
        fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len,
@@ -1909,7 +1885,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
                ret = -ENOMEM;
                goto err_ret;
        }
-       default_par = (struct riva_par *) info->par;
+       default_par = info->par;
        default_par->pdev = pd;
 
        info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
@@ -2070,7 +2046,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
 
 err_iounmap_screen_base:
 #ifdef CONFIG_FB_RIVA_I2C
-       riva_delete_i2c_busses((struct riva_par *) info->par);
+       riva_delete_i2c_busses(info->par);
 #endif
        iounmap(info->screen_base);
 err_iounmap_pramin:
@@ -2093,7 +2069,7 @@ err_ret:
 static void __exit rivafb_remove(struct pci_dev *pd)
 {
        struct fb_info *info = pci_get_drvdata(pd);
-       struct riva_par *par = (struct riva_par *) info->par;
+       struct riva_par *par = info->par;
        
        NVTRACE_ENTER();
        if (!info)
index 77151d8e076661d4a44fd92cd9d8737190725987..8b1967fc116ad19636309da4bd0cd77f4ed7ed9a 100644 (file)
@@ -30,7 +30,7 @@
 
 static void riva_gpio_setscl(void* data, int state)
 {
-       struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
+       struct riva_i2c_chan    *chan = data;
        struct riva_par         *par = chan->par;
        u32                     val;
 
@@ -48,7 +48,7 @@ static void riva_gpio_setscl(void* data, int state)
 
 static void riva_gpio_setsda(void* data, int state)
 {
-       struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
+       struct riva_i2c_chan    *chan = data;
        struct riva_par         *par = chan->par;
        u32                     val;
 
@@ -66,7 +66,7 @@ static void riva_gpio_setsda(void* data, int state)
 
 static int riva_gpio_getscl(void* data)
 {
-       struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
+       struct riva_i2c_chan    *chan = data;
        struct riva_par         *par = chan->par;
        u32                     val = 0;
 
@@ -81,7 +81,7 @@ static int riva_gpio_getscl(void* data)
 
 static int riva_gpio_getsda(void* data)
 {
-       struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
+       struct riva_i2c_chan    *chan = data;
        struct riva_par         *par = chan->par;
        u32                     val = 0;
 
index fe99d17a21d7f8a6b1f6bd39d6ea687322a1b1ed..d574dd3c9c8aabe3f9f779dff79cb36aa85d9e07 100644 (file)
@@ -552,7 +552,7 @@ static inline void modify_gpio(void __iomem *reg,
  * s3c2410fb_init_registers - Initialise all LCD-related registers
  */
 
-int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
+static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
 {
        unsigned long flags;
 
@@ -634,7 +634,7 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r)
 
 static char driver_name[]="s3c2410fb";
 
-int __init s3c2410fb_probe(struct platform_device *pdev)
+static int __init s3c2410fb_probe(struct platform_device *pdev)
 {
        struct s3c2410fb_info *info;
        struct fb_info     *fbinfo;
@@ -667,8 +667,6 @@ int __init s3c2410fb_probe(struct platform_device *pdev)
        info->fb = fbinfo;
        platform_set_drvdata(pdev, fbinfo);
 
-       s3c2410fb_init_registers(info);
-
        dprintk("devinit\n");
 
        strcpy(fbinfo->fix.id, driver_name);
@@ -701,8 +699,8 @@ int __init s3c2410fb_probe(struct platform_device *pdev)
        fbinfo->var.yres_virtual    = mach_info->yres.defval;
        fbinfo->var.bits_per_pixel  = mach_info->bpp.defval;
 
-       fbinfo->var.upper_margin    = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) +1;
-       fbinfo->var.lower_margin    = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) +1;
+       fbinfo->var.upper_margin    = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
+       fbinfo->var.lower_margin    = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1;
        fbinfo->var.vsync_len       = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
 
        fbinfo->var.left_margin     = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
index 3c98457783c42f4caf050c9c14060bef5cb583ac..00719a91479f9d772352c01588d439861558f79a 100644 (file)
@@ -49,7 +49,7 @@
 
 static void savage4_gpio_setscl(void *data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        unsigned int r;
 
        r = readl(chan->ioaddr + chan->reg);
@@ -63,7 +63,7 @@ static void savage4_gpio_setscl(void *data, int val)
 
 static void savage4_gpio_setsda(void *data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        unsigned int r;
        r = readl(chan->ioaddr + chan->reg);
@@ -77,21 +77,21 @@ static void savage4_gpio_setsda(void *data, int val)
 
 static int savage4_gpio_getscl(void *data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SCL_IN));
 }
 
 static int savage4_gpio_getsda(void *data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SDA_IN));
 }
 
 static void prosavage_gpio_setscl(void* data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        u32                       r;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
@@ -107,7 +107,7 @@ static void prosavage_gpio_setscl(void* data, int val)
 
 static void prosavage_gpio_setsda(void* data, int val)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
        unsigned int r;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
@@ -123,7 +123,7 @@ static void prosavage_gpio_setsda(void* data, int val)
 
 static int prosavage_gpio_getscl(void* data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
        return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
@@ -131,7 +131,7 @@ static int prosavage_gpio_getscl(void* data)
 
 static int prosavage_gpio_getsda(void* data)
 {
-       struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data;
+       struct savagefb_i2c_chan *chan = data;
 
        SET_CR_IX(chan->ioaddr, chan->reg);
        return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
@@ -140,10 +140,9 @@ static int prosavage_gpio_getsda(void* data)
 static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                                const char *name)
 {
-       int (*add_bus)(struct i2c_adapter *) = symbol_get(i2c_bit_add_bus);
        int rc = 0;
 
-       if (add_bus && chan->par) {
+       if (chan->par) {
                strcpy(chan->adapter.name, name);
                chan->adapter.owner             = THIS_MODULE;
                chan->adapter.id                = I2C_HW_B_SAVAGE;
@@ -161,7 +160,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                chan->algo.setscl(chan, 1);
                udelay(20);
 
-               rc = add_bus(&chan->adapter);
+               rc = i2c_bit_add_bus(&chan->adapter);
 
                if (rc == 0)
                        dev_dbg(&chan->par->pcidev->dev,
@@ -169,8 +168,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
                else
                        dev_warn(&chan->par->pcidev->dev,
                                 "Failed to register I2C bus %s.\n", name);
-
-               symbol_put(i2c_bit_add_bus);
        } else
                chan->par = NULL;
 
@@ -179,7 +176,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
 
 void savagefb_create_i2c_busses(struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        par->chan.par   = par;
 
        switch(info->fix.accel) {
@@ -193,6 +190,7 @@ void savagefb_create_i2c_busses(struct fb_info *info)
                par->chan.algo.getscl = prosavage_gpio_getscl;
                break;
        case FB_ACCEL_SAVAGE4:
+       case FB_ACCEL_SAVAGE2000:
                par->chan.reg         = 0xff20;
                par->chan.ioaddr      = par->mmio.vbase;
                par->chan.algo.setsda = savage4_gpio_setsda;
@@ -209,14 +207,10 @@ void savagefb_create_i2c_busses(struct fb_info *info)
 
 void savagefb_delete_i2c_busses(struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
-       int (*del_bus)(struct i2c_adapter *) =
-               symbol_get(i2c_bit_del_bus);
+       struct savagefb_par *par = info->par;
 
-       if (del_bus && par->chan.par) {
-               del_bus(&par->chan.adapter);
-               symbol_put(i2c_bit_del_bus);
-       }
+       if (par->chan.par)
+               i2c_bit_del_bus(&par->chan.adapter);
 
        par->chan.par = NULL;
 }
@@ -224,8 +218,6 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
 static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
 {
        u8 start = 0x0;
-       int (*transfer)(struct i2c_adapter *, struct i2c_msg *, int) =
-               symbol_get(i2c_transfer);
        struct i2c_msg msgs[] = {
                {
                        .addr   = SAVAGE_DDC,
@@ -239,21 +231,19 @@ static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan)
        };
        u8 *buf = NULL;
 
-       if (transfer && chan->par) {
+       if (chan->par) {
                buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
 
                if (buf) {
                        msgs[1].buf = buf;
 
-                       if (transfer(&chan->adapter, msgs, 2) != 2) {
+                       if (i2c_transfer(&chan->adapter, msgs, 2) != 2) {
                                dev_dbg(&chan->par->pcidev->dev,
                                        "Unable to read EDID block.\n");
                                kfree(buf);
                                buf = NULL;
                        }
                }
-
-               symbol_put(i2c_transfer);
        }
 
        return buf;
index bac8ea3a0108ac0bea6c10274103f2f46cf77ade..bbcc055d3bb75a28b15d249b9207f7e8b49104ff 100644 (file)
@@ -21,7 +21,7 @@ static u32 savagefb_rop[] = {
 
 int savagefb_sync(struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
 
        par->SavageWaitIdle(par);
        return 0;
@@ -29,7 +29,7 @@ int savagefb_sync(struct fb_info *info)
 
 void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int sx = region->sx, dx = region->dx;
        int sy = region->sy, dy = region->dy;
        int cmd;
@@ -63,7 +63,7 @@ void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 
 void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int cmd, color;
 
        if (!rect->width || !rect->height)
@@ -90,7 +90,7 @@ void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 
 void savagefb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int fg, bg, size, i, width;
        int cmd;
        u32 *src = (u32 *) image->data;
index 09e2f28419015559b0cd57a8b163acd65d45c36f..ab727eaa7f43f3819ca45cff046a3bf057e28b0c 100644 (file)
@@ -686,7 +686,7 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode
 static int savagefb_check_var (struct fb_var_screeninfo   *var,
                               struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int memlen, vramlen, mode_valid = 0;
 
        DBG("savagefb_check_var");
@@ -1025,7 +1025,7 @@ static int savagefb_setcolreg(unsigned        regno,
                              unsigned        transp,
                              struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
 
        if (regno >= NR_PALETTE)
                return -EINVAL;
@@ -1328,7 +1328,7 @@ static void savagefb_set_fix(struct fb_info *info)
 #if defined(CONFIG_FB_SAVAGE_ACCEL)
 static void savagefb_set_clip(struct fb_info *info)
 {
-    struct savagefb_par *par = (struct savagefb_par *)info->par;
+    struct savagefb_par *par = info->par;
     int cmd;
 
     cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW;
@@ -1342,7 +1342,7 @@ static void savagefb_set_clip(struct fb_info *info)
 
 static int savagefb_set_par (struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        struct fb_var_screeninfo *var = &info->var;
        int err;
 
@@ -1381,29 +1381,9 @@ static int savagefb_set_par (struct fb_info *info)
 static int savagefb_pan_display (struct fb_var_screeninfo *var,
                                 struct fb_info           *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
-       u_int y_bottom;
-
-       y_bottom = var->yoffset;
-
-       if (!(var->vmode & FB_VMODE_YWRAP))
-               y_bottom += var->yres;
-
-       if (var->xoffset > (var->xres_virtual - var->xres))
-               return -EINVAL;
-       if (y_bottom > info->var.yres_virtual)
-               return -EINVAL;
+       struct savagefb_par *par = info->par;
 
        savagefb_update_start (par, var);
-
-       info->var.xoffset = var->xoffset;
-       info->var.yoffset = var->yoffset;
-
-       if (var->vmode & FB_VMODE_YWRAP)
-               info->var.vmode |= FB_VMODE_YWRAP;
-       else
-               info->var.vmode &= ~FB_VMODE_YWRAP;
-
        return 0;
 }
 
@@ -1534,7 +1514,7 @@ static void savage_disable_mmio (struct savagefb_par *par)
 
 static int __devinit savage_map_mmio (struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        DBG ("savage_map_mmio");
 
        if (S3_SAVAGE3D_SERIES (par->chip))
@@ -1567,7 +1547,7 @@ static int __devinit savage_map_mmio (struct fb_info *info)
 
 static void __devinit savage_unmap_mmio (struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        DBG ("savage_unmap_mmio");
 
        savage_disable_mmio(par);
@@ -1581,7 +1561,7 @@ static void __devinit savage_unmap_mmio (struct fb_info *info)
 static int __devinit savage_map_video (struct fb_info *info,
                                       int video_len)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int resource;
 
        DBG("savage_map_video");
@@ -1619,7 +1599,7 @@ static int __devinit savage_map_video (struct fb_info *info,
 
 static void __devinit savage_unmap_video (struct fb_info *info)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
 
        DBG("savage_unmap_video");
 
@@ -1869,7 +1849,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
                                          struct pci_dev *dev,
                                          const struct pci_device_id *id)
 {
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct savagefb_par *par = info->par;
        int err = 0;
 
        par->pcidev  = dev;
@@ -2139,8 +2119,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
 
 static void __devexit savagefb_remove (struct pci_dev *dev)
 {
-       struct fb_info *info =
-               (struct fb_info *)pci_get_drvdata(dev);
+       struct fb_info *info = pci_get_drvdata(dev);
 
        DBG("savagefb_remove");
 
@@ -2174,9 +2153,8 @@ static void __devexit savagefb_remove (struct pci_dev *dev)
 
 static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
 {
-       struct fb_info *info =
-               (struct fb_info *)pci_get_drvdata(dev);
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct fb_info *info = pci_get_drvdata(dev);
+       struct savagefb_par *par = info->par;
 
        DBG("savagefb_suspend");
 
@@ -2210,9 +2188,8 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
 
 static int savagefb_resume (struct pci_dev* dev)
 {
-       struct fb_info *info =
-               (struct fb_info *)pci_get_drvdata(dev);
-       struct savagefb_par *par = (struct savagefb_par *)info->par;
+       struct fb_info *info = pci_get_drvdata(dev);
+       struct savagefb_par *par = info->par;
        int cur_state = par->pm_state;
 
        DBG("savage_resume");
index a01e7ecc15ed01daf66d0bcbad8a0834f85688bd..9b707771d7578a5746fb71c1ded1ffaa63ae70b1 100644 (file)
@@ -115,7 +115,8 @@ static struct fb_fix_screeninfo xxxfb_fix __initdata = {
     /*
      *  If your driver supports multiple boards or it supports multiple 
      *  framebuffers, you should make these arrays, or allocate them 
-     *  dynamically (using kmalloc()). 
+     *  dynamically using framebuffer_alloc() and free them with
+     *  framebuffer_release().
      */ 
 static struct fb_info info;
 
@@ -179,18 +180,31 @@ static int xxxfb_release(const struct fb_info *info, int user)
  *     intent to only test a mode and not actually set it. The stuff in 
  *     modedb.c is a example of this. If the var passed in is slightly 
  *     off by what the hardware can support then we alter the var PASSED in
- *     to what we can do. If the hardware doesn't support mode change 
- *     a -EINVAL will be returned by the upper layers. You don't need to 
- *     implement this function then. If you hardware doesn't support 
- *     changing the resolution then this function is not needed. In this
- *     case the driver woudl just provide a var that represents the static
- *     state the screen is in.
+ *     to what we can do.
+ *
+ *      For values that are off, this function must round them _up_ to the
+ *      next value that is supported by the hardware.  If the value is
+ *      greater than the highest value supported by the hardware, then this
+ *      function must return -EINVAL.
+ *
+ *      Exception to the above rule:  Some drivers have a fixed mode, ie,
+ *      the hardware is already set at boot up, and cannot be changed.  In
+ *      this case, it is more acceptable that this function just return
+ *      a copy of the currently working var (info->var). Better is to not
+ *      implement this function, as the upper layer will do the copying
+ *      of the current var for you.
+ *
+ *      Note:  This is the only function where the contents of var can be
+ *      freely adjusted after the driver has been registered. If you find
+ *      that you have code outside of this function that alters the content
+ *      of var, then you are doing something wrong.  Note also that the
+ *      contents of info->var must be left untouched at all times after
+ *      driver registration.
  *
  *     Returns negative errno on error, or zero on success.
  */
 static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-    const struct xxx_par *par = (const struct xxx_par *) info->par;
     /* ... */
     return 0;          
 }
@@ -204,14 +218,39 @@ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  *     fb_fix_screeninfo stored in fb_info. It doesn't not alter var in 
  *     fb_info since we are using that data. This means we depend on the
  *     data in var inside fb_info to be supported by the hardware. 
- *     xxxfb_check_var is always called before xxxfb_set_par to ensure this.
+ *
+ *      This function is also used to recover/restore the hardware to a
+ *      known working state.
+ *
+ *     xxxfb_check_var is always called before xxxfb_set_par to ensure that
+ *      the contents of var is always valid.
+ *
  *     Again if you can't change the resolution you don't need this function.
  *
+ *      However, even if your hardware does not support mode changing,
+ *      a set_par might be needed to at least initialize the hardware to
+ *      a known working state, especially if it came back from another
+ *      process that also modifies the same hardware, such as X.
+ *
+ *      If this is the case, a combination such as the following should work:
+ *
+ *      static int xxxfb_check_var(struct fb_var_screeninfo *var,
+ *                                struct fb_info *info)
+ *      {
+ *              *var = info->var;
+ *              return 0;
+ *      }
+ *
+ *      static int xxxfb_set_par(struct fb_info *info)
+ *      {
+ *              init your hardware here
+ *      }
+ *
  *     Returns negative errno on error, or zero on success.
  */
 static int xxxfb_set_par(struct fb_info *info)
 {
-    struct xxx_par *par = (struct xxx_par *) info->par;
+    struct xxx_par *par = info->par;
     /* ... */
     return 0;  
 }
@@ -258,70 +297,110 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
      *   var->{color}.offset contains start of bitfield
      *   var->{color}.length contains length of bitfield
      *   {hardwarespecific} contains width of DAC
-     *   cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
+     *   pseudo_palette[X] is programmed to (X << red.offset) |
+     *                                      (X << green.offset) |
+     *                                      (X << blue.offset)
      *   RAMDAC[X] is programmed to (red, green, blue)
+     *   color depth = SUM(var->{color}.length)
      *
      * Pseudocolor:
-     *    uses offset = 0 && length = DAC register width.
      *    var->{color}.offset is 0
-     *    var->{color}.length contains widht of DAC
-     *    cmap is not used
-     *    DAC[X] is programmed to (red, green, blue)
+     *    var->{color}.length contains width of DAC or the number of unique
+     *                        colors available (color depth)
+     *    pseudo_palette is not used
+     *    RAMDAC[X] is programmed to (red, green, blue)
+     *    color depth = var->{color}.length
+     *
+     * Static pseudocolor:
+     *    same as Pseudocolor, but the RAMDAC is not programmed (read-only)
+     *
+     * Mono01/Mono10:
+     *    Has only 2 values, black on white or white on black (fg on bg),
+     *    var->{color}.offset is 0
+     *    white = (1 << var->{color}.length) - 1, black = 0
+     *    pseudo_palette is not used
+     *    RAMDAC does not exist
+     *    color depth is always 2
+     *
      * Truecolor:
      *    does not use RAMDAC (usually has 3 of them).
      *    var->{color}.offset contains start of bitfield
      *    var->{color}.length contains length of bitfield
-     *    cmap is programmed to (red << red.offset) | (green << green.offset) |
-     *                      (blue << blue.offset) | (transp << transp.offset)
+     *    pseudo_palette is programmed to (red << red.offset) |
+     *                                    (green << green.offset) |
+     *                                    (blue << blue.offset) |
+     *                                    (transp << transp.offset)
      *    RAMDAC does not exist
+     *    color depth = SUM(var->{color}.length})
+     *
+     *  The color depth is used by fbcon for choosing the logo and also
+     *  for color palette transformation if color depth < 4
+     *
+     *  As can be seen from the above, the field bits_per_pixel is _NOT_
+     *  a criteria for describing the color visual.
+     *
+     *  A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor,
+     *  and higher than that, true/directcolor.  This is incorrect, one needs
+     *  to look at the fix->visual.
+     *
+     *  Another common mistake is using bits_per_pixel to calculate the color
+     *  depth.  The bits_per_pixel field does not directly translate to color
+     *  depth. You have to compute for the color depth (using the color
+     *  bitfields) and fix->visual as seen above.
+     */
+
+    /*
+     * This is the point where the color is converted to something that
+     * is acceptable by the hardware.
      */
 #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
-    switch (info->fix.visual) {
-       case FB_VISUAL_TRUECOLOR:
-       case FB_VISUAL_PSEUDOCOLOR:
-               red = CNVT_TOHW(red, info->var.red.length);
-               green = CNVT_TOHW(green, info->var.green.length);
-               blue = CNVT_TOHW(blue, info->var.blue.length);
-               transp = CNVT_TOHW(transp, info->var.transp.length);
-               break;
-       case FB_VISUAL_DIRECTCOLOR:
-              /* example here assumes 8 bit DAC. Might be different 
-               * for your hardware */  
-               red = CNVT_TOHW(red, 8);       
-               green = CNVT_TOHW(green, 8);
-               blue = CNVT_TOHW(blue, 8);
-               /* hey, there is bug in transp handling... */
-               transp = CNVT_TOHW(transp, 8);
-               break;
-    }
+    red = CNVT_TOHW(red, info->var.red.length);
+    green = CNVT_TOHW(green, info->var.green.length);
+    blue = CNVT_TOHW(blue, info->var.blue.length);
+    transp = CNVT_TOHW(transp, info->var.transp.length);
 #undef CNVT_TOHW
-    /* Truecolor has hardware independent palette */
-    if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
-       u32 v;
-
-       if (regno >= 16)
-           return -EINVAL;
-
-       v = (red << info->var.red.offset) |
-           (green << info->var.green.offset) |
-           (blue << info->var.blue.offset) |
-           (transp << info->var.transp.offset);
-
-       switch (info->var.bits_per_pixel) {
-               case 8:
-                       /* Yes some hand held devices have this. */ 
-                       ((u8*)(info->pseudo_palette))[regno] = v;
-                       break;  
-               case 16:
-                       ((u16*)(info->pseudo_palette))[regno] = v;
-                       break;
-               case 24:
-               case 32:        
-                       ((u32*)(info->pseudo_palette))[regno] = v;
-                       break;
-       }
-       return 0;
+    /*
+     * This is the point where the function feeds the color to the hardware
+     * palette after converting the colors to something acceptable by
+     * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and
+     * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette.
+     * If you have code that writes to the hardware CLUT, and it's not
+     * any of the above visuals, then you are doing something wrong.
+     */
+    if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
+       info->fix.visual == FB_VISUAL_TRUECOLOR)
+           write_{red|green|blue|transp}_to_clut();
+
+    /* This is the point were you need to fill up the contents of
+     * info->pseudo_palette. This structure is used _only_ by fbcon, thus
+     * it only contains 16 entries to match the number of colors supported
+     * by the console. The pseudo_palette is used only if the visual is
+     * in directcolor or truecolor mode.  With other visuals, the
+     * pseudo_palette is not used. (This might change in the future.)
+     *
+     * The contents of the pseudo_palette is in raw pixel format.  Ie, each
+     * entry can be written directly to the framebuffer without any conversion.
+     * The pseudo_palette is (void *).  However, if using the generic
+     * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette
+     * must be casted to (u32 *) _regardless_ of the bits per pixel. If the
+     * driver is using its own drawing functions, then it can use whatever
+     * size it wants.
+     */
+    if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+       info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+           u32 v;
+
+           if (regno >= 16)
+                   return -EINVAL;
+
+           v = (red << info->var.red.offset) |
+                   (green << info->var.green.offset) |
+                   (blue << info->var.blue.offset) |
+                   (transp << info->var.transp.offset);
+
+           ((u32*)(info->pseudo_palette))[regno] = v;
     }
+
     /* ... */
     return 0;
 }
@@ -340,6 +419,17 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int xxxfb_pan_display(struct fb_var_screeninfo *var,
                             const struct fb_info *info)
 {
+    /*
+     * If your hardware does not support panning, _do_ _not_ implement this
+     * function. Creating a dummy function will just confuse user apps.
+     */
+
+    /*
+     * Note that even if this function is fully functional, a setting of
+     * 0 in both xpanstep and ypanstep means that this function will never
+     * get called.
+     */
+
     /* ... */
     return 0;
 }
@@ -349,15 +439,20 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var,
  *      @blank_mode: the blank mode we want. 
  *      @info: frame buffer structure that represents a single frame buffer
  *
- *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
- *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a 
- *      video mode which doesn't support it. Implements VESA suspend
- *      and powerdown modes on hardware that supports disabling hsync/vsync:
- *      blank_mode == 2: suspend vsync
- *      blank_mode == 3: suspend hsync
- *      blank_mode == 4: powerdown
+ *      Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank.
+ *      Return 0 if blanking succeeded, != 0 if un-/blanking failed due to
+ *      e.g. a video mode which doesn't support it.
  *
- *      Returns negative errno on error, or zero on success.
+ *      Implements VESA suspend and powerdown modes on hardware that supports
+ *      disabling hsync/vsync:
+ *
+ *      FB_BLANK_NORMAL = display is blanked, syncs are on.
+ *      FB_BLANK_HSYNC_SUSPEND = hsync off
+ *      FB_BLANK_VSYNC_SUSPEND = vsync off
+ *      FB_BLANK_POWERDOWN =  hsync and vsync off
+ *
+ *      If implementing this function, at least support FB_BLANK_UNBLANK.
+ *      Return !0 for any modes that are unimplemented.
  *
  */
 static int xxxfb_blank(int blank_mode, const struct fb_info *info)
@@ -454,6 +549,14 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image)
  *     @data: The actual data used to construct the image on the display.
  *     @cmap: The colormap used for color images.   
  */
+
+/*
+ * The generic function, cfb_imageblit, expects that the bitmap scanlines are
+ * padded to the next byte.  Most hardware accelerators may require padding to
+ * the next u16 or the next u32.  If that is the case, the driver can specify
+ * this by setting info->pixmap.scan_align = 2 or 4.  See a more
+ * comprehensive description of the pixmap below.
+ */
 }
 
 /**
@@ -517,6 +620,7 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
  */
 void xxxfb_rotate(struct fb_info *info, int angle)
 {
+/* Will be deprecated */
 }
 
 /**
@@ -540,6 +644,9 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait)
  *                  so we can have consistent display output. 
  *
  *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *      If the driver has implemented its own hardware-based drawing function,
+ *      implementing this function is highly recommended.
  */
 void xxxfb_sync(struct fb_info *info)
 {
@@ -549,20 +656,25 @@ void xxxfb_sync(struct fb_info *info)
      *  Initialization
      */
 
-int __init xxxfb_init(void)
+/* static int __init xxfb_probe (struct device *device) -- for platform devs */
+static int __init xxxfb_probe(struct pci_dev *dev,
+                             const_struct pci_device_id *ent)
 {
+    struct fb_info *info;
+    struct xxx_par *par;
+    struct device = &dev->dev; /* for pci drivers */
     int cmap_len, retval;      
    
     /*
-     *  For kernel boot options (in 'video=xxxfb:<options>' format)
+     * Dynamically allocate info and par
      */
-#ifndef MODULE
-    char *option = NULL;
+    info = framebuffer_alloc(sizeof(struct xxx_par), device);
 
-    if (fb_get_options("xxxfb", &option))
-           return -ENODEV;
-    xxxfb_setup(option);
-#endif
+    if (!info) {
+           /* goto error path */
+    }
+
+    par = info->par;
 
     /* 
      * Here we set the screen_base to the virtual memory address
@@ -570,18 +682,87 @@ int __init xxxfb_init(void)
      * from the bus layer and then translate it to virtual memory
      * space via ioremap. Consult ioport.h. 
      */
-    info.screen_base = framebuffer_virtual_memory;     
-    info.fbops = &xxxfb_ops;
-    info.fix = xxxfb_fix;
-    info.pseudo_palette = pseudo_palette;
-
+    info->screen_base = framebuffer_virtual_memory;
+    info->fbops = &xxxfb_ops;
+    info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
+                           * used, so mark it as __initdata
+                           */
+    info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
+                                           * 16-member array
+                                           */
     /*
      * Set up flags to indicate what sort of acceleration your
      * driver can provide (pan/wrap/copyarea/etc.) and whether it
      * is a module -- see FBINFO_* in include/linux/fb.h
+     *
+     * If your hardware can support any of the hardware accelerated functions
+     * fbcon performance will improve if info->flags is set properly.
+     *
+     * FBINFO_HWACCEL_COPYAREA - hardware moves
+     * FBINFO_HWACCEL_FILLRECT - hardware fills
+     * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion
+     * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis
+     * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis
+     * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled
+     * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion
+     * FBINFO_MISC_TILEBLITTING - hardware can do tile blits
+     *
+     * NOTE: These are for fbcon use only.
+     */
+    info->flags = FBINFO_DEFAULT;
+
+/********************* This stage is optional ******************************/
+     /*
+     * The struct pixmap is a scratch pad for the drawing functions. This
+     * is where the monochrome bitmap is constructed by the higher layers
+     * and then passed to the accelerator.  For drivers that uses
+     * cfb_imageblit, you can skip this part.  For those that have a more
+     * rigorous requirement, this stage is needed
+     */
+
+    /* PIXMAP_SIZE should be small enough to optimize drawing, but not
+     * large enough that memory is wasted.  A safe size is
+     * (max_xres * max_font_height/8). max_xres is driver dependent,
+     * max_font_height is 32.
+     */
+    info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
+    if (!info->pixmap.addr) {
+           /* goto error */
+    }
+
+    info->pixmap.size = PIXMAP_SIZE;
+
+    /*
+     * FB_PIXMAP_SYSTEM - memory is in system ram
+     * FB_PIXMAP_IO     - memory is iomapped
+     * FB_PIXMAP_SYNC   - if set, will call fb_sync() per access to pixmap,
+     *                    usually if FB_PIXMAP_IO is set.
+     *
+     * Currently, FB_PIXMAP_IO is unimplemented.
+     */
+    info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+    /*
+     * scan_align is the number of padding for each scanline.  It is in bytes.
+     * Thus for accelerators that need padding to the next u32, put 4 here.
+     */
+    info->pixmap.scan_align = 4;
+
+    /*
+     * buf_align is the amount to be padded for the buffer. For example,
+     * the i810fb needs a scan_align of 2 but expects it to be fed with
+     * dwords, so a buf_align = 4 is required.
      */
-    info.flags = FBINFO_DEFAULT;
-    info.par = current_par;
+    info->pixmap.buf_align = 4;
+
+    /* access_align is how many bits can be accessed from the framebuffer
+     * ie. some epson cards allow 16-bit access only.  Most drivers will
+     * be safe with u32 here.
+     *
+     * NOTE: This field is currently unused.
+     */
+    info->pixmap.scan_align = 32
+/***************************** End optional stage ***************************/
 
     /*
      * This should give a reasonable default video mode. The following is
@@ -590,42 +771,145 @@ int __init xxxfb_init(void)
     if (!mode_option)
        mode_option = "640x480@60";             
 
-    retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8);
+    retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8);
   
     if (!retval || retval == 4)
        return -EINVAL;                 
 
     /* This has to been done !!! */    
-    fb_alloc_cmap(&info.cmap, cmap_len, 0);
+    fb_alloc_cmap(info->cmap, cmap_len, 0);
        
     /* 
      * The following is done in the case of having hardware with a static 
      * mode. If we are setting the mode ourselves we don't call this. 
      */        
-    info.var = xxxfb_var;
-       
-    if (register_framebuffer(&info) < 0)
+    info->var = xxxfb_var;
+
+    /*
+     * For drivers that can...
+     */
+    xxxfb_check_var(&info->var, info);
+
+    /*
+     * Does a call to fb_set_par() before register_framebuffer needed?  This
+     * will depend on you and the hardware.  If you are sure that your driver
+     * is the only device in the system, a call to fb_set_par() is safe.
+     *
+     * Hardware in x86 systems has a VGA core.  Calling set_par() at this
+     * point will corrupt the VGA console, so it might be safer to skip a
+     * call to set_par here and just allow fbcon to do it for you.
+     */
+    /* xxxfb_set_par(info); */
+
+    if (register_framebuffer(info) < 0)
        return -EINVAL;
-    printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node,
-          info.fix.id);
+    printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+          info->fix.id);
+    pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
     return 0;
 }
 
     /*
      *  Cleanup
      */
+/* static void __exit xxxfb_remove(struct device *device) */
+static void __exit xxxfb_remove(struct pci_dev *dev)
+{
+       struct fb_info *info = pci_get_drv_data(dev);
+       /* or dev_get_drv_data(device); */
+
+       if (info) {
+               unregister_framebuffer(info);
+               fb_dealloc_cmap(&info.cmap);
+               /* ... */
+               framebuffer_release(info);
+       }
+
+       return 0;
+}
 
-static void __exit xxxfb_cleanup(void)
+#if CONFIG_PCI
+/* For PCI drivers */
+static struct pci_driver xxxfb_driver = {
+       .name =         "xxxfb",
+       .id_table =     xxxfb_devices,
+       .probe =        xxxfb_probe,
+       .remove =       __devexit_p(xxxfb_remove),
+       .suspend =      xxxfb_suspend, /* optional */
+       .resume =       xxxfb_resume,  /* optional */
+};
+
+static int __init xxxfb_init(void)
 {
-    /*
-     *  If your driver supports multiple boards, you should unregister and
-     *  clean up all instances.
-     */
+       /*
+        *  For kernel boot options (in 'video=xxxfb:<options>' format)
+        */
+#ifndef MODULE
+       char *option = NULL;
 
-    unregister_framebuffer(info);
-    fb_dealloc_cmap(&info.cmap);
-    /* ... */
+       if (fb_get_options("xxxfb", &option))
+               return -ENODEV;
+       xxxfb_setup(option);
+#endif
+
+       return pci_register_driver(&xxxfb_driver);
+}
+
+static void __exit xxxfb_exit(void)
+{
+       pci_unregister_driver(&xxxfb_driver);
 }
+#else
+#include <linux/platform_device.h>
+/* for platform devices */
+static struct device_driver xxxfb_driver = {
+       .name = "xxxfb",
+       .bus  = &platform_bus_type,
+       .probe = xxxfb_probe,
+       .remove = xxxfb_remove,
+       .suspend = xxxfb_suspend, /* optional */
+       .resume = xxxfb_resume,   /* optional */
+};
+
+static struct platform_device xxxfb_device = {
+       .name = "xxxfb",
+};
+
+static int __init xxxfb_init(void)
+{
+       int ret;
+       /*
+        *  For kernel boot options (in 'video=xxxfb:<options>' format)
+        */
+#ifndef MODULE
+       char *option = NULL;
+
+       if (fb_get_options("xxxfb", &option))
+               return -ENODEV;
+       xxxfb_setup(option);
+#endif
+       ret = driver_register(&xxxfb_driver);
+
+       if (!ret) {
+               ret = platform_device_register(&xxxfb_device);
+               if (ret)
+                       driver_unregister(&xxxfb_driver);
+       }
+
+       return ret;
+}
+
+static void __exit xxxfb_exit(void)
+{
+       platform_device_unregister(&xxxfb_device);
+       driver_unregister(&xxxfb_driver);
+}
+#endif
+
+MODULE_LICENSE("GPL");
+module_init(xxxfb_init);
+module_exit(xxxfb_exit);
+
 
     /*
      *  Setup
index e0f14df840d927129bf4865248c1d066b5ebc6d6..8a5ce210bb27c6b6876dc83bf1b250819f49f32b 100644 (file)
@@ -382,7 +382,7 @@ static void sstfb_clear_screen(struct fb_info *info)
 static int sstfb_check_var(struct fb_var_screeninfo *var,
                struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int hSyncOff   = var->xres + var->right_margin + var->left_margin;
        int vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
        int vBackPorch = var->left_margin, yDim = var->yres;
@@ -542,7 +542,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var,
  */
 static int sstfb_set_par(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
        struct pci_dev *sst_dev = par->dev;
        unsigned int freq;
@@ -748,13 +748,14 @@ static int sstfb_set_par(struct fb_info *info)
 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                            u_int transp, struct fb_info *info)
 {
+       struct sstfb_par *par = info->par;
        u32 col;
 
        f_dddprintk("sstfb_setcolreg\n");
        f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n",
                    regno, red, green, blue, transp);
-       if (regno >= 16)
-               return -EINVAL;
+       if (regno > 15)
+               return 0;
 
        red    >>= (16 - info->var.red.length);
        green  >>= (16 - info->var.green.length);
@@ -765,7 +766,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
            | (blue  << info->var.blue.offset)
            | (transp << info->var.transp.offset);
        
-       ((u32 *)info->pseudo_palette)[regno] = col;
+       par->palette[regno] = col;
 
        return 0;
 }
@@ -773,7 +774,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 static int sstfb_ioctl(struct inode *inode, struct file *file,
                        u_int cmd, u_long arg, struct fb_info *info )
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        struct pci_dev *sst_dev = par->dev;
        u32 fbiinit0, tmp, val;
        u_long p;
@@ -830,7 +831,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file,
 #if 0
 static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 stride = info->fix.line_length;
    
        if (!IS_VOODOO2(par))
@@ -855,7 +856,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
  */
 static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u32 stride = info->fix.line_length;
 
        if (!IS_VOODOO2(par))
@@ -925,7 +926,7 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
 
 static int __devinit sst_detect_att(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int i, mir, dir;
 
        for (i=0; i<3; i++) {
@@ -950,7 +951,7 @@ static int __devinit sst_detect_att(struct fb_info *info)
 
 static int __devinit sst_detect_ti(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int i, mir, dir;
 
        for (i = 0; i<3; i++) {
@@ -986,7 +987,7 @@ static int __devinit sst_detect_ti(struct fb_info *info)
  */
 static int __devinit sst_detect_ics(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        int m_clk0_1, m_clk0_7, m_clk1_b;
        int n_clk0_1, n_clk0_7, n_clk1_b;
        int i;
@@ -1023,7 +1024,7 @@ static int __devinit sst_detect_ics(struct fb_info *info)
 static int sst_set_pll_att_ti(struct fb_info *info, 
                const struct pll_timing *t, const int clock)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 cr0, cc;
 
        /* enable indexed mode */
@@ -1077,7 +1078,7 @@ static int sst_set_pll_att_ti(struct fb_info *info,
 static int sst_set_pll_ics(struct fb_info *info,
                const struct pll_timing *t, const int clock)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 pll_ctrl;
 
        sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
@@ -1114,7 +1115,7 @@ static int sst_set_pll_ics(struct fb_info *info,
 
 static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        u8 cr0;
 
        sst_dac_write(DACREG_WMA, 0);   /* backdoor */
@@ -1149,7 +1150,7 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp)
 
 static void sst_set_vidmod_ics(struct fb_info *info, const int bpp)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
 
        switch(bpp) {
        case 16:
@@ -1308,7 +1309,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
 
 static void  __devexit sst_shutdown(struct fb_info *info)
 {
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        struct pci_dev *dev = par->dev;
        struct pll_timing gfx_timings;
        int Fout;
@@ -1394,12 +1395,6 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        struct sst_spec *spec;
        int err;
 
-       struct all_info {
-               struct fb_info info;
-               struct sstfb_par par;
-               u32 pseudo_palette[16];
-       } *all;
-       
        /* Enable device in PCI config. */
        if ((err=pci_enable_device(pdev))) {
                eprintk("cannot enable device\n");
@@ -1407,14 +1402,13 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
        }
 
        /* Allocate the fb and par structures.  */
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all)
+       info = framebuffer_alloc(sizeof(struct sstfb_par), &pdev->dev);
+       if (!info)
                return -ENOMEM;
-       memset(all, 0, sizeof(*all));
-       pci_set_drvdata(pdev, all);
+
+       pci_set_drvdata(pdev, info);
        
-       info = &all->info;
-       par  = info->par = &all->par;
+       par  = info->par;
        fix  = &info->fix;
        
        par->type = id->driver_data;
@@ -1471,7 +1465,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
 
        info->flags     = FBINFO_DEFAULT;
        info->fbops     = &sstfb_ops;
-       info->pseudo_palette = &all->pseudo_palette;
+       info->pseudo_palette = par->palette;
 
        fix->type       = FB_TYPE_PACKED_PIXELS;
        fix->visual     = FB_VISUAL_TRUECOLOR;
@@ -1527,7 +1521,7 @@ fail_mmio_remap:
 fail_fb_mem:
        release_mem_region(fix->mmio_start, info->fix.mmio_len);
 fail_mmio_mem:
-       kfree(info);
+       framebuffer_release(info);
        return -ENXIO;  /* no voodoo detected */
 }
 
@@ -1537,7 +1531,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
        struct fb_info *info;
 
        info = pci_get_drvdata(pdev);
-       par = (struct sstfb_par *) info->par;
+       par = info->par;
        
        sst_shutdown(info);
        unregister_framebuffer(info);
@@ -1545,7 +1539,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
        iounmap(par->mmio_vbase);
        release_mem_region(info->fix.smem_start, 0x400000);
        release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
-       kfree(info);
+       framebuffer_release(info);
 }
 
 
@@ -1613,7 +1607,7 @@ static int sstfb_dump_regs(struct fb_info *info)
 
        const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]);
        const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]);
-       struct sstfb_par *par = (struct sstfb_par *) info->par;
+       struct sstfb_par *par = info->par;
        struct pci_dev *dev = par->dev;
        u32 pci_res[pci_s];
        u32 sst_res[sst_s];
index 9d53387e6a666119337353c3efeb2e42a77f60fd..3e7baf4c9fa8066be24cab44fb97e0aafd8fde5a 100644 (file)
@@ -291,7 +291,7 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
  
 static int banshee_wait_idle(struct fb_info *info)
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par; 
+       struct tdfx_par *par = info->par;
        int i = 0;
 
        banshee_make_room(par, 1);
@@ -364,7 +364,7 @@ static u32 do_calc_pll(int freq, int* freq_out)
 
 static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par; 
+       struct tdfx_par *par = info->par;
        int i;
 
        banshee_wait_idle(info);
@@ -469,7 +469,7 @@ static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
 
 static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par; 
+       struct tdfx_par *par = info->par;
        u32 lpitch;
 
        if (var->bits_per_pixel != 8  && var->bits_per_pixel != 16 &&
@@ -558,7 +558,7 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info)
 
 static int tdfxfb_set_par(struct fb_info *info)
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;   
+       struct tdfx_par *par = info->par;
        u32 hdispend, hsyncsta, hsyncend, htotal;
        u32 hd, hs, he, ht, hbs, hbe;
        u32 vd, vs, ve, vt, vbs, vbe;
@@ -780,7 +780,7 @@ static int tdfxfb_set_par(struct fb_info *info)
 static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,  
                            unsigned blue,unsigned transp,struct fb_info *info) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        u32 rgbcol;
    
        if (regno >= info->cmap.len || regno > 255) return 1;
@@ -794,11 +794,15 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
                        break;
                /* Truecolor has no hardware color palettes. */
                case FB_VISUAL_TRUECOLOR:
-                       rgbcol = (CNVT_TOHW( red, info->var.red.length) << info->var.red.offset) |
-                                (CNVT_TOHW( green, info->var.green.length) << info->var.green.offset) |
-                                (CNVT_TOHW( blue, info->var.blue.length) << info->var.blue.offset) |
-                                (CNVT_TOHW( transp, info->var.transp.length) << info->var.transp.offset);
-                               ((u32*)(info->pseudo_palette))[regno] = rgbcol;
+                       rgbcol = (CNVT_TOHW( red, info->var.red.length) <<
+                                 info->var.red.offset) |
+                                (CNVT_TOHW( green, info->var.green.length) <<
+                                 info->var.green.offset) |
+                                (CNVT_TOHW( blue, info->var.blue.length) <<
+                                 info->var.blue.offset) |
+                                (CNVT_TOHW( transp, info->var.transp.length) <<
+                                 info->var.transp.offset);
+                               par->palette[regno] = rgbcol;
                        break;
                default:
                        DPRINTK("bad depth %u\n", info->var.bits_per_pixel);
@@ -810,7 +814,7 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
 static int tdfxfb_blank(int blank, struct fb_info *info)
 { 
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        u32 dacmode, state = 0, vgablank = 0;
 
        dacmode = tdfx_inl(par, DACMODE);
@@ -855,7 +859,7 @@ static int tdfxfb_blank(int blank, struct fb_info *info)
 static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
                              struct fb_info *info) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        u32 addr;       
 
        if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
@@ -878,7 +882,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
  */
 static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        u32 bpp = info->var.bits_per_pixel;
        u32 stride = info->fix.line_length;
        u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
@@ -894,7 +898,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect
        if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
                tdfx_outl(par,  COLORFORE, rect->color);
        } else { /* FB_VISUAL_TRUECOLOR */
-               tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[rect->color]);
+               tdfx_outl(par, COLORFORE, par->palette[rect->color]);
        }
        tdfx_outl(par,  COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
        tdfx_outl(par,  DSTSIZE,    rect->width | (rect->height << 16));
@@ -906,7 +910,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect
  */
 static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)  
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
        u32 bpp = info->var.bits_per_pixel;
        u32 stride = info->fix.line_length;
@@ -938,7 +942,7 @@ static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area
 
 static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) 
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        int size = image->height * ((image->width * image->depth + 7)>>3);
        int fifo_free;
        int i, stride = info->fix.line_length;
@@ -961,8 +965,10 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
                                break;
                        case FB_VISUAL_TRUECOLOR:
                        default:
-                               tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[image->fg_color]);
-                               tdfx_outl(par, COLORBACK, ((u32*)(info->pseudo_palette))[image->bg_color]);
+                               tdfx_outl(par, COLORFORE,
+                                         par->palette[image->fg_color]);
+                               tdfx_outl(par, COLORBACK,
+                                         par->palette[image->bg_color]);
                }
 #ifdef __BIG_ENDIAN
                srcfmt = 0x400000 | BIT(20);
@@ -1007,7 +1013,7 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
 #ifdef TDFX_HARDWARE_CURSOR
 static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
        unsigned long flags;
 
        /*
@@ -1157,18 +1163,17 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
 {
        struct tdfx_par *default_par;
        struct fb_info *info;
-       int size, err, lpitch;
+       int err, lpitch;
 
        if ((err = pci_enable_device(pdev))) {
                printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err);
                return err;
        }
 
-       size = sizeof(struct tdfx_par)+256*sizeof(u32);
+       info = framebuffer_alloc(sizeof(struct tdfx_par), &pdev->dev);
 
-       info = framebuffer_alloc(size, &pdev->dev);
-
-       if (!info)      return -ENOMEM;
+       if (!info)
+               return -ENOMEM;
                
        default_par = info->par;
  
@@ -1248,7 +1253,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
    
        info->fbops             = &tdfxfb_ops;
        info->fix               = tdfx_fix;     
-       info->pseudo_palette    = (void *)(default_par + 1); 
+       info->pseudo_palette    = default_par->palette;
        info->flags             = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 #ifdef CONFIG_FB_3DFX_ACCEL
        info->flags             |= FBINFO_HWACCEL_FILLRECT |
@@ -1307,7 +1312,7 @@ out_err:
 }
 
 #ifndef MODULE
-void tdfxfb_setup(char *options)
+static void tdfxfb_setup(char *options)
 {
        char* this_opt;
 
@@ -1340,7 +1345,7 @@ void tdfxfb_setup(char *options)
 static void __devexit tdfxfb_remove(struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
-       struct tdfx_par *par = (struct tdfx_par *) info->par;
+       struct tdfx_par *par = info->par;
 
        unregister_framebuffer(info);
        iounmap(par->regbase_virt);
index 3e58ddc2bc3829de17a73ddb496ad67ac7624534..8982e540214c56b2de7d0299ce8c15258d76fc83 100644 (file)
@@ -57,7 +57,6 @@ static unsigned short  *pmi_base  = NULL;
 static void            (*pmi_start)(void);
 static void            (*pmi_pal)(void);
 static int             depth;
-static int             vga_compat;
 
 /* --------------------------------------------------------------------- */
 
@@ -67,15 +66,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
 #ifdef __i386__
        int offset;
 
-       if (!ypan)
-               return -EINVAL;
-       if (var->xoffset)
-               return -EINVAL;
-       if (var->yoffset > var->yres_virtual)
-               return -EINVAL;
-       if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)
-               return -EINVAL;
-
        offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
 
         __asm__ __volatile__(
@@ -90,37 +80,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
        return 0;
 }
 
-static int vesafb_blank(int blank, struct fb_info *info)
-{
-       int err = 1;
-
-       if (vga_compat) {
-               int loop = 10000;
-               u8 seq = 0, crtc17 = 0;
-
-               if (blank == FB_BLANK_POWERDOWN) {
-                       seq = 0x20;
-                       crtc17 = 0x00;
-                       err = 0;
-               } else {
-                       seq = 0x00;
-                       crtc17 = 0x80;
-                       err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
-               }
-
-               vga_wseq(NULL, 0x00, 0x01);
-               seq |= vga_rseq(NULL, 0x01) & ~0x20;
-               vga_wseq(NULL, 0x00, seq);
-
-               crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
-               while (loop--);
-               vga_wcrt(NULL, 0x17, crtc17);
-               vga_wseq(NULL, 0x00, 0x03);
-       }
-
-       return err;
-}
-
 static void vesa_setpalette(int regno, unsigned red, unsigned green,
                            unsigned blue)
 {
@@ -205,7 +164,6 @@ static struct fb_ops vesafb_ops = {
        .owner          = THIS_MODULE,
        .fb_setcolreg   = vesafb_setcolreg,
        .fb_pan_display = vesafb_pan_display,
-       .fb_blank       = vesafb_blank,
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
@@ -459,9 +417,8 @@ static int __init vesafb_probe(struct platform_device *dev)
        info->flags = FBINFO_FLAG_DEFAULT |
                (ypan) ? FBINFO_HWACCEL_YPAN : 0;
 
-       vga_compat = (screen_info.capabilities & 2) ? 0 : 1;
-       printk("vesafb: Mode is %sVGA compatible\n",
-              (vga_compat) ? "" : "not ");
+       if (!ypan)
+               info->fbops->fb_pan_display = NULL;
 
        if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
                err = -ENOMEM;
index 226ae8a8848202cdb1e09abc82b5dc608f27dc47..f3f16fd9f2316d32c89a2d9ae63b47864cd28fb0 100644 (file)
@@ -705,15 +705,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 static int vga16fb_pan_display(struct fb_var_screeninfo *var,
                               struct fb_info *info) 
 {
-       if (var->xoffset + info->var.xres > info->var.xres_virtual ||
-           var->yoffset + info->var.yres > info->var.yres_virtual)
-               return -EINVAL;
-
        vga16fb_pan_var(info, var);
-
-       info->var.xoffset = var->xoffset;
-       info->var.yoffset = var->yoffset;
-       info->var.vmode &= ~FB_VMODE_YWRAP;
        return 0;
 }
 
index d9e01daee630dae2283c27bdf559dd93597b5c1a..15179ec62339f4dd6a02897442ded8bf85d6ab3e 100644 (file)
@@ -356,10 +356,11 @@ int save_vga(struct vgastate *state)
 {
        struct regstate *saved;
 
-       saved = kmalloc(sizeof(struct regstate), GFP_KERNEL);
+       saved = kzalloc(sizeof(struct regstate), GFP_KERNEL);
+
        if (saved == NULL)
                return 1;
-       memset (saved, 0, sizeof(struct regstate));
+
        state->vidstate = (void *)saved;
                
        if (state->flags & VGA_SAVE_CMAP) {
index ae0f06b3c11a041659d6fea8db12e0cf0732114e..2c4fa75be025db71498905564520905a07ad3782 100644 (file)
@@ -91,7 +91,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
        sb->s_op = &v9fs_super_ops;
 
        sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
-           MS_NODIRATIME | MS_NOATIME;
+           MS_NOATIME;
 }
 
 /**
index 382e3b2883d5b59bfba82a78a3a30f6f1e340da9..ef78e3a42d322c5435fc200f93f5c93a18ddc75f 100644 (file)
@@ -798,7 +798,7 @@ config PROC_KCORE
 
 config PROC_VMCORE
         bool "/proc/vmcore support (EXPERIMENTAL)"
-        depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP
+        depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP
         help
         Exports the dump image of crashed kernel in ELF format.
 
index 35e9aec608e4945565a5f20bc829006da5a9d72d..1db711319c80f5fe260c5459ac66a1a035439da5 100644 (file)
@@ -14,7 +14,7 @@ obj-y :=      open.o read_write.o file_table.o buffer.o  bio.o super.o \
 
 obj-$(CONFIG_INOTIFY)          += inotify.o
 obj-$(CONFIG_EPOLL)            += eventpoll.o
-obj-$(CONFIG_COMPAT)           += compat.o
+obj-$(CONFIG_COMPAT)           += compat.o compat_ioctl.o
 
 nfsd-$(CONFIG_NFSD)            := nfsctl.o
 obj-y                          += $(nfsd-y) $(nfsd-m)
index 541b19e6fec9e71db12e60bba01eb5e15a291f42..14aa70282e8ca8feb20875cfbe86485386f556d8 100644 (file)
@@ -86,7 +86,7 @@ static int autofs4_root_readdir(struct file *file, void *dirent,
 
 /* Update usage from here to top of tree, so that scan of
    top-level directories will give a useful result */
-static void autofs4_update_usage(struct dentry *dentry)
+static void autofs4_update_usage(struct vfsmount *mnt, struct dentry *dentry)
 {
        struct dentry *top = dentry->d_sb->s_root;
 
@@ -95,7 +95,7 @@ static void autofs4_update_usage(struct dentry *dentry)
                struct autofs_info *ino = autofs4_dentry_ino(dentry);
 
                if (ino) {
-                       update_atime(dentry->d_inode);
+                       touch_atime(mnt, dentry);
                        ino->last_used = jiffies;
                }
        }
@@ -289,10 +289,10 @@ out:
        return autofs4_dcache_readdir(file, dirent, filldir);
 }
 
-static int try_to_fill_dentry(struct dentry *dentry, 
-                             struct super_block *sb,
-                             struct autofs_sb_info *sbi, int flags)
+static int try_to_fill_dentry(struct vfsmount *mnt, struct dentry *dentry, int flags)
 {
+       struct super_block *sb = mnt->mnt_sb;
+       struct autofs_sb_info *sbi = autofs4_sbi(sb);
        struct autofs_info *de_info = autofs4_dentry_ino(dentry);
        int status = 0;
 
@@ -367,7 +367,7 @@ static int try_to_fill_dentry(struct dentry *dentry,
        /* We don't update the usages for the autofs daemon itself, this
           is necessary for recursive autofs mounts */
        if (!autofs4_oz_mode(sbi))
-               autofs4_update_usage(dentry);
+               autofs4_update_usage(mnt, dentry);
 
        spin_lock(&dentry->d_lock);
        dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
@@ -392,7 +392,7 @@ static int autofs4_revalidate(struct dentry * dentry, struct nameidata *nd)
        /* Pending dentry */
        if (autofs4_ispending(dentry)) {
                if (!oz_mode)
-                       status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags);
+                       status = try_to_fill_dentry(nd->mnt, dentry, flags);
                return status;
        }
 
@@ -409,14 +409,14 @@ static int autofs4_revalidate(struct dentry * dentry, struct nameidata *nd)
                         dentry, dentry->d_name.len, dentry->d_name.name);
                spin_unlock(&dcache_lock);
                if (!oz_mode)
-                       status = try_to_fill_dentry(dentry, dir->i_sb, sbi, flags);
+                       status = try_to_fill_dentry(nd->mnt, dentry, flags);
                return status;
        }
        spin_unlock(&dcache_lock);
 
        /* Update the usage list */
        if (!oz_mode)
-               autofs4_update_usage(dentry);
+               autofs4_update_usage(nd->mnt, dentry);
 
        return 1;
 }
index 72011826f0cb340aabc54f65ee7d31653fc7d364..f312103434d4594fcd8d532c90bb8b4cf4698289 100644 (file)
@@ -33,8 +33,6 @@ static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout_library(struct file*);
 static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 static struct linux_binfmt aout_format = {
        .module         = THIS_MODULE,
        .load_binary    = load_aout_binary,
index 80ca932ba0bddaaf2d5a520d5fe408c14af508db..a4f6f57d91aa4398b1c49db596c1fec22d907cfd 100644 (file)
@@ -622,7 +622,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                                goto out_free_file;
 
                        retval = -ENOMEM;
-                       elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
+                       elf_interpreter = kmalloc(elf_ppnt->p_filesz,
                                                           GFP_KERNEL);
                        if (!elf_interpreter)
                                goto out_free_file;
index e0344f69c79d971ce4fb95992ca4d3e13f32fbe5..5b3076e8ee906a62d16be19588779a125cba4a86 100644 (file)
@@ -187,7 +187,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
                                goto error;
 
                        /* read the name of the interpreter into memory */
-                       interpreter_name = (char *) kmalloc(phdr->p_filesz, GFP_KERNEL);
+                       interpreter_name = kmalloc(phdr->p_filesz, GFP_KERNEL);
                        if (!interpreter_name)
                                goto error;
 
index 9d6625829b996f1700f67bfe7f4996384da422b4..b72dc31a0970d7f8c241d20c3067559bfdecf8f9 100644 (file)
@@ -77,8 +77,6 @@ static int load_flat_shared_library(int id, struct lib_info *p);
 static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
 static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
-extern void dump_thread(struct pt_regs *, struct user *);
-
 static struct linux_binfmt flat_format = {
        .module         = THIS_MODULE,
        .load_binary    = load_flat_binary,
index decd138f14d47e6a424760c83d6d5eb0487e0575..da2ad5b451ace4ce7e7dff902b87512d39a8f295 100644 (file)
@@ -242,7 +242,7 @@ static signed char UniCaseRangeLff20[27] = {
 /*
  * Lower Case Range
  */
-const static struct UniCaseRange CifsUniLowerRange[] = {
+static const struct UniCaseRange CifsUniLowerRange[] = {
        0x0380, 0x03ab, UniCaseRangeL0380,
        0x0400, 0x042f, UniCaseRangeL0400,
        0x0490, 0x04cb, UniCaseRangeL0490,
index 55d9a3a954cfe7fc35a5ccdc4eb7b6f1afbcff72..890bc30fbe2003563e4dbd52559decd06d724c23 100644 (file)
@@ -10,7 +10,6 @@
  * ioctls.
  */
 
-#ifdef INCLUDES
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/compat.h>
 #include <linux/capi.h>
 
 #include <scsi/scsi.h>
-/* Ugly hack. */
-#undef __KERNEL__
 #include <scsi/scsi_ioctl.h>
-#define __KERNEL__
 #include <scsi/sg.h>
 
-#include <asm/types.h>
 #include <asm/uaccess.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -95,7 +90,6 @@
 #include <linux/watchdog.h>
 #include <linux/dm-ioctl.h>
 
-#include <asm/module.h>
 #include <linux/soundcard.h>
 #include <linux/lp.h>
 #include <linux/ppdev.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/video.h>
 
-#undef INCLUDES
-#endif
-
-#ifdef CODE
-
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
 #define EXT2_IOC32_GETVERSION             _IOR('v', 1, int)
 #define EXT2_IOC32_SETVERSION             _IOW('v', 2, int)
 
+static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
+                             unsigned long arg, struct file *f)
+{
+       return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
+}
+
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        mm_segment_t old_fs = get_fs();
@@ -2475,6 +2470,49 @@ static int old_bridge_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg
        return -EINVAL;
 }
 
+#define RTC_IRQP_READ32                _IOR('p', 0x0b, compat_ulong_t)
+#define RTC_IRQP_SET32         _IOW('p', 0x0c, compat_ulong_t)
+#define RTC_EPOCH_READ32       _IOR('p', 0x0d, compat_ulong_t)
+#define RTC_EPOCH_SET32                _IOW('p', 0x0e, compat_ulong_t)
+
+static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
+{
+       mm_segment_t oldfs = get_fs();
+       compat_ulong_t val32;
+       unsigned long kval;
+       int ret;
+
+       switch (cmd) {
+       case RTC_IRQP_READ32:
+       case RTC_EPOCH_READ32:
+               set_fs(KERNEL_DS);
+               ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ?
+                                       RTC_IRQP_READ : RTC_EPOCH_READ,
+                                       (unsigned long)&kval);
+               set_fs(oldfs);
+               if (ret)
+                       return ret;
+               val32 = kval;
+               return put_user(val32, (unsigned int __user *)arg);
+       case RTC_IRQP_SET32:
+       case RTC_EPOCH_SET32:
+               ret = get_user(val32, (unsigned int __user *)arg);
+               if (ret)
+                       return ret;
+               kval = val32;
+
+               set_fs(KERNEL_DS);
+               ret = sys_ioctl(fd, (cmd == RTC_IRQP_SET32) ?
+                               RTC_IRQP_SET : RTC_EPOCH_SET,
+                               (unsigned long)&kval);
+               set_fs(oldfs);
+               return ret;
+       default:
+               /* unreached */
+               return -ENOIOCTLCMD;
+       }
+}
+
 #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
 struct ncp_ioctl_request_32 {
        u32 function;
@@ -2662,10 +2700,20 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
 }
 #endif
 
-#undef CODE
-#endif
+#define HANDLE_IOCTL(cmd,handler) \
+       { (cmd), (ioctl_trans_handler_t)(handler) },
+
+/* pointer to compatible structure or no argument */
+#define COMPATIBLE_IOCTL(cmd) \
+       { (cmd), do_ioctl32_pointer },
+
+/* argument is an unsigned long integer, not a pointer */
+#define ULONG_IOCTL(cmd) \
+       { (cmd), (ioctl_trans_handler_t)sys_ioctl },
 
-#ifdef DECLARES
+
+struct ioctl_trans ioctl_start[] = {
+#include <linux/compat_ioctl.h>
 HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
 HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
 #ifdef CONFIG_NET
@@ -2858,6 +2906,10 @@ HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
 HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
+HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
+HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl)
 
 #if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE)
 HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest)
@@ -2874,6 +2926,6 @@ HANDLE_IOCTL(DMX_GET_EVENT, do_dmx_get_event)
 HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event)
 HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture)
 HANDLE_IOCTL(VIDEO_SET_SPU_PALETTE, do_video_set_spu_palette)
+};
 
-#undef DECLARES
-#endif
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 1536f15c4d4c785a1ad2d49a78d03c5c4bd0067c..134d6775183f80b393317b5fa9d691fce7eb2fa1 100644 (file)
@@ -808,10 +808,14 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
  *
  * Fill in inode information in the entry. On success, it returns NULL.
  * If an unhashed alias of "entry" already exists, then we return the
- * aliased dentry instead.
+ * aliased dentry instead and drop one reference to inode.
  *
  * Note that in order to avoid conflicts with rename() etc, the caller
  * had better be holding the parent directory semaphore.
+ *
+ * This also assumes that the inode count has been incremented
+ * (or otherwise set) by the caller to indicate that it is now
+ * in use by the dcache.
  */
 struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
 {
@@ -838,6 +842,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
                dget_locked(alias);
                spin_unlock(&dcache_lock);
                BUG_ON(!d_unhashed(alias));
+               iput(inode);
                return alias;
        }
        list_add(&entry->d_alias, &inode->i_dentry);
index fd02ea4a81e96b8c1d748d7aed28980843cb2c2b..b5bcf1aae0abe61a6d7524b2614bcda7c78e18da 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -632,10 +632,10 @@ static inline int de_thread(struct task_struct *tsk)
                 * synchronize with any firing (by calling del_timer_sync)
                 * before we can safely let the old group leader die.
                 */
-               sig->real_timer.data = (unsigned long)current;
+               sig->real_timer.data = current;
                spin_unlock_irq(lock);
-               if (del_timer_sync(&sig->real_timer))
-                       add_timer(&sig->real_timer);
+               if (hrtimer_cancel(&sig->real_timer))
+                       hrtimer_restart(&sig->real_timer);
                spin_lock_irq(lock);
        }
        while (atomic_read(&sig->count) > count) {
index 20145b74623f880c807cb5e16104381c83f02b14..e9983a0dd39674fe68133ac741a09385e384d61d 100644 (file)
@@ -7,8 +7,12 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
+#ifdef EXT2FS_DEBUG
+
 #include <linux/buffer_head.h>
 
+#include "ext2.h"
+
 static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
 
 unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
@@ -23,3 +27,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
                        nibblemap[(map->b_data[i] >> 4) & 0xf];
        return (sum);
 }
+
+#endif  /*  EXT2FS_DEBUG  */
+
index f7a3b5fee274595afbfde2e06efafbb5a94073b0..a2ca3107d475c855f549886853f62141376e5a6d 100644 (file)
@@ -389,10 +389,6 @@ ext2_xattr_set(struct inode *inode, int name_index, const char *name,
        ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
                  name_index, name, value, (long)value_len);
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               return -EPERM;
        if (value == NULL)
                value_len = 0;
        if (name == NULL)
index 52b30ee6a25f31003fe3ad96c5ab087e3f27805d..2c072bfea23ba9a5f55049ab410b62fc529badd5 100644 (file)
@@ -38,8 +38,6 @@ ext2_xattr_trusted_get(struct inode *inode, const char *name,
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
        return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name,
                              buffer, size);
 }
@@ -50,8 +48,6 @@ ext2_xattr_trusted_set(struct inode *inode, const char *name,
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
        return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name,
                              value, size, flags);
 }
index 0c03ea131a948da241849d9bb82953f4b4e9cabd..f383e7c3a7b5bd18b8ca0bd43026c12ed689ce41 100644 (file)
@@ -35,16 +35,10 @@ static int
 ext2_xattr_user_get(struct inode *inode, const char *name,
                    void *buffer, size_t size)
 {
-       int error;
-
        if (strcmp(name, "") == 0)
                return -EINVAL;
        if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
-       error = permission(inode, MAY_READ, NULL);
-       if (error)
-               return error;
-
        return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size);
 }
 
@@ -52,18 +46,10 @@ static int
 ext2_xattr_user_set(struct inode *inode, const char *name,
                    const void *value, size_t size, int flags)
 {
-       int error;
-
        if (strcmp(name, "") == 0)
                return -EINVAL;
        if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
-       if ( !S_ISREG(inode->i_mode) &&
-           (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-               return -EPERM;
-       error = permission(inode, MAY_WRITE, NULL);
-       if (error)
-               return error;
 
        return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name,
                              value, size, flags);
index ae1148c24c53333fd13e7d18e3cd0fc306886db9..c6393fb4c35a476997e6938e3afacfd105a489a0 100644 (file)
@@ -20,8 +20,6 @@
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
 
-#include "bitmap.h"
-
 /*
  * balloc.c contains the blocks allocation and deallocation routines
  */
index 5b4ba3e246e60ebc72e7c538bf61453d29494a53..cb16b4c5d5df4110fffe112518ef32c9c2c06ef7 100644 (file)
@@ -7,8 +7,11 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
+#ifdef EXT3FS_DEBUG
+
 #include <linux/buffer_head.h>
-#include "bitmap.h"
+
+#include "ext3_fs.h"
 
 static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
 
@@ -24,3 +27,6 @@ unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars)
                        nibblemap[(map->b_data[i] >> 4) & 0xf];
        return (sum);
 }
+
+#endif  /*  EXT3FS_DEBUG  */
+
diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
deleted file mode 100644 (file)
index 6ee503a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/*  linux/fs/ext3/bitmap.c
- *
- * Copyright (C) 2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
-*/
-
-extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
index 69078079b19cc46c03921193246473923d8964c1..dc826464f313d884a55276786a0a7aed008fe711 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <asm/byteorder.h>
 
-#include "bitmap.h"
 #include "xattr.h"
 #include "acl.h"
 
index 238199d82ce547791aa735665f1741ab99c3a573..e8d60bf6b7df7b6bc964eccc2046d72dd5c0064e 100644 (file)
@@ -946,10 +946,6 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
        };
        int error;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               return -EPERM;
        if (!name)
                return -EINVAL;
        if (strlen(name) > 255)
index f68bfd1cf519f6f55d24fcd5728e2d442ba18440..7c693c94f14d8eb7e070e2bc74ad1ce4a92e7bcc 100644 (file)
@@ -39,8 +39,6 @@ ext3_xattr_trusted_get(struct inode *inode, const char *name,
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
        return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name,
                              buffer, size);
 }
@@ -51,8 +49,6 @@ ext3_xattr_trusted_set(struct inode *inode, const char *name,
 {
        if (strcmp(name, "") == 0)
                return -EINVAL;
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
        return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name,
                              value, size, flags);
 }
index e907cae7a07c34617983bf808125e1a526235801..a85a0a17c4fd4bc8d5981f9da79d48289876e1ad 100644 (file)
@@ -37,16 +37,10 @@ static int
 ext3_xattr_user_get(struct inode *inode, const char *name,
                    void *buffer, size_t size)
 {
-       int error;
-
        if (strcmp(name, "") == 0)
                return -EINVAL;
        if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
-       error = permission(inode, MAY_READ, NULL);
-       if (error)
-               return error;
-
        return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size);
 }
 
@@ -54,19 +48,10 @@ static int
 ext3_xattr_user_set(struct inode *inode, const char *name,
                    const void *value, size_t size, int flags)
 {
-       int error;
-
        if (strcmp(name, "") == 0)
                return -EINVAL;
        if (!test_opt(inode->i_sb, XATTR_USER))
                return -EOPNOTSUPP;
-       if ( !S_ISREG(inode->i_mode) &&
-           (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-               return -EPERM;
-       error = permission(inode, MAY_WRITE, NULL);
-       if (error)
-               return error;
-
        return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
                              value, size, flags);
 }
index df16fcbff3fbd00a6ff8876187b651c085f9679c..0fa1ab6250bffb55d93af2676e874a483d86ba2b 100644 (file)
@@ -143,9 +143,6 @@ struct hfsplus_sb_info {
 
        unsigned long flags;
 
-       atomic_t inode_cnt;
-       u32 last_inode_cnt;
-
        struct hlist_head rsrc_inodes;
 };
 
index 983bcd02ac1cd7095bba0ea7558369cec6f54c97..7acff6c5464ffdca66599d0dbebe524571139c40 100644 (file)
@@ -182,11 +182,6 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent
        igrab(dir);
        hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes);
        mark_inode_dirty(inode);
-       {
-       void hfsplus_inode_check(struct super_block *sb);
-       atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
-       hfsplus_inode_check(sb);
-       }
 out:
        d_add(dentry, inode);
        return NULL;
@@ -317,11 +312,6 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
        if (!inode)
                return NULL;
 
-       {
-       void hfsplus_inode_check(struct super_block *sb);
-       atomic_inc(&HFSPLUS_SB(sb).inode_cnt);
-       hfsplus_inode_check(sb);
-       }
        inode->i_ino = HFSPLUS_SB(sb).next_cnid++;
        inode->i_mode = mode;
        inode->i_uid = current->fsuid;
index 6daaf7c755a6894a9e1616d778e8b9816f9945ae..d791780def50fb98bff0343eee81fa602ad6fb31 100644 (file)
@@ -22,29 +22,12 @@ static void hfsplus_destroy_inode(struct inode *inode);
 
 #include "hfsplus_fs.h"
 
-void hfsplus_inode_check(struct super_block *sb)
-{
-#if 0
-       u32 cnt = atomic_read(&HFSPLUS_SB(sb).inode_cnt);
-       u32 last_cnt = HFSPLUS_SB(sb).last_inode_cnt;
-
-       if (cnt <= (last_cnt / 2) ||
-           cnt >= (last_cnt * 2)) {
-               HFSPLUS_SB(sb).last_inode_cnt = cnt;
-               printk("inode_check: %u,%u,%u\n", cnt, last_cnt,
-                       HFSPLUS_SB(sb).cat_tree ? HFSPLUS_SB(sb).cat_tree->node_hash_cnt : 0);
-       }
-#endif
-}
-
 static void hfsplus_read_inode(struct inode *inode)
 {
        struct hfs_find_data fd;
        struct hfsplus_vh *vhdr;
        int err;
 
-       atomic_inc(&HFSPLUS_SB(inode->i_sb).inode_cnt);
-       hfsplus_inode_check(inode->i_sb);
        INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
        init_MUTEX(&HFSPLUS_I(inode).extents_lock);
        HFSPLUS_I(inode).flags = 0;
@@ -155,12 +138,10 @@ static int hfsplus_write_inode(struct inode *inode, int unused)
 static void hfsplus_clear_inode(struct inode *inode)
 {
        dprint(DBG_INODE, "hfsplus_clear_inode: %lu\n", inode->i_ino);
-       atomic_dec(&HFSPLUS_SB(inode->i_sb).inode_cnt);
        if (HFSPLUS_IS_RSRC(inode)) {
                HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL;
                iput(HFSPLUS_I(inode).rsrc_inode);
        }
-       hfsplus_inode_check(inode->i_sb);
 }
 
 static void hfsplus_write_super(struct super_block *sb)
index e08767fd57b0eb0c62ccc19d3bdc42a11c0f4dcc..108138d4e909301ed1e6389bb3132127fdb9e4b4 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
 #include <linux/inotify.h>
+#include <linux/mount.h>
 
 /*
  * This is needed for the following functions:
@@ -1176,22 +1177,33 @@ sector_t bmap(struct inode * inode, sector_t block)
 EXPORT_SYMBOL(bmap);
 
 /**
- *     update_atime    -       update the access time
+ *     touch_atime     -       update the access time
+ *     @mnt: mount the inode is accessed on
  *     @inode: inode accessed
  *
  *     Update the accessed time on an inode and mark it for writeback.
  *     This function automatically handles read only file systems and media,
  *     as well as the "noatime" flag and inode specific "noatime" markers.
  */
-void update_atime(struct inode *inode)
+void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
 {
+       struct inode *inode = dentry->d_inode;
        struct timespec now;
 
-       if (IS_NOATIME(inode))
+       if (IS_RDONLY(inode))
                return;
-       if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
+
+       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)))
                return;
-       if (IS_RDONLY(inode))
+
+       /*
+        * 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;
 
        now = current_fs_time(inode->i_sb);
@@ -1201,19 +1213,23 @@ void update_atime(struct inode *inode)
        }
 }
 
-EXPORT_SYMBOL(update_atime);
+EXPORT_SYMBOL(touch_atime);
 
 /**
- *     inode_update_time       -       update mtime and ctime time
- *     @inode: inode accessed
- *     @ctime_too: update ctime too
+ *     file_update_time        -       update mtime and ctime time
+ *     @file: file accessed
  *
- *     Update the mtime time on an inode and mark it for writeback.
- *     When ctime_too is specified update the ctime too.
+ *     Update the mtime and ctime members of an inode and mark the inode
+ *     for writeback.  Note that this function is meant exclusively for
+ *     usage in the file write path of filesystems, and filesystems may
+ *     choose to explicitly ignore update via this function with the
+ *     S_NOCTIME inode flag, e.g. for network filesystem where these
+ *     timestamps are handled by the server.
  */
 
-void inode_update_time(struct inode *inode, int ctime_too)
+void file_update_time(struct file *file)
 {
+       struct inode *inode = file->f_dentry->d_inode;
        struct timespec now;
        int sync_it = 0;
 
@@ -1227,16 +1243,15 @@ void inode_update_time(struct inode *inode, int ctime_too)
                sync_it = 1;
        inode->i_mtime = now;
 
-       if (ctime_too) {
-               if (!timespec_equal(&inode->i_ctime, &now))
-                       sync_it = 1;
-               inode->i_ctime = now;
-       }
+       if (!timespec_equal(&inode->i_ctime, &now))
+               sync_it = 1;
+       inode->i_ctime = now;
+
        if (sync_it)
                mark_inode_dirty_sync(inode);
 }
 
-EXPORT_SYMBOL(inode_update_time);
+EXPORT_SYMBOL(file_update_time);
 
 int inode_needs_sync(struct inode *inode)
 {
index 23aa5066b5a438014d84a2d0491c79e49b25e4dd..952da5f917cdc7ad4133ccc1a8cf46e5bd94ec14 100644 (file)
@@ -83,21 +83,6 @@ struct ea_buffer {
 #define EA_NEW         0x0004
 #define EA_MALLOC      0x0008
 
-/* Namespaces */
-#define XATTR_SYSTEM_PREFIX "system."
-#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
-
-#define XATTR_USER_PREFIX "user."
-#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
-
-#define XATTR_OS2_PREFIX "os2."
-#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
-
-/* XATTR_SECURITY_PREFIX is defined in include/linux/xattr.h */
-#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
-
-#define XATTR_TRUSTED_PREFIX "trusted."
-#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
 
 /*
  * These three routines are used to recognize on-disk extended attributes
@@ -773,36 +758,23 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
 static int can_set_xattr(struct inode *inode, const char *name,
                         const void *value, size_t value_len)
 {
-       if (IS_RDONLY(inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               return -EPERM;
-
-       if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
-               /*
-                * "system.*"
-                */
+       if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
                return can_set_system_xattr(inode, name, value, value_len);
 
-       if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)
-               return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
-
-#ifdef CONFIG_JFS_SECURITY
-       if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)
-           == 0)
-               return 0;       /* Leave it to the security module */
-#endif
-               
-       if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
-          (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
+       /*
+        * Don't allow setting an attribute in an unknown namespace.
+        */
+       if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) &&
+           strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) &&
+           strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) &&
+           strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))
                return -EOPNOTSUPP;
 
        if (!S_ISREG(inode->i_mode) &&
            (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
                return -EPERM;
 
-       return permission(inode, MAY_WRITE, NULL);
+       return 0;
 }
 
 int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
@@ -972,22 +944,6 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        return rc;
 }
 
-static int can_get_xattr(struct inode *inode, const char *name)
-{
-#ifdef CONFIG_JFS_SECURITY
-       if(strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0)
-               return 0;
-#endif
-
-       if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)
-               return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
-
-       if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
-               return 0;
-
-       return permission(inode, MAY_READ, NULL);
-}
-
 ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
                       size_t buf_size)
 {
@@ -998,12 +954,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
        ssize_t size;
        int namelen = strlen(name);
        char *os2name = NULL;
-       int rc;
        char *value;
 
-       if ((rc = can_get_xattr(inode, name)))
-               return rc;
-
        if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
                os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
                                  GFP_KERNEL);
index f0e353f5bc3083fd38dcf19af5d8e8437e7c872e..2ca6145f43d6b047a4b98eabab9e1ccfd447ba81 100644 (file)
@@ -355,14 +355,14 @@ static int show_vfsmnt(struct seq_file *m, void *v)
                { MS_SYNCHRONOUS, ",sync" },
                { MS_DIRSYNC, ",dirsync" },
                { MS_MANDLOCK, ",mand" },
-               { MS_NOATIME, ",noatime" },
-               { MS_NODIRATIME, ",nodiratime" },
                { 0, NULL }
        };
        static struct proc_fs_info mnt_info[] = {
                { MNT_NOSUID, ",nosuid" },
                { MNT_NODEV, ",nodev" },
                { MNT_NOEXEC, ",noexec" },
+               { MNT_NOATIME, ",noatime" },
+               { MNT_NODIRATIME, ",nodiratime" },
                { 0, NULL }
        };
        struct proc_fs_info *fs_infop;
@@ -1286,7 +1286,13 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                mnt_flags |= MNT_NODEV;
        if (flags & MS_NOEXEC)
                mnt_flags |= MNT_NOEXEC;
-       flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE);
+       if (flags & MS_NOATIME)
+               mnt_flags |= MNT_NOATIME;
+       if (flags & MS_NODIRATIME)
+               mnt_flags |= MNT_NODIRATIME;
+
+       flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
+                  MS_NOATIME | MS_NODIRATIME);
 
        /* ... and get the mountpoint */
        retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
index 4947d9b11fc134f1efa75ad3d47ab274a9cd6c9e..973b444d691427cd05fc1e4ed8105606e04e1143 100644 (file)
@@ -262,7 +262,7 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
        }
        vfree(bouncebuffer);
 
-       inode_update_time(inode, 1);
+       file_update_time(file);
 
        *ppos = pos;
 
index 3e4ba9cb7f806c7ee8681e97398f51001a288b69..a77ee95b7efb955fcd02d596c4581f7670821ddd 100644 (file)
@@ -950,11 +950,20 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 
        /* Flush out writes to the server in order to update c/mtime */
        nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
-       if (__IS_FLG(inode, MS_NOATIME))
-               need_atime = 0;
-       else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
+
+       /*
+        * We may force a getattr if the user cares about atime.
+        *
+        * Note that we only have to check the vfsmount flags here:
+        *  - NFS always sets S_NOATIME by so checking it would give a
+        *    bogus result
+        *  - NFS never sets MS_NOATIME or MS_NODIRATIME so there is
+        *    no point in checking those.
+        */
+       if ((mnt->mnt_flags & MNT_NOATIME) ||
+           ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
                need_atime = 0;
-       /* We may force a getattr if the user cares about atime */
+
        if (need_atime)
                err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
        else
index bb36b430449145355ccb79d1e99e72c75e72acc3..eef0576a77857577805e053d428ebe13bd6ce9a6 100644 (file)
@@ -48,8 +48,8 @@
 #include <linux/fsnotify.h>
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
-#ifdef CONFIG_NFSD_V4
 #include <linux/xattr.h>
+#ifdef CONFIG_NFSD_V4
 #include <linux/nfs4.h>
 #include <linux/nfs4_acl.h>
 #include <linux/nfsd_idmap.h>
@@ -365,8 +365,30 @@ out_nfserr:
        goto out;
 }
 
-#if defined(CONFIG_NFSD_V4)
+#if defined(CONFIG_NFSD_V2_ACL) || \
+    defined(CONFIG_NFSD_V3_ACL) || \
+    defined(CONFIG_NFSD_V4)
+static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
+{
+       ssize_t buflen;
+       int error;
+
+       buflen = vfs_getxattr(dentry, key, NULL, 0);
+       if (buflen <= 0)
+               return buflen;
 
+       *buf = kmalloc(buflen, GFP_KERNEL);
+       if (!*buf)
+               return -ENOMEM;
+
+       error = vfs_getxattr(dentry, key, *buf, buflen);
+       if (error < 0)
+               return error;
+       return buflen;
+}
+#endif
+
+#if defined(CONFIG_NFSD_V4)
 static int
 set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
 {
@@ -374,7 +396,6 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
        size_t buflen;
        char *buf = NULL;
        int error = 0;
-       struct inode *inode = dentry->d_inode;
 
        buflen = posix_acl_xattr_size(pacl->a_count);
        buf = kmalloc(buflen, GFP_KERNEL);
@@ -388,15 +409,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
                goto out;
        }
 
-       error = -EOPNOTSUPP;
-       if (inode->i_op && inode->i_op->setxattr) {
-               mutex_lock(&inode->i_mutex);
-               security_inode_setxattr(dentry, key, buf, len, 0);
-               error = inode->i_op->setxattr(dentry, key, buf, len, 0);
-               if (!error)
-                       security_inode_post_setxattr(dentry, key, buf, len, 0);
-               mutex_unlock(&inode->i_mutex);
-       }
+       error = vfs_setxattr(dentry, key, buf, len, 0);
 out:
        kfree(buf);
        return error;
@@ -455,44 +468,19 @@ out_nfserr:
 static struct posix_acl *
 _get_posix_acl(struct dentry *dentry, char *key)
 {
-       struct inode *inode = dentry->d_inode;
-       char *buf = NULL;
-       int buflen, error = 0;
+       void *buf = NULL;
        struct posix_acl *pacl = NULL;
+       int buflen;
 
-       error = -EOPNOTSUPP;
-       if (inode->i_op == NULL)
-               goto out_err;
-       if (inode->i_op->getxattr == NULL)
-               goto out_err;
-
-       error = security_inode_getxattr(dentry, key);
-       if (error)
-               goto out_err;
-
-       buflen = inode->i_op->getxattr(dentry, key, NULL, 0);
-       if (buflen <= 0) {
-               error = buflen < 0 ? buflen : -ENODATA;
-               goto out_err;
-       }
-
-       buf = kmalloc(buflen, GFP_KERNEL);
-       if (buf == NULL) {
-               error = -ENOMEM;
-               goto out_err;
-       }
-
-       error = inode->i_op->getxattr(dentry, key, buf, buflen);
-       if (error < 0)
-               goto out_err;
+       buflen = nfsd_getxattr(dentry, key, &buf);
+       if (!buflen)
+               buflen = -ENODATA;
+       if (buflen <= 0)
+               return ERR_PTR(buflen);
 
        pacl = posix_acl_from_xattr(buf, buflen);
- out:
        kfree(buf);
        return pacl;
- out_err:
-       pacl = ERR_PTR(error);
-       goto out;
 }
 
 int
@@ -1884,39 +1872,25 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type)
        ssize_t size;
        struct posix_acl *acl;
 
-       if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr)
+       if (!IS_POSIXACL(inode))
+               return ERR_PTR(-EOPNOTSUPP);
+
+       switch (type) {
+       case ACL_TYPE_ACCESS:
+               name = POSIX_ACL_XATTR_ACCESS;
+               break;
+       case ACL_TYPE_DEFAULT:
+               name = POSIX_ACL_XATTR_DEFAULT;
+               break;
+       default:
                return ERR_PTR(-EOPNOTSUPP);
-       switch(type) {
-               case ACL_TYPE_ACCESS:
-                       name = POSIX_ACL_XATTR_ACCESS;
-                       break;
-               case ACL_TYPE_DEFAULT:
-                       name = POSIX_ACL_XATTR_DEFAULT;
-                       break;
-               default:
-                       return ERR_PTR(-EOPNOTSUPP);
        }
 
-       size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0);
+       size = nfsd_getxattr(fhp->fh_dentry, name, &value);
+       if (size < 0)
+               return ERR_PTR(size);
 
-       if (size < 0) {
-               acl = ERR_PTR(size);
-               goto getout;
-       } else if (size > 0) {
-               value = kmalloc(size, GFP_KERNEL);
-               if (!value) {
-                       acl = ERR_PTR(-ENOMEM);
-                       goto getout;
-               }
-               size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size);
-               if (size < 0) {
-                       acl = ERR_PTR(size);
-                       goto getout;
-               }
-       }
        acl = posix_acl_from_xattr(value, size);
-
-getout:
        kfree(value);
        return acl;
 }
@@ -1957,16 +1931,13 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
        } else
                size = 0;
 
-       if (!fhp->fh_locked)
-               fh_lock(fhp);  /* unlocking is done automatically */
        if (size)
-               error = inode->i_op->setxattr(fhp->fh_dentry, name,
-                                             value, size, 0);
+               error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
        else {
                if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
                        error = 0;
                else {
-                       error = inode->i_op->removexattr(fhp->fh_dentry, name);
+                       error = vfs_removexattr(fhp->fh_dentry, name);
                        if (error == -ENODATA)
                                error = 0;
                }
index 30f71acdc1cbfdcb313385f351a94e7c4ba529b2..fb413d3d861875932742b3ccea65d40ac99ef47b 100644 (file)
@@ -2173,7 +2173,7 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
        err = remove_suid(file->f_dentry);
        if (err)
                goto out;
-       inode_update_time(inode, 1);
+       file_update_time(file);
        written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos,
                        count);
 out:
index bda7a08911a5749a4dad22054b53faaf73dd179b..ea1bd3feea1b7dac830a03fd55ef41d2dfe15a9b 100644 (file)
@@ -2767,7 +2767,25 @@ unm_done:
        up_write(&ni->runlist.lock);
 done:
        /* Update the mtime and ctime on the base inode. */
-       inode_update_time(VFS_I(base_ni), 1);
+       /* normally ->truncate shouldn't update ctime or mtime,
+        * but ntfs did before so it got a copy & paste version
+        * of file_update_time.  one day someone should fix this
+        * for real.
+        */
+       if (!IS_NOCMTIME(VFS_I(base_ni)) && !IS_RDONLY(VFS_I(base_ni))) {
+               struct timespec now = current_fs_time(VFS_I(base_ni)->i_sb);
+               int sync_it = 0;
+
+               if (!timespec_equal(&VFS_I(base_ni)->i_mtime, &now) ||
+                   !timespec_equal(&VFS_I(base_ni)->i_ctime, &now))
+                       sync_it = 1;
+               VFS_I(base_ni)->i_mtime = now;
+               VFS_I(base_ni)->i_ctime = now;
+
+               if (sync_it)
+                       mark_inode_dirty_sync(VFS_I(base_ni));
+       }
+
        if (likely(!err)) {
                NInoClearTruncateFailed(ni);
                ntfs_debug("Done.");
index 280e383fc84edae6a72b7e7ba5db703fc2421e01..c3a3f1a8310b58477286e481bcf5986512456fc9 100644 (file)
@@ -443,8 +443,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
 
        ntfs_debug("Entering with remount options string: %s", opt);
 #ifndef NTFS_RW
-       /* For read-only compiled driver, enforce all read-only flags. */
-       *flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+       /* For read-only compiled driver, enforce read-only flag. */
+       *flags |= MS_RDONLY;
 #else /* NTFS_RW */
        /*
         * For the read-write compiled driver, if we are remounting read-write,
@@ -1721,7 +1721,7 @@ static BOOL load_system_files(ntfs_volume *vol)
                                                es3);
                                goto iput_mirr_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s",
                                        !vol->mftmirr_ino ? es1 : es2, es3);
                } else
@@ -1837,7 +1837,7 @@ get_ctx_vol_failed:
                                                es1, es2);
                                goto iput_vol_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
@@ -1874,7 +1874,7 @@ get_ctx_vol_failed:
                                }
                                goto iput_logfile_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
@@ -1919,7 +1919,7 @@ get_ctx_vol_failed:
                                                es1, es2);
                                goto iput_root_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
@@ -1943,7 +1943,7 @@ get_ctx_vol_failed:
                        goto iput_root_err_out;
                }
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               sb->s_flags |= MS_RDONLY;
                /*
                 * Do not set NVolErrors() because ntfs_remount() might manage
                 * to set the dirty flag in which case all would be well.
@@ -1970,7 +1970,7 @@ get_ctx_vol_failed:
                        goto iput_root_err_out;
                }
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               sb->s_flags |= MS_RDONLY;
                NVolSetErrors(vol);
        }
 #endif
@@ -1989,7 +1989,7 @@ get_ctx_vol_failed:
                        goto iput_root_err_out;
                }
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               sb->s_flags |= MS_RDONLY;
                NVolSetErrors(vol);
        }
 #endif /* NTFS_RW */
@@ -2030,7 +2030,7 @@ get_ctx_vol_failed:
                                                es1, es2);
                                goto iput_quota_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
@@ -2053,7 +2053,7 @@ get_ctx_vol_failed:
                        goto iput_quota_err_out;
                }
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               sb->s_flags |= MS_RDONLY;
                NVolSetErrors(vol);
        }
        /*
@@ -2074,7 +2074,7 @@ get_ctx_vol_failed:
                                                es1, es2);
                                goto iput_usnjrnl_err_out;
                        }
-                       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+                       sb->s_flags |= MS_RDONLY;
                        ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
                } else
                        ntfs_warning(sb, "%s.  Will not be able to remount "
@@ -2097,7 +2097,7 @@ get_ctx_vol_failed:
                        goto iput_usnjrnl_err_out;
                }
                ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
-               sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+               sb->s_flags |= MS_RDONLY;
                NVolSetErrors(vol);
        }
 #endif /* NTFS_RW */
@@ -2689,7 +2689,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
 
        ntfs_debug("Entering.");
 #ifndef NTFS_RW
-       sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+       sb->s_flags |= MS_RDONLY;
 #endif /* ! NTFS_RW */
        /* Allocate a new ntfs_volume and place it in sb->s_fs_info. */
        sb->s_fs_info = kmalloc(sizeof(ntfs_volume), GFP_NOFS);
index afdeec4b0eefb2530cf9dba77cb1eaccaf8f91d1..843cf9ddefe8aa659b09c23138da2184717074b2 100644 (file)
@@ -80,12 +80,8 @@ static struct vm_operations_struct ocfs2_file_vm_ops = {
        .nopage = ocfs2_nopage,
 };
 
-int ocfs2_mmap(struct file *file,
-              struct vm_area_struct *vma)
+int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-       struct inode *inode = mapping->host;
-
        /* We don't want to support shared writable mappings yet. */
        if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
            && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
@@ -95,7 +91,7 @@ int ocfs2_mmap(struct file *file,
                return -EINVAL;
        }
 
-       update_atime(inode);
+       file_accessed(file);
        vma->vm_ops = &ocfs2_file_vm_ops;
        return 0;
 }
index acb030b61fb080dfd4619ecf1c335d5b2c7502c7..eef0f29e86ef3de20913fef86bd9412c3751e898 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -347,7 +347,7 @@ out:
                kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
        }
        if (ret > 0)
-               inode_update_time(inode, 1);    /* mtime and ctime */
+               file_update_time(filp);
        return ret;
 }
 
index 5e9251f6531705671ba017d0c4c5a208e76d6aaa..7eb1bd7f800c13f74bfc33d6ec862f6fd35f820b 100644 (file)
@@ -330,7 +330,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
        unsigned long  min_flt = 0,  maj_flt = 0;
        cputime_t cutime, cstime, utime, stime;
        unsigned long rsslim = 0;
-       unsigned long it_real_value = 0;
+       DEFINE_KTIME(it_real_value);
        struct task_struct *t;
        char tcomm[sizeof(task->comm)];
 
@@ -386,7 +386,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
                        utime = cputime_add(utime, task->signal->utime);
                        stime = cputime_add(stime, task->signal->stime);
                }
-               it_real_value = task->signal->it_real_value;
+               it_real_value = task->signal->real_timer.expires;
        }
        ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
        read_unlock(&tasklist_lock);
@@ -435,7 +435,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
                priority,
                nice,
                num_threads,
-               jiffies_to_clock_t(it_real_value),
+               (long) ktime_to_clock_t(it_real_value),
                start_time,
                vsize,
                mm ? get_mm_rss(mm) : 0,
index 3b2e7b69e63adb0c337005237e846292300d4c18..5378d7c78419cd57d04ef29bad34a395d3c1e2fd 100644 (file)
@@ -35,6 +35,9 @@ static size_t elfcorebuf_sz;
 /* Total size of vmcore file. */
 static u64 vmcore_size;
 
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
 struct proc_dir_entry *proc_vmcore = NULL;
 
 /* Reads a page from the oldmem device from given offset. */
index 127e7d2cabddc3f6589cde8645f6012061c541ff..ad6fa964b0e7e892de207307223a71887d1bc6ac 100644 (file)
@@ -1360,7 +1360,7 @@ static ssize_t reiserfs_file_write(struct file *file,     /* the file we are going t
        if (res)
                goto out;
 
-       inode_update_time(inode, 1);    /* Both mtime and ctime */
+       file_update_time(file);
 
        // Ok, we are done with all the checks.
 
index f1895f0a278eb3277c353444f8dd7903e3d8d8d8..6f99e01f94abac117509ef97247624c52c30f1a9 100644 (file)
@@ -497,12 +497,6 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
        struct iattr newattrs;
        __u32 xahash = 0;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-               return -EPERM;
-
        if (get_inode_sd_version(inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
@@ -758,9 +752,6 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
        struct dentry *dir;
        int err;
 
-       if (IS_RDONLY(inode))
-               return -EROFS;
-
        dir = open_xa_dir(inode, FL_READONLY);
        if (IS_ERR(dir)) {
                err = PTR_ERR(dir);
@@ -984,12 +975,6 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
            get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       if (IS_RDONLY(dentry->d_inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
-               return -EROFS;
-
        reiserfs_write_lock_xattr_i(dentry->d_inode);
        lock = !has_xattr_dir(dentry->d_inode);
        if (lock)
@@ -1019,12 +1004,6 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name)
            get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       if (IS_RDONLY(dentry->d_inode))
-               return -EROFS;
-
-       if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
-               return -EPERM;
-
        reiserfs_write_lock_xattr_i(dentry->d_inode);
        reiserfs_read_lock_xattrs(dentry->d_sb);
 
index 51458048ca6623fd0eb825ef6b304b38b3c1940a..073f39364b1136dcd9cbb808f5820b3e5581ff58 100644 (file)
@@ -16,18 +16,10 @@ static int
 user_get(struct inode *inode, const char *name, void *buffer, size_t size)
 {
 
-       int error;
-
        if (strlen(name) < sizeof(XATTR_USER_PREFIX))
                return -EINVAL;
-
        if (!reiserfs_xattrs_user(inode->i_sb))
                return -EOPNOTSUPP;
-
-       error = reiserfs_permission_locked(inode, MAY_READ, NULL);
-       if (error)
-               return error;
-
        return reiserfs_xattr_get(inode, name, buffer, size);
 }
 
@@ -36,43 +28,21 @@ user_set(struct inode *inode, const char *name, const void *buffer,
         size_t size, int flags)
 {
 
-       int error;
-
        if (strlen(name) < sizeof(XATTR_USER_PREFIX))
                return -EINVAL;
 
        if (!reiserfs_xattrs_user(inode->i_sb))
                return -EOPNOTSUPP;
-
-       if (!S_ISREG(inode->i_mode) &&
-           (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-               return -EPERM;
-
-       error = reiserfs_permission_locked(inode, MAY_WRITE, NULL);
-       if (error)
-               return error;
-
        return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
 static int user_del(struct inode *inode, const char *name)
 {
-       int error;
-
        if (strlen(name) < sizeof(XATTR_USER_PREFIX))
                return -EINVAL;
 
        if (!reiserfs_xattrs_user(inode->i_sb))
                return -EOPNOTSUPP;
-
-       if (!S_ISREG(inode->i_mode) &&
-           (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
-               return -EPERM;
-
-       error = reiserfs_permission_locked(inode, MAY_WRITE, NULL);
-       if (error)
-               return error;
-
        return 0;
 }
 
index 386a532ee5a9acff40b2d4855c42e656213b202f..80eca7d3d69f68272a70b4a79bdc7c8f6d273ebf 100644 (file)
 #include <linux/fsnotify.h>
 #include <asm/uaccess.h>
 
+
+/*
+ * Check permissions for extended attribute access.  This is a bit complicated
+ * because different namespaces have very different rules.
+ */
+static int
+xattr_permission(struct inode *inode, const char *name, int mask)
+{
+       /*
+        * We can never set or remove an extended attribute on a read-only
+        * filesystem  or on an immutable / append-only inode.
+        */
+       if (mask & MAY_WRITE) {
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+               if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+                       return -EPERM;
+       }
+
+       /*
+        * No restriction for security.* and system.* from the VFS.  Decision
+        * on these is left to the underlying filesystem / security module.
+        */
+       if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
+           !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
+               return 0;
+
+       /*
+        * The trusted.* namespace can only accessed by a privilegued user.
+        */
+       if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN))
+               return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
+
+       if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
+               if (!S_ISREG(inode->i_mode) &&
+                   (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+                       return -EPERM;
+       }
+
+       return permission(inode, mask, NULL);
+}
+
+int
+vfs_setxattr(struct dentry *dentry, char *name, void *value,
+               size_t size, int flags)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+
+       error = xattr_permission(inode, name, MAY_WRITE);
+       if (error)
+               return error;
+
+       mutex_lock(&inode->i_mutex);
+       error = security_inode_setxattr(dentry, name, value, size, flags);
+       if (error)
+               goto out;
+       error = -EOPNOTSUPP;
+       if (inode->i_op->setxattr) {
+               error = inode->i_op->setxattr(dentry, name, value, size, flags);
+               if (!error) {
+                       fsnotify_xattr(dentry);
+                       security_inode_post_setxattr(dentry, name, value,
+                                                    size, flags);
+               }
+       } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
+                               XATTR_SECURITY_PREFIX_LEN)) {
+               const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
+               error = security_inode_setsecurity(inode, suffix, value,
+                                                  size, flags);
+               if (!error)
+                       fsnotify_xattr(dentry);
+       }
+out:
+       mutex_unlock(&inode->i_mutex);
+       return error;
+}
+EXPORT_SYMBOL_GPL(vfs_setxattr);
+
+ssize_t
+vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+
+       error = xattr_permission(inode, name, MAY_READ);
+       if (error)
+               return error;
+
+       error = security_inode_getxattr(dentry, name);
+       if (error)
+               return error;
+
+       if (inode->i_op->getxattr)
+               error = inode->i_op->getxattr(dentry, name, value, size);
+       else
+               error = -EOPNOTSUPP;
+
+       if (!strncmp(name, XATTR_SECURITY_PREFIX,
+                               XATTR_SECURITY_PREFIX_LEN)) {
+               const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
+               int ret = security_inode_getsecurity(inode, suffix, value,
+                                                    size, error);
+               /*
+                * Only overwrite the return value if a security module
+                * is actually active.
+                */
+               if (ret != -EOPNOTSUPP)
+                       error = ret;
+       }
+
+       return error;
+}
+EXPORT_SYMBOL_GPL(vfs_getxattr);
+
+int
+vfs_removexattr(struct dentry *dentry, char *name)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+
+       if (!inode->i_op->removexattr)
+               return -EOPNOTSUPP;
+
+       error = xattr_permission(inode, name, MAY_WRITE);
+       if (error)
+               return error;
+
+       error = security_inode_removexattr(dentry, name);
+       if (error)
+               return error;
+
+       mutex_lock(&inode->i_mutex);
+       error = inode->i_op->removexattr(dentry, name);
+       mutex_unlock(&inode->i_mutex);
+
+       if (!error)
+               fsnotify_xattr(dentry);
+       return error;
+}
+EXPORT_SYMBOL_GPL(vfs_removexattr);
+
+
 /*
  * Extended attribute SET operations
  */
@@ -51,29 +194,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
                }
        }
 
-       mutex_lock(&d->d_inode->i_mutex);
-       error = security_inode_setxattr(d, kname, kvalue, size, flags);
-       if (error)
-               goto out;
-       error = -EOPNOTSUPP;
-       if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
-               error = d->d_inode->i_op->setxattr(d, kname, kvalue,
-                                                  size, flags);
-               if (!error) {
-                       fsnotify_xattr(d);
-                       security_inode_post_setxattr(d, kname, kvalue,
-                                                    size, flags);
-               }
-       } else if (!strncmp(kname, XATTR_SECURITY_PREFIX,
-                           sizeof XATTR_SECURITY_PREFIX - 1)) {
-               const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
-               error = security_inode_setsecurity(d->d_inode, suffix, kvalue,
-                                                  size, flags);
-               if (!error)
-                       fsnotify_xattr(d);
-       }
-out:
-       mutex_unlock(&d->d_inode->i_mutex);
+       error = vfs_setxattr(d, kname, kvalue, size, flags);
        kfree(kvalue);
        return error;
 }
@@ -147,22 +268,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
                        return -ENOMEM;
        }
 
-       error = security_inode_getxattr(d, kname);
-       if (error)
-               goto out;
-       error = -EOPNOTSUPP;
-       if (d->d_inode->i_op && d->d_inode->i_op->getxattr)
-               error = d->d_inode->i_op->getxattr(d, kname, kvalue, size);
-
-       if (!strncmp(kname, XATTR_SECURITY_PREFIX,
-                    sizeof XATTR_SECURITY_PREFIX - 1)) {
-               const char *suffix = kname + sizeof XATTR_SECURITY_PREFIX - 1;
-               int rv = security_inode_getsecurity(d->d_inode, suffix, kvalue,
-                                                   size, error);
-               /* Security module active: overwrite error value */
-               if (rv != -EOPNOTSUPP)
-                       error = rv;
-       }
+       error = vfs_getxattr(d, kname, kvalue, size);
        if (error > 0) {
                if (size && copy_to_user(value, kvalue, error))
                        error = -EFAULT;
@@ -171,7 +277,6 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
                   than XATTR_SIZE_MAX bytes. Not possible. */
                error = -E2BIG;
        }
-out:
        kfree(kvalue);
        return error;
 }
@@ -318,19 +423,7 @@ removexattr(struct dentry *d, char __user *name)
        if (error < 0)
                return error;
 
-       error = -EOPNOTSUPP;
-       if (d->d_inode->i_op && d->d_inode->i_op->removexattr) {
-               error = security_inode_removexattr(d, kname);
-               if (error)
-                       goto out;
-               mutex_lock(&d->d_inode->i_mutex);
-               error = d->d_inode->i_op->removexattr(d, kname);
-               mutex_unlock(&d->d_inode->i_mutex);
-               if (!error)
-                       fsnotify_xattr(d);
-       }
-out:
-       return error;
+       return vfs_removexattr(d, kname);
 }
 
 asmlinkage long
diff --git a/fs/xfs/Kbuild b/fs/xfs/Kbuild
new file mode 100644 (file)
index 0000000..2566e96
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# The xfs people like to share Makefile with 2.6 and 2.4.
+# Utilise file named Kbuild file which has precedence over Makefile.
+#
+
+include $(srctree)/$(obj)/Makefile-linux-2.6
index b78b5eb9e96ca620dbbc9eaf6d37a04ddc4a2fc4..f98c5be3dfe7072689bb766d404e1a337fcd6dc4 100644 (file)
@@ -530,6 +530,8 @@ xfs_attrmulti_attr_set(
        char                    *kbuf;
        int                     error = EFAULT;
 
+       if (IS_RDONLY(&vp->v_inode))
+               return -EROFS;
        if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
                return EPERM;
        if (len > XATTR_SIZE_MAX)
@@ -557,6 +559,9 @@ xfs_attrmulti_attr_remove(
 {
        int                     error;
 
+
+       if (IS_RDONLY(&vp->v_inode))
+               return -EROFS;
        if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
                return EPERM;
 
index c83ae15bb0e64b17869ce1c313e5d00f6320431b..a7c9ba1a9f7b86ac34ef0c626927d42b68be3935 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/compat.h>
 #include <linux/init.h>
 #include <linux/ioctl.h>
-#include <linux/ioctl32.h>
 #include <linux/syscalls.h>
 #include <linux/types.h>
 #include <linux/fs.h>
index 41c478bb1ffcaf22b330fec169e609892349493f..97fb1470cf28693478aeb05cb6e338e7347a6e80 100644 (file)
@@ -54,6 +54,9 @@
 #include <linux/xattr.h>
 #include <linux/namei.h>
 
+#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) ||      \
+       (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
+
 /*
  * Change the requested timestamp in the given inode.
  * We don't lock across timestamp updates, and we don't log them but
index 5675117ef2270239a71fcae7496dac14625fa454..885dfafeabeee6fb6359c167d203091476e741a9 100644 (file)
@@ -713,7 +713,7 @@ start:
        }
 
        if (likely(!(ioflags & IO_INVIS))) {
-               inode_update_time(inode, 1);
+               file_update_time(file);
                xfs_ichgtime_fast(xip, inode,
                                  XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
        }
index 5484eeb460c84253c59687825e34b3304c772bea..1a11c2b517011f5e49840e92b0bebc4f92c78117 100644 (file)
@@ -117,11 +117,6 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
             ip->i_d.di_anextents == 0))
                return(ENOATTR);
 
-       if (!(flags & (ATTR_KERNACCESS|ATTR_SECURE))) {
-               if ((error = xfs_iaccess(ip, S_IRUSR, cred)))
-                       return(XFS_ERROR(error));
-       }
-
        /*
         * Fill in the arg structure for this request.
         */
@@ -425,7 +420,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
             struct cred *cred)
 {
        xfs_inode_t     *dp;
-       int             namelen, error;
+       int             namelen;
 
        namelen = strlen(name);
        if (namelen >= MAXNAMELEN)
@@ -437,14 +432,6 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return (EIO);
 
-       xfs_ilock(dp, XFS_ILOCK_SHARED);
-       if (!(flags & ATTR_SECURE) &&
-            (error = xfs_iaccess(dp, S_IWUSR, cred))) {
-               xfs_iunlock(dp, XFS_ILOCK_SHARED);
-               return(XFS_ERROR(error));
-       }
-       xfs_iunlock(dp, XFS_ILOCK_SHARED);
-
        return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags);
 }
 
@@ -579,7 +566,7 @@ int
 xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
 {
        xfs_inode_t         *dp;
-       int                 namelen, error;
+       int                 namelen;
 
        namelen = strlen(name);
        if (namelen >= MAXNAMELEN)
@@ -592,11 +579,7 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
                return (EIO);
 
        xfs_ilock(dp, XFS_ILOCK_SHARED);
-       if (!(flags & ATTR_SECURE) &&
-            (error = xfs_iaccess(dp, S_IWUSR, cred))) {
-               xfs_iunlock(dp, XFS_ILOCK_SHARED);
-               return(XFS_ERROR(error));
-       } else if (XFS_IFORK_Q(dp) == 0 ||
+       if (XFS_IFORK_Q(dp) == 0 ||
                   (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
                    dp->i_d.di_anextents == 0)) {
                xfs_iunlock(dp, XFS_ILOCK_SHARED);
@@ -668,12 +651,6 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
                return (EIO);
 
        xfs_ilock(dp, XFS_ILOCK_SHARED);
-       if (!(flags & ATTR_SECURE) &&
-            (error = xfs_iaccess(dp, S_IRUSR, cred))) {
-               xfs_iunlock(dp, XFS_ILOCK_SHARED);
-               return(XFS_ERROR(error));
-       }
-
        /*
         * Decide on what work routines to call based on the inode size.
         */
index 2cbb7d0e9dc6f1825b789754985350c60d17e448..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,74 +1 @@
-/*
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMARM_IOCTL_H
-#define _ASMARM_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASMARM_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 2cbb7d0e9dc6f1825b789754985350c60d17e448..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,74 +1 @@
-/*
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMARM_IOCTL_H
-#define _ASMARM_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASMARM_IOCTL_H */
+#include <asm-generic/ioctl.h>
index be2d8f667a386bb6bdd0a80485b34fce08935844..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,83 +1 @@
-/*
- * linux/ioctl.h for Linux by H.H. Bergman.
- *
- * This is the same as the i386 version.
- */
-
-#ifndef _ASMCRIS_IOCTL_H
-#define _ASMCRIS_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* provoke compile error for invalid uses of size argument */
-extern int __invalid_size_argument_for_IOC;
-#define _IOC_TYPECHECK(t) \
-       ((sizeof(t) == sizeof(t[1]) && \
-         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
-         sizeof(t) : __invalid_size_argument_for_IOC)
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASMCRIS_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 8aee76905545cf9b008747ed6a01279cc21ec0d4..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,80 +1 @@
-/*
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASM_IOCTL_H
-#define _ASM_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * I don't really have any idea about what this should look like, so
- * for the time being, this is heavily based on the PC definitions.
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASM_IOCTL_H */
-
+#include <asm-generic/ioctl.h>
diff --git a/include/asm-generic/ioctl.h b/include/asm-generic/ioctl.h
new file mode 100644 (file)
index 0000000..cd02729
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef _ASM_GENERIC_IOCTL_H
+#define _ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The generic ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS    8
+#define _IOC_TYPEBITS  8
+#define _IOC_SIZEBITS  14
+#define _IOC_DIRBITS   2
+
+#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT   0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE      0U
+#define _IOC_WRITE     1U
+#define _IOC_READ      2U
+
+#define _IOC(dir,type,nr,size) \
+       (((dir)  << _IOC_DIRSHIFT) | \
+        ((type) << _IOC_TYPESHIFT) | \
+        ((nr)   << _IOC_NRSHIFT) | \
+        ((size) << _IOC_SIZESHIFT))
+
+/* provoke compile error for invalid uses of size argument */
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _IOC_TYPECHECK(t) \
+       ((sizeof(t) == sizeof(t[1]) && \
+         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
+         sizeof(t) : __invalid_size_argument_for_IOC)
+
+/* used to create numbers */
+#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size)        _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
+
+#endif /* _ASM_GENERIC_IOCTL_H */
index 031c623478b3192addbd7abb6aeabf532db1d07f..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,80 +1 @@
-/* $Id: ioctl.h,v 1.1 2002/11/19 02:09:26 gerg Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _H8300_IOCTL_H
-#define _H8300_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * I don't really have any idea about what this should look like, so
- * for the time being, this is heavily based on the PC definitions.
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _H8300_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 543f7843d553a7ac9b2b673a9920c858171535ab..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,85 +1 @@
-/* $Id: ioctl.h,v 1.5 1993/07/19 21:53:50 root Exp root $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMI386_IOCTL_H
-#define _ASMI386_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* provoke compile error for invalid uses of size argument */
-extern unsigned int __invalid_size_argument_for_IOC;
-#define _IOC_TYPECHECK(t) \
-       ((sizeof(t) == sizeof(t[1]) && \
-         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
-         sizeof(t) : __invalid_size_argument_for_IOC)
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR_BAD(type,nr,size)        _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASMI386_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 6ed2a03e37b3495785179e224aac0f68dbd8b0ad..53f0e06672dc1487c8ca22aff551e6ce111edcb6 100644 (file)
@@ -2,6 +2,8 @@
 #define _I386_KEXEC_H
 
 #include <asm/fixmap.h>
+#include <asm/ptrace.h>
+#include <asm/string.h>
 
 /*
  * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
 #define KEXEC_ARCH KEXEC_ARCH_386
 
 #define MAX_NOTE_BYTES 1024
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
 
-extern note_buf_t crash_notes[];
+/* CPU does not save ss and esp on stack if execution is already
+ * running in kernel mode at the time of NMI occurrence. This code
+ * fixes it.
+ */
+static inline void crash_fixup_ss_esp(struct pt_regs *newregs,
+                                       struct pt_regs *oldregs)
+{
+       memcpy(newregs, oldregs, sizeof(*newregs));
+       newregs->esp = (unsigned long)&(oldregs->esp);
+       __asm__ __volatile__(
+                       "xorl %%eax, %%eax\n\t"
+                       "movw %%ss, %%ax\n\t"
+                       :"=a"(newregs->xss));
+}
+
+/*
+ * This function is responsible for capturing register states if coming
+ * via panic otherwise just fix up the ss and esp if coming via kernel
+ * mode exception.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                       struct pt_regs *oldregs)
+{
+       if (oldregs)
+               crash_fixup_ss_esp(newregs, oldregs);
+       else {
+               __asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->ebx));
+               __asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->ecx));
+               __asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->edx));
+               __asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->esi));
+               __asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->edi));
+               __asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->ebp));
+               __asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->eax));
+               __asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->esp));
+               __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(newregs->xss));
+               __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(newregs->xcs));
+               __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(newregs->xds));
+               __asm__ __volatile__("movw %%es, %%ax;" :"=a"(newregs->xes));
+               __asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->eflags));
+
+               newregs->eip = (unsigned long)current_text_addr();
+       }
+}
 
 #endif /* _I386_KEXEC_H */
index ca916a892877edaddd26d048f74a33352dc6cd8f..27cac050a60e56cb71c750a196a80c8894e8abb1 100644 (file)
@@ -40,6 +40,7 @@ typedef u8 kprobe_opcode_t;
 
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)pentry
 #define ARCH_SUPPORTS_KRETPROBES
+#define arch_remove_kprobe(p)  do {} while (0)
 
 void kretprobe_trampoline(void);
 
@@ -76,14 +77,6 @@ static inline void restore_interrupts(struct pt_regs *regs)
                local_irq_enable();
 }
 
-#ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
-#else                          /* !CONFIG_KPROBES */
-static inline int kprobe_exceptions_notify(struct notifier_block *self,
-                                          unsigned long val, void *data)
-{
-       return 0;
-}
-#endif
 #endif                         /* _ASM_KPROBES_H */
index be9cc2403d2a07f329129c72ced512d2277cdee7..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,77 +1 @@
-#ifndef _ASM_IA64_IOCTL_H
-#define _ASM_IA64_IOCTL_H
-
-/*
- * Based on <asm-i386/ioctl.h>.
- *
- * Modified 1998, 1999
- *     David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The ia64 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASM_IA64_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 592abb000e29bc9260257a5f9fb806eae367a21d..a74b68104559a556e335e80b7262c46594086a89 100644 (file)
@@ -89,6 +89,7 @@ struct kprobe_ctlblk {
 #define IP_RELATIVE_PREDICT_OPCODE     (7)
 #define LONG_BRANCH_OPCODE             (0xC)
 #define LONG_CALL_OPCODE               (0xD)
+#define arch_remove_kprobe(p)          do {} while (0)
 
 typedef struct kprobe_opcode {
        bundle_t bundle;
@@ -110,12 +111,6 @@ struct arch_specific_insn {
        unsigned short target_br_reg;
 };
 
-/* ia64 does not need this */
-static inline void arch_copy_kprobe(struct kprobe *p)
-{
-}
-
-#ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
 
@@ -124,11 +119,4 @@ static inline void jprobe_return(void)
 {
 }
 
-#else                          /* !CONFIG_KPROBES */
-static inline int kprobe_exceptions_notify(struct notifier_block *self,
-                                          unsigned long val, void *data)
-{
-       return 0;
-}
-#endif
 #endif                         /* _ASM_KPROBES_H */
index 87d8f7db6af1ebac552d319c159bf347c28dff5b..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,78 +1 @@
-#ifndef _ASM_M32R_IOCTL_H
-#define _ASM_M32R_IOCTL_H
-
-/* $Id$ */
-
-/* orig : i386 2.4.18 */
-
-/*
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASM_M32R_IOCTL_H */
+#include <asm-generic/ioctl.h>
index fd68914ab2927e110941c066f114092886485f16..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,80 +1 @@
-/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _M68K_IOCTL_H
-#define _M68K_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * I don't really have any idea about what this should look like, so
- * for the time being, this is heavily based on the PC definitions.
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _M68K_IOCTL_H */
+#include <asm-generic/ioctl.h>
index cff72f33350fc2b6033fbb39d103a39de8c0d9ee..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1 +1 @@
-#include <asm-m68k/ioctl.h>
+#include <asm-generic/ioctl.h>
index 4395b7bc1ed462b839d21881e7ef3f1382988bcf..b263fb2fa6e4376312677746cc00a10911f676df 100644 (file)
@@ -34,9 +34,11 @@ struct device_node;
 extern int eeh_subsystem_enabled;
 
 /* Values for eeh_mode bits in device_node */
-#define EEH_MODE_SUPPORTED     (1<<0)
-#define EEH_MODE_NOCHECK       (1<<1)
-#define EEH_MODE_ISOLATED      (1<<2)
+#define EEH_MODE_SUPPORTED     (1<<0)
+#define EEH_MODE_NOCHECK       (1<<1)
+#define EEH_MODE_ISOLATED      (1<<2)
+#define EEH_MODE_RECOVERING    (1<<3)
+#define EEH_MODE_IRQ_DISABLED  (1<<4)
 
 /* Max number of EEH freezes allowed before we consider the device
  * to be permanently disabled. */
index 5e11a00b6fa01722031e647e610f03d00faab3b9..93d55a2bebfdc9e4acc660679d9a4391d7905f73 100644 (file)
@@ -30,7 +30,7 @@ struct eeh_event {
        struct list_head     list;
        struct device_node      *dn;   /* struct device node */
        struct pci_dev       *dev;  /* affected device */
-       int                  state;
+       enum pci_channel_state state; /* PCI bus state for the affected device */
        int time_unavail;    /* milliseconds until device might be available */
 };
 
@@ -47,8 +47,11 @@ struct eeh_event {
  */
 int eeh_send_failure_event (struct device_node *dn,
                             struct pci_dev *dev,
-                            int reset_state,
+                            enum pci_channel_state state,
                             int time_unavail);
 
+/* Main recovery function */
+void handle_eeh_events (struct eeh_event *);
+
 #endif /* __KERNEL__ */
 #endif /* ASM_PPC64_EEH_EVENT_H */
index 4263af3cadfde4edaf1b1742fd2b060034350914..fffdf690b8404548b47d3747a17b521682158038 100644 (file)
@@ -38,9 +38,6 @@
 #ifdef CONFIG_KEXEC
 
 #define MAX_NOTE_BYTES 1024
-typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
-
-extern note_buf_t crash_notes[];
 
 #ifdef __powerpc64__
 extern void kexec_smp_wait(void);      /* get and clear naca physid, wait for
@@ -58,6 +55,12 @@ extern void default_machine_crash_shutdown(struct pt_regs *regs);
 
 #endif /* !CONFIG_KEXEC */
 
+/*
+ * Provide a dummy definition to avoid build failures. Will remain
+ * empty till crash dump support is enabled.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                       struct pt_regs *oldregs) { }
 #endif /* ! __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KEXEC_H */
index 0654f79b06df9b81c9c00816ae0a4e9408924c1e..f466bc804f41ee21a7372cd1cc0328e872629508 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/percpu.h>
 
+#define  __ARCH_WANT_KPROBES_INSN_SLOT
+
 struct pt_regs;
+struct kprobe;
 
 typedef unsigned int kprobe_opcode_t;
 #define BREAKPOINT_INSTRUCTION 0x7fe00008      /* trap */
@@ -48,6 +51,7 @@ typedef unsigned int kprobe_opcode_t;
 
 #define ARCH_SUPPORTS_KRETPROBES
 void kretprobe_trampoline(void);
+extern void arch_remove_kprobe(struct kprobe *p);
 
 /* Architecture specific copy of original instruction */
 struct arch_specific_insn {
@@ -69,15 +73,7 @@ struct kprobe_ctlblk {
        struct prev_kprobe prev_kprobe;
 };
 
-#ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
-                                   unsigned long val, void *data);
-#else                          /* !CONFIG_KPROBES */
-static inline int kprobe_exceptions_notify(struct notifier_block *self,
-                                          unsigned long val, void *data)
-{
-       return 0;
-}
-#endif
+                                       unsigned long val, void *data);
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KPROBES_H */
index 1a08860e789ec7e5bae3005770bd42b63f519df5..b0d816fe2e27ef3bf0069fa34547782bd19557ec 100644 (file)
@@ -61,16 +61,17 @@ struct pci_controller;
 struct iommu_table;
 
 struct pci_dn {
-       int     busno;                  /* for pci devices */
-       int     bussubno;               /* for pci devices */
-       int     devfn;                  /* for pci devices */
+       int     busno;                  /* pci bus number */
+       int     bussubno;               /* pci subordinate bus number */
+       int     devfn;                  /* pci device and function number */
+       int     class_code;             /* pci device class */
 
 #ifdef CONFIG_PPC_PSERIES
        int     eeh_mode;               /* See eeh.h for possible EEH_MODEs */
        int     eeh_config_addr;
+       int     eeh_pe_config_addr; /* new-style partition endpoint address */
        int     eeh_check_count;        /* # times driver ignored error */
        int     eeh_freeze_count;       /* # times this device froze up. */
-       int     eeh_is_bridge;          /* device is pci-to-pci bridge */
 #endif
        int     pci_ext_config_space;   /* for pci devices */
        struct  pci_controller *phb;    /* for pci devices */
index bdef312900a1d23c2b98708cf34aa42733492f53..f80482c7231f174dbfed90fc6df0b612e80fdc01 100644 (file)
@@ -52,6 +52,21 @@ extern unsigned long pci_probe_only;
 
 /* ---- EEH internal-use-only related routines ---- */
 #ifdef CONFIG_EEH
+
+void pci_addr_cache_insert_device(struct pci_dev *dev);
+void pci_addr_cache_remove_device(struct pci_dev *dev);
+void pci_addr_cache_build(void);
+struct pci_dev *pci_get_device_by_addr(unsigned long addr);
+
+/**
+ * eeh_slot_error_detail -- record and EEH error condition to the log
+ * @severity: 1 if temporary, 2 if permanent failure.
+ *
+ * Obtains the the EEH error details from the RTAS subsystem,
+ * and then logs these details with the RTAS error log system.
+ */
+void eeh_slot_error_detail (struct pci_dn *pdn, int severity);
+
 /**
  * rtas_set_slot_reset -- unfreeze a frozen slot
  *
@@ -59,8 +74,10 @@ extern unsigned long pci_probe_only;
  * does this by asserting the PCI #RST line for 1/8th of
  * a second; this routine will sleep while the adapter is
  * being reset.
+ *
+ * Returns a non-zero value if the reset failed.
  */
-void rtas_set_slot_reset (struct pci_dn *);
+int rtas_set_slot_reset (struct pci_dn *);
 
 /** 
  * eeh_restore_bars - Restore device configuration info.
@@ -84,6 +101,7 @@ void eeh_restore_bars(struct pci_dn *);
 void rtas_configure_bridge(struct pci_dn *);
 
 int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
+int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);
 
 /**
  * mark and clear slots: find "partition endpoint" PE and set or 
@@ -92,6 +110,9 @@ int rtas_write_config(struct pci_dn *, int where, int size, u32 val);
 void eeh_mark_slot (struct device_node *dn, int mode_flag);
 void eeh_clear_slot (struct device_node *dn, int mode_flag);
 
+/* Find the associated "Partiationable Endpoint" PE */
+struct device_node * find_device_pe(struct device_node *dn);
+
 #endif
 
 #endif /* __KERNEL__ */
index 6dc9546d6908c2604692a531a16043fa1983f6f5..3e8589b43cb2b27657e54154c36a2c1814ef0b72 100644 (file)
 /* Default baud base if not found in device-tree */
 #define BASE_BAUD ( 1843200 / 16 )
 
+#ifdef CONFIG_PPC_UDBG_16550
 extern void find_legacy_serial_ports(void);
+#else
+#define find_legacy_serial_ports()     do { } while (0)
+#endif
 
 #endif /* _PPC64_SERIAL_H */
index df7394345ac40131b7bc8348c11e2fb265c06906..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,88 +1 @@
-/*
- *  include/asm-s390/ioctl.h
- *
- *  S390 version
- *
- *  Derived from "include/asm-i386/ioctl.h"
- */
-
-#ifndef _S390_IOCTL_H
-#define _S390_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* provoke compile error for invalid uses of size argument */
-extern unsigned long __invalid_size_argument_for_IOC;
-#define _IOC_TYPECHECK(t) \
-       ((sizeof(t) == sizeof(t[1]) && \
-         sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
-         sizeof(t) : __invalid_size_argument_for_IOC)
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR_BAD(type,nr,size)        _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _S390_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 54cf7d9f251c69f78e171f3f81068ce852fc8210..ce28ddda0f507266a10e297844e7500d73ff290d 100644 (file)
@@ -35,8 +35,9 @@
 #define KEXEC_ARCH KEXEC_ARCH_S390
 
 #define MAX_NOTE_BYTES 1024
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
 
-extern note_buf_t crash_notes[];
+/* Provide a dummy definition to avoid build failures. */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                       struct pt_regs *oldregs) { }
 
 #endif /*_S390_KEXEC_H */
index 524700e84acd83bd9dabbde9146cfdab14ea4fd7..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,75 +1 @@
-/* $Id: ioctl.h,v 1.1.1.1 2001/10/15 20:45:09 mrbrown Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef __ASM_SH_IOCTL_H
-#define __ASM_SH_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* __ASM_SH_IOCTL_H */
+#include <asm-generic/ioctl.h>
index cfafaa73b2b071628121d9bea52141dc31305731..dee4f77929a45523089d5e98fa46a95ce890aa75 100644 (file)
@@ -143,12 +143,12 @@ extern unsigned long pciio_virt;
  * Change virtual addresses to physical addresses and vv.
  * These are trivial on the 1:1 Linux/SuperH mapping
  */
-extern __inline__ unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
 {
        return __pa(address);
 }
 
-extern __inline__ void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
 {
        return __va(address);
 }
@@ -156,12 +156,12 @@ extern __inline__ void * phys_to_virt(unsigned long address)
 extern void * __ioremap(unsigned long phys_addr, unsigned long size,
                        unsigned long flags);
 
-extern __inline__ void * ioremap(unsigned long phys_addr, unsigned long size)
+static inline void * ioremap(unsigned long phys_addr, unsigned long size)
 {
        return __ioremap(phys_addr, size, 1);
 }
 
-extern __inline__ void * ioremap_nocache (unsigned long phys_addr, unsigned long size)
+static inline void * ioremap_nocache (unsigned long phys_addr, unsigned long size)
 {
        return __ioremap(phys_addr, size, 0);
 }
index c089a6fb78e02971f74f4acbbe43665e631c1cac..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,83 +1 @@
-#ifndef __ASM_SH64_IOCTL_H
-#define __ASM_SH64_IOCTL_H
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * include/asm-sh64/ioctl.h
- *
- * Copyright (C) 2000, 2001  Paolo Alberelli
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- *
- */
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* __ASM_SH64_IOCTL_H */
+#include <asm-generic/ioctl.h>
index f062e1513272745e1f1432749894ddcb1cf5660c..991cfda4cdf66f2be9c1caa0af5de484f8fd72ac 100644 (file)
@@ -50,7 +50,7 @@ extern pgd_t *mmu_pdtp_cache;
  */
 #define MMU_VPN_MASK   0xfffff000
 
-extern __inline__ void
+static inline void
 get_new_mmu_context(struct mm_struct *mm)
 {
        extern void flush_tlb_all(void);
index b25f5df5535c0450801c00d3f0ac9cd5901b691d..678251ac1db8b5297f0b7143430af58109532d8a 100644 (file)
@@ -38,14 +38,14 @@ static inline void pgd_init(unsigned long page)
  * if any.
  */
 
-extern __inline__ pgd_t *get_pgd_slow(void)
+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);
        return ret;
 }
 
-extern __inline__ pgd_t *get_pgd_fast(void)
+static inline pgd_t *get_pgd_fast(void)
 {
        unsigned long *ret;
 
@@ -62,14 +62,14 @@ extern __inline__ pgd_t *get_pgd_fast(void)
        return (pgd_t *)ret;
 }
 
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
+static inline void free_pgd_fast(pgd_t *pgd)
 {
        *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
        pgd_quicklist = (unsigned long *) pgd;
        pgtable_cache_size++;
 }
 
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
+static inline void free_pgd_slow(pgd_t *pgd)
 {
        kfree((void *)pgd);
 }
@@ -77,7 +77,7 @@ extern __inline__ void free_pgd_slow(pgd_t *pgd)
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
 extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long address_preadjusted);
 
-extern __inline__ pte_t *get_pte_fast(void)
+static inline pte_t *get_pte_fast(void)
 {
        unsigned long *ret;
 
@@ -89,7 +89,7 @@ extern __inline__ pte_t *get_pte_fast(void)
        return (pte_t *)ret;
 }
 
-extern __inline__ void free_pte_fast(pte_t *pte)
+static inline void free_pte_fast(pte_t *pte)
 {
        *(unsigned long *)pte = (unsigned long) pte_quicklist;
        pte_quicklist = (unsigned long *) pte;
@@ -167,7 +167,7 @@ static __inline__ void pmd_free(pmd_t *pmd)
 
 extern int do_check_pgt_cache(int, int);
 
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
+static inline void set_pgdir(unsigned long address, pgd_t entry)
 {
        struct task_struct * p;
        pgd_t *pgd;
index a1906a772df9b66594bb39da22866e0097317d11..57af6b3eb271e02116e4dab16f4c6092f78c819e 100644 (file)
@@ -421,18 +421,18 @@ static inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; }
 static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
 static inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_WRITE; }
 
-extern inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_READ)); return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
-extern inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_EXECUTE)); return pte; }
-extern inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
-extern inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
+static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_READ)); return pte; }
+static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
+static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_EXECUTE)); return pte; }
+static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
+static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
 
-extern inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_READ)); return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_WRITE)); return pte; }
-extern inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE)); return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
-extern inline pte_t pte_mkhuge(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
+static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_READ)); return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_WRITE)); return pte; }
+static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE)); return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
+static inline pte_t pte_mkhuge(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
 
 
 /*
@@ -456,7 +456,7 @@ extern inline pte_t pte_mkhuge(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) | _
 #define mk_pte_phys(physpage, pgprot) \
 ({ pte_t __pte; set_pte(&__pte, __pte(physpage | pgprot_val(pgprot))); __pte; })
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
 
 typedef pte_t *pte_addr_t;
index a51bd41e6fbc02d1a57a72b434b345ce1ef52285..1bf252dad8249e5d7f3078dde23f440729d59fad 100644 (file)
@@ -228,7 +228,7 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
  * FPU lazy state save handling.
  */
 
-extern __inline__ void release_fpu(void)
+static inline void release_fpu(void)
 {
        unsigned long long __dummy;
 
@@ -240,7 +240,7 @@ extern __inline__ void release_fpu(void)
                             : "r" (SR_FD));
 }
 
-extern __inline__ void grab_fpu(void)
+static inline void grab_fpu(void)
 {
        unsigned long long __dummy;
 
index 42510e496eb528f10894343e3b0dc3387f396255..3002e988180c5a8ee68dae4438df1c45c1be2a80 100644 (file)
@@ -132,7 +132,7 @@ static __inline__ void local_irq_disable(void)
        (flags != 0);                   \
 })
 
-extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
 {
        unsigned long flags, retval;
 
@@ -143,7 +143,7 @@ extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
        return retval;
 }
 
-extern __inline__ unsigned long xchg_u8(volatile unsigned char * m, unsigned long val)
+static inline unsigned long xchg_u8(volatile unsigned char * m, unsigned long val)
 {
        unsigned long flags, retval;
 
index 15c0719eecc34662db79a7e04ab09f94c3654aba..e45beadc29ee860066996c8989893c497acfb550 100644 (file)
@@ -20,7 +20,7 @@ extern void flush_tlb_mm(struct mm_struct *mm);
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                            unsigned long end);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                      unsigned long start, unsigned long end)
 {
 }
index 56aa3cf0f2734da96dda1ce66469dd4d5b4fcb13..f4936d8fa617fe9b7ecc8e2895055147f492fa4c 100644 (file)
@@ -287,7 +287,7 @@ __sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count);
  */
 extern long __strnlen_user(const char *__s, long __n);
 
-extern __inline__ long strnlen_user(const char *s, long n)
+static inline long strnlen_user(const char *s, long n)
 {
        if (!__addr_ok(s))
                return 0;
index 7ba845320f5c05d0d9450d89cbf2dacf72b72819..e4efe652b54b91322a81025a42e11f44ddcc2bbe 100644 (file)
@@ -12,6 +12,7 @@ typedef u32 kprobe_opcode_t;
 #define MAX_INSN_SIZE 2
 
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)pentry
+#define arch_remove_kprobe(p)  do {} while (0)
 
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
@@ -38,15 +39,6 @@ struct kprobe_ctlblk {
        struct prev_kprobe prev_kprobe;
 };
 
-#ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
-#else                          /* !CONFIG_KPROBES */
-static inline int kprobe_exceptions_notify(struct notifier_block *self,
-                                          unsigned long val, void *data)
-{
-       return 0;
-}
-#endif
-
 #endif /* _SPARC64_KPROBES_H */
index 075771c371f6a40be8b1e1dc5e6a0731711d11ec..da07a69ce82a5bda77c7746faa22b8c4afdd8a99 100644 (file)
@@ -89,7 +89,6 @@ extern struct task_struct *alloc_task_struct(void);
 
 extern void release_thread(struct task_struct *);
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-extern void dump_thread(struct pt_regs *regs, struct user *u);
 
 static inline void prepare_to_copy(struct task_struct *tsk)
 {
index 1765df6c7b87ffc050835f3b0af5f64da888eb9c..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,80 +1 @@
-/* $Id: ioctl.h,v 1.1 2002/09/28 14:58:41 gerg Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _V850_IOCTL_H
-#define _V850_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * I don't really have any idea about what this should look like, so
- * for the time being, this is heavily based on the PC definitions.
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* __V850_IOCTL_H__ */
+#include <asm-generic/ioctl.h>
index e682edc24a68072c97da7611be582f92b9000425..8dcc32665240fbaa657029e34c65274f8e234fd4 100644 (file)
@@ -55,6 +55,7 @@ extern unsigned long e820_hole_size(unsigned long start_pfn,
                                    unsigned long end_pfn);
 
 extern void __init parse_memopt(char *p, char **end);
+extern void __init parse_memmapopt(char *p, char **end);
 
 extern struct e820map e820;
 #endif/*!__ASSEMBLY__*/
index 609b663b6bf4ad144930e49c130dffa8c03499b0..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,75 +1 @@
-/* $Id: ioctl.h,v 1.2 2001/07/04 09:08:13 ak Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMX8664_IOCTL_H
-#define _ASMX8664_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif /* _ASMX8664_IOCTL_H */
+#include <asm-generic/ioctl.h>
index 42d2ff15c592d41ab6058d5d543f008f1179a220..ae28cd44bcd3158433641c67e3afdf26a1a25cd8 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <asm/page.h>
 #include <asm/proto.h>
+#include <asm/ptrace.h>
 
 /*
  * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
 #define KEXEC_ARCH KEXEC_ARCH_X86_64
 
 #define MAX_NOTE_BYTES 1024
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
 
-extern note_buf_t crash_notes[];
+/*
+ * Saving the registers of the cpu on which panic occured in
+ * crash_kexec to save a valid sp. The registers of other cpus
+ * will be saved in machine_crash_shutdown while shooting down them.
+ */
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                               struct pt_regs *oldregs)
+{
+       if (oldregs)
+               memcpy(newregs, oldregs, sizeof(*newregs));
+       else {
+               __asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->rbx));
+               __asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->rcx));
+               __asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->rdx));
+               __asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->rsi));
+               __asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->rdi));
+               __asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->rbp));
+               __asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->rax));
+               __asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->rsp));
+               __asm__ __volatile__("movq %%r8,%0" : "=m"(newregs->r8));
+               __asm__ __volatile__("movq %%r9,%0" : "=m"(newregs->r9));
+               __asm__ __volatile__("movq %%r10,%0" : "=m"(newregs->r10));
+               __asm__ __volatile__("movq %%r11,%0" : "=m"(newregs->r11));
+               __asm__ __volatile__("movq %%r12,%0" : "=m"(newregs->r12));
+               __asm__ __volatile__("movq %%r13,%0" : "=m"(newregs->r13));
+               __asm__ __volatile__("movq %%r14,%0" : "=m"(newregs->r14));
+               __asm__ __volatile__("movq %%r15,%0" : "=m"(newregs->r15));
+               __asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss));
+               __asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs));
+               __asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->eflags));
 
+               newregs->rip = (unsigned long)current_text_addr();
+       }
+}
 #endif /* _X86_64_KEXEC_H */
index 4dd7a7e148d450d6ba93c347c655cc8975ac8230..98a1e95ddb981c22e84e2d2e82ea754c242f43f7 100644 (file)
 #include <linux/ptrace.h>
 #include <linux/percpu.h>
 
+#define  __ARCH_WANT_KPROBES_INSN_SLOT
+
 struct pt_regs;
+struct kprobe;
 
 typedef u8 kprobe_opcode_t;
 #define BREAKPOINT_INSTRUCTION 0xcc
@@ -42,6 +45,7 @@ typedef u8 kprobe_opcode_t;
 #define ARCH_SUPPORTS_KRETPROBES
 
 void kretprobe_trampoline(void);
+extern void arch_remove_kprobe(struct kprobe *p);
 
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
index 856c605d62b1f7288303a8404362d5d1ef6809d4..b279fe06dfe5bea925eccf4b39c8908b23379b6a 100644 (file)
@@ -1,83 +1 @@
-/*
- * include/asm-xtensa/ioctl.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003 - 2005 Tensilica Inc.
- *
- * Derived from "include/asm-i386/ioctl.h"
- */
-
-#ifndef _XTENSA_IOCTL_H
-#define _XTENSA_IOCTL_H
-
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The i386 ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS    8
-#define _IOC_TYPEBITS  8
-#define _IOC_SIZEBITS  14
-#define _IOC_DIRBITS   2
-
-#define _IOC_NRMASK    ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK  ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK  ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK   ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT   0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT  (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE      0U
-#define _IOC_WRITE     1U
-#define _IOC_READ      2U
-
-#define _IOC(dir,type,nr,size) \
-       (((dir)  << _IOC_DIRSHIFT) | \
-        ((type) << _IOC_TYPESHIFT) | \
-        ((nr)   << _IOC_NRSHIFT) | \
-        ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr)           _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size)    _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)           (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)          (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)            (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)          (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN         (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT                (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT      ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK   (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT  (_IOC_SIZESHIFT)
-
-#endif
+#include <asm-generic/ioctl.h>
diff --git a/include/linux/calc64.h b/include/linux/calc64.h
new file mode 100644 (file)
index 0000000..ebf4b8f
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _LINUX_CALC64_H
+#define _LINUX_CALC64_H
+
+#include <linux/types.h>
+#include <asm/div64.h>
+
+/*
+ * This is a generic macro which is used when the architecture
+ * specific div64.h does not provide a optimized one.
+ *
+ * The 64bit dividend is divided by the divisor (data type long), the
+ * result is returned and the remainder stored in the variable
+ * referenced by remainder (data type long *). In contrast to the
+ * do_div macro the dividend is kept intact.
+ */
+#ifndef div_long_long_rem
+#define div_long_long_rem(dividend, divisor, remainder)        \
+       do_div_llr((dividend), divisor, remainder)
+
+static inline unsigned long do_div_llr(const long long dividend,
+                                      const long divisor, long *remainder)
+{
+       u64 result = dividend;
+
+       *(remainder) = do_div(result, divisor);
+       return (unsigned long) result;
+}
+#endif
+
+/*
+ * Sign aware variation of the above. On some architectures a
+ * negative dividend leads to an divide overflow exception, which
+ * is avoided by the sign check.
+ */
+static inline long div_long_long_rem_signed(const long long dividend,
+                                           const long divisor, long *remainder)
+{
+       long res;
+
+       if (unlikely(dividend < 0)) {
+               res = -div_long_long_rem(-dividend, divisor, remainder);
+               *remainder = -(*remainder);
+       } else
+               res = div_long_long_rem(dividend, divisor, remainder);
+
+       return res;
+}
+
+#endif
index 339878952f12f7fe4e3b81ff86691a6923344a34..8fad50f8e3890d9f267ec3e7361d619390557f38 100644 (file)
@@ -2,14 +2,6 @@
  * compatible types passed or none at all... Please include
  * only stuff that is compatible on *all architectures*.
  */
-#ifndef COMPATIBLE_IOCTL /* pointer to compatible structure or no argument */
-#define COMPATIBLE_IOCTL(cmd)  HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
-#endif
-
-#ifndef ULONG_IOCTL /* argument is an unsigned long integer, not a pointer */
-#define ULONG_IOCTL(cmd)  HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)sys_ioctl)
-#endif
-
 
 COMPATIBLE_IOCTL(0x4B50)   /* KDGHWCLK - not in the kernel, but don't complain */
 COMPATIBLE_IOCTL(0x4B51)   /* KDSHWCLK - not in the kernel, but don't complain */
index 92ae3e2067b0dfd8318232a43abdc847847a087c..d1e370d25f7bbe76ed799a4a8788f155950473ff 100644 (file)
@@ -114,8 +114,7 @@ extern int dir_notify_enable;
 /*
  * Superblock flags that can be altered by MS_REMOUNT
  */
-#define MS_RMT_MASK    (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|\
-                        MS_NODIRATIME)
+#define MS_RMT_MASK    (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
 
 /*
  * Old magic mount flag and mask
@@ -161,8 +160,6 @@ extern int dir_notify_enable;
 #define IS_NOQUOTA(inode)      ((inode)->i_flags & S_NOQUOTA)
 #define IS_APPEND(inode)       ((inode)->i_flags & S_APPEND)
 #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
-#define IS_NOATIME(inode)      (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
-#define IS_NODIRATIME(inode)   __IS_FLG(inode, MS_NODIRATIME)
 #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
 
 #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
@@ -235,9 +232,6 @@ struct kstatfs;
 struct vm_area_struct;
 struct vfsmount;
 
-/* Used to be a macro which just called the function, now just a function */
-extern void update_atime (struct inode *);
-
 extern void __init inode_init(unsigned long);
 extern void __init inode_init_early(void);
 extern void __init mnt_init(unsigned long);
@@ -1118,12 +1112,7 @@ static inline void mark_inode_dirty_sync(struct inode *inode)
        __mark_inode_dirty(inode, I_DIRTY_SYNC);
 }
 
-static inline void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
-{
-       /* per-mountpoint checks will go here */
-       update_atime(dentry->d_inode);
-}
-
+extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry);
 static inline void file_accessed(struct file *file)
 {
        if (!(file->f_flags & O_NOATIME))
@@ -1716,7 +1705,7 @@ extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const vo
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern int __must_check inode_setattr(struct inode *, struct iattr *);
 
-extern void inode_update_time(struct inode *inode, int ctime_too);
+extern void file_update_time(struct file *file);
 
 static inline ino_t parent_ino(struct dentry *dentry)
 {
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
new file mode 100644 (file)
index 0000000..cf5cfdf
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ *  include/linux/hrtimer.h
+ *
+ *  hrtimers - High-resolution kernel timers
+ *
+ *   Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
+ *   Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
+ *
+ *  data type definitions, declarations, prototypes
+ *
+ *  Started by: Thomas Gleixner and Ingo Molnar
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+#ifndef _LINUX_HRTIMER_H
+#define _LINUX_HRTIMER_H
+
+#include <linux/rbtree.h>
+#include <linux/ktime.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+
+/*
+ * Mode arguments of xxx_hrtimer functions:
+ */
+enum hrtimer_mode {
+       HRTIMER_ABS,    /* Time value is absolute */
+       HRTIMER_REL,    /* Time value is relative to now */
+};
+
+enum hrtimer_restart {
+       HRTIMER_NORESTART,
+       HRTIMER_RESTART,
+};
+
+/*
+ * Timer states:
+ */
+enum hrtimer_state {
+       HRTIMER_INACTIVE,       /* Timer is inactive */
+       HRTIMER_EXPIRED,                /* Timer is expired */
+       HRTIMER_PENDING,                /* Timer is pending */
+};
+
+struct hrtimer_base;
+
+/**
+ * struct hrtimer - the basic hrtimer structure
+ *
+ * @node:      red black tree node for time ordered insertion
+ * @list:      list head for easier access to the time ordered list,
+ *             without walking the red black tree.
+ * @expires:   the absolute expiry time in the hrtimers internal
+ *             representation. The time is related to the clock on
+ *             which the timer is based.
+ * @state:     state of the timer
+ * @function:  timer expiry callback function
+ * @data:      argument for the callback function
+ * @base:      pointer to the timer base (per cpu and per clock)
+ *
+ * The hrtimer structure must be initialized by init_hrtimer_#CLOCKTYPE()
+ */
+struct hrtimer {
+       struct rb_node          node;
+       struct list_head        list;
+       ktime_t                 expires;
+       enum hrtimer_state      state;
+       int                     (*function)(void *);
+       void                    *data;
+       struct hrtimer_base     *base;
+};
+
+/**
+ * struct hrtimer_base - the timer base for a specific clock
+ *
+ * @index:     clock type index for per_cpu support when moving a timer
+ *             to a base on another cpu.
+ * @lock:      lock protecting the base and associated timers
+ * @active:    red black tree root node for the active timers
+ * @pending:   list of pending timers for simple time ordered access
+ * @resolution:        the resolution of the clock, in nanoseconds
+ * @get_time:  function to retrieve the current time of the clock
+ * @curr_timer:        the timer which is executing a callback right now
+ */
+struct hrtimer_base {
+       clockid_t               index;
+       spinlock_t              lock;
+       struct rb_root          active;
+       struct list_head        pending;
+       unsigned long           resolution;
+       ktime_t                 (*get_time)(void);
+       struct hrtimer          *curr_timer;
+};
+
+/*
+ * clock_was_set() is a NOP for non- high-resolution systems. The
+ * time-sorted order guarantees that a timer does not expire early and
+ * is expired in the next softirq when the clock was advanced.
+ */
+#define clock_was_set()                do { } while (0)
+
+/* Exported timer functions: */
+
+/* Initialize timers: */
+extern void hrtimer_init(struct hrtimer *timer, const clockid_t which_clock);
+extern void hrtimer_rebase(struct hrtimer *timer, const clockid_t which_clock);
+
+
+/* Basic timer operations: */
+extern int hrtimer_start(struct hrtimer *timer, ktime_t tim,
+                        const enum hrtimer_mode mode);
+extern int hrtimer_cancel(struct hrtimer *timer);
+extern int hrtimer_try_to_cancel(struct hrtimer *timer);
+
+#define hrtimer_restart(timer) hrtimer_start((timer), (timer)->expires, HRTIMER_ABS)
+
+/* Query timers: */
+extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer);
+extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp);
+
+static inline int hrtimer_active(const struct hrtimer *timer)
+{
+       return timer->state == HRTIMER_PENDING;
+}
+
+/* Forward a hrtimer so it expires after now: */
+extern unsigned long hrtimer_forward(struct hrtimer *timer,
+                                    const ktime_t interval);
+
+/* Precise sleep: */
+extern long hrtimer_nanosleep(struct timespec *rqtp,
+                             struct timespec __user *rmtp,
+                             const enum hrtimer_mode mode,
+                             const clockid_t clockid);
+
+/* Soft interrupt function to run the hrtimer queues: */
+extern void hrtimer_run_queues(void);
+
+/* Bootup initialization: */
+extern void __init hrtimers_init(void);
+
+#endif
index 7c6eae7f6ed73cacc5ab81268684020bd768bac1..45b3d48f0978d925c42f83be226f85ba58ecfa36 100644 (file)
@@ -4,47 +4,12 @@
 /*#define              ISICOM_DEBUG*/
 /*#define              ISICOM_DEBUG_DTR_RTS*/
 
-
-/*
- *     Firmware Loader definitions ...
- */
-#define                __MultiTech             ('M'<<8)
-#define                MIOCTL_LOAD_FIRMWARE    (__MultiTech | 0x01)
-#define         MIOCTL_READ_FIRMWARE    (__MultiTech | 0x02)
-#define         MIOCTL_XFER_CTRL       (__MultiTech | 0x03)
-#define         MIOCTL_RESET_CARD      (__MultiTech | 0x04)
-
-#define                DATA_SIZE       16
-
-typedef        struct  {
-               unsigned short  exec_segment;
-               unsigned short  exec_addr;
-}      exec_record;
-
-typedef        struct  {
-               int             board;          /* Board to load */
-               unsigned short  addr;
-               unsigned short  count;
-}      bin_header;
-
-typedef        struct  {
-               int             board;          /* Board to load */
-               unsigned short  addr;
-               unsigned short  count;
-               unsigned short  segment;
-               unsigned char   bin_data[DATA_SIZE];
-}      bin_frame;
-
 #ifdef __KERNEL__
 
 #define                YES     1
 #define                NO      0
 
-#define                ISILOAD_MISC_MINOR      155     /* /dev/isctl */
-#define                ISILOAD_NAME            "ISILoad"
-
-/*     
+/*
  *  ISICOM Driver definitions ...
  *
  */
@@ -55,8 +20,8 @@ typedef       struct  {
  *      PCI definitions
  */
 
- #define        DEVID_COUNT     9
- #define        VENDOR_ID       0x10b5
+#define                DEVID_COUNT     9
+#define                VENDOR_ID       0x10b5
 
 /*
  *     These are now officially allocated numbers
@@ -66,9 +31,9 @@ typedef       struct  {
 #define                ISICOM_CMAJOR   113     /* callout */
 #define                ISICOM_MAGIC    (('M' << 8) | 'T')
 
-#define                WAKEUP_CHARS    256     /* hard coded for now   */ 
-#define                TX_SIZE         254 
+#define                WAKEUP_CHARS    256     /* hard coded for now   */
+#define                TX_SIZE         254
+
 #define                BOARD_COUNT     4
 #define                PORT_COUNT      (BOARD_COUNT*16)
 
@@ -98,18 +63,15 @@ typedef     struct  {
 #define                ISICOM_INITIATE_XONXOFF 0x04
 #define                ISICOM_RESPOND_XONXOFF  0x08
 
-#define InterruptTheCard(base) (outw(0,(base)+0xc)) 
-#define ClearInterrupt(base) (inw((base)+0x0a))        
-
 #define        BOARD(line)  (((line) >> 4) & 0x3)
 
        /*      isi kill queue bitmap   */
-       
+
 #define                ISICOM_KILLTX           0x01
 #define                ISICOM_KILLRX           0x02
 
        /* isi_board status bitmap */
-       
+
 #define                FIRMWARE_LOADED         0x0001
 #define                BOARD_ACTIVE            0x0002
 
@@ -123,9 +85,8 @@ typedef      struct  {
 #define                ISI_RTS                 0x0200
 
 
-#define                ISI_TXOK                0x0001 
+#define                ISI_TXOK                0x0001
+
 #endif /*      __KERNEL__      */
 
 #endif /*      ISICOM_H        */
-
index 6acfdbba734b17f554a089ca30f27ef12102789e..99905e180532e094c2efb0fc8c3ce6c66c63d92b 100644 (file)
@@ -1,21 +1,12 @@
 #ifndef _LINUX_JIFFIES_H
 #define _LINUX_JIFFIES_H
 
+#include <linux/calc64.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <asm/param.h>                 /* for HZ */
-#include <asm/div64.h>
-
-#ifndef div_long_long_rem
-#define div_long_long_rem(dividend,divisor,remainder) \
-({                                                     \
-       u64 result = dividend;                          \
-       *remainder = do_div(result,divisor);            \
-       result;                                         \
-})
-#endif
 
 /*
  * The following defines establish the engineering parameters of the PLL
@@ -373,8 +364,11 @@ jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
         * one divide.
         */
        u64 nsec = (u64)jiffies * TICK_NSEC;
-       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &value->tv_usec);
-       value->tv_usec /= NSEC_PER_USEC;
+       long tv_usec;
+
+       value->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tv_usec);
+       tv_usec /= NSEC_PER_USEC;
+       value->tv_usec = tv_usec;
 }
 
 /*
index 7428198111eb1c1e914b38d21f1f6ee1a64e44db..45f625d7d0b2aab6ca2ee0e99dda5f0cd03109e3 100644 (file)
@@ -151,7 +151,7 @@ extern unsigned int keymap_count;
 
 static inline void con_schedule_flip(struct tty_struct *t)
 {
-       schedule_work(&t->flip.work);
+       schedule_work(&t->buf.work);
 }
 
 #endif
index d0e6ca3b00ef0510b13b308640ba8b1eff2efcce..e6ee2d95da7a3604d0a7c473ef7396896d21ead9 100644 (file)
@@ -47,6 +47,8 @@ extern int console_printk[];
 #define default_console_loglevel (console_printk[3])
 
 struct completion;
+struct pt_regs;
+struct user;
 
 /**
  * might_sleep - annotation for functions that can sleep
@@ -123,6 +125,8 @@ extern int __kernel_text_address(unsigned long addr);
 extern int kernel_text_address(unsigned long addr);
 extern int session_of_pgrp(int pgrp);
 
+extern void dump_thread(struct pt_regs *regs, struct user *dump);
+
 #ifdef CONFIG_PRINTK
 asmlinkage int vprintk(const char *fmt, va_list args)
        __attribute__ ((format (printf, 1, 0)));
index c8468472aec0945a28c2d807912a47e5e5f621e6..94abc07cb1648b72692b5c02654bea3c1451c6b1 100644 (file)
@@ -41,7 +41,7 @@ typedef unsigned long kimage_entry_t;
 #define IND_DONE         0x4
 #define IND_SOURCE       0x8
 
-#define KEXEC_SEGMENT_MAX 8
+#define KEXEC_SEGMENT_MAX 16
 struct kexec_segment {
        void __user *buf;
        size_t bufsz;
@@ -125,6 +125,8 @@ extern struct kimage *kexec_image;
 /* Location of a reserved region to hold the crash kernel.
  */
 extern struct resource crashk_res;
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+extern note_buf_t *crash_notes;
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
index c03f2dc933de04a7503d75f2cacb9fa68963ca13..10005bc92a316000321e89ea87a76d3e7599b1ea 100644 (file)
@@ -149,11 +149,10 @@ struct kretprobe_instance {
 };
 
 extern spinlock_t kretprobe_lock;
+extern struct semaphore kprobe_mutex;
 extern int arch_prepare_kprobe(struct kprobe *p);
-extern void arch_copy_kprobe(struct kprobe *p);
 extern void arch_arm_kprobe(struct kprobe *p);
 extern void arch_disarm_kprobe(struct kprobe *p);
-extern void arch_remove_kprobe(struct kprobe *p);
 extern int arch_init_kprobes(void);
 extern void show_registers(struct pt_regs *regs);
 extern kprobe_opcode_t *get_insn_slot(void);
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
new file mode 100644 (file)
index 0000000..222a047
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ *  include/linux/ktime.h
+ *
+ *  ktime_t - nanosecond-resolution time format.
+ *
+ *   Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
+ *   Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
+ *
+ *  data type definitions, declarations, prototypes and macros.
+ *
+ *  Started by: Thomas Gleixner and Ingo Molnar
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+#ifndef _LINUX_KTIME_H
+#define _LINUX_KTIME_H
+
+#include <linux/time.h>
+#include <linux/jiffies.h>
+
+/*
+ * ktime_t:
+ *
+ * On 64-bit CPUs a single 64-bit variable is used to store the hrtimers
+ * internal representation of time values in scalar nanoseconds. The
+ * design plays out best on 64-bit CPUs, where most conversions are
+ * NOPs and most arithmetic ktime_t operations are plain arithmetic
+ * operations.
+ *
+ * On 32-bit CPUs an optimized representation of the timespec structure
+ * is used to avoid expensive conversions from and to timespecs. The
+ * endian-aware order of the tv struct members is choosen to allow
+ * mathematical operations on the tv64 member of the union too, which
+ * for certain operations produces better code.
+ *
+ * For architectures with efficient support for 64/32-bit conversions the
+ * plain scalar nanosecond based representation can be selected by the
+ * config switch CONFIG_KTIME_SCALAR.
+ */
+typedef union {
+       s64     tv64;
+#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
+       struct {
+# ifdef __BIG_ENDIAN
+       s32     sec, nsec;
+# else
+       s32     nsec, sec;
+# endif
+       } tv;
+#endif
+} ktime_t;
+
+#define KTIME_MAX                      (~((u64)1 << 63))
+
+/*
+ * ktime_t definitions when using the 64-bit scalar representation:
+ */
+
+#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)
+
+/* Define a ktime_t variable and initialize it to zero: */
+#define DEFINE_KTIME(kt)               ktime_t kt = { .tv64 = 0 }
+
+/**
+ * ktime_set - Set a ktime_t variable from a seconds/nanoseconds value
+ *
+ * @secs:      seconds to set
+ * @nsecs:     nanoseconds to set
+ *
+ * Return the ktime_t representation of the value
+ */
+static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
+{
+       return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs };
+}
+
+/* Subtract two ktime_t variables. rem = lhs -rhs: */
+#define ktime_sub(lhs, rhs) \
+               ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
+
+/* Add two ktime_t variables. res = lhs + rhs: */
+#define ktime_add(lhs, rhs) \
+               ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
+
+/*
+ * Add a ktime_t variable and a scalar nanosecond value.
+ * res = kt + nsval:
+ */
+#define ktime_add_ns(kt, nsval) \
+               ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
+
+/* convert a timespec to ktime_t format: */
+#define timespec_to_ktime(ts)          ktime_set((ts).tv_sec, (ts).tv_nsec)
+
+/* convert a timeval to ktime_t format: */
+#define timeval_to_ktime(tv)           ktime_set((tv).tv_sec, (tv).tv_usec * 1000)
+
+/* Map the ktime_t to timespec conversion to ns_to_timespec function */
+#define ktime_to_timespec(kt)          ns_to_timespec((kt).tv64)
+
+/* Map the ktime_t to timeval conversion to ns_to_timeval function */
+#define ktime_to_timeval(kt)           ns_to_timeval((kt).tv64)
+
+/* Map the ktime_t to clock_t conversion to the inline in jiffies.h: */
+#define ktime_to_clock_t(kt)           nsec_to_clock_t((kt).tv64)
+
+/* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
+#define ktime_to_ns(kt)                        ((kt).tv64)
+
+#else
+
+/*
+ * Helper macros/inlines to get the ktime_t math right in the timespec
+ * representation. The macros are sometimes ugly - their actual use is
+ * pretty okay-ish, given the circumstances. We do all this for
+ * performance reasons. The pure scalar nsec_t based code was nice and
+ * simple, but created too many 64-bit / 32-bit conversions and divisions.
+ *
+ * Be especially aware that negative values are represented in a way
+ * that the tv.sec field is negative and the tv.nsec field is greater
+ * or equal to zero but less than nanoseconds per second. This is the
+ * same representation which is used by timespecs.
+ *
+ *   tv.sec < 0 and 0 >= tv.nsec < NSEC_PER_SEC
+ */
+
+/* Define a ktime_t variable and initialize it to zero: */
+#define DEFINE_KTIME(kt)               ktime_t kt = { .tv64 = 0 }
+
+/* Set a ktime_t variable to a value in sec/nsec representation: */
+static inline ktime_t ktime_set(const long secs, const unsigned long nsecs)
+{
+       return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs } };
+}
+
+/**
+ * ktime_sub - subtract two ktime_t variables
+ *
+ * @lhs:       minuend
+ * @rhs:       subtrahend
+ *
+ * Returns the remainder of the substraction
+ */
+static inline ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs)
+{
+       ktime_t res;
+
+       res.tv64 = lhs.tv64 - rhs.tv64;
+       if (res.tv.nsec < 0)
+               res.tv.nsec += NSEC_PER_SEC;
+
+       return res;
+}
+
+/**
+ * ktime_add - add two ktime_t variables
+ *
+ * @add1:      addend1
+ * @add2:      addend2
+ *
+ * Returns the sum of addend1 and addend2
+ */
+static inline ktime_t ktime_add(const ktime_t add1, const ktime_t add2)
+{
+       ktime_t res;
+
+       res.tv64 = add1.tv64 + add2.tv64;
+       /*
+        * performance trick: the (u32) -NSEC gives 0x00000000Fxxxxxxx
+        * so we subtract NSEC_PER_SEC and add 1 to the upper 32 bit.
+        *
+        * it's equivalent to:
+        *   tv.nsec -= NSEC_PER_SEC
+        *   tv.sec ++;
+        */
+       if (res.tv.nsec >= NSEC_PER_SEC)
+               res.tv64 += (u32)-NSEC_PER_SEC;
+
+       return res;
+}
+
+/**
+ * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
+ *
+ * @kt:                addend
+ * @nsec:      the scalar nsec value to add
+ *
+ * Returns the sum of kt and nsec in ktime_t format
+ */
+extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
+
+/**
+ * timespec_to_ktime - convert a timespec to ktime_t format
+ *
+ * @ts:                the timespec variable to convert
+ *
+ * Returns a ktime_t variable with the converted timespec value
+ */
+static inline ktime_t timespec_to_ktime(const struct timespec ts)
+{
+       return (ktime_t) { .tv = { .sec = (s32)ts.tv_sec,
+                                  .nsec = (s32)ts.tv_nsec } };
+}
+
+/**
+ * timeval_to_ktime - convert a timeval to ktime_t format
+ *
+ * @tv:                the timeval variable to convert
+ *
+ * Returns a ktime_t variable with the converted timeval value
+ */
+static inline ktime_t timeval_to_ktime(const struct timeval tv)
+{
+       return (ktime_t) { .tv = { .sec = (s32)tv.tv_sec,
+                                  .nsec = (s32)tv.tv_usec * 1000 } };
+}
+
+/**
+ * ktime_to_timespec - convert a ktime_t variable to timespec format
+ *
+ * @kt:                the ktime_t variable to convert
+ *
+ * Returns the timespec representation of the ktime value
+ */
+static inline struct timespec ktime_to_timespec(const ktime_t kt)
+{
+       return (struct timespec) { .tv_sec = (time_t) kt.tv.sec,
+                                  .tv_nsec = (long) kt.tv.nsec };
+}
+
+/**
+ * ktime_to_timeval - convert a ktime_t variable to timeval format
+ *
+ * @kt:                the ktime_t variable to convert
+ *
+ * Returns the timeval representation of the ktime value
+ */
+static inline struct timeval ktime_to_timeval(const ktime_t kt)
+{
+       return (struct timeval) {
+               .tv_sec = (time_t) kt.tv.sec,
+               .tv_usec = (suseconds_t) (kt.tv.nsec / NSEC_PER_USEC) };
+}
+
+/**
+ * ktime_to_clock_t - convert a ktime_t variable to clock_t format
+ * @kt:                the ktime_t variable to convert
+ *
+ * Returns a clock_t variable with the converted value
+ */
+static inline clock_t ktime_to_clock_t(const ktime_t kt)
+{
+       return nsec_to_clock_t( (u64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec);
+}
+
+/**
+ * ktime_to_ns - convert a ktime_t variable to scalar nanoseconds
+ * @kt:                the ktime_t variable to convert
+ *
+ * Returns the scalar nanoseconds representation of kt
+ */
+static inline u64 ktime_to_ns(const ktime_t kt)
+{
+       return (u64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
+}
+
+#endif
+
+/*
+ * The resolution of the clocks. The resolution value is returned in
+ * the clock_getres() system call to give application programmers an
+ * idea of the (in)accuracy of timers. Timer values are rounded up to
+ * this resolution values.
+ */
+#define KTIME_REALTIME_RES     (NSEC_PER_SEC/HZ)
+#define KTIME_MONOTONIC_RES    (NSEC_PER_SEC/HZ)
+
+/* Get the monotonic time in timespec format: */
+extern void ktime_get_ts(struct timespec *ts);
+
+/* Get the real (wall-) time in timespec format: */
+#define ktime_get_real_ts(ts)  getnstimeofday(ts)
+
+#endif
index 8e3388284530093dc71a1231c263d4436cf8a88d..945daa1f13dd05d6a7ad95e6022108a824d6a3dd 100644 (file)
@@ -435,6 +435,20 @@ static inline void list_splice_init(struct list_head *list,
             &pos->member != (head);                                            \
             pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
+/**
+ * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
+ *                                   removal of list entry
+ * @pos:       the type * to use as a loop counter.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)         \
+       for (pos = list_entry((head)->prev, typeof(*pos), member),      \
+               n = list_entry(pos->member.prev, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
 /**
  * list_for_each_rcu   -       iterate over an rcu-protected list
  * @pos:       the &struct list_head to use as a loop counter.
index b98a709f179406e1fec94a3679eb9184cb8f98e3..b7472ae91fa4a8396e9eaa9a2bedb6c1af916b64 100644 (file)
 #define MNT_NOSUID     0x01
 #define MNT_NODEV      0x02
 #define MNT_NOEXEC     0x04
-#define MNT_SHARED     0x10    /* if the vfsmount is a shared mount */
-#define MNT_UNBINDABLE 0x20    /* if the vfsmount is a unbindable mount */
+#define MNT_NOATIME    0x08
+#define MNT_NODIRATIME 0x10
 
-#define MNT_PNODE_MASK (MNT_SHARED | MNT_UNBINDABLE)
+#define MNT_SHARED     0x1000  /* if the vfsmount is a shared mount */
+#define MNT_UNBINDABLE 0x2000  /* if the vfsmount is a unbindable mount */
+#define MNT_PNODE_MASK 0x3000  /* propogation flag mask */
 
 struct vfsmount {
        struct list_head mnt_hash;
index 455660eafba943f159313d198702f14cbcaed646..b699e427c00cc1c6ef8d2dbb331040ba81b4ff4c 100644 (file)
@@ -74,7 +74,7 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
 extern void release_open_intent(struct nameidata *);
 
 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry * lookup_hash(struct nameidata *);
+extern __deprecated_for_modules struct dentry * lookup_hash(struct nameidata *);
 
 extern int follow_down(struct vfsmount **, struct dentry **);
 extern int follow_up(struct vfsmount **, struct dentry **);
index c3caa93efb10209bd24c200c96a08d2d7ddcbf66..f55c98a68aa913c0a12aefb233ddcc7fcff9e3d2 100644 (file)
 #define PCI_DEVICE_ID_NS_87560_USB     0x0012
 #define PCI_DEVICE_ID_NS_83815         0x0020
 #define PCI_DEVICE_ID_NS_83820         0x0022
+#define PCI_DEVICE_ID_NS_CS5535_ISA    0x002b
 #define PCI_DEVICE_ID_NS_CS5535_IDE    0x002d
 #define PCI_DEVICE_ID_NS_CS5535_AUDIO  0x002e
 #define PCI_DEVICE_ID_NS_CS5535_USB    0x002f
 #define PCI_DEVICE_ID_AMD_8111_AUDIO   0x746d
 #define PCI_DEVICE_ID_AMD_8151_0       0x7454
 #define PCI_DEVICE_ID_AMD_8131_APIC     0x7450
+#define PCI_DEVICE_ID_AMD_CS5536_ISA    0x2090
+#define PCI_DEVICE_ID_AMD_CS5536_FLASH  0x2091
+#define PCI_DEVICE_ID_AMD_CS5536_AUDIO  0x2093
+#define PCI_DEVICE_ID_AMD_CS5536_OHC    0x2094
+#define PCI_DEVICE_ID_AMD_CS5536_EHC    0x2095
+#define PCI_DEVICE_ID_AMD_CS5536_UDC    0x2096
+#define PCI_DEVICE_ID_AMD_CS5536_UOC    0x2097
+#define PCI_DEVICE_ID_AMD_CS5536_IDE    0x209A
 
 #define PCI_DEVICE_ID_AMD_CS5536_IDE   0x209A
 
 #define PCI_DEVICE_ID_NVIDIA_NVENET_6          0x00e6
 #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO                0x00ea
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2    0x00ee
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1 0x00f1
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT   0x00f9
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR       0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR       0x0101
 #define PCI_DEVICE_ID_NVIDIA_QUADRO            0x0103
index f942e2bad8e354ff44123e7f460bd97326fbf0c7..54faf5236da01370e7dc2f366dade682fec05de8 100644 (file)
@@ -42,7 +42,7 @@ struct k_itimer {
        timer_t it_id;                  /* timer id */
        int it_overrun;                 /* overrun on pending signal  */
        int it_overrun_last;            /* overrun on last delivered signal */
-       int it_requeue_pending;         /* waiting to requeue this timer */
+       int it_requeue_pending;         /* waiting to requeue this timer */
 #define REQUEUE_PENDING 1
        int it_sigev_notify;            /* notify word of sigevent struct */
        int it_sigev_signo;             /* signo word of sigevent struct */
@@ -51,10 +51,8 @@ struct k_itimer {
        struct sigqueue *sigq;          /* signal queue entry. */
        union {
                struct {
-                       struct timer_list timer;
-                       struct list_head abs_timer_entry; /* clock abs_timer_list */
-                       struct timespec wall_to_prev;   /* wall_to_monotonic used when set */
-                       unsigned long incr; /* interval in jiffies */
+                       struct hrtimer timer;
+                       ktime_t interval;
                } real;
                struct cpu_timer_list cpu;
                struct {
@@ -66,18 +64,14 @@ struct k_itimer {
        } it;
 };
 
-struct k_clock_abs {
-       struct list_head list;
-       spinlock_t lock;
-};
 struct k_clock {
-       int res;                /* in nano seconds */
-       int (*clock_getres) (clockid_t which_clock, struct timespec *tp);
-       struct k_clock_abs *abs_struct;
-       int (*clock_set) (clockid_t which_clock, struct timespec * tp);
-       int (*clock_get) (clockid_t which_clock, struct timespec * tp);
+       int res;                /* in nanoseconds */
+       int (*clock_getres) (const clockid_t which_clock, struct timespec *tp);
+       int (*clock_set) (const clockid_t which_clock, struct timespec * tp);
+       int (*clock_get) (const clockid_t which_clock, struct timespec * tp);
        int (*timer_create) (struct k_itimer *timer);
-       int (*nsleep) (clockid_t which_clock, int flags, struct timespec *);
+       int (*nsleep) (const clockid_t which_clock, int flags,
+                      struct timespec *, struct timespec __user *);
        int (*timer_set) (struct k_itimer * timr, int flags,
                          struct itimerspec * new_setting,
                          struct itimerspec * old_setting);
@@ -87,53 +81,35 @@ struct k_clock {
                           struct itimerspec * cur_setting);
 };
 
-void register_posix_clock(clockid_t clock_id, struct k_clock *new_clock);
+void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock);
 
-/* Error handlers for timer_create, nanosleep and settime */
+/* error handlers for timer_create, nanosleep and settime */
 int do_posix_clock_notimer_create(struct k_itimer *timer);
-int do_posix_clock_nonanosleep(clockid_t, int flags, struct timespec *);
-int do_posix_clock_nosettime(clockid_t, struct timespec *tp);
+int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *,
+                              struct timespec __user *);
+int do_posix_clock_nosettime(const clockid_t, struct timespec *tp);
 
 /* function to call to trigger timer event */
 int posix_timer_event(struct k_itimer *timr, int si_private);
 
-struct now_struct {
-       unsigned long jiffies;
-};
-
-#define posix_get_now(now) (now)->jiffies = jiffies;
-#define posix_time_before(timer, now) \
-                      time_before((timer)->expires, (now)->jiffies)
-
-#define posix_bump_timer(timr, now)                                    \
-         do {                                                          \
-              long delta, orun;                                                \
-             delta = now.jiffies - (timr)->it.real.timer.expires;      \
-              if (delta >= 0) {                                                \
-                  orun = 1 + (delta / (timr)->it.real.incr);           \
-                 (timr)->it.real.timer.expires +=                      \
-                        orun * (timr)->it.real.incr;                   \
-                  (timr)->it_overrun += orun;                          \
-              }                                                                \
-            }while (0)
-
-int posix_cpu_clock_getres(clockid_t which_clock, struct timespec *);
-int posix_cpu_clock_get(clockid_t which_clock, struct timespec *);
-int posix_cpu_clock_set(clockid_t which_clock, const struct timespec *tp);
-int posix_cpu_timer_create(struct k_itimer *);
-int posix_cpu_nsleep(clockid_t, int, struct timespec *);
-int posix_cpu_timer_set(struct k_itimer *, int,
-                       struct itimerspec *, struct itimerspec *);
-int posix_cpu_timer_del(struct k_itimer *);
-void posix_cpu_timer_get(struct k_itimer *, struct itimerspec *);
-
-void posix_cpu_timer_schedule(struct k_itimer *);
-
-void run_posix_cpu_timers(struct task_struct *);
-void posix_cpu_timers_exit(struct task_struct *);
-void posix_cpu_timers_exit_group(struct task_struct *);
-
-void set_process_cpu_timer(struct task_struct *, unsigned int,
-                          cputime_t *, cputime_t *);
+int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *ts);
+int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *ts);
+int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *ts);
+int posix_cpu_timer_create(struct k_itimer *timer);
+int posix_cpu_nsleep(const clockid_t which_clock, int flags,
+                    struct timespec *rqtp, struct timespec __user *rmtp);
+int posix_cpu_timer_set(struct k_itimer *timer, int flags,
+                       struct itimerspec *new, struct itimerspec *old);
+int posix_cpu_timer_del(struct k_itimer *timer);
+void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp);
+
+void posix_cpu_timer_schedule(struct k_itimer *timer);
+
+void run_posix_cpu_timers(struct task_struct *task);
+void posix_cpu_timers_exit(struct task_struct *task);
+void posix_cpu_timers_exit_group(struct task_struct *task);
+
+void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
+                          cputime_t *newval, cputime_t *oldval);
 
 #endif
index 157d7e3236b59c7f114540d6ff32e37aa84b7141..f54772d0e7f821981e6db96b5586977f3acb5051 100644 (file)
@@ -337,8 +337,8 @@ static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
 
 /**
  * RIO_DEVICE - macro used to describe a specific RIO device
- * @vid: the 16 bit RIO vendor ID
- * @did: the 16 bit RIO device ID
+ * @dev: the 16 bit RIO device ID
+ * @ven: the 16 bit RIO vendor ID
  *
  * This macro is used to create a struct rio_device_id that matches a
  * specific device.  The assembly vendor and assembly device fields
index 85b53f87c7035ac7d6386b56db89c1abd0355559..c4ee35dd18aec3baca993e342233f5ccfda96e56 100644 (file)
@@ -105,6 +105,7 @@ extern unsigned long nr_iowait(void);
 #include <linux/param.h>
 #include <linux/resource.h>
 #include <linux/timer.h>
+#include <linux/hrtimer.h>
 
 #include <asm/processor.h>
 
@@ -398,8 +399,8 @@ struct signal_struct {
        struct list_head posix_timers;
 
        /* ITIMER_REAL timer for the process */
-       struct timer_list real_timer;
-       unsigned long it_real_value, it_real_incr;
+       struct hrtimer real_timer;
+       ktime_t it_real_incr;
 
        /* ITIMER_PROF and ITIMER_VIRTUAL timers for the process */
        cputime_t it_prof_expires, it_virt_expires;
@@ -1389,12 +1390,8 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm)
 extern long sched_setaffinity(pid_t pid, cpumask_t new_mask);
 extern long sched_getaffinity(pid_t pid, cpumask_t *mask);
 
-#ifdef CONFIG_MAGIC_SYSRQ
-
 extern void normalize_rt_tasks(void);
 
-#endif
-
 #ifdef CONFIG_PM
 /*
  * Check if a process has been frozen
index 76850b75b3f6892392b7e5e5480712225405d74f..6336987dae6283806a531b6f7bf8d13efc0e9840 100644 (file)
@@ -41,8 +41,7 @@ struct screen_info {
        u16 vesapm_off;         /* 0x30 */
        u16 pages;              /* 0x32 */
        u16 vesa_attributes;    /* 0x34 */
-       u32  capabilities;      /* 0x36 */
-                               /* 0x3a -- 0x3f reserved for future expansion */
+                               /* 0x36 -- 0x3f reserved for future expansion */
 };
 
 extern struct screen_info screen_info;
index 797ccd813bb004a1f02e52651f0c49260617254d..f2aca7ec63257e67cffba81dc93c6e04a019ba88 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 
 #ifdef __KERNEL__
-#include <linux/seqlock.h>
+# include <linux/seqlock.h>
 #endif
 
 #ifndef _STRUCT_TIMESPEC
@@ -13,7 +13,7 @@ struct timespec {
        time_t  tv_sec;         /* seconds */
        long    tv_nsec;        /* nanoseconds */
 };
-#endif /* _STRUCT_TIMESPEC */
+#endif
 
 struct timeval {
        time_t          tv_sec;         /* seconds */
@@ -27,93 +27,103 @@ struct timezone {
 
 #ifdef __KERNEL__
 
-/* Parameters used to convert the timespec values */
-#define MSEC_PER_SEC (1000L)
-#define USEC_PER_SEC (1000000L)
-#define NSEC_PER_SEC (1000000000L)
-#define NSEC_PER_USEC (1000L)
+/* Parameters used to convert the timespec values: */
+#define MSEC_PER_SEC           1000L
+#define USEC_PER_SEC           1000000L
+#define NSEC_PER_SEC           1000000000L
+#define NSEC_PER_USEC          1000L
 
-static __inline__ int timespec_equal(struct timespec *a, struct timespec *b) 
-{ 
+static __inline__ int timespec_equal(struct timespec *a, struct timespec *b)
+{
        return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
-} 
+}
 
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
+extern unsigned long mktime(const unsigned int year, const unsigned int mon,
+                           const unsigned int day, const unsigned int hour,
+                           const unsigned int min, const unsigned int sec);
+
+extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
+
+/*
+ * Returns true if the timespec is norm, false if denorm:
  */
-static inline unsigned long
-mktime (unsigned int year, unsigned int mon,
-       unsigned int day, unsigned int hour,
-       unsigned int min, unsigned int sec)
-{
-       if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
-               mon += 12;              /* Puts Feb last since it has leap day */
-               year -= 1;
-       }
-
-       return (((
-               (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
-                       year*365 - 719499
-           )*24 + hour /* now have hours */
-         )*60 + min /* now have minutes */
-       )*60 + sec; /* finally seconds */
-}
+#define timespec_valid(ts) \
+       (((ts)->tv_sec >= 0) && (((unsigned) (ts)->tv_nsec) < NSEC_PER_SEC))
+
+/*
+ * 64-bit nanosec type. Large enough to span 292+ years in nanosecond
+ * resolution. Ought to be enough for a while.
+ */
+typedef s64 nsec_t;
 
 extern struct timespec xtime;
 extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock;
 
 static inline unsigned long get_seconds(void)
-{ 
+{
        return xtime.tv_sec;
 }
 
 struct timespec current_kernel_time(void);
 
-#define CURRENT_TIME (current_kernel_time())
-#define CURRENT_TIME_SEC ((struct timespec) { xtime.tv_sec, 0 })
+#define CURRENT_TIME           (current_kernel_time())
+#define CURRENT_TIME_SEC       ((struct timespec) { xtime.tv_sec, 0 })
 
 extern void do_gettimeofday(struct timeval *tv);
 extern int do_settimeofday(struct timespec *tv);
 extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
-extern void clock_was_set(void); // call when ever the clock is set
-extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
-extern long do_utimes(char __user * filename, struct timeval * times);
+#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
+extern long do_utimes(char __user *filename, struct timeval *times);
 struct itimerval;
-extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
+extern int do_setitimer(int which, struct itimerval *value,
+                       struct itimerval *ovalue);
 extern int do_getitimer(int which, struct itimerval *value);
-extern void getnstimeofday (struct timespec *tv);
-extern void getnstimestamp(struct timespec *ts);
+extern void getnstimeofday(struct timespec *tv);
 
 extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 
-static inline void
-set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
+/**
+ * timespec_to_ns - Convert timespec to nanoseconds
+ * @ts:                pointer to the timespec variable to be converted
+ *
+ * Returns the scalar nanosecond representation of the timespec
+ * parameter.
+ */
+static inline nsec_t timespec_to_ns(const struct timespec *ts)
 {
-       while (nsec >= NSEC_PER_SEC) {
-               nsec -= NSEC_PER_SEC;
-               ++sec;
-       }
-       while (nsec < 0) {
-               nsec += NSEC_PER_SEC;
-               --sec;
-       }
-       ts->tv_sec = sec;
-       ts->tv_nsec = nsec;
+       return ((nsec_t) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
 }
 
+/**
+ * timeval_to_ns - Convert timeval to nanoseconds
+ * @ts:                pointer to the timeval variable to be converted
+ *
+ * Returns the scalar nanosecond representation of the timeval
+ * parameter.
+ */
+static inline nsec_t timeval_to_ns(const struct timeval *tv)
+{
+       return ((nsec_t) tv->tv_sec * NSEC_PER_SEC) +
+               tv->tv_usec * NSEC_PER_USEC;
+}
+
+/**
+ * ns_to_timespec - Convert nanoseconds to timespec
+ * @nsec:      the nanoseconds value to be converted
+ *
+ * Returns the timespec representation of the nsec parameter.
+ */
+extern struct timespec ns_to_timespec(const nsec_t nsec);
+
+/**
+ * ns_to_timeval - Convert nanoseconds to timeval
+ * @nsec:      the nanoseconds value to be converted
+ *
+ * Returns the timeval representation of the nsec parameter.
+ */
+extern struct timeval ns_to_timeval(const nsec_t nsec);
+
 #endif /* __KERNEL__ */
 
 #define NFDBITS                        __NFDBITS
@@ -126,49 +136,41 @@ set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
 
 /*
  * Names of the interval timers, and structure
- * defining a timer setting.
+ * defining a timer setting:
  */
-#define        ITIMER_REAL     0
-#define        ITIMER_VIRTUAL  1
-#define        ITIMER_PROF     2
+#define        ITIMER_REAL             0
+#define        ITIMER_VIRTUAL          1
+#define        ITIMER_PROF             2
 
-struct  itimerspec {
-        struct  timespec it_interval;    /* timer period */
-        struct  timespec it_value;       /* timer expiration */
+struct itimerspec {
+       struct timespec it_interval;    /* timer period */
+       struct timespec it_value;       /* timer expiration */
 };
 
-struct itimerval {
-       struct  timeval it_interval;    /* timer interval */
-       struct  timeval it_value;       /* current value */
+struct itimerval {
+       struct timeval it_interval;     /* timer interval */
+       struct timeval it_value;        /* current value */
 };
 
-
 /*
- * The IDs of the various system clocks (for POSIX.1b interval timers).
+ * The IDs of the various system clocks (for POSIX.1b interval timers):
  */
-#define CLOCK_REALTIME           0
-#define CLOCK_MONOTONIC          1
-#define CLOCK_PROCESS_CPUTIME_ID 2
-#define CLOCK_THREAD_CPUTIME_ID         3
-#define CLOCK_REALTIME_HR       4
-#define CLOCK_MONOTONIC_HR       5
+#define CLOCK_REALTIME                 0
+#define CLOCK_MONOTONIC                        1
+#define CLOCK_PROCESS_CPUTIME_ID       2
+#define CLOCK_THREAD_CPUTIME_ID                3
 
 /*
- * The IDs of various hardware clocks
+ * The IDs of various hardware clocks:
  */
-
-
-#define CLOCK_SGI_CYCLE 10
-#define MAX_CLOCKS 16
-#define CLOCKS_MASK  (CLOCK_REALTIME | CLOCK_MONOTONIC | \
-                     CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
-#define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR)
+#define CLOCK_SGI_CYCLE                        10
+#define MAX_CLOCKS                     16
+#define CLOCKS_MASK                    (CLOCK_REALTIME | CLOCK_MONOTONIC)
+#define CLOCKS_MONO                    CLOCK_MONOTONIC
 
 /*
- * The various flags for setting POSIX.1b interval timers.
+ * The various flags for setting POSIX.1b interval timers:
  */
-
-#define TIMER_ABSTIME 0x01
-
+#define TIMER_ABSTIME                  0x01
 
 #endif
index 72f3a7781106ab1290198d25edd33a8723588e0b..9b9877fd25059e1ad919d9ba87924d6374b26716 100644 (file)
@@ -96,6 +96,6 @@ static inline void add_timer(struct timer_list *timer)
 
 extern void init_timers(void);
 extern void run_local_timers(void);
-extern void it_real_fn(unsigned long);
+extern int it_real_fn(void *);
 
 #endif
index 57449704a47be99355e1b467692ee7efe7cf2228..3787102e4b129abe52f3b53461ff1e7fffb33b40 100644 (file)
  */
 #define TTY_FLIPBUF_SIZE 512
 
-struct tty_flip_buffer {
+struct tty_buffer {
+       struct tty_buffer *next;
+       char *char_buf_ptr;
+       unsigned char *flag_buf_ptr;
+       int used;
+       int size;
+       /* Data points here */
+       unsigned long data[0];
+};
+
+struct tty_bufhead {
        struct work_struct              work;
        struct semaphore pty_sem;
-       char            *char_buf_ptr;
-       unsigned char   *flag_buf_ptr;
-       int             count;
-       int             buf_num;
-       unsigned char   char_buf[2*TTY_FLIPBUF_SIZE];
-       char            flag_buf[2*TTY_FLIPBUF_SIZE];
-       unsigned char   slop[4]; /* N.B. bug overwrites buffer by 1 */
+       struct tty_buffer *head;        /* Queue head */
+       struct tty_buffer *tail;        /* Active buffer */
+       struct tty_buffer *free;        /* Free queue head */
 };
 /*
  * The pty uses char_buf and flag_buf as a contiguous buffer
@@ -186,10 +192,11 @@ struct tty_struct {
        unsigned char stopped:1, hw_stopped:1, flow_stopped:1, packet:1;
        unsigned char low_latency:1, warned:1;
        unsigned char ctrl_status;
+       unsigned int receive_room;      /* Bytes free for queue */
 
        struct tty_struct *link;
        struct fasync_struct *fasync;
-       struct tty_flip_buffer flip;
+       struct tty_bufhead buf;
        int max_flip_cnt;
        int alt_speed;          /* For magic substitution of 38400 bps */
        wait_queue_head_t write_wait;
index abe9bfcf226ce12a020e0aae60b0b897feab7940..be1400e82482f8aebd4d14e17e9d5ea99958cd85 100644 (file)
@@ -1,25 +1,33 @@
 #ifndef _LINUX_TTY_FLIP_H
 #define _LINUX_TTY_FLIP_H
 
+extern int tty_buffer_request_room(struct tty_struct *tty, size_t size);
+extern int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size);
+extern int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size);
+extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size);
+extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size);
+
 #ifdef INCLUDE_INLINE_FUNCS
 #define _INLINE_ extern
 #else
 #define _INLINE_ static __inline__
 #endif
 
-_INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
+_INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
                                   unsigned char ch, char flag)
 {
-       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-               tty->flip.count++;
-               *tty->flip.flag_buf_ptr++ = flag;
-               *tty->flip.char_buf_ptr++ = ch;
+       struct tty_buffer *tb = tty->buf.tail;
+       if (tb && tb->used < tb->size) {
+               tb->flag_buf_ptr[tb->used] = flag;
+               tb->char_buf_ptr[tb->used++] = ch;
+               return 1;
        }
+       return tty_insert_flip_string_flags(tty, &ch, &flag, 1);
 }
 
 _INLINE_ void tty_schedule_flip(struct tty_struct *tty)
 {
-       schedule_delayed_work(&tty->flip.work, 1);
+       schedule_delayed_work(&tty->buf.work, 1);
 }
 
 #undef _INLINE_
index 6066afde5ce4dc5d53b24c302c7c3e25f507c5f7..83c6e6c10ebb57b52ed41742fcf6a0bd830668a6 100644 (file)
  *     pointer of flag bytes which indicate whether a character was
  *     received with a parity error, etc.
  * 
- * int (*receive_room)(struct tty_struct *);
- *
- *     This function is called by the low-level tty driver to
- *     determine how many characters the line discpline can accept.
- *     The low-level driver must not send more characters than was
- *     indicated by receive_room, or the line discpline may drop
- *     those characters.
- * 
  * void        (*write_wakeup)(struct tty_struct *);
  *
  *     This function is called by the low-level tty driver to signal
@@ -136,7 +128,6 @@ struct tty_ldisc {
         */
        void    (*receive_buf)(struct tty_struct *, const unsigned char *cp,
                               char *fp, int count);
-       int     (*receive_room)(struct tty_struct *);
        void    (*write_wakeup)(struct tty_struct *);
 
        struct  module *owner;
index 23f9c61d9546b7fd39f9fb90501463935a760697..cda8a96e2fa039f6e43c92b973f34eac9d5d8e6d 100644 (file)
 #define XATTR_CREATE   0x1     /* set value, fail if attr already exists */
 #define XATTR_REPLACE  0x2     /* set value, fail if attr does not exist */
 
+/* Namespaces */
+#define XATTR_OS2_PREFIX "os2."
+#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
+
 #define XATTR_SECURITY_PREFIX  "security."
+#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
+
+#define XATTR_SYSTEM_PREFIX "system."
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
+
+#define XATTR_TRUSTED_PREFIX "trusted."
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
+
+#define XATTR_USER_PREFIX "user."
+#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
+
 
 struct xattr_handler {
        char *prefix;
@@ -25,6 +40,10 @@ struct xattr_handler {
                   size_t size, int flags);
 };
 
+ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
+int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
+int vfs_removexattr(struct dentry *, char *);
+
 ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
 int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
index 74f7b78c22d2fb46136999370edd154290a2f745..4fa32f0d4df8a0ad345dabc793c4105cb4094648 100644 (file)
@@ -442,9 +442,11 @@ extern int deflateInit2 (z_streamp strm,
    not perform any compression: this will be done by deflate().
 */
                             
+#if 0
 extern int zlib_deflateSetDictionary (z_streamp strm,
                                                     const Byte *dictionary,
                                                     uInt  dictLength);
+#endif
 /*
      Initializes the compression dictionary from the given byte sequence
    without producing any compressed output. This function must be called
@@ -478,7 +480,10 @@ extern int zlib_deflateSetDictionary (z_streamp strm,
    perform any compression: this will be done by deflate().
 */
 
+#if 0
 extern int zlib_deflateCopy (z_streamp dest, z_streamp source);
+#endif
+
 /*
      Sets the destination stream as a complete copy of the source stream.
 
@@ -511,7 +516,9 @@ static inline unsigned long deflateBound(unsigned long s)
        return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11;
 }
 
+#if 0
 extern int zlib_deflateParams (z_streamp strm, int level, int strategy);
+#endif
 /*
      Dynamically update the compression level and compression strategy.  The
    interpretation of level and strategy is as in deflateInit2.  This can be
@@ -571,7 +578,9 @@ extern int zlib_inflateSetDictionary (z_streamp strm,
    inflate().
 */
 
+#if 0
 extern int zlib_inflateSync (z_streamp strm);
+#endif
 /* 
     Skips invalid compressed data until a full flush point (see above the
   description of deflate with Z_FULL_FLUSH) can be found, or until all
@@ -636,7 +645,9 @@ extern int zlib_inflateInit2_ (z_streamp strm, int  windowBits,
 #endif
 
 extern const char  * zlib_zError           (int err);
+#if 0
 extern int           zlib_inflateSyncPoint (z_streamp z);
+#endif
 extern const uLong * zlib_get_crc_table    (void);
 
 #endif /* _ZLIB_H */
index 90ac6132ea3bced84ced0246e9af8a274313036e..3093e3ddcf36cd3e7ed1204937ab443b153b0056 100644 (file)
@@ -317,7 +317,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 /**
  * snd_printd - debug printk
- * @format: format string
+ * @fmt: format string
  *
  * Compiled only when Works like snd_printk() for debugging purpose.
  * Ignored when CONFIG_SND_DEBUG is not set.
@@ -331,7 +331,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
 /**
  * snd_assert - run-time assertion macro
  * @expr: expression
- * @args...: the action
  *
  * This macro checks the expression in run-time and invokes the commands
  * given in the rest arguments if the assertion is failed.
index 1bed37cfa68cf04bae064c0d2be5216e571f0616..dba7de2ee4a86f8643807dd5bc3f31c91e30b8de 100644 (file)
@@ -15,6 +15,7 @@
 struct kyrofb_info {
        void __iomem *regbase;
 
+       u32 palette[16];
        u32 HTot;       /* Hor Total Time    */
        u32 HFP;        /* Hor Front Porch   */
        u32 HST;        /* Hor Sync Time     */
index bdaee70868dd00cdad9d612dd60454eb43fad5e9..1d69049bd4c196ee13ab3e7a6439d20d5cf47008 100644 (file)
@@ -196,6 +196,7 @@ struct neofb_par {
        int internal_display;
        int external_display;
        int libretto;
+       u32 palette[16];
 };
 
 typedef struct {
index 812dac5b55f4a5eb35e77cfabb7fbe23d02be114..1f5ebeaa818f4241d98e7a7e5f8e4cb0f1a1625f 100644 (file)
@@ -382,7 +382,8 @@ typedef struct {
 #define VC2_IREG_CONTROL       0x10
 #define VC2_IREG_CONFIG        0x20
 
-extern __inline__ void newport_vc2_set(struct newport_regs *regs, unsigned char vc2ireg,
+static inline void newport_vc2_set(struct newport_regs *regs,
+                                  unsigned char vc2ireg,
                                   unsigned short val)
 {
        regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W3 |
@@ -390,7 +391,7 @@ extern __inline__ void newport_vc2_set(struct newport_regs *regs, unsigned char
        regs->set.dcbdata0.byword = (vc2ireg << 24) | (val << 8);
 }
 
-extern __inline__ unsigned short newport_vc2_get(struct newport_regs *regs,
+static inline unsigned short newport_vc2_get(struct newport_regs *regs,
                                             unsigned char vc2ireg)
 {
        regs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_INDEX | NPORT_DMODE_W1 |
index 0d77b5205372b611ed2a289b1330f313a51ef43f..3570f9c9b1112be92a4e5b409abf5d6a5582d038 100644 (file)
@@ -334,6 +334,7 @@ struct sst_spec {
 };
 
 struct sstfb_par {
+       u32 palette[16];
        unsigned int yDim;
        unsigned int hSyncOn;   /* hsync_len */
        unsigned int hSyncOff;  /* left_margin + xres + right_margin */
index 04237676b17ccabbea7cb7461a1c794e69b3e9f9..c1cc94ba3fddd1420715d850ed6be46a32e426cf 100644 (file)
 #ifdef __KERNEL__
 
 struct banshee_reg {
-  /* VGA rubbish */
-  unsigned char att[21];
-  unsigned char crt[25];
-  unsigned char gra[ 9];
-  unsigned char misc[1];
-  unsigned char seq[ 5];
-
-  /* Banshee extensions */
-  unsigned char ext[2];
-  unsigned long vidcfg;
-  unsigned long vidpll;
-  unsigned long mempll;
-  unsigned long gfxpll;
-  unsigned long dacmode;
-  unsigned long vgainit0;
-  unsigned long vgainit1;
-  unsigned long screensize;
-  unsigned long stride;
-  unsigned long cursloc;
-  unsigned long curspataddr;
-  unsigned long cursc0;
-  unsigned long cursc1;
-  unsigned long startaddr;
-  unsigned long clip0min;
-  unsigned long clip0max;
-  unsigned long clip1min;
-  unsigned long clip1max;
-  unsigned long srcbase;
-  unsigned long dstbase;
-  unsigned long miscinit0;     
+       /* VGA rubbish */
+       unsigned char att[21];
+       unsigned char crt[25];
+       unsigned char gra[ 9];
+       unsigned char misc[1];
+       unsigned char seq[ 5];
+
+       /* Banshee extensions */
+       unsigned char ext[2];
+       unsigned long vidcfg;
+       unsigned long vidpll;
+       unsigned long mempll;
+       unsigned long gfxpll;
+       unsigned long dacmode;
+       unsigned long vgainit0;
+       unsigned long vgainit1;
+       unsigned long screensize;
+       unsigned long stride;
+       unsigned long cursloc;
+       unsigned long curspataddr;
+       unsigned long cursc0;
+       unsigned long cursc1;
+       unsigned long startaddr;
+       unsigned long clip0min;
+       unsigned long clip0max;
+       unsigned long clip1min;
+       unsigned long clip1max;
+       unsigned long srcbase;
+       unsigned long dstbase;
+       unsigned long miscinit0;
 };
 
 struct tdfx_par {
-  u32 max_pixclock;
-
-  void __iomem *regbase_virt;
-  unsigned long iobase;
-  u32 baseline;
-
-  struct {
-     int w,u,d;
-     unsigned long enable,disable;
-     struct timer_list timer;
-  } hwcursor; 
-
-  spinlock_t DAClock;
+       u32 max_pixclock;
+       u32 palette[16];
+       void __iomem *regbase_virt;
+       unsigned long iobase;
+       u32 baseline;
+
+       struct {
+               int w,u,d;
+               unsigned long enable,disable;
+               struct timer_list timer;
+       } hwcursor;
+
+       spinlock_t DAClock;
 };
 
 #endif /* __KERNEL__ */
index f8f6929d8f254ea70422589d916d3cb2fc796766..9bdd5492a95b4e8711a7e5969322fcc1e1c0dee6 100644 (file)
@@ -230,9 +230,7 @@ source "usr/Kconfig"
 
 config UID16
        bool "Enable 16-bit UID system calls" if EMBEDDED
-       depends !ALPHA && !PPC && !PPC64 && !PARISC && !V850 && !ARCH_S390X
-       depends !X86_64 || IA32_EMULATION
-       depends !SPARC64 || SPARC32_COMPAT
+       depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION)
        default y
        help
          This enables the legacy 16-bit UID syscall wrappers.
index 8342c2890b16dd364f9222855e9a6bb7b5b8fc7d..e092b1979a9052022d20696c42a2ee22698738ae 100644 (file)
@@ -485,6 +485,7 @@ asmlinkage void __init start_kernel(void)
        init_IRQ();
        pidhash_init();
        init_timers();
+       hrtimers_init();
        softirq_init();
        time_init();
 
index a940bac028379d923ace8f304ed253622c2e0520..355126606d1bda3a958cc4ad8847d10bdf4189ff 100644 (file)
@@ -7,7 +7,8 @@ obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
            sysctl.o capability.o ptrace.o timer.o user.o \
            signal.o sys.o kmod.o workqueue.o pid.o \
            rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-           kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o
+           kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
+           hrtimer.o
 
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
 obj-$(CONFIG_FUTEX) += futex.o
@@ -30,7 +31,6 @@ obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 
index 102296e21ea86671f10fb922acf67feb81b22b1e..256e5d9f06470480283a04cfc8f5f15e8113b30a 100644 (file)
@@ -514,6 +514,24 @@ static int put_compat_itimerspec(struct compat_itimerspec __user *dst,
        return 0;
 } 
 
+long compat_sys_timer_create(clockid_t which_clock,
+                       struct compat_sigevent __user *timer_event_spec,
+                       timer_t __user *created_timer_id)
+{
+       struct sigevent __user *event = NULL;
+
+       if (timer_event_spec) {
+               struct sigevent kevent;
+
+               event = compat_alloc_user_space(sizeof(*event));
+               if (get_compat_sigevent(&kevent, timer_event_spec) ||
+                   copy_to_user(event, &kevent, sizeof(*event)))
+                       return -EFAULT;
+       }
+
+       return sys_timer_create(which_clock, event, created_timer_id);
+}
+
 long compat_sys_timer_settime(timer_t timer_id, int flags,
                          struct compat_itimerspec __user *new, 
                          struct compat_itimerspec __user *old)
@@ -649,8 +667,6 @@ int get_compat_sigevent(struct sigevent *event,
                ? -EFAULT : 0;
 }
 
-/* timer_create is architecture specific because it needs sigevent conversion */
-
 long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
                       unsigned long bitmap_size)
 {
index 309a46fa16f8e7b76af222e61336ee49ea4acb78..802722814925d6391bb021d99106314c7c6b085e 100644 (file)
@@ -842,7 +842,7 @@ fastcall NORET_TYPE void do_exit(long code)
        }
        group_dead = atomic_dec_and_test(&tsk->signal->live);
        if (group_dead) {
-               del_timer_sync(&tsk->signal->real_timer);
+               hrtimer_cancel(&tsk->signal->real_timer);
                exit_itimers(tsk->signal);
                acct_process(code);
        }
@@ -1071,6 +1071,9 @@ static int wait_task_zombie(task_t *p, int noreap,
        }
 
        if (likely(p->real_parent == p->parent) && likely(p->signal)) {
+               struct signal_struct *psig;
+               struct signal_struct *sig;
+
                /*
                 * The resource counters for the group leader are in its
                 * own task_struct.  Those for dead threads in the group
@@ -1087,24 +1090,26 @@ static int wait_task_zombie(task_t *p, int noreap,
                 * here reaping other children at the same time.
                 */
                spin_lock_irq(&p->parent->sighand->siglock);
-               p->parent->signal->cutime =
-                       cputime_add(p->parent->signal->cutime,
+               psig = p->parent->signal;
+               sig = p->signal;
+               psig->cutime =
+                       cputime_add(psig->cutime,
                        cputime_add(p->utime,
-                       cputime_add(p->signal->utime,
-                                   p->signal->cutime)));
-               p->parent->signal->cstime =
-                       cputime_add(p->parent->signal->cstime,
+                       cputime_add(sig->utime,
+                                   sig->cutime)));
+               psig->cstime =
+                       cputime_add(psig->cstime,
                        cputime_add(p->stime,
-                       cputime_add(p->signal->stime,
-                                   p->signal->cstime)));
-               p->parent->signal->cmin_flt +=
-                       p->min_flt + p->signal->min_flt + p->signal->cmin_flt;
-               p->parent->signal->cmaj_flt +=
-                       p->maj_flt + p->signal->maj_flt + p->signal->cmaj_flt;
-               p->parent->signal->cnvcsw +=
-                       p->nvcsw + p->signal->nvcsw + p->signal->cnvcsw;
-               p->parent->signal->cnivcsw +=
-                       p->nivcsw + p->signal->nivcsw + p->signal->cnivcsw;
+                       cputime_add(sig->stime,
+                                   sig->cstime)));
+               psig->cmin_flt +=
+                       p->min_flt + sig->min_flt + sig->cmin_flt;
+               psig->cmaj_flt +=
+                       p->maj_flt + sig->maj_flt + sig->cmaj_flt;
+               psig->cnvcsw +=
+                       p->nvcsw + sig->nvcsw + sig->cnvcsw;
+               psig->cnivcsw +=
+                       p->nivcsw + sig->nivcsw + sig->cnivcsw;
                spin_unlock_irq(&p->parent->sighand->siglock);
        }
 
index b18d64554feb7e48f1cbde8e2d58bafd52af1f04..3bdcab49998d2dd43bf951ae87a855e955eaf090 100644 (file)
@@ -801,10 +801,10 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
        init_sigpending(&sig->shared_pending);
        INIT_LIST_HEAD(&sig->posix_timers);
 
-       sig->it_real_value = sig->it_real_incr = 0;
+       hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC);
+       sig->it_real_incr.tv64 = 0;
        sig->real_timer.function = it_real_fn;
-       sig->real_timer.data = (unsigned long) tsk;
-       init_timer(&sig->real_timer);
+       sig->real_timer.data = tsk;
 
        sig->it_virt_expires = cputime_zero;
        sig->it_virt_incr = cputime_zero;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
new file mode 100644 (file)
index 0000000..f073a24
--- /dev/null
@@ -0,0 +1,821 @@
+/*
+ *  linux/kernel/hrtimer.c
+ *
+ *  Copyright(C) 2005, Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright(C) 2005, Red Hat, Inc., Ingo Molnar
+ *
+ *  High-resolution kernel timers
+ *
+ *  In contrast to the low-resolution timeout API implemented in
+ *  kernel/timer.c, hrtimers provide finer resolution and accuracy
+ *  depending on system configuration and capabilities.
+ *
+ *  These timers are currently used for:
+ *   - itimers
+ *   - POSIX timers
+ *   - nanosleep
+ *   - precise in-kernel timing
+ *
+ *  Started by: Thomas Gleixner and Ingo Molnar
+ *
+ *  Credits:
+ *     based on kernel/timer.c
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/hrtimer.h>
+#include <linux/notifier.h>
+#include <linux/syscalls.h>
+#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
+
+/**
+ * ktime_get - get the monotonic time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+static ktime_t ktime_get(void)
+{
+       struct timespec now;
+
+       ktime_get_ts(&now);
+
+       return timespec_to_ktime(now);
+}
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+static ktime_t ktime_get_real(void)
+{
+       struct timespec now;
+
+       getnstimeofday(&now);
+
+       return timespec_to_ktime(now);
+}
+
+EXPORT_SYMBOL_GPL(ktime_get_real);
+
+/*
+ * The timer bases:
+ */
+
+#define MAX_HRTIMER_BASES 2
+
+static DEFINE_PER_CPU(struct hrtimer_base, hrtimer_bases[MAX_HRTIMER_BASES]) =
+{
+       {
+               .index = CLOCK_REALTIME,
+               .get_time = &ktime_get_real,
+               .resolution = KTIME_REALTIME_RES,
+       },
+       {
+               .index = CLOCK_MONOTONIC,
+               .get_time = &ktime_get,
+               .resolution = KTIME_MONOTONIC_RES,
+       },
+};
+
+/**
+ * ktime_get_ts - get the monotonic clock in timespec format
+ *
+ * @ts:                pointer to timespec variable
+ *
+ * The function calculates the monotonic clock from the realtime
+ * clock and the wall_to_monotonic offset and stores the result
+ * in normalized timespec format in the variable pointed to by ts.
+ */
+void ktime_get_ts(struct timespec *ts)
+{
+       struct timespec tomono;
+       unsigned long seq;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+               getnstimeofday(ts);
+               tomono = wall_to_monotonic;
+
+       } while (read_seqretry(&xtime_lock, seq));
+
+       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
+                               ts->tv_nsec + tomono.tv_nsec);
+}
+EXPORT_SYMBOL_GPL(ktime_get_ts);
+
+/*
+ * Functions and macros which are different for UP/SMP systems are kept in a
+ * single place
+ */
+#ifdef CONFIG_SMP
+
+#define set_curr_timer(b, t)           do { (b)->curr_timer = (t); } while (0)
+
+/*
+ * We are using hashed locking: holding per_cpu(hrtimer_bases)[n].lock
+ * means that all timers which are tied to this base via timer->base are
+ * locked, and the base itself is locked too.
+ *
+ * So __run_timers/migrate_timers can safely modify all timers which could
+ * be found on the lists/queues.
+ *
+ * When the timer's base is locked, and the timer removed from list, it is
+ * possible to set timer->base = NULL and drop the lock: the timer remains
+ * locked.
+ */
+static struct hrtimer_base *lock_hrtimer_base(const struct hrtimer *timer,
+                                             unsigned long *flags)
+{
+       struct hrtimer_base *base;
+
+       for (;;) {
+               base = timer->base;
+               if (likely(base != NULL)) {
+                       spin_lock_irqsave(&base->lock, *flags);
+                       if (likely(base == timer->base))
+                               return base;
+                       /* The timer has migrated to another CPU: */
+                       spin_unlock_irqrestore(&base->lock, *flags);
+               }
+               cpu_relax();
+       }
+}
+
+/*
+ * Switch the timer base to the current CPU when possible.
+ */
+static inline struct hrtimer_base *
+switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_base *base)
+{
+       struct hrtimer_base *new_base;
+
+       new_base = &__get_cpu_var(hrtimer_bases[base->index]);
+
+       if (base != new_base) {
+               /*
+                * We are trying to schedule the timer on the local CPU.
+                * However we can't change timer's base while it is running,
+                * so we keep it on the same CPU. No hassle vs. reprogramming
+                * the event source in the high resolution case. The softirq
+                * code will take care of this when the timer function has
+                * completed. There is no conflict as we hold the lock until
+                * the timer is enqueued.
+                */
+               if (unlikely(base->curr_timer == timer))
+                       return base;
+
+               /* See the comment in lock_timer_base() */
+               timer->base = NULL;
+               spin_unlock(&base->lock);
+               spin_lock(&new_base->lock);
+               timer->base = new_base;
+       }
+       return new_base;
+}
+
+#else /* CONFIG_SMP */
+
+#define set_curr_timer(b, t)           do { } while (0)
+
+static inline struct hrtimer_base *
+lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
+{
+       struct hrtimer_base *base = timer->base;
+
+       spin_lock_irqsave(&base->lock, *flags);
+
+       return base;
+}
+
+#define switch_hrtimer_base(t, b)      (b)
+
+#endif /* !CONFIG_SMP */
+
+/*
+ * Functions for the union type storage format of ktime_t which are
+ * too large for inlining:
+ */
+#if BITS_PER_LONG < 64
+# ifndef CONFIG_KTIME_SCALAR
+/**
+ * ktime_add_ns - Add a scalar nanoseconds value to a ktime_t variable
+ *
+ * @kt:                addend
+ * @nsec:      the scalar nsec value to add
+ *
+ * Returns the sum of kt and nsec in ktime_t format
+ */
+ktime_t ktime_add_ns(const ktime_t kt, u64 nsec)
+{
+       ktime_t tmp;
+
+       if (likely(nsec < NSEC_PER_SEC)) {
+               tmp.tv64 = nsec;
+       } else {
+               unsigned long rem = do_div(nsec, NSEC_PER_SEC);
+
+               tmp = ktime_set((long)nsec, rem);
+       }
+
+       return ktime_add(kt, tmp);
+}
+
+#else /* CONFIG_KTIME_SCALAR */
+
+# endif /* !CONFIG_KTIME_SCALAR */
+
+/*
+ * Divide a ktime value by a nanosecond value
+ */
+static unsigned long ktime_divns(const ktime_t kt, nsec_t div)
+{
+       u64 dclc, inc, dns;
+       int sft = 0;
+
+       dclc = dns = ktime_to_ns(kt);
+       inc = div;
+       /* Make sure the divisor is less than 2^32: */
+       while (div >> 32) {
+               sft++;
+               div >>= 1;
+       }
+       dclc >>= sft;
+       do_div(dclc, (unsigned long) div);
+
+       return (unsigned long) dclc;
+}
+
+#else /* BITS_PER_LONG < 64 */
+# define ktime_divns(kt, div)          (unsigned long)((kt).tv64 / (div))
+#endif /* BITS_PER_LONG >= 64 */
+
+/*
+ * Counterpart to lock_timer_base above:
+ */
+static inline
+void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
+{
+       spin_unlock_irqrestore(&timer->base->lock, *flags);
+}
+
+/**
+ * hrtimer_forward - forward the timer expiry
+ *
+ * @timer:     hrtimer to forward
+ * @interval:  the interval to forward
+ *
+ * Forward the timer expiry so it will expire in the future.
+ * The number of overruns is added to the overrun field.
+ */
+unsigned long
+hrtimer_forward(struct hrtimer *timer, const ktime_t interval)
+{
+       unsigned long orun = 1;
+       ktime_t delta, now;
+
+       now = timer->base->get_time();
+
+       delta = ktime_sub(now, timer->expires);
+
+       if (delta.tv64 < 0)
+               return 0;
+
+       if (unlikely(delta.tv64 >= interval.tv64)) {
+               nsec_t incr = ktime_to_ns(interval);
+
+               orun = ktime_divns(delta, incr);
+               timer->expires = ktime_add_ns(timer->expires, incr * orun);
+               if (timer->expires.tv64 > now.tv64)
+                       return orun;
+               /*
+                * This (and the ktime_add() below) is the
+                * correction for exact:
+                */
+               orun++;
+       }
+       timer->expires = ktime_add(timer->expires, interval);
+
+       return orun;
+}
+
+/*
+ * enqueue_hrtimer - internal function to (re)start a timer
+ *
+ * The timer is inserted in expiry order. Insertion into the
+ * red black tree is O(log(n)). Must hold the base lock.
+ */
+static void enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
+{
+       struct rb_node **link = &base->active.rb_node;
+       struct list_head *prev = &base->pending;
+       struct rb_node *parent = NULL;
+       struct hrtimer *entry;
+
+       /*
+        * Find the right place in the rbtree:
+        */
+       while (*link) {
+               parent = *link;
+               entry = rb_entry(parent, struct hrtimer, node);
+               /*
+                * We dont care about collisions. Nodes with
+                * the same expiry time stay together.
+                */
+               if (timer->expires.tv64 < entry->expires.tv64)
+                       link = &(*link)->rb_left;
+               else {
+                       link = &(*link)->rb_right;
+                       prev = &entry->list;
+               }
+       }
+
+       /*
+        * Insert the timer to the rbtree and to the sorted list:
+        */
+       rb_link_node(&timer->node, parent, link);
+       rb_insert_color(&timer->node, &base->active);
+       list_add(&timer->list, prev);
+
+       timer->state = HRTIMER_PENDING;
+}
+
+
+/*
+ * __remove_hrtimer - internal function to remove a timer
+ *
+ * Caller must hold the base lock.
+ */
+static void __remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
+{
+       /*
+        * Remove the timer from the sorted list and from the rbtree:
+        */
+       list_del(&timer->list);
+       rb_erase(&timer->node, &base->active);
+}
+
+/*
+ * remove hrtimer, called with base lock held
+ */
+static inline int
+remove_hrtimer(struct hrtimer *timer, struct hrtimer_base *base)
+{
+       if (hrtimer_active(timer)) {
+               __remove_hrtimer(timer, base);
+               timer->state = HRTIMER_INACTIVE;
+               return 1;
+       }
+       return 0;
+}
+
+/**
+ * hrtimer_start - (re)start an relative timer on the current CPU
+ *
+ * @timer:     the timer to be added
+ * @tim:       expiry time
+ * @mode:      expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL)
+ *
+ * Returns:
+ *  0 on success
+ *  1 when the timer was active
+ */
+int
+hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
+{
+       struct hrtimer_base *base, *new_base;
+       unsigned long flags;
+       int ret;
+
+       base = lock_hrtimer_base(timer, &flags);
+
+       /* Remove an active timer from the queue: */
+       ret = remove_hrtimer(timer, base);
+
+       /* Switch the timer base, if necessary: */
+       new_base = switch_hrtimer_base(timer, base);
+
+       if (mode == HRTIMER_REL)
+               tim = ktime_add(tim, new_base->get_time());
+       timer->expires = tim;
+
+       enqueue_hrtimer(timer, new_base);
+
+       unlock_hrtimer_base(timer, &flags);
+
+       return ret;
+}
+
+/**
+ * hrtimer_try_to_cancel - try to deactivate a timer
+ *
+ * @timer:     hrtimer to stop
+ *
+ * Returns:
+ *  0 when the timer was not active
+ *  1 when the timer was active
+ * -1 when the timer is currently excuting the callback function and
+ *    can not be stopped
+ */
+int hrtimer_try_to_cancel(struct hrtimer *timer)
+{
+       struct hrtimer_base *base;
+       unsigned long flags;
+       int ret = -1;
+
+       base = lock_hrtimer_base(timer, &flags);
+
+       if (base->curr_timer != timer)
+               ret = remove_hrtimer(timer, base);
+
+       unlock_hrtimer_base(timer, &flags);
+
+       return ret;
+
+}
+
+/**
+ * hrtimer_cancel - cancel a timer and wait for the handler to finish.
+ *
+ * @timer:     the timer to be cancelled
+ *
+ * Returns:
+ *  0 when the timer was not active
+ *  1 when the timer was active
+ */
+int hrtimer_cancel(struct hrtimer *timer)
+{
+       for (;;) {
+               int ret = hrtimer_try_to_cancel(timer);
+
+               if (ret >= 0)
+                       return ret;
+       }
+}
+
+/**
+ * hrtimer_get_remaining - get remaining time for the timer
+ *
+ * @timer:     the timer to read
+ */
+ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
+{
+       struct hrtimer_base *base;
+       unsigned long flags;
+       ktime_t rem;
+
+       base = lock_hrtimer_base(timer, &flags);
+       rem = ktime_sub(timer->expires, timer->base->get_time());
+       unlock_hrtimer_base(timer, &flags);
+
+       return rem;
+}
+
+/**
+ * hrtimer_rebase - rebase an initialized hrtimer to a different base
+ *
+ * @timer:     the timer to be rebased
+ * @clock_id:  the clock to be used
+ */
+void hrtimer_rebase(struct hrtimer *timer, const clockid_t clock_id)
+{
+       struct hrtimer_base *bases;
+
+       bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
+       timer->base = &bases[clock_id];
+}
+
+/**
+ * hrtimer_init - initialize a timer to the given clock
+ *
+ * @timer:     the timer to be initialized
+ * @clock_id:  the clock to be used
+ */
+void hrtimer_init(struct hrtimer *timer, const clockid_t clock_id)
+{
+       memset(timer, 0, sizeof(struct hrtimer));
+       hrtimer_rebase(timer, clock_id);
+}
+
+/**
+ * hrtimer_get_res - get the timer resolution for a clock
+ *
+ * @which_clock: which clock to query
+ * @tp:                 pointer to timespec variable to store the resolution
+ *
+ * Store the resolution of the clock selected by which_clock in the
+ * variable pointed to by tp.
+ */
+int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
+{
+       struct hrtimer_base *bases;
+
+       tp->tv_sec = 0;
+       bases = per_cpu(hrtimer_bases, raw_smp_processor_id());
+       tp->tv_nsec = bases[which_clock].resolution;
+
+       return 0;
+}
+
+/*
+ * Expire the per base hrtimer-queue:
+ */
+static inline void run_hrtimer_queue(struct hrtimer_base *base)
+{
+       ktime_t now = base->get_time();
+
+       spin_lock_irq(&base->lock);
+
+       while (!list_empty(&base->pending)) {
+               struct hrtimer *timer;
+               int (*fn)(void *);
+               int restart;
+               void *data;
+
+               timer = list_entry(base->pending.next, struct hrtimer, list);
+               if (now.tv64 <= timer->expires.tv64)
+                       break;
+
+               fn = timer->function;
+               data = timer->data;
+               set_curr_timer(base, timer);
+               __remove_hrtimer(timer, base);
+               spin_unlock_irq(&base->lock);
+
+               /*
+                * fn == NULL is special case for the simplest timer
+                * variant - wake up process and do not restart:
+                */
+               if (!fn) {
+                       wake_up_process(data);
+                       restart = HRTIMER_NORESTART;
+               } else
+                       restart = fn(data);
+
+               spin_lock_irq(&base->lock);
+
+               if (restart == HRTIMER_RESTART)
+                       enqueue_hrtimer(timer, base);
+               else
+                       timer->state = HRTIMER_EXPIRED;
+       }
+       set_curr_timer(base, NULL);
+       spin_unlock_irq(&base->lock);
+}
+
+/*
+ * Called from timer softirq every jiffy, expire hrtimers:
+ */
+void hrtimer_run_queues(void)
+{
+       struct hrtimer_base *base = __get_cpu_var(hrtimer_bases);
+       int i;
+
+       for (i = 0; i < MAX_HRTIMER_BASES; i++)
+               run_hrtimer_queue(&base[i]);
+}
+
+/*
+ * Sleep related functions:
+ */
+
+/**
+ * schedule_hrtimer - sleep until timeout
+ *
+ * @timer:     hrtimer variable initialized with the correct clock base
+ * @mode:      timeout value is abs/rel
+ *
+ * Make the current task sleep until @timeout is
+ * elapsed.
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout is guaranteed to
+ * pass before the routine returns. The routine will return 0
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task. In this case the remaining time
+ * will be returned
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this
+ * routine returns.
+ */
+static ktime_t __sched
+schedule_hrtimer(struct hrtimer *timer, const enum hrtimer_mode mode)
+{
+       /* fn stays NULL, meaning single-shot wakeup: */
+       timer->data = current;
+
+       hrtimer_start(timer, timer->expires, mode);
+
+       schedule();
+       hrtimer_cancel(timer);
+
+       /* Return the remaining time: */
+       if (timer->state != HRTIMER_EXPIRED)
+               return ktime_sub(timer->expires, timer->base->get_time());
+       else
+               return (ktime_t) {.tv64 = 0 };
+}
+
+static inline ktime_t __sched
+schedule_hrtimer_interruptible(struct hrtimer *timer,
+                              const enum hrtimer_mode mode)
+{
+       set_current_state(TASK_INTERRUPTIBLE);
+
+       return schedule_hrtimer(timer, mode);
+}
+
+static long __sched
+nanosleep_restart(struct restart_block *restart, clockid_t clockid)
+{
+       struct timespec __user *rmtp, tu;
+       void *rfn_save = restart->fn;
+       struct hrtimer timer;
+       ktime_t rem;
+
+       restart->fn = do_no_restart_syscall;
+
+       hrtimer_init(&timer, clockid);
+
+       timer.expires.tv64 = ((u64)restart->arg1 << 32) | (u64) restart->arg0;
+
+       rem = schedule_hrtimer_interruptible(&timer, HRTIMER_ABS);
+
+       if (rem.tv64 <= 0)
+               return 0;
+
+       rmtp = (struct timespec __user *) restart->arg2;
+       tu = ktime_to_timespec(rem);
+       if (rmtp && copy_to_user(rmtp, &tu, sizeof(tu)))
+               return -EFAULT;
+
+       restart->fn = rfn_save;
+
+       /* The other values in restart are already filled in */
+       return -ERESTART_RESTARTBLOCK;
+}
+
+static long __sched nanosleep_restart_mono(struct restart_block *restart)
+{
+       return nanosleep_restart(restart, CLOCK_MONOTONIC);
+}
+
+static long __sched nanosleep_restart_real(struct restart_block *restart)
+{
+       return nanosleep_restart(restart, CLOCK_REALTIME);
+}
+
+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+                      const enum hrtimer_mode mode, const clockid_t clockid)
+{
+       struct restart_block *restart;
+       struct hrtimer timer;
+       struct timespec tu;
+       ktime_t rem;
+
+       hrtimer_init(&timer, clockid);
+
+       timer.expires = timespec_to_ktime(*rqtp);
+
+       rem = schedule_hrtimer_interruptible(&timer, mode);
+       if (rem.tv64 <= 0)
+               return 0;
+
+       /* Absolute timers do not update the rmtp value: */
+       if (mode == HRTIMER_ABS)
+               return -ERESTARTNOHAND;
+
+       tu = ktime_to_timespec(rem);
+
+       if (rmtp && copy_to_user(rmtp, &tu, sizeof(tu)))
+               return -EFAULT;
+
+       restart = &current_thread_info()->restart_block;
+       restart->fn = (clockid == CLOCK_MONOTONIC) ?
+               nanosleep_restart_mono : nanosleep_restart_real;
+       restart->arg0 = timer.expires.tv64 & 0xFFFFFFFF;
+       restart->arg1 = timer.expires.tv64 >> 32;
+       restart->arg2 = (unsigned long) rmtp;
+
+       return -ERESTART_RESTARTBLOCK;
+}
+
+asmlinkage long
+sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
+{
+       struct timespec tu;
+
+       if (copy_from_user(&tu, rqtp, sizeof(tu)))
+               return -EFAULT;
+
+       if (!timespec_valid(&tu))
+               return -EINVAL;
+
+       return hrtimer_nanosleep(&tu, rmtp, HRTIMER_REL, CLOCK_MONOTONIC);
+}
+
+/*
+ * Functions related to boot-time initialization:
+ */
+static void __devinit init_hrtimers_cpu(int cpu)
+{
+       struct hrtimer_base *base = per_cpu(hrtimer_bases, cpu);
+       int i;
+
+       for (i = 0; i < MAX_HRTIMER_BASES; i++) {
+               spin_lock_init(&base->lock);
+               INIT_LIST_HEAD(&base->pending);
+               base++;
+       }
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static void migrate_hrtimer_list(struct hrtimer_base *old_base,
+                               struct hrtimer_base *new_base)
+{
+       struct hrtimer *timer;
+       struct rb_node *node;
+
+       while ((node = rb_first(&old_base->active))) {
+               timer = rb_entry(node, struct hrtimer, node);
+               __remove_hrtimer(timer, old_base);
+               timer->base = new_base;
+               enqueue_hrtimer(timer, new_base);
+       }
+}
+
+static void migrate_hrtimers(int cpu)
+{
+       struct hrtimer_base *old_base, *new_base;
+       int i;
+
+       BUG_ON(cpu_online(cpu));
+       old_base = per_cpu(hrtimer_bases, cpu);
+       new_base = get_cpu_var(hrtimer_bases);
+
+       local_irq_disable();
+
+       for (i = 0; i < MAX_HRTIMER_BASES; i++) {
+
+               spin_lock(&new_base->lock);
+               spin_lock(&old_base->lock);
+
+               BUG_ON(old_base->curr_timer);
+
+               migrate_hrtimer_list(old_base, new_base);
+
+               spin_unlock(&old_base->lock);
+               spin_unlock(&new_base->lock);
+               old_base++;
+               new_base++;
+       }
+
+       local_irq_enable();
+       put_cpu_var(hrtimer_bases);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static int __devinit hrtimer_cpu_notify(struct notifier_block *self,
+                                       unsigned long action, void *hcpu)
+{
+       long cpu = (long)hcpu;
+
+       switch (action) {
+
+       case CPU_UP_PREPARE:
+               init_hrtimers_cpu(cpu);
+               break;
+
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_DEAD:
+               migrate_hrtimers(cpu);
+               break;
+#endif
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __devinitdata hrtimers_nb = {
+       .notifier_call = hrtimer_cpu_notify,
+};
+
+void __init hrtimers_init(void)
+{
+       hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
+                         (void *)(long)smp_processor_id());
+       register_cpu_notifier(&hrtimers_nb);
+}
+
index 7c1b25e25e4743ec920bdfd62c8e57f3261ca450..c2c05c4ff28d5bd7bd32cf8ca1eea1dc768b71c2 100644 (file)
 #include <linux/syscalls.h>
 #include <linux/time.h>
 #include <linux/posix-timers.h>
+#include <linux/hrtimer.h>
 
 #include <asm/uaccess.h>
 
-static unsigned long it_real_value(struct signal_struct *sig)
+/**
+ * itimer_get_remtime - get remaining time for the timer
+ *
+ * @timer: the timer to read
+ *
+ * Returns the delta between the expiry time and now, which can be
+ * less than zero or 1usec for an pending expired timer
+ */
+static struct timeval itimer_get_remtime(struct hrtimer *timer)
 {
-       unsigned long val = 0;
-       if (timer_pending(&sig->real_timer)) {
-               val = sig->real_timer.expires - jiffies;
+       ktime_t rem = hrtimer_get_remaining(timer);
 
-               /* look out for negative/zero itimer.. */
-               if ((long) val <= 0)
-                       val = 1;
-       }
-       return val;
+       /*
+        * Racy but safe: if the itimer expires after the above
+        * hrtimer_get_remtime() call but before this condition
+        * then we return 0 - which is correct.
+        */
+       if (hrtimer_active(timer)) {
+               if (rem.tv64 <= 0)
+                       rem.tv64 = NSEC_PER_USEC;
+       } else
+               rem.tv64 = 0;
+
+       return ktime_to_timeval(rem);
 }
 
 int do_getitimer(int which, struct itimerval *value)
 {
        struct task_struct *tsk = current;
-       unsigned long interval, val;
        cputime_t cinterval, cval;
 
        switch (which) {
        case ITIMER_REAL:
-               spin_lock_irq(&tsk->sighand->siglock);
-               interval = tsk->signal->it_real_incr;
-               val = it_real_value(tsk->signal);
-               spin_unlock_irq(&tsk->sighand->siglock);
-               jiffies_to_timeval(val, &value->it_value);
-               jiffies_to_timeval(interval, &value->it_interval);
+               value->it_value = itimer_get_remtime(&tsk->signal->real_timer);
+               value->it_interval =
+                       ktime_to_timeval(tsk->signal->it_real_incr);
                break;
        case ITIMER_VIRTUAL:
                read_lock(&tasklist_lock);
@@ -113,59 +123,45 @@ asmlinkage long sys_getitimer(int which, struct itimerval __user *value)
 }
 
 
-void it_real_fn(unsigned long __data)
+/*
+ * The timer is automagically restarted, when interval != 0
+ */
+int it_real_fn(void *data)
 {
-       struct task_struct * p = (struct task_struct *) __data;
-       unsigned long inc = p->signal->it_real_incr;
+       struct task_struct *tsk = (struct task_struct *) data;
 
-       send_group_sig_info(SIGALRM, SEND_SIG_PRIV, p);
+       send_group_sig_info(SIGALRM, SEND_SIG_PRIV, tsk);
 
-       /*
-        * Now restart the timer if necessary.  We don't need any locking
-        * here because do_setitimer makes sure we have finished running
-        * before it touches anything.
-        * Note, we KNOW we are (or should be) at a jiffie edge here so
-        * we don't need the +1 stuff.  Also, we want to use the prior
-        * expire value so as to not "slip" a jiffie if we are late.
-        * Deal with requesting a time prior to "now" here rather than
-        * in add_timer.
-        */
-       if (!inc)
-               return;
-       while (time_before_eq(p->signal->real_timer.expires, jiffies))
-               p->signal->real_timer.expires += inc;
-       add_timer(&p->signal->real_timer);
+       if (tsk->signal->it_real_incr.tv64 != 0) {
+               hrtimer_forward(&tsk->signal->real_timer,
+                              tsk->signal->it_real_incr);
+
+               return HRTIMER_RESTART;
+       }
+       return HRTIMER_NORESTART;
 }
 
 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 {
        struct task_struct *tsk = current;
-       unsigned long val, interval, expires;
+       struct hrtimer *timer;
+       ktime_t expires;
        cputime_t cval, cinterval, nval, ninterval;
 
        switch (which) {
        case ITIMER_REAL:
-again:
-               spin_lock_irq(&tsk->sighand->siglock);
-               interval = tsk->signal->it_real_incr;
-               val = it_real_value(tsk->signal);
-               /* We are sharing ->siglock with it_real_fn() */
-               if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
-                       spin_unlock_irq(&tsk->sighand->siglock);
-                       goto again;
-               }
-               tsk->signal->it_real_incr =
-                       timeval_to_jiffies(&value->it_interval);
-               expires = timeval_to_jiffies(&value->it_value);
-               if (expires)
-                       mod_timer(&tsk->signal->real_timer,
-                                 jiffies + 1 + expires);
-               spin_unlock_irq(&tsk->sighand->siglock);
+               timer = &tsk->signal->real_timer;
+               hrtimer_cancel(timer);
                if (ovalue) {
-                       jiffies_to_timeval(val, &ovalue->it_value);
-                       jiffies_to_timeval(interval,
-                                          &ovalue->it_interval);
+                       ovalue->it_value = itimer_get_remtime(timer);
+                       ovalue->it_interval
+                               = ktime_to_timeval(tsk->signal->it_real_incr);
                }
+               tsk->signal->it_real_incr =
+                       timeval_to_ktime(value->it_interval);
+               expires = timeval_to_ktime(value->it_value);
+               if (expires.tv64 != 0)
+                       hrtimer_start(timer, expires, HRTIMER_REL);
                break;
        case ITIMER_VIRTUAL:
                nval = timeval_to_cputime(&value->it_value);
index 2c95848fbce8261463e54833d60d68573e9fb9b8..de1441656efdacf2d86a5db5226fb6e7f1469655 100644 (file)
@@ -26,6 +26,9 @@
 #include <asm/system.h>
 #include <asm/semaphore.h>
 
+/* Per cpu memory for storing cpu states in case of system crash. */
+note_buf_t* crash_notes;
+
 /* Location of the reserved area for the crash kernel */
 struct resource crashk_res = {
        .name  = "Crash kernel",
@@ -1054,9 +1057,24 @@ void crash_kexec(struct pt_regs *regs)
        if (!locked) {
                image = xchg(&kexec_crash_image, NULL);
                if (image) {
-                       machine_crash_shutdown(regs);
+                       struct pt_regs fixed_regs;
+                       crash_setup_regs(&fixed_regs, regs);
+                       machine_crash_shutdown(&fixed_regs);
                        machine_kexec(image);
                }
                xchg(&kexec_lock, 0);
        }
 }
+
+static int __init crash_notes_memory_init(void)
+{
+       /* Allocate memory for saving cpu registers. */
+       crash_notes = alloc_percpu(note_buf_t);
+       if (!crash_notes) {
+               printk("Kexec: Memory allocation for saving cpu register"
+               " states failed\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+module_init(crash_notes_memory_init)
index 3bb71e63a37e0bfa47217c99b2b5e6dbe0a8f2d5..34a885bb82e0d94a38a7ebec8e8014cf2dc197d1 100644 (file)
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
-static DEFINE_SPINLOCK(kprobe_lock);   /* Protects kprobe_table */
+DECLARE_MUTEX(kprobe_mutex);           /* Protects kprobe_table */
 DEFINE_SPINLOCK(kretprobe_lock);       /* Protects kretprobe_inst_table */
 static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
 
+#ifdef __ARCH_WANT_KPROBES_INSN_SLOT
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
  * single-stepped. x86_64, POWER4 and above have no-exec support and
@@ -151,6 +152,7 @@ void __kprobes free_insn_slot(kprobe_opcode_t *slot)
                }
        }
 }
+#endif
 
 /* We have preemption disabled.. so it is safe to use __ versions */
 static inline void set_kprobe_instance(struct kprobe *kp)
@@ -165,7 +167,7 @@ static inline void reset_kprobe_instance(void)
 
 /*
  * This routine is called either:
- *     - under the kprobe_lock spinlock - during kprobe_[un]register()
+ *     - under the kprobe_mutex - during kprobe_[un]register()
  *                             OR
  *     - with preemption disabled - from arch/xxx/kernel/kprobes.c
  */
@@ -418,7 +420,6 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
 /*
  * This is the second or subsequent kprobe at the address - handle
  * the intricacies
- * TODO: Move kcalloc outside the spin_lock
  */
 static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
                                          struct kprobe *p)
@@ -430,7 +431,7 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
                copy_kprobe(old_p, p);
                ret = add_new_kprobe(old_p, p);
        } else {
-               ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
+               ap = kzalloc(sizeof(struct kprobe), GFP_KERNEL);
                if (!ap)
                        return -ENOMEM;
                add_aggr_kprobe(ap, old_p);
@@ -440,25 +441,6 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
        return ret;
 }
 
-/* kprobe removal house-keeping routines */
-static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
-{
-       arch_disarm_kprobe(p);
-       hlist_del_rcu(&p->hlist);
-       spin_unlock_irqrestore(&kprobe_lock, flags);
-       arch_remove_kprobe(p);
-}
-
-static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
-               struct kprobe *p, unsigned long flags)
-{
-       list_del_rcu(&p->list);
-       if (list_empty(&old_p->list))
-               cleanup_kprobe(old_p, flags);
-       else
-               spin_unlock_irqrestore(&kprobe_lock, flags);
-}
-
 static int __kprobes in_kprobes_functions(unsigned long addr)
 {
        if (addr >= (unsigned long)__kprobes_text_start
@@ -470,7 +452,6 @@ static int __kprobes in_kprobes_functions(unsigned long addr)
 int __kprobes register_kprobe(struct kprobe *p)
 {
        int ret = 0;
-       unsigned long flags = 0;
        struct kprobe *old_p;
        struct module *mod;
 
@@ -482,18 +463,17 @@ int __kprobes register_kprobe(struct kprobe *p)
                        (unlikely(!try_module_get(mod))))
                return -EINVAL;
 
-       if ((ret = arch_prepare_kprobe(p)) != 0)
-               goto rm_kprobe;
-
        p->nmissed = 0;
-       spin_lock_irqsave(&kprobe_lock, flags);
+       down(&kprobe_mutex);
        old_p = get_kprobe(p->addr);
        if (old_p) {
                ret = register_aggr_kprobe(old_p, p);
                goto out;
        }
 
-       arch_copy_kprobe(p);
+       if ((ret = arch_prepare_kprobe(p)) != 0)
+               goto out;
+
        INIT_HLIST_NODE(&p->hlist);
        hlist_add_head_rcu(&p->hlist,
                       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
@@ -501,10 +481,8 @@ int __kprobes register_kprobe(struct kprobe *p)
        arch_arm_kprobe(p);
 
 out:
-       spin_unlock_irqrestore(&kprobe_lock, flags);
-rm_kprobe:
-       if (ret == -EEXIST)
-               arch_remove_kprobe(p);
+       up(&kprobe_mutex);
+
        if (ret && mod)
                module_put(mod);
        return ret;
@@ -512,29 +490,50 @@ rm_kprobe:
 
 void __kprobes unregister_kprobe(struct kprobe *p)
 {
-       unsigned long flags;
-       struct kprobe *old_p;
        struct module *mod;
+       struct kprobe *old_p, *list_p;
+       int cleanup_p;
 
-       spin_lock_irqsave(&kprobe_lock, flags);
+       down(&kprobe_mutex);
        old_p = get_kprobe(p->addr);
-       if (old_p) {
-               /* cleanup_*_kprobe() does the spin_unlock_irqrestore */
-               if (old_p->pre_handler == aggr_pre_handler)
-                       cleanup_aggr_kprobe(old_p, p, flags);
-               else
-                       cleanup_kprobe(p, flags);
+       if (unlikely(!old_p)) {
+               up(&kprobe_mutex);
+               return;
+       }
+       if (p != old_p) {
+               list_for_each_entry_rcu(list_p, &old_p->list, list)
+                       if (list_p == p)
+                       /* kprobe p is a valid probe */
+                               goto valid_p;
+               up(&kprobe_mutex);
+               return;
+       }
+valid_p:
+       if ((old_p == p) || ((old_p->pre_handler == aggr_pre_handler) &&
+               (p->list.next == &old_p->list) &&
+               (p->list.prev == &old_p->list))) {
+               /* Only probe on the hash list */
+               arch_disarm_kprobe(p);
+               hlist_del_rcu(&old_p->hlist);
+               cleanup_p = 1;
+       } else {
+               list_del_rcu(&p->list);
+               cleanup_p = 0;
+       }
 
-               synchronize_sched();
+       up(&kprobe_mutex);
 
-               if ((mod = module_text_address((unsigned long)p->addr)))
-                       module_put(mod);
+       synchronize_sched();
+       if ((mod = module_text_address((unsigned long)p->addr)))
+               module_put(mod);
 
-               if (old_p->pre_handler == aggr_pre_handler &&
-                               list_empty(&old_p->list))
+       if (cleanup_p) {
+               if (p != old_p) {
+                       list_del_rcu(&p->list);
                        kfree(old_p);
-       } else
-               spin_unlock_irqrestore(&kprobe_lock, flags);
+               }
+               arch_remove_kprobe(p);
+       }
 }
 
 static struct notifier_block kprobe_exceptions_nb = {
index 99af8b05eeaa754de098195a7299bff216040180..d5eeae0fa5bc5c6de327a7c0f583c4fdaca16b50 100644 (file)
@@ -51,16 +51,6 @@ static ssize_t uevent_helper_store(struct subsystem *subsys, const char *page, s
 KERNEL_ATTR_RW(uevent_helper);
 #endif
 
-#ifdef CONFIG_KEXEC
-#include <asm/kexec.h>
-
-static ssize_t crash_notes_show(struct subsystem *subsys, char *page)
-{
-       return sprintf(page, "%p\n", (void *)crash_notes);
-}
-KERNEL_ATTR_RO(crash_notes);
-#endif
-
 decl_subsys(kernel, NULL, NULL);
 EXPORT_SYMBOL_GPL(kernel_subsys);
 
@@ -68,9 +58,6 @@ static struct attribute * kernel_attrs[] = {
 #ifdef CONFIG_HOTPLUG
        &uevent_seqnum_attr.attr,
        &uevent_helper_attr.attr,
-#endif
-#ifdef CONFIG_KEXEC
-       &crash_notes_attr.attr,
 #endif
        NULL
 };
index 4c68edff900b17bbe46e504c78b12c1231dbf3de..520f6c59948d24c55721c2a2299defe964efaadf 100644 (file)
@@ -7,7 +7,7 @@
 #include <asm/uaccess.h>
 #include <linux/errno.h>
 
-static int check_clock(clockid_t which_clock)
+static int check_clock(const clockid_t which_clock)
 {
        int error = 0;
        struct task_struct *p;
@@ -31,7 +31,7 @@ static int check_clock(clockid_t which_clock)
 }
 
 static inline union cpu_time_count
-timespec_to_sample(clockid_t which_clock, const struct timespec *tp)
+timespec_to_sample(const clockid_t which_clock, const struct timespec *tp)
 {
        union cpu_time_count ret;
        ret.sched = 0;          /* high half always zero when .cpu used */
@@ -43,7 +43,7 @@ timespec_to_sample(clockid_t which_clock, const struct timespec *tp)
        return ret;
 }
 
-static void sample_to_timespec(clockid_t which_clock,
+static void sample_to_timespec(const clockid_t which_clock,
                               union cpu_time_count cpu,
                               struct timespec *tp)
 {
@@ -55,7 +55,7 @@ static void sample_to_timespec(clockid_t which_clock,
        }
 }
 
-static inline int cpu_time_before(clockid_t which_clock,
+static inline int cpu_time_before(const clockid_t which_clock,
                                  union cpu_time_count now,
                                  union cpu_time_count then)
 {
@@ -65,7 +65,7 @@ static inline int cpu_time_before(clockid_t which_clock,
                return cputime_lt(now.cpu, then.cpu);
        }
 }
-static inline void cpu_time_add(clockid_t which_clock,
+static inline void cpu_time_add(const clockid_t which_clock,
                                union cpu_time_count *acc,
                                union cpu_time_count val)
 {
@@ -75,7 +75,7 @@ static inline void cpu_time_add(clockid_t which_clock,
                acc->cpu = cputime_add(acc->cpu, val.cpu);
        }
 }
-static inline union cpu_time_count cpu_time_sub(clockid_t which_clock,
+static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock,
                                                union cpu_time_count a,
                                                union cpu_time_count b)
 {
@@ -151,7 +151,7 @@ static inline unsigned long long sched_ns(struct task_struct *p)
        return (p == current) ? current_sched_time(p) : p->sched_time;
 }
 
-int posix_cpu_clock_getres(clockid_t which_clock, struct timespec *tp)
+int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
 {
        int error = check_clock(which_clock);
        if (!error) {
@@ -169,7 +169,7 @@ int posix_cpu_clock_getres(clockid_t which_clock, struct timespec *tp)
        return error;
 }
 
-int posix_cpu_clock_set(clockid_t which_clock, const struct timespec *tp)
+int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
 {
        /*
         * You can never reset a CPU clock, but we check for other errors
@@ -186,7 +186,7 @@ int posix_cpu_clock_set(clockid_t which_clock, const struct timespec *tp)
 /*
  * Sample a per-thread clock for the given task.
  */
-static int cpu_clock_sample(clockid_t which_clock, struct task_struct *p,
+static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
                            union cpu_time_count *cpu)
 {
        switch (CPUCLOCK_WHICH(which_clock)) {
@@ -248,7 +248,7 @@ static int cpu_clock_sample_group_locked(unsigned int clock_idx,
  * Sample a process (thread group) clock for the given group_leader task.
  * Must be called with tasklist_lock held for reading.
  */
-static int cpu_clock_sample_group(clockid_t which_clock,
+static int cpu_clock_sample_group(const clockid_t which_clock,
                                  struct task_struct *p,
                                  union cpu_time_count *cpu)
 {
@@ -262,7 +262,7 @@ static int cpu_clock_sample_group(clockid_t which_clock,
 }
 
 
-int posix_cpu_clock_get(clockid_t which_clock, struct timespec *tp)
+int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
 {
        const pid_t pid = CPUCLOCK_PID(which_clock);
        int error = -EINVAL;
@@ -1399,8 +1399,8 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
 
 static long posix_cpu_clock_nanosleep_restart(struct restart_block *);
 
-int posix_cpu_nsleep(clockid_t which_clock, int flags,
-                    struct timespec *rqtp)
+int posix_cpu_nsleep(const clockid_t which_clock, int flags,
+                    struct timespec *rqtp, struct timespec __user *rmtp)
 {
        struct restart_block *restart_block =
            &current_thread_info()->restart_block;
@@ -1425,7 +1425,6 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags,
        error = posix_cpu_timer_create(&timer);
        timer.it_process = current;
        if (!error) {
-               struct timespec __user *rmtp;
                static struct itimerspec zero_it;
                struct itimerspec it = { .it_value = *rqtp,
                                         .it_interval = {} };
@@ -1472,7 +1471,6 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags,
                /*
                 * Report back to the user the time still remaining.
                 */
-               rmtp = (struct timespec __user *) restart_block->arg1;
                if (rmtp != NULL && !(flags & TIMER_ABSTIME) &&
                    copy_to_user(rmtp, &it.it_value, sizeof *rmtp))
                        return -EFAULT;
@@ -1480,6 +1478,7 @@ int posix_cpu_nsleep(clockid_t which_clock, int flags,
                restart_block->fn = posix_cpu_clock_nanosleep_restart;
                /* Caller already set restart_block->arg1 */
                restart_block->arg0 = which_clock;
+               restart_block->arg1 = (unsigned long) rmtp;
                restart_block->arg2 = rqtp->tv_sec;
                restart_block->arg3 = rqtp->tv_nsec;
 
@@ -1493,21 +1492,28 @@ static long
 posix_cpu_clock_nanosleep_restart(struct restart_block *restart_block)
 {
        clockid_t which_clock = restart_block->arg0;
-       struct timespec t = { .tv_sec = restart_block->arg2,
-                             .tv_nsec = restart_block->arg3 };
+       struct timespec __user *rmtp;
+       struct timespec t;
+
+       rmtp = (struct timespec __user *) restart_block->arg1;
+       t.tv_sec = restart_block->arg2;
+       t.tv_nsec = restart_block->arg3;
+
        restart_block->fn = do_no_restart_syscall;
-       return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t);
+       return posix_cpu_nsleep(which_clock, TIMER_ABSTIME, &t, rmtp);
 }
 
 
 #define PROCESS_CLOCK  MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)
 #define THREAD_CLOCK   MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED)
 
-static int process_cpu_clock_getres(clockid_t which_clock, struct timespec *tp)
+static int process_cpu_clock_getres(const clockid_t which_clock,
+                                   struct timespec *tp)
 {
        return posix_cpu_clock_getres(PROCESS_CLOCK, tp);
 }
-static int process_cpu_clock_get(clockid_t which_clock, struct timespec *tp)
+static int process_cpu_clock_get(const clockid_t which_clock,
+                                struct timespec *tp)
 {
        return posix_cpu_clock_get(PROCESS_CLOCK, tp);
 }
@@ -1516,16 +1522,19 @@ static int process_cpu_timer_create(struct k_itimer *timer)
        timer->it_clock = PROCESS_CLOCK;
        return posix_cpu_timer_create(timer);
 }
-static int process_cpu_nsleep(clockid_t which_clock, int flags,
-                             struct timespec *rqtp)
+static int process_cpu_nsleep(const clockid_t which_clock, int flags,
+                             struct timespec *rqtp,
+                             struct timespec __user *rmtp)
 {
-       return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp);
+       return posix_cpu_nsleep(PROCESS_CLOCK, flags, rqtp, rmtp);
 }
-static int thread_cpu_clock_getres(clockid_t which_clock, struct timespec *tp)
+static int thread_cpu_clock_getres(const clockid_t which_clock,
+                                  struct timespec *tp)
 {
        return posix_cpu_clock_getres(THREAD_CLOCK, tp);
 }
-static int thread_cpu_clock_get(clockid_t which_clock, struct timespec *tp)
+static int thread_cpu_clock_get(const clockid_t which_clock,
+                               struct timespec *tp)
 {
        return posix_cpu_clock_get(THREAD_CLOCK, tp);
 }
@@ -1534,8 +1543,8 @@ static int thread_cpu_timer_create(struct k_itimer *timer)
        timer->it_clock = THREAD_CLOCK;
        return posix_cpu_timer_create(timer);
 }
-static int thread_cpu_nsleep(clockid_t which_clock, int flags,
-                             struct timespec *rqtp)
+static int thread_cpu_nsleep(const clockid_t which_clock, int flags,
+                             struct timespec *rqtp, struct timespec __user *rmtp)
 {
        return -EINVAL;
 }
index 5870efb3e2007e70ae577c76f4d71e71245914f2..9e66e614862afd20acb0d1190dcb12f9a2101488 100644 (file)
 #include <linux/workqueue.h>
 #include <linux/module.h>
 
-#ifndef div_long_long_rem
-#include <asm/div64.h>
-
-#define div_long_long_rem(dividend,divisor,remainder) ({ \
-                      u64 result = dividend;           \
-                      *remainder = do_div(result,divisor); \
-                      result; })
-
-#endif
-#define CLOCK_REALTIME_RES TICK_NSEC  /* In nano seconds. */
-
-static inline u64  mpy_l_X_l_ll(unsigned long mpy1,unsigned long mpy2)
-{
-       return (u64)mpy1 * mpy2;
-}
 /*
  * Management arrays for POSIX timers.  Timers are kept in slab memory
  * Timer ids are allocated by an external routine that keeps track of the
@@ -148,18 +133,18 @@ static DEFINE_SPINLOCK(idr_lock);
  */
 
 static struct k_clock posix_clocks[MAX_CLOCKS];
+
 /*
- * We only have one real clock that can be set so we need only one abs list,
- * even if we should want to have several clocks with differing resolutions.
+ * These ones are defined below.
  */
-static struct k_clock_abs abs_list = {.list = LIST_HEAD_INIT(abs_list.list),
-                                     .lock = SPIN_LOCK_UNLOCKED};
+static int common_nsleep(const clockid_t, int flags, struct timespec *t,
+                        struct timespec __user *rmtp);
+static void common_timer_get(struct k_itimer *, struct itimerspec *);
+static int common_timer_set(struct k_itimer *, int,
+                           struct itimerspec *, struct itimerspec *);
+static int common_timer_del(struct k_itimer *timer);
 
-static void posix_timer_fn(unsigned long);
-static u64 do_posix_clock_monotonic_gettime_parts(
-       struct timespec *tp, struct timespec *mo);
-int do_posix_clock_monotonic_gettime(struct timespec *tp);
-static int do_posix_clock_monotonic_get(clockid_t, struct timespec *tp);
+static int posix_timer_fn(void *data);
 
 static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags);
 
@@ -184,7 +169,7 @@ static inline void unlock_timer(struct k_itimer *timr, unsigned long flags)
  * the function pointer CALL in struct k_clock.
  */
 
-static inline int common_clock_getres(clockid_t which_clock,
+static inline int common_clock_getres(const clockid_t which_clock,
                                      struct timespec *tp)
 {
        tp->tv_sec = 0;
@@ -192,39 +177,33 @@ static inline int common_clock_getres(clockid_t which_clock,
        return 0;
 }
 
-static inline int common_clock_get(clockid_t which_clock, struct timespec *tp)
+/*
+ * Get real time for posix timers
+ */
+static int common_clock_get(clockid_t which_clock, struct timespec *tp)
 {
-       getnstimeofday(tp);
+       ktime_get_real_ts(tp);
        return 0;
 }
 
-static inline int common_clock_set(clockid_t which_clock, struct timespec *tp)
+static inline int common_clock_set(const clockid_t which_clock,
+                                  struct timespec *tp)
 {
        return do_sys_settimeofday(tp, NULL);
 }
 
 static inline int common_timer_create(struct k_itimer *new_timer)
 {
-       INIT_LIST_HEAD(&new_timer->it.real.abs_timer_entry);
-       init_timer(&new_timer->it.real.timer);
-       new_timer->it.real.timer.data = (unsigned long) new_timer;
+       hrtimer_init(&new_timer->it.real.timer, new_timer->it_clock);
+       new_timer->it.real.timer.data = new_timer;
        new_timer->it.real.timer.function = posix_timer_fn;
        return 0;
 }
 
 /*
- * These ones are defined below.
- */
-static int common_nsleep(clockid_t, int flags, struct timespec *t);
-static void common_timer_get(struct k_itimer *, struct itimerspec *);
-static int common_timer_set(struct k_itimer *, int,
-                           struct itimerspec *, struct itimerspec *);
-static int common_timer_del(struct k_itimer *timer);
-
-/*
- * Return nonzero iff we know a priori this clockid_t value is bogus.
+ * Return nonzero if we know a priori this clockid_t value is bogus.
  */
-static inline int invalid_clockid(clockid_t which_clock)
+static inline int invalid_clockid(const clockid_t which_clock)
 {
        if (which_clock < 0)    /* CPU clock, posix_cpu_* will check it */
                return 0;
@@ -232,26 +211,32 @@ static inline int invalid_clockid(clockid_t which_clock)
                return 1;
        if (posix_clocks[which_clock].clock_getres != NULL)
                return 0;
-#ifndef CLOCK_DISPATCH_DIRECT
        if (posix_clocks[which_clock].res != 0)
                return 0;
-#endif
        return 1;
 }
 
+/*
+ * Get monotonic time for posix timers
+ */
+static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
+{
+       ktime_get_ts(tp);
+       return 0;
+}
 
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
 static __init int init_posix_timers(void)
 {
-       struct k_clock clock_realtime = {.res = CLOCK_REALTIME_RES,
-                                        .abs_struct = &abs_list
+       struct k_clock clock_realtime = {
+               .clock_getres = hrtimer_get_res,
        };
-       struct k_clock clock_monotonic = {.res = CLOCK_REALTIME_RES,
-               .abs_struct = NULL,
-               .clock_get = do_posix_clock_monotonic_get,
-               .clock_set = do_posix_clock_nosettime
+       struct k_clock clock_monotonic = {
+               .clock_getres = hrtimer_get_res,
+               .clock_get = posix_ktime_get_ts,
+               .clock_set = do_posix_clock_nosettime,
        };
 
        register_posix_clock(CLOCK_REALTIME, &clock_realtime);
@@ -265,117 +250,17 @@ static __init int init_posix_timers(void)
 
 __initcall(init_posix_timers);
 
-static void tstojiffie(struct timespec *tp, int res, u64 *jiff)
-{
-       long sec = tp->tv_sec;
-       long nsec = tp->tv_nsec + res - 1;
-
-       if (nsec >= NSEC_PER_SEC) {
-               sec++;
-               nsec -= NSEC_PER_SEC;
-       }
-
-       /*
-        * The scaling constants are defined in <linux/time.h>
-        * The difference between there and here is that we do the
-        * res rounding and compute a 64-bit result (well so does that
-        * but it then throws away the high bits).
-        */
-       *jiff =  (mpy_l_X_l_ll(sec, SEC_CONVERSION) +
-                 (mpy_l_X_l_ll(nsec, NSEC_CONVERSION) >> 
-                  (NSEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
-}
-
-/*
- * This function adjusts the timer as needed as a result of the clock
- * being set.  It should only be called for absolute timers, and then
- * under the abs_list lock.  It computes the time difference and sets
- * the new jiffies value in the timer.  It also updates the timers
- * reference wall_to_monotonic value.  It is complicated by the fact
- * that tstojiffies() only handles positive times and it needs to work
- * with both positive and negative times.  Also, for negative offsets,
- * we need to defeat the res round up.
- *
- * Return is true if there is a new time, else false.
- */
-static long add_clockset_delta(struct k_itimer *timr,
-                              struct timespec *new_wall_to)
-{
-       struct timespec delta;
-       int sign = 0;
-       u64 exp;
-
-       set_normalized_timespec(&delta,
-                               new_wall_to->tv_sec -
-                               timr->it.real.wall_to_prev.tv_sec,
-                               new_wall_to->tv_nsec -
-                               timr->it.real.wall_to_prev.tv_nsec);
-       if (likely(!(delta.tv_sec | delta.tv_nsec)))
-               return 0;
-       if (delta.tv_sec < 0) {
-               set_normalized_timespec(&delta,
-                                       -delta.tv_sec,
-                                       1 - delta.tv_nsec -
-                                       posix_clocks[timr->it_clock].res);
-               sign++;
-       }
-       tstojiffie(&delta, posix_clocks[timr->it_clock].res, &exp);
-       timr->it.real.wall_to_prev = *new_wall_to;
-       timr->it.real.timer.expires += (sign ? -exp : exp);
-       return 1;
-}
-
-static void remove_from_abslist(struct k_itimer *timr)
-{
-       if (!list_empty(&timr->it.real.abs_timer_entry)) {
-               spin_lock(&abs_list.lock);
-               list_del_init(&timr->it.real.abs_timer_entry);
-               spin_unlock(&abs_list.lock);
-       }
-}
-
 static void schedule_next_timer(struct k_itimer *timr)
 {
-       struct timespec new_wall_to;
-       struct now_struct now;
-       unsigned long seq;
-
-       /*
-        * Set up the timer for the next interval (if there is one).
-        * Note: this code uses the abs_timer_lock to protect
-        * it.real.wall_to_prev and must hold it until exp is set, not exactly
-        * obvious...
-
-        * This function is used for CLOCK_REALTIME* and
-        * CLOCK_MONOTONIC* timers.  If we ever want to handle other
-        * CLOCKs, the calling code (do_schedule_next_timer) would need
-        * to pull the "clock" info from the timer and dispatch the
-        * "other" CLOCKs "next timer" code (which, I suppose should
-        * also be added to the k_clock structure).
-        */
-       if (!timr->it.real.incr)
+       if (timr->it.real.interval.tv64 == 0)
                return;
 
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               new_wall_to =   wall_to_monotonic;
-               posix_get_now(&now);
-       } while (read_seqretry(&xtime_lock, seq));
-
-       if (!list_empty(&timr->it.real.abs_timer_entry)) {
-               spin_lock(&abs_list.lock);
-               add_clockset_delta(timr, &new_wall_to);
-
-               posix_bump_timer(timr, now);
-
-               spin_unlock(&abs_list.lock);
-       } else {
-               posix_bump_timer(timr, now);
-       }
+       timr->it_overrun += hrtimer_forward(&timr->it.real.timer,
+                                           timr->it.real.interval);
        timr->it_overrun_last = timr->it_overrun;
        timr->it_overrun = -1;
        ++timr->it_requeue_pending;
-       add_timer(&timr->it.real.timer);
+       hrtimer_restart(&timr->it.real.timer);
 }
 
 /*
@@ -396,31 +281,23 @@ void do_schedule_next_timer(struct siginfo *info)
 
        timr = lock_timer(info->si_tid, &flags);
 
-       if (!timr || timr->it_requeue_pending != info->si_sys_private)
-               goto exit;
+       if (timr && timr->it_requeue_pending == info->si_sys_private) {
+               if (timr->it_clock < 0)
+                       posix_cpu_timer_schedule(timr);
+               else
+                       schedule_next_timer(timr);
 
-       if (timr->it_clock < 0) /* CPU clock */
-               posix_cpu_timer_schedule(timr);
-       else
-               schedule_next_timer(timr);
-       info->si_overrun = timr->it_overrun_last;
-exit:
-       if (timr)
-               unlock_timer(timr, flags);
+               info->si_overrun = timr->it_overrun_last;
+       }
+
+       unlock_timer(timr, flags);
 }
 
 int posix_timer_event(struct k_itimer *timr,int si_private)
 {
        memset(&timr->sigq->info, 0, sizeof(siginfo_t));
        timr->sigq->info.si_sys_private = si_private;
-       /*
-        * Send signal to the process that owns this timer.
-
-        * This code assumes that all the possible abs_lists share the
-        * same lock (there is only one list at this time). If this is
-        * not the case, the CLOCK info would need to be used to find
-        * the proper abs list lock.
-        */
+       /* Send signal to the process that owns this timer.*/
 
        timr->sigq->info.si_signo = timr->it_sigev_signo;
        timr->sigq->info.si_errno = 0;
@@ -454,64 +331,35 @@ EXPORT_SYMBOL_GPL(posix_timer_event);
 
  * This code is for CLOCK_REALTIME* and CLOCK_MONOTONIC* timers.
  */
-static void posix_timer_fn(unsigned long __data)
+static int posix_timer_fn(void *data)
 {
-       struct k_itimer *timr = (struct k_itimer *) __data;
+       struct k_itimer *timr = data;
        unsigned long flags;
-       unsigned long seq;
-       struct timespec delta, new_wall_to;
-       u64 exp = 0;
-       int do_notify = 1;
+       int si_private = 0;
+       int ret = HRTIMER_NORESTART;
 
        spin_lock_irqsave(&timr->it_lock, flags);
-       if (!list_empty(&timr->it.real.abs_timer_entry)) {
-               spin_lock(&abs_list.lock);
-               do {
-                       seq = read_seqbegin(&xtime_lock);
-                       new_wall_to =   wall_to_monotonic;
-               } while (read_seqretry(&xtime_lock, seq));
-               set_normalized_timespec(&delta,
-                                       new_wall_to.tv_sec -
-                                       timr->it.real.wall_to_prev.tv_sec,
-                                       new_wall_to.tv_nsec -
-                                       timr->it.real.wall_to_prev.tv_nsec);
-               if (likely((delta.tv_sec | delta.tv_nsec ) == 0)) {
-                       /* do nothing, timer is on time */
-               } else if (delta.tv_sec < 0) {
-                       /* do nothing, timer is already late */
-               } else {
-                       /* timer is early due to a clock set */
-                       tstojiffie(&delta,
-                                  posix_clocks[timr->it_clock].res,
-                                  &exp);
-                       timr->it.real.wall_to_prev = new_wall_to;
-                       timr->it.real.timer.expires += exp;
-                       add_timer(&timr->it.real.timer);
-                       do_notify = 0;
-               }
-               spin_unlock(&abs_list.lock);
 
-       }
-       if (do_notify)  {
-               int si_private=0;
+       if (timr->it.real.interval.tv64 != 0)
+               si_private = ++timr->it_requeue_pending;
 
-               if (timr->it.real.incr)
-                       si_private = ++timr->it_requeue_pending;
-               else {
-                       remove_from_abslist(timr);
+       if (posix_timer_event(timr, si_private)) {
+               /*
+                * signal was not sent because of sig_ignor
+                * we will not get a call back to restart it AND
+                * it should be restarted.
+                */
+               if (timr->it.real.interval.tv64 != 0) {
+                       timr->it_overrun +=
+                               hrtimer_forward(&timr->it.real.timer,
+                                               timr->it.real.interval);
+                       ret = HRTIMER_RESTART;
                }
-
-               if (posix_timer_event(timr, si_private))
-                       /*
-                        * signal was not sent because of sig_ignor
-                        * we will not get a call back to restart it AND
-                        * it should be restarted.
-                        */
-                       schedule_next_timer(timr);
        }
-       unlock_timer(timr, flags); /* hold thru abs lock to keep irq off */
-}
 
+       unlock_timer(timr, flags);
+       return ret;
+}
 
 static inline struct task_struct * good_sigevent(sigevent_t * event)
 {
@@ -530,7 +378,7 @@ static inline struct task_struct * good_sigevent(sigevent_t * event)
        return rtn;
 }
 
-void register_posix_clock(clockid_t clock_id, struct k_clock *new_clock)
+void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock)
 {
        if ((unsigned) clock_id >= MAX_CLOCKS) {
                printk("POSIX clock register failed for clock_id %d\n",
@@ -576,7 +424,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
 /* Create a POSIX.1b interval timer. */
 
 asmlinkage long
-sys_timer_create(clockid_t which_clock,
+sys_timer_create(const clockid_t which_clock,
                 struct sigevent __user *timer_event_spec,
                 timer_t __user * created_timer_id)
 {
@@ -602,8 +450,7 @@ sys_timer_create(clockid_t which_clock,
                goto out;
        }
        spin_lock_irq(&idr_lock);
-       error = idr_get_new(&posix_timers_id,
-                           (void *) new_timer,
+       error = idr_get_new(&posix_timers_id, (void *) new_timer,
                            &new_timer_id);
        spin_unlock_irq(&idr_lock);
        if (error == -EAGAIN)
@@ -703,27 +550,6 @@ out:
        return error;
 }
 
-/*
- * good_timespec
- *
- * This function checks the elements of a timespec structure.
- *
- * Arguments:
- * ts       : Pointer to the timespec structure to check
- *
- * Return value:
- * If a NULL pointer was passed in, or the tv_nsec field was less than 0
- * or greater than NSEC_PER_SEC, or the tv_sec field was less than 0,
- * this function returns 0. Otherwise it returns 1.
- */
-static int good_timespec(const struct timespec *ts)
-{
-       if ((!ts) || (ts->tv_sec < 0) ||
-                       ((unsigned) ts->tv_nsec >= NSEC_PER_SEC))
-               return 0;
-       return 1;
-}
-
 /*
  * Locking issues: We need to protect the result of the id look up until
  * we get the timer locked down so it is not deleted under us.  The
@@ -776,39 +602,39 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
 static void
 common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
 {
-       unsigned long expires;
-       struct now_struct now;
-
-       do
-               expires = timr->it.real.timer.expires;
-       while ((volatile long) (timr->it.real.timer.expires) != expires);
-
-       posix_get_now(&now);
-
-       if (expires &&
-           ((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) &&
-           !timr->it.real.incr &&
-           posix_time_before(&timr->it.real.timer, &now))
-               timr->it.real.timer.expires = expires = 0;
-       if (expires) {
-               if (timr->it_requeue_pending & REQUEUE_PENDING ||
-                   (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
-                       posix_bump_timer(timr, now);
-                       expires = timr->it.real.timer.expires;
-               }
-               else
-                       if (!timer_pending(&timr->it.real.timer))
-                               expires = 0;
-               if (expires)
-                       expires -= now.jiffies;
-       }
-       jiffies_to_timespec(expires, &cur_setting->it_value);
-       jiffies_to_timespec(timr->it.real.incr, &cur_setting->it_interval);
+       ktime_t remaining;
+       struct hrtimer *timer = &timr->it.real.timer;
+
+       memset(cur_setting, 0, sizeof(struct itimerspec));
+       remaining = hrtimer_get_remaining(timer);
 
-       if (cur_setting->it_value.tv_sec < 0) {
+       /* Time left ? or timer pending */
+       if (remaining.tv64 > 0 || hrtimer_active(timer))
+               goto calci;
+       /* interval timer ? */
+       if (timr->it.real.interval.tv64 == 0)
+               return;
+       /*
+        * When a requeue is pending or this is a SIGEV_NONE timer
+        * move the expiry time forward by intervals, so expiry is >
+        * now.
+        */
+       if (timr->it_requeue_pending & REQUEUE_PENDING ||
+           (timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
+               timr->it_overrun +=
+                       hrtimer_forward(timer, timr->it.real.interval);
+               remaining = hrtimer_get_remaining(timer);
+       }
+ calci:
+       /* interval timer ? */
+       if (timr->it.real.interval.tv64 != 0)
+               cur_setting->it_interval =
+                       ktime_to_timespec(timr->it.real.interval);
+       /* Return 0 only, when the timer is expired and not pending */
+       if (remaining.tv64 <= 0)
                cur_setting->it_value.tv_nsec = 1;
-               cur_setting->it_value.tv_sec = 0;
-       }
+       else
+               cur_setting->it_value = ktime_to_timespec(remaining);
 }
 
 /* Get the time remaining on a POSIX.1b interval timer. */
@@ -832,6 +658,7 @@ sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting)
 
        return 0;
 }
+
 /*
  * Get the number of overruns of a POSIX.1b interval timer.  This is to
  * be the overrun of the timer last delivered.  At the same time we are
@@ -841,7 +668,6 @@ sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting)
  * the call back to do_schedule_next_timer().  So all we need to do is
  * to pick up the frozen overrun.
  */
-
 asmlinkage long
 sys_timer_getoverrun(timer_t timer_id)
 {
@@ -858,84 +684,6 @@ sys_timer_getoverrun(timer_t timer_id)
 
        return overrun;
 }
-/*
- * Adjust for absolute time
- *
- * If absolute time is given and it is not CLOCK_MONOTONIC, we need to
- * adjust for the offset between the timer clock (CLOCK_MONOTONIC) and
- * what ever clock he is using.
- *
- * If it is relative time, we need to add the current (CLOCK_MONOTONIC)
- * time to it to get the proper time for the timer.
- */
-static int adjust_abs_time(struct k_clock *clock, struct timespec *tp, 
-                          int abs, u64 *exp, struct timespec *wall_to)
-{
-       struct timespec now;
-       struct timespec oc = *tp;
-       u64 jiffies_64_f;
-       int rtn =0;
-
-       if (abs) {
-               /*
-                * The mask pick up the 4 basic clocks 
-                */
-               if (!((clock - &posix_clocks[0]) & ~CLOCKS_MASK)) {
-                       jiffies_64_f = do_posix_clock_monotonic_gettime_parts(
-                               &now,  wall_to);
-                       /*
-                        * If we are doing a MONOTONIC clock
-                        */
-                       if((clock - &posix_clocks[0]) & CLOCKS_MONO){
-                               now.tv_sec += wall_to->tv_sec;
-                               now.tv_nsec += wall_to->tv_nsec;
-                       }
-               } else {
-                       /*
-                        * Not one of the basic clocks
-                        */
-                       clock->clock_get(clock - posix_clocks, &now);
-                       jiffies_64_f = get_jiffies_64();
-               }
-               /*
-                * Take away now to get delta and normalize
-                */
-               set_normalized_timespec(&oc, oc.tv_sec - now.tv_sec,
-                                       oc.tv_nsec - now.tv_nsec);
-       }else{
-               jiffies_64_f = get_jiffies_64();
-       }
-       /*
-        * Check if the requested time is prior to now (if so set now)
-        */
-       if (oc.tv_sec < 0)
-               oc.tv_sec = oc.tv_nsec = 0;
-
-       if (oc.tv_sec | oc.tv_nsec)
-               set_normalized_timespec(&oc, oc.tv_sec,
-                                       oc.tv_nsec + clock->res);
-       tstojiffie(&oc, clock->res, exp);
-
-       /*
-        * Check if the requested time is more than the timer code
-        * can handle (if so we error out but return the value too).
-        */
-       if (*exp > ((u64)MAX_JIFFY_OFFSET))
-                       /*
-                        * This is a considered response, not exactly in
-                        * line with the standard (in fact it is silent on
-                        * possible overflows).  We assume such a large 
-                        * value is ALMOST always a programming error and
-                        * try not to compound it by setting a really dumb
-                        * value.
-                        */
-                       rtn = -EINVAL;
-       /*
-        * return the actual jiffies expire time, full 64 bits
-        */
-       *exp += jiffies_64_f;
-       return rtn;
-}
 
 /* Set a POSIX.1b interval timer. */
 /* timr->it_lock is taken. */
@@ -943,68 +691,48 @@ static inline int
 common_timer_set(struct k_itimer *timr, int flags,
                 struct itimerspec *new_setting, struct itimerspec *old_setting)
 {
-       struct k_clock *clock = &posix_clocks[timr->it_clock];
-       u64 expire_64;
+       struct hrtimer *timer = &timr->it.real.timer;
 
        if (old_setting)
                common_timer_get(timr, old_setting);
 
        /* disable the timer */
-       timr->it.real.incr = 0;
+       timr->it.real.interval.tv64 = 0;
        /*
         * careful here.  If smp we could be in the "fire" routine which will
         * be spinning as we hold the lock.  But this is ONLY an SMP issue.
         */
-       if (try_to_del_timer_sync(&timr->it.real.timer) < 0) {
-#ifdef CONFIG_SMP
-               /*
-                * It can only be active if on an other cpu.  Since
-                * we have cleared the interval stuff above, it should
-                * clear once we release the spin lock.  Of course once
-                * we do that anything could happen, including the
-                * complete melt down of the timer.  So return with
-                * a "retry" exit status.
-                */
+       if (hrtimer_try_to_cancel(timer) < 0)
                return TIMER_RETRY;
-#endif
-       }
-
-       remove_from_abslist(timr);
 
        timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
                ~REQUEUE_PENDING;
        timr->it_overrun_last = 0;
-       timr->it_overrun = -1;
-       /*
-        *switch off the timer when it_value is zero
-        */
-       if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec) {
-               timr->it.real.timer.expires = 0;
-               return 0;
-       }
 
-       if (adjust_abs_time(clock,
-                           &new_setting->it_value, flags & TIMER_ABSTIME, 
-                           &expire_64, &(timr->it.real.wall_to_prev))) {
-               return -EINVAL;
-       }
-       timr->it.real.timer.expires = (unsigned long)expire_64;
-       tstojiffie(&new_setting->it_interval, clock->res, &expire_64);
-       timr->it.real.incr = (unsigned long)expire_64;
+       /* switch off the timer when it_value is zero */
+       if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
+               return 0;
 
-       /*
-        * We do not even queue SIGEV_NONE timers!  But we do put them
-        * in the abs list so we can do that right.
+       /* Posix madness. Only absolute CLOCK_REALTIME timers
+        * are affected by clock sets. So we must reiniatilize
+        * the timer.
         */
-       if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE))
-               add_timer(&timr->it.real.timer);
-
-       if (flags & TIMER_ABSTIME && clock->abs_struct) {
-               spin_lock(&clock->abs_struct->lock);
-               list_add_tail(&(timr->it.real.abs_timer_entry),
-                             &(clock->abs_struct->list));
-               spin_unlock(&clock->abs_struct->lock);
-       }
+       if (timr->it_clock == CLOCK_REALTIME && (flags & TIMER_ABSTIME))
+               hrtimer_rebase(timer, CLOCK_REALTIME);
+       else
+               hrtimer_rebase(timer, CLOCK_MONOTONIC);
+
+       timer->expires = timespec_to_ktime(new_setting->it_value);
+
+       /* Convert interval */
+       timr->it.real.interval = timespec_to_ktime(new_setting->it_interval);
+
+       /* SIGEV_NONE timers are not queued ! See common_timer_get */
+       if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE))
+               return 0;
+
+       hrtimer_start(timer, timer->expires, (flags & TIMER_ABSTIME) ?
+                     HRTIMER_ABS : HRTIMER_REL);
        return 0;
 }
 
@@ -1026,8 +754,8 @@ sys_timer_settime(timer_t timer_id, int flags,
        if (copy_from_user(&new_spec, new_setting, sizeof (new_spec)))
                return -EFAULT;
 
-       if ((!good_timespec(&new_spec.it_interval)) ||
-           (!good_timespec(&new_spec.it_value)))
+       if (!timespec_valid(&new_spec.it_interval) ||
+           !timespec_valid(&new_spec.it_value))
                return -EINVAL;
 retry:
        timr = lock_timer(timer_id, &flag);
@@ -1043,8 +771,8 @@ retry:
                goto retry;
        }
 
-       if (old_setting && !error && copy_to_user(old_setting,
-                                                 &old_spec, sizeof (old_spec)))
+       if (old_setting && !error &&
+           copy_to_user(old_setting, &old_spec, sizeof (old_spec)))
                error = -EFAULT;
 
        return error;
@@ -1052,24 +780,10 @@ retry:
 
 static inline int common_timer_del(struct k_itimer *timer)
 {
-       timer->it.real.incr = 0;
+       timer->it.real.interval.tv64 = 0;
 
-       if (try_to_del_timer_sync(&timer->it.real.timer) < 0) {
-#ifdef CONFIG_SMP
-               /*
-                * It can only be active if on an other cpu.  Since
-                * we have cleared the interval stuff above, it should
-                * clear once we release the spin lock.  Of course once
-                * we do that anything could happen, including the
-                * complete melt down of the timer.  So return with
-                * a "retry" exit status.
-                */
+       if (hrtimer_try_to_cancel(&timer->it.real.timer) < 0)
                return TIMER_RETRY;
-#endif
-       }
-
-       remove_from_abslist(timer);
-
        return 0;
 }
 
@@ -1085,24 +799,16 @@ sys_timer_delete(timer_t timer_id)
        struct k_itimer *timer;
        long flags;
 
-#ifdef CONFIG_SMP
-       int error;
 retry_delete:
-#endif
        timer = lock_timer(timer_id, &flags);
        if (!timer)
                return -EINVAL;
 
-#ifdef CONFIG_SMP
-       error = timer_delete_hook(timer);
-
-       if (error == TIMER_RETRY) {
+       if (timer_delete_hook(timer) == TIMER_RETRY) {
                unlock_timer(timer, flags);
                goto retry_delete;
        }
-#else
-       timer_delete_hook(timer);
-#endif
+
        spin_lock(&current->sighand->siglock);
        list_del(&timer->list);
        spin_unlock(&current->sighand->siglock);
@@ -1119,6 +825,7 @@ retry_delete:
        release_posix_timer(timer, IT_ID_SET);
        return 0;
 }
+
 /*
  * return timer owned by the process, used by exit_itimers
  */
@@ -1126,22 +833,13 @@ static inline void itimer_delete(struct k_itimer *timer)
 {
        unsigned long flags;
 
-#ifdef CONFIG_SMP
-       int error;
 retry_delete:
-#endif
        spin_lock_irqsave(&timer->it_lock, flags);
 
-#ifdef CONFIG_SMP
-       error = timer_delete_hook(timer);
-
-       if (error == TIMER_RETRY) {
+       if (timer_delete_hook(timer) == TIMER_RETRY) {
                unlock_timer(timer, flags);
                goto retry_delete;
        }
-#else
-       timer_delete_hook(timer);
-#endif
        list_del(&timer->list);
        /*
         * This keeps any tasks waiting on the spin lock from thinking
@@ -1170,57 +868,8 @@ void exit_itimers(struct signal_struct *sig)
        }
 }
 
-/*
- * And now for the "clock" calls
- *
- * These functions are called both from timer functions (with the timer
- * spin_lock_irq() held and from clock calls with no locking.  They must
- * use the save flags versions of locks.
- */
-
-/*
- * We do ticks here to avoid the irq lock ( they take sooo long).
- * The seqlock is great here.  Since we a reader, we don't really care
- * if we are interrupted since we don't take lock that will stall us or
- * any other cpu. Voila, no irq lock is needed.
- *
- */
-
-static u64 do_posix_clock_monotonic_gettime_parts(
-       struct timespec *tp, struct timespec *mo)
-{
-       u64 jiff;
-       unsigned int seq;
-
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               getnstimeofday(tp);
-               *mo = wall_to_monotonic;
-               jiff = jiffies_64;
-
-       } while(read_seqretry(&xtime_lock, seq));
-
-       return jiff;
-}
-
-static int do_posix_clock_monotonic_get(clockid_t clock, struct timespec *tp)
-{
-       struct timespec wall_to_mono;
-
-       do_posix_clock_monotonic_gettime_parts(tp, &wall_to_mono);
-
-       set_normalized_timespec(tp, tp->tv_sec + wall_to_mono.tv_sec,
-                               tp->tv_nsec + wall_to_mono.tv_nsec);
-
-       return 0;
-}
-
-int do_posix_clock_monotonic_gettime(struct timespec *tp)
-{
-       return do_posix_clock_monotonic_get(CLOCK_MONOTONIC, tp);
-}
-
-int do_posix_clock_nosettime(clockid_t clockid, struct timespec *tp)
+/* Not available / possible... functions */
+int do_posix_clock_nosettime(const clockid_t clockid, struct timespec *tp)
 {
        return -EINVAL;
 }
@@ -1232,7 +881,8 @@ int do_posix_clock_notimer_create(struct k_itimer *timer)
 }
 EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create);
 
-int do_posix_clock_nonanosleep(clockid_t clock, int flags, struct timespec *t)
+int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
+                              struct timespec *t, struct timespec __user *r)
 {
 #ifndef ENOTSUP
        return -EOPNOTSUPP;     /* aka ENOTSUP in userland for POSIX */
@@ -1242,8 +892,8 @@ int do_posix_clock_nonanosleep(clockid_t clock, int flags, struct timespec *t)
 }
 EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep);
 
-asmlinkage long
-sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
+asmlinkage long sys_clock_settime(const clockid_t which_clock,
+                                 const struct timespec __user *tp)
 {
        struct timespec new_tp;
 
@@ -1256,7 +906,7 @@ sys_clock_settime(clockid_t which_clock, const struct timespec __user *tp)
 }
 
 asmlinkage long
-sys_clock_gettime(clockid_t which_clock, struct timespec __user *tp)
+sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp)
 {
        struct timespec kernel_tp;
        int error;
@@ -1273,7 +923,7 @@ sys_clock_gettime(clockid_t which_clock, struct timespec __user *tp)
 }
 
 asmlinkage long
-sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
+sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
 {
        struct timespec rtn_tp;
        int error;
@@ -1292,117 +942,34 @@ sys_clock_getres(clockid_t which_clock, struct timespec __user *tp)
 }
 
 /*
- * The standard says that an absolute nanosleep call MUST wake up at
- * the requested time in spite of clock settings.  Here is what we do:
- * For each nanosleep call that needs it (only absolute and not on
- * CLOCK_MONOTONIC* (as it can not be set)) we thread a little structure
- * into the "nanosleep_abs_list".  All we need is the task_struct pointer.
- * When ever the clock is set we just wake up all those tasks.  The rest
- * is done by the while loop in clock_nanosleep().
- *
- * On locking, clock_was_set() is called from update_wall_clock which
- * holds (or has held for it) a write_lock_irq( xtime_lock) and is
- * called from the timer bh code.  Thus we need the irq save locks.
- *
- * Also, on the call from update_wall_clock, that is done as part of a
- * softirq thing.  We don't want to delay the system that much (possibly
- * long list of timers to fix), so we defer that work to keventd.
+ * nanosleep for monotonic and realtime clocks
  */
-
-static DECLARE_WAIT_QUEUE_HEAD(nanosleep_abs_wqueue);
-static DECLARE_WORK(clock_was_set_work, (void(*)(void*))clock_was_set, NULL);
-
-static DECLARE_MUTEX(clock_was_set_lock);
-
-void clock_was_set(void)
-{
-       struct k_itimer *timr;
-       struct timespec new_wall_to;
-       LIST_HEAD(cws_list);
-       unsigned long seq;
-
-
-       if (unlikely(in_interrupt())) {
-               schedule_work(&clock_was_set_work);
-               return;
+static int common_nsleep(const clockid_t which_clock, int flags,
+                        struct timespec *tsave, struct timespec __user *rmtp)
+{
+       int mode = flags & TIMER_ABSTIME ? HRTIMER_ABS : HRTIMER_REL;
+       int clockid = which_clock;
+
+       switch (which_clock) {
+       case CLOCK_REALTIME:
+               /* Posix madness. Only absolute timers on clock realtime
+                  are affected by clock set. */
+               if (mode != HRTIMER_ABS)
+                       clockid = CLOCK_MONOTONIC;
+       case CLOCK_MONOTONIC:
+               break;
+       default:
+               return -EINVAL;
        }
-       wake_up_all(&nanosleep_abs_wqueue);
-
-       /*
-        * Check if there exist TIMER_ABSTIME timers to correct.
-        *
-        * Notes on locking: This code is run in task context with irq
-        * on.  We CAN be interrupted!  All other usage of the abs list
-        * lock is under the timer lock which holds the irq lock as
-        * well.  We REALLY don't want to scan the whole list with the
-        * interrupt system off, AND we would like a sequence lock on
-        * this code as well.  Since we assume that the clock will not
-        * be set often, it seems ok to take and release the irq lock
-        * for each timer.  In fact add_timer will do this, so this is
-        * not an issue.  So we know when we are done, we will move the
-        * whole list to a new location.  Then as we process each entry,
-        * we will move it to the actual list again.  This way, when our
-        * copy is empty, we are done.  We are not all that concerned
-        * about preemption so we will use a semaphore lock to protect
-        * aginst reentry.  This way we will not stall another
-        * processor.  It is possible that this may delay some timers
-        * that should have expired, given the new clock, but even this
-        * will be minimal as we will always update to the current time,
-        * even if it was set by a task that is waiting for entry to
-        * this code.  Timers that expire too early will be caught by
-        * the expire code and restarted.
-
-        * Absolute timers that repeat are left in the abs list while
-        * waiting for the task to pick up the signal.  This means we
-        * may find timers that are not in the "add_timer" list, but are
-        * in the abs list.  We do the same thing for these, save
-        * putting them back in the "add_timer" list.  (Note, these are
-        * left in the abs list mainly to indicate that they are
-        * ABSOLUTE timers, a fact that is used by the re-arm code, and
-        * for which we have no other flag.)
-
-        */
-
-       down(&clock_was_set_lock);
-       spin_lock_irq(&abs_list.lock);
-       list_splice_init(&abs_list.list, &cws_list);
-       spin_unlock_irq(&abs_list.lock);
-       do {
-               do {
-                       seq = read_seqbegin(&xtime_lock);
-                       new_wall_to =   wall_to_monotonic;
-               } while (read_seqretry(&xtime_lock, seq));
-
-               spin_lock_irq(&abs_list.lock);
-               if (list_empty(&cws_list)) {
-                       spin_unlock_irq(&abs_list.lock);
-                       break;
-               }
-               timr = list_entry(cws_list.next, struct k_itimer,
-                                 it.real.abs_timer_entry);
-
-               list_del_init(&timr->it.real.abs_timer_entry);
-               if (add_clockset_delta(timr, &new_wall_to) &&
-                   del_timer(&timr->it.real.timer))  /* timer run yet? */
-                       add_timer(&timr->it.real.timer);
-               list_add(&timr->it.real.abs_timer_entry, &abs_list.list);
-               spin_unlock_irq(&abs_list.lock);
-       } while (1);
-
-       up(&clock_was_set_lock);
+       return hrtimer_nanosleep(tsave, rmtp, mode, clockid);
 }
 
-long clock_nanosleep_restart(struct restart_block *restart_block);
-
 asmlinkage long
-sys_clock_nanosleep(clockid_t which_clock, int flags,
+sys_clock_nanosleep(const clockid_t which_clock, int flags,
                    const struct timespec __user *rqtp,
                    struct timespec __user *rmtp)
 {
        struct timespec t;
-       struct restart_block *restart_block =
-           &(current_thread_info()->restart_block);
-       int ret;
 
        if (invalid_clockid(which_clock))
                return -EINVAL;
@@ -1410,125 +977,9 @@ sys_clock_nanosleep(clockid_t which_clock, int flags,
        if (copy_from_user(&t, rqtp, sizeof (struct timespec)))
                return -EFAULT;
 
-       if ((unsigned) t.tv_nsec >= NSEC_PER_SEC || t.tv_sec < 0)
+       if (!timespec_valid(&t))
                return -EINVAL;
 
-       /*
-        * Do this here as nsleep function does not have the real address.
-        */
-       restart_block->arg1 = (unsigned long)rmtp;
-
-       ret = CLOCK_DISPATCH(which_clock, nsleep, (which_clock, flags, &t));
-
-       if ((ret == -ERESTART_RESTARTBLOCK) && rmtp &&
-                                       copy_to_user(rmtp, &t, sizeof (t)))
-               return -EFAULT;
-       return ret;
-}
-
-
-static int common_nsleep(clockid_t which_clock,
-                        int flags, struct timespec *tsave)
-{
-       struct timespec t, dum;
-       DECLARE_WAITQUEUE(abs_wqueue, current);
-       u64 rq_time = (u64)0;
-       s64 left;
-       int abs;
-       struct restart_block *restart_block =
-           &current_thread_info()->restart_block;
-
-       abs_wqueue.flags = 0;
-       abs = flags & TIMER_ABSTIME;
-
-       if (restart_block->fn == clock_nanosleep_restart) {
-               /*
-                * Interrupted by a non-delivered signal, pick up remaining
-                * time and continue.  Remaining time is in arg2 & 3.
-                */
-               restart_block->fn = do_no_restart_syscall;
-
-               rq_time = restart_block->arg3;
-               rq_time = (rq_time << 32) + restart_block->arg2;
-               if (!rq_time)
-                       return -EINTR;
-               left = rq_time - get_jiffies_64();
-               if (left <= (s64)0)
-                       return 0;       /* Already passed */
-       }
-
-       if (abs && (posix_clocks[which_clock].clock_get !=
-                           posix_clocks[CLOCK_MONOTONIC].clock_get))
-               add_wait_queue(&nanosleep_abs_wqueue, &abs_wqueue);
-
-       do {
-               t = *tsave;
-               if (abs || !rq_time) {
-                       adjust_abs_time(&posix_clocks[which_clock], &t, abs,
-                                       &rq_time, &dum);
-               }
-
-               left = rq_time - get_jiffies_64();
-               if (left >= (s64)MAX_JIFFY_OFFSET)
-                       left = (s64)MAX_JIFFY_OFFSET;
-               if (left < (s64)0)
-                       break;
-
-               schedule_timeout_interruptible(left);
-
-               left = rq_time - get_jiffies_64();
-       } while (left > (s64)0 && !test_thread_flag(TIF_SIGPENDING));
-
-       if (abs_wqueue.task_list.next)
-               finish_wait(&nanosleep_abs_wqueue, &abs_wqueue);
-
-       if (left > (s64)0) {
-
-               /*
-                * Always restart abs calls from scratch to pick up any
-                * clock shifting that happened while we are away.
-                */
-               if (abs)
-                       return -ERESTARTNOHAND;
-
-               left *= TICK_NSEC;
-               tsave->tv_sec = div_long_long_rem(left, 
-                                                 NSEC_PER_SEC, 
-                                                 &tsave->tv_nsec);
-               /*
-                * Restart works by saving the time remaing in 
-                * arg2 & 3 (it is 64-bits of jiffies).  The other
-                * info we need is the clock_id (saved in arg0). 
-                * The sys_call interface needs the users 
-                * timespec return address which _it_ saves in arg1.
-                * Since we have cast the nanosleep call to a clock_nanosleep
-                * both can be restarted with the same code.
-                */
-               restart_block->fn = clock_nanosleep_restart;
-               restart_block->arg0 = which_clock;
-               /*
-                * Caller sets arg1
-                */
-               restart_block->arg2 = rq_time & 0xffffffffLL;
-               restart_block->arg3 = rq_time >> 32;
-
-               return -ERESTART_RESTARTBLOCK;
-       }
-
-       return 0;
-}
-/*
- * This will restart clock_nanosleep.
- */
-long
-clock_nanosleep_restart(struct restart_block *restart_block)
-{
-       struct timespec t;
-       int ret = common_nsleep(restart_block->arg0, 0, &t);
-
-       if ((ret == -ERESTART_RESTARTBLOCK) && restart_block->arg1 &&
-           copy_to_user((struct timespec __user *)(restart_block->arg1), &t,
-                        sizeof (t)))
-               return -EFAULT;
-       return ret;
+       return CLOCK_DISPATCH(which_clock, nsleep,
+                             (which_clock, flags, &t, rmtp));
 }
index 92285d822de6c9ce3a75825b7b876b8379d522d6..e3080fcc66a3b1237e30326782eed2a8fd184323 100644 (file)
@@ -464,7 +464,7 @@ struct resource * __request_region(struct resource *parent, unsigned long start,
 
 EXPORT_SYMBOL(__request_region);
 
-int __deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n)
+int __check_region(struct resource *parent, unsigned long start, unsigned long n)
 {
        struct resource * res;
 
index b3d4dc858e3540a521ee69c32a9eab1798a67a44..dcfb5d731466257f7f003ba5eb84083f0185d22c 100644 (file)
@@ -87,13 +87,9 @@ static int stop_machine(void)
 {
        int i, ret = 0;
        struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
-       mm_segment_t old_fs = get_fs();
 
        /* One high-prio thread per cpu.  We'll do this one. */
-       set_fs(KERNEL_DS);
-       sys_sched_setscheduler(current->pid, SCHED_FIFO,
-                               (struct sched_param __user *)&param);
-       set_fs(old_fs);
+       sched_setscheduler(current, SCHED_FIFO, &param);
 
        atomic_set(&stopmachine_thread_ack, 0);
        stopmachine_num_threads = 0;
index b94bfa8c03e0ce045c02195942dcdfc16172bdab..169e8329e0b63ba59ce29f438dd90f182280ce03 100644 (file)
@@ -154,6 +154,9 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
        static int firsttime = 1;
        int error = 0;
 
+       if (!timespec_valid(tv))
+               return -EINVAL;
+
        error = security_settime(tv, tz);
        if (error)
                return error;
@@ -561,27 +564,107 @@ void getnstimeofday(struct timespec *tv)
 EXPORT_SYMBOL_GPL(getnstimeofday);
 #endif
 
-void getnstimestamp(struct timespec *ts)
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+unsigned long
+mktime(const unsigned int year0, const unsigned int mon0,
+       const unsigned int day, const unsigned int hour,
+       const unsigned int min, const unsigned int sec)
 {
-       unsigned int seq;
-       struct timespec wall2mono;
+       unsigned int mon = mon0, year = year0;
 
-       /* synchronize with settimeofday() changes */
-       do {
-               seq = read_seqbegin(&xtime_lock);
-               getnstimeofday(ts);
-               wall2mono = wall_to_monotonic;
-       } while(unlikely(read_seqretry(&xtime_lock, seq)));
-
-       /* adjust to monotonicaly-increasing values */
-       ts->tv_sec += wall2mono.tv_sec;
-       ts->tv_nsec += wall2mono.tv_nsec;
-       while (unlikely(ts->tv_nsec >= NSEC_PER_SEC)) {
-               ts->tv_nsec -= NSEC_PER_SEC;
-               ts->tv_sec++;
+       /* 1..12 -> 11,12,1..10 */
+       if (0 >= (int) (mon -= 2)) {
+               mon += 12;      /* Puts Feb last since it has leap day */
+               year -= 1;
        }
+
+       return ((((unsigned long)
+                 (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+                 year*365 - 719499
+           )*24 + hour /* now have hours */
+         )*60 + min /* now have minutes */
+       )*60 + sec; /* finally seconds */
+}
+
+EXPORT_SYMBOL(mktime);
+
+/**
+ * set_normalized_timespec - set timespec sec and nsec parts and normalize
+ *
+ * @ts:                pointer to timespec variable to be set
+ * @sec:       seconds to set
+ * @nsec:      nanoseconds to set
+ *
+ * Set seconds and nanoseconds field of a timespec variable and
+ * normalize to the timespec storage format
+ *
+ * Note: The tv_nsec part is always in the range of
+ *     0 <= tv_nsec < NSEC_PER_SEC
+ * For negative values only the tv_sec field is negative !
+ */
+void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
+{
+       while (nsec >= NSEC_PER_SEC) {
+               nsec -= NSEC_PER_SEC;
+               ++sec;
+       }
+       while (nsec < 0) {
+               nsec += NSEC_PER_SEC;
+               --sec;
+       }
+       ts->tv_sec = sec;
+       ts->tv_nsec = nsec;
+}
+
+/**
+ * ns_to_timespec - Convert nanoseconds to timespec
+ * @nsec:       the nanoseconds value to be converted
+ *
+ * Returns the timespec representation of the nsec parameter.
+ */
+inline struct timespec ns_to_timespec(const nsec_t nsec)
+{
+       struct timespec ts;
+
+       if (nsec)
+               ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC,
+                                                    &ts.tv_nsec);
+       else
+               ts.tv_sec = ts.tv_nsec = 0;
+
+       return ts;
+}
+
+/**
+ * ns_to_timeval - Convert nanoseconds to timeval
+ * @nsec:       the nanoseconds value to be converted
+ *
+ * Returns the timeval representation of the nsec parameter.
+ */
+struct timeval ns_to_timeval(const nsec_t nsec)
+{
+       struct timespec ts = ns_to_timespec(nsec);
+       struct timeval tv;
+
+       tv.tv_sec = ts.tv_sec;
+       tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
+
+       return tv;
 }
-EXPORT_SYMBOL_GPL(getnstimestamp);
 
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void)
index 074b4bd5cfd8b62a9b92555514455a4a06f0416e..4f1cb0ab5251aed2b690003527a26258e15c49a0 100644 (file)
@@ -858,6 +858,7 @@ static void run_timer_softirq(struct softirq_action *h)
 {
        tvec_base_t *base = &__get_cpu_var(tvec_bases);
 
+       hrtimer_run_queues();
        if (time_after_eq(jiffies, base->timer_jiffies))
                __run_timers(base);
 }
@@ -1119,62 +1120,6 @@ asmlinkage long sys_gettid(void)
        return current->pid;
 }
 
-static long __sched nanosleep_restart(struct restart_block *restart)
-{
-       unsigned long expire = restart->arg0, now = jiffies;
-       struct timespec __user *rmtp = (struct timespec __user *) restart->arg1;
-       long ret;
-
-       /* Did it expire while we handled signals? */
-       if (!time_after(expire, now))
-               return 0;
-
-       expire = schedule_timeout_interruptible(expire - now);
-
-       ret = 0;
-       if (expire) {
-               struct timespec t;
-               jiffies_to_timespec(expire, &t);
-
-               ret = -ERESTART_RESTARTBLOCK;
-               if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
-                       ret = -EFAULT;
-               /* The 'restart' block is already filled in */
-       }
-       return ret;
-}
-
-asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
-{
-       struct timespec t;
-       unsigned long expire;
-       long ret;
-
-       if (copy_from_user(&t, rqtp, sizeof(t)))
-               return -EFAULT;
-
-       if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
-               return -EINVAL;
-
-       expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-       expire = schedule_timeout_interruptible(expire);
-
-       ret = 0;
-       if (expire) {
-               struct restart_block *restart;
-               jiffies_to_timespec(expire, &t);
-               if (rmtp && copy_to_user(rmtp, &t, sizeof(t)))
-                       return -EFAULT;
-
-               restart = &current_thread_info()->restart_block;
-               restart->fn = nanosleep_restart;
-               restart->arg0 = jiffies + expire;
-               restart->arg1 = (unsigned long) rmtp;
-               ret = -ERESTART_RESTARTBLOCK;
-       }
-       return ret;
-}
-
 /*
  * sys_sysinfo - fill in sysinfo struct
  */ 
index 1fcd856edec1913e463551c8715abb61b70b55b2..a609235a517f5b52ed7897366a14624e47bd4c12 100644 (file)
@@ -9,15 +9,9 @@ config PRINTK_TIME
          in kernel startup.
 
 
-config DEBUG_KERNEL
-       bool "Kernel debugging"
-       help
-         Say Y here if you are developing drivers or trying to debug and
-         identify kernel problems.
-
 config MAGIC_SYSRQ
        bool "Magic SysRq key"
-       depends on DEBUG_KERNEL && !UML
+       depends on !UML
        help
          If you say Y here, you will have some control over the system even
          if the system crashes for example during kernel debugging (e.g., you
@@ -29,6 +23,12 @@ config MAGIC_SYSRQ
          keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
          unless you really know what this hack does.
 
+config DEBUG_KERNEL
+       bool "Kernel debugging"
+       help
+         Say Y here if you are developing drivers or trying to debug and
+         identify kernel problems.
+
 config LOG_BUF_SHIFT
        int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
        range 12 21
index dcd4be9bd4e56801ffe12d1f87a789b0b2a9b8d4..c8bb8cc899d70017111e9388990cc2d76f8b5844 100644 (file)
@@ -19,10 +19,11 @@ static void spin_bug(spinlock_t *lock, const char *msg)
        if (xchg(&print_once, 0)) {
                if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
                        owner = lock->owner;
-               printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
+               printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
                        msg, raw_smp_processor_id(),
                        current->comm, current->pid);
-               printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
+               printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, "
+                               ".owner_cpu: %d\n",
                        lock, lock->magic,
                        owner ? owner->comm : "<none>",
                        owner ? owner->pid : -1,
@@ -78,7 +79,8 @@ static void __spin_lock_debug(spinlock_t *lock)
                /* lockup suspected: */
                if (print_once) {
                        print_once = 0;
-                       printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
+                       printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, "
+                                       "%s/%d, %p\n",
                                raw_smp_processor_id(), current->comm,
                                current->pid, lock);
                        dump_stack();
@@ -120,8 +122,8 @@ static void rwlock_bug(rwlock_t *lock, const char *msg)
        static long print_once = 1;
 
        if (xchg(&print_once, 0)) {
-               printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
-                       raw_smp_processor_id(), current->comm,
+               printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n",
+                       msg, raw_smp_processor_id(), current->comm,
                        current->pid, lock);
                dump_stack();
 #ifdef CONFIG_SMP
@@ -149,7 +151,8 @@ static void __read_lock_debug(rwlock_t *lock)
                /* lockup suspected: */
                if (print_once) {
                        print_once = 0;
-                       printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
+                       printk(KERN_EMERG "BUG: read-lock lockup on CPU#%d, "
+                                       "%s/%d, %p\n",
                                raw_smp_processor_id(), current->comm,
                                current->pid, lock);
                        dump_stack();
@@ -221,7 +224,8 @@ static void __write_lock_debug(rwlock_t *lock)
                /* lockup suspected: */
                if (print_once) {
                        print_once = 0;
-                       printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
+                       printk(KERN_EMERG "BUG: write-lock lockup on CPU#%d, "
+                                       "%s/%d, %p\n",
                                raw_smp_processor_id(), current->comm,
                                current->pid, lock);
                        dump_stack();
index ad9a1bf4fc632056664eddb840fd13e947bdb8e8..1653dd9bb01a459aa6105e44b678928c52327c47 100644 (file)
@@ -255,6 +255,7 @@ int zlib_deflateInit2_(
 }
 
 /* ========================================================================= */
+#if 0
 int zlib_deflateSetDictionary(
        z_streamp strm,
        const Byte *dictionary,
@@ -297,6 +298,7 @@ int zlib_deflateSetDictionary(
     if (hash_head) hash_head = 0;  /* to make compiler happy */
     return Z_OK;
 }
+#endif  /*  0  */
 
 /* ========================================================================= */
 int zlib_deflateReset(
@@ -330,6 +332,7 @@ int zlib_deflateReset(
 }
 
 /* ========================================================================= */
+#if 0
 int zlib_deflateParams(
        z_streamp strm,
        int level,
@@ -365,6 +368,7 @@ int zlib_deflateParams(
     s->strategy = strategy;
     return err;
 }
+#endif  /*  0  */
 
 /* =========================================================================
  * Put a short in the pending buffer. The 16-bit value is put in MSB order.
@@ -572,6 +576,7 @@ int zlib_deflateEnd(
 /* =========================================================================
  * Copy the source state to the destination state.
  */
+#if 0
 int zlib_deflateCopy (
        z_streamp dest,
        z_streamp source
@@ -624,6 +629,7 @@ int zlib_deflateCopy (
     return Z_OK;
 #endif
 }
+#endif  /*  0  */
 
 /* ===========================================================================
  * Read a new buffer from the current input stream, update the adler32
index 5985b28c8e307b4e510d3433d50dcba7816d1b91..767b573d1ef66a931ff62eecd19cb9c91abb06c2 100644 (file)
@@ -16,6 +16,4 @@ EXPORT_SYMBOL(zlib_deflateInit_);
 EXPORT_SYMBOL(zlib_deflateInit2_);
 EXPORT_SYMBOL(zlib_deflateEnd);
 EXPORT_SYMBOL(zlib_deflateReset);
-EXPORT_SYMBOL(zlib_deflateCopy);
-EXPORT_SYMBOL(zlib_deflateParams);
 MODULE_LICENSE("GPL");
index 50f21ca4ef7fc4cd151ccdec038386b31d54c65b..c16cdeff51aa9342615f6343ba15f1f8abe6f31b 100644 (file)
@@ -338,6 +338,7 @@ int zlib_inflate_blocks_free(
 }
 
 
+#if 0
 void zlib_inflate_set_dictionary(
        inflate_blocks_statef *s,
        const Byte *d,
@@ -347,15 +348,18 @@ void zlib_inflate_set_dictionary(
   memcpy(s->window, d, n);
   s->read = s->write = s->window + n;
 }
+#endif  /*  0  */
 
 
 /* Returns true if inflate is currently at the end of a block generated
  * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
  * IN assertion: s != NULL
  */
+#if 0
 int zlib_inflate_blocks_sync_point(
        inflate_blocks_statef *s
 )
 {
   return s->mode == LENS;
 }
+#endif  /*  0  */
index f5221ddf605402aea510216b6a211eabdd7be0c1..ceee60b5107cd4ffa4abdd66037a886c2b521b43 100644 (file)
@@ -33,12 +33,16 @@ extern int zlib_inflate_blocks_free (
     inflate_blocks_statef *,
     z_streamp);
 
+#if 0
 extern void zlib_inflate_set_dictionary (
     inflate_blocks_statef *s,
     const Byte *d,  /* dictionary */
     uInt  n);       /* dictionary length */
+#endif  /*  0  */
 
+#if 0
 extern int zlib_inflate_blocks_sync_point (
     inflate_blocks_statef *s);
+#endif  /*  0  */
 
 #endif /* _INFBLOCK_H */
index aa1b081891219d84a27feb3b012021aeb306cf7a..ef49738f57eca196c012508994883c0bf24911f5 100644 (file)
@@ -15,8 +15,6 @@ EXPORT_SYMBOL(zlib_inflate);
 EXPORT_SYMBOL(zlib_inflateInit_);
 EXPORT_SYMBOL(zlib_inflateInit2_);
 EXPORT_SYMBOL(zlib_inflateEnd);
-EXPORT_SYMBOL(zlib_inflateSync);
 EXPORT_SYMBOL(zlib_inflateReset);
-EXPORT_SYMBOL(zlib_inflateSyncPoint);
 EXPORT_SYMBOL(zlib_inflateIncomp); 
 MODULE_LICENSE("GPL");
index e07bdb21f55cad6dafb4c6407bd1cd13723bffdc..61411ff89d6160da831df3ac73bbd2f551b75c8e 100644 (file)
@@ -7,6 +7,7 @@
 #include "infblock.h"
 #include "infutil.h"
 
+#if 0
 int zlib_inflateSync(
        z_streamp z
 )
@@ -57,6 +58,7 @@ int zlib_inflateSync(
   z->state->mode = BLOCKS;
   return Z_OK;
 }
+#endif  /*  0  */
 
 
 /* Returns true if inflate is currently at the end of a block generated
@@ -66,6 +68,7 @@ int zlib_inflateSync(
  * decompressing, PPP checks that at the end of input packet, inflate is
  * waiting for these length bytes.
  */
+#if 0
 int zlib_inflateSyncPoint(
        z_streamp z
 )
@@ -74,6 +77,7 @@ int zlib_inflateSyncPoint(
     return Z_STREAM_ERROR;
   return zlib_inflate_blocks_sync_point(z->state->blocks);
 }
+#endif  /*  0  */
 
 /*
  * This subroutine adds the data at next_in/avail_in to the output history
index 5fca2737c971085ca1748c184c26b936a07cd535..96de772be487b7c8e6df4e591bd2f3cf9b8647ab 100644 (file)
@@ -2108,7 +2108,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
        if (err)
                goto out;
 
-       inode_update_time(inode, 1);
+       file_update_time(file);
 
        /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
        if (unlikely(file->f_flags & O_DIRECT)) {
index e2b34e95913eac480e1067bc0288d96b457be282..b960ac8e5918dcb33e64b9b4f822f25540ddb4b4 100644 (file)
@@ -383,7 +383,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
        if (ret)
                goto out_backing;
 
-       inode_update_time(inode, 1);
+       file_update_time(filp);
 
        ret = __xip_file_write (filp, buf, count, pos, ppos);
 
index 158a9c46d863274e45fac67a9e594deaaa7667cc..f57cde78c3de1c705c52ee4a276772b6bfda0743 100644 (file)
@@ -480,13 +480,8 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
        BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
 
        if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-               register int i;
-               for (i = 0; i < skb->len; i++) {
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               tty_flip_buffer_push(tty);
-
-                       tty_insert_flip_char(tty, skb->data[i], 0);
-               }
+               tty_buffer_request_room(tty, skb->len);
+               tty_insert_flip_string(tty, skb->data, skb->len);
                tty_flip_buffer_push(tty);
        } else
                tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
index e1da81d261d1d98a6636da92383dd7e1320dad24..58adaf208dd63b1ae7e46a59757865bcf3b115ae 100644 (file)
@@ -16,6 +16,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
+#include <net/iw_handler.h>
 
 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
@@ -294,13 +295,19 @@ static ssize_t wireless_show(struct class_device *cd, char *buf,
                                               char *))
 {
        struct net_device *dev = to_net_dev(cd);
-       const struct iw_statistics *iw;
+       const struct iw_statistics *iw = NULL;
        ssize_t ret = -EINVAL;
        
        read_lock(&dev_base_lock);
-       if (dev_isalive(dev) && dev->get_wireless_stats 
-           && (iw = dev->get_wireless_stats(dev)) != NULL) 
-               ret = (*format)(iw, buf);
+       if (dev_isalive(dev)) {
+               if(dev->wireless_handlers &&
+                  dev->wireless_handlers->get_wireless_stats)
+                       iw = dev->wireless_handlers->get_wireless_stats(dev);
+               else if (dev->get_wireless_stats)
+                       iw = dev->get_wireless_stats(dev);
+               if (iw != NULL)
+                       ret = (*format)(iw, buf);
+       }
        read_unlock(&dev_base_lock);
 
        return ret;
@@ -402,7 +409,8 @@ void netdev_unregister_sysfs(struct net_device * net)
                sysfs_remove_group(&class_dev->kobj, &netstat_group);
 
 #ifdef WIRELESS_EXT
-       if (net->get_wireless_stats)
+       if (net->get_wireless_stats || (net->wireless_handlers &&
+                       net->wireless_handlers->get_wireless_stats))
                sysfs_remove_group(&class_dev->kobj, &wireless_group);
 #endif
        class_device_del(class_dev);
@@ -427,10 +435,12 @@ int netdev_register_sysfs(struct net_device *net)
                goto out_unreg; 
 
 #ifdef WIRELESS_EXT
-       if (net->get_wireless_stats &&
-           (ret = sysfs_create_group(&class_dev->kobj, &wireless_group)))
-               goto out_cleanup; 
-
+       if (net->get_wireless_stats || (net->wireless_handlers &&
+                       net->wireless_handlers->get_wireless_stats)) {
+               ret = sysfs_create_group(&class_dev->kobj, &wireless_group);
+               if (ret)
+                       goto out_cleanup;
+       }
        return 0;
 out_cleanup:
        if (net->get_stats)
index 5530ac8c6df959ef36a9f5592ebec9004968dd57..a44da8b3d24076383c97574f4bb27cb957f22eb8 100644 (file)
@@ -268,7 +268,8 @@ rpc_shutdown_client(struct rpc_clnt *clnt)
                clnt->cl_oneshot = 0;
                clnt->cl_dead = 0;
                rpc_killall_tasks(clnt);
-               sleep_on_timeout(&destroy_wait, 1*HZ);
+               wait_event_timeout(destroy_wait,
+                       atomic_read(&clnt->cl_users) > 0, 1*HZ);
        }
 
        if (atomic_read(&clnt->cl_users) < 0) {
index db3c708e546b81cfac87bd206998d87848252a70..0168d6c37075dd46b4b5bd090ac7c85fb153ce60 100644 (file)
@@ -3,6 +3,7 @@
 
 # Convinient variables
 comma   := ,
+squote  := '
 empty   :=
 space   := $(empty) $(empty)
 
@@ -11,6 +12,10 @@ space   := $(empty) $(empty)
 # contain a comma
 depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
 
+###
+# Escape single quote for use in echo statements
+escsq = $(subst $(squote),'\$(squote)',$1)
+
 ###
 # filechk is used to check if the content of a generated file is updated.
 # Sample usage:
@@ -47,7 +52,7 @@ build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
 
 # If quiet is set, only print short version of command
 cmd = @$(if $($(quiet)cmd_$(1)),\
-      echo '  $(subst ','\'',$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
+      echo '  $(call escsq,$($(quiet)cmd_$(1)))' &&) $(cmd_$(1))
 
 # Add $(obj)/ for paths that is not absolute
 objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
@@ -68,7 +73,7 @@ endif
 
 # echo command. Short version is $(quiet) equals quiet, otherwise full command
 echo-cmd = $(if $($(quiet)cmd_$(1)), \
-       echo '  $(subst ','\'',$($(quiet)cmd_$(1)))';)
+       echo '  $(call escsq,$($(quiet)cmd_$(1)))';)
 
 # function to only execute the passed command if necessary
 # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file
@@ -78,7 +83,7 @@ if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
        @set -e; \
        $(echo-cmd) \
        $(cmd_$(1)); \
-       echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
+       echo 'cmd_$@ := $(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
 
 # execute the command and also postprocess generated .d dependencies
 # file
@@ -87,7 +92,7 @@ if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
        @set -e; \
        $(echo-cmd) \
        $(cmd_$(1)); \
-       scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
+       scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
        rm -f $(depfile); \
        mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
 
index 506e3f3befe3104b35d2518fd42af7fb53048f67..c33e62bde6b0f6f6f67756eea2ec9ffa6abeee3b 100644 (file)
@@ -179,10 +179,10 @@ endif
 define rule_cc_o_c
        $(if $($(quiet)cmd_checksrc),echo '  $($(quiet)cmd_checksrc)';)   \
        $(cmd_checksrc)                                                   \
-       $(if $($(quiet)cmd_cc_o_c),echo '  $(subst ','\'',$($(quiet)cmd_cc_o_c))';)  \
+       $(if $($(quiet)cmd_cc_o_c),echo '  $(call escsq,$($(quiet)cmd_cc_o_c))';)  \
        $(cmd_cc_o_c);                                                    \
        $(cmd_modversions)                                                \
-       scripts/basic/fixdep $(depfile) $@ '$(subst ','\'',$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp;  \
+       scripts/basic/fixdep $(depfile) $@ '$(call escsq,$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp;  \
        rm -f $(depfile);                                                 \
        mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
 endef
index a45a13fb26ed7a58e41f5d716a374dc25de03b5f..8f41d9a57aaa89ab401d6b93920df74cf258a71a 100644 (file)
@@ -1,42 +1,18 @@
-HOST_EXTRACFLAGS := -DLOCALE 
-ifeq ($(shell uname),SunOS)
-HOST_LOADLIBES   := -lcurses
-else
-HOST_LOADLIBES   := -lncurses
-endif
+# Makefile to build lxdialog package
+#
 
-ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
-        HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
-else
-ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h))
-        HOST_EXTRACFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"
-else
-ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h))
-        HOST_EXTRACFLAGS += -DCURSES_LOC="<ncurses.h>"
-else
-       HOST_EXTRACFLAGS += -DCURSES_LOC="<curses.h>"
-endif
-endif
-endif
+check-lxdialog   := $(srctree)/$(src)/check-lxdialog.sh
+HOST_EXTRACFLAGS := $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
+HOST_LOADLIBES   := $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags)
+HOST_EXTRACFLAGS += -DLOCALE 
+
+.PHONY: dochecklxdialog
+$(obj)/dochecklxdialog:
+       $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES)
 
 hostprogs-y    := lxdialog
-always         := ncurses $(hostprogs-y)
+always         := $(hostprogs-y) dochecklxdialog
 
 lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \
                 util.o lxdialog.o msgbox.o
-
-.PHONY: $(obj)/ncurses
-$(obj)/ncurses:
-       @echo "main() {}" > lxtemp.c
-       @if $(HOSTCC) lxtemp.c  $(HOST_LOADLIBES); then \
-               rm -f lxtemp.c a.out; \
-       else \
-               rm -f lxtemp.c; \
-               echo -e "\007" ;\
-               echo ">> Unable to find the Ncurses libraries." ;\
-               echo ">>" ;\
-               echo ">> You must install ncurses-devel in order" ;\
-               echo ">> to use 'make menuconfig'" ;\
-               echo ;\
-               exit 1 ;\
-       fi
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
new file mode 100644 (file)
index 0000000..a3c141b
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh
+# Check ncurses compatibility
+
+# What library to link
+ldflags()
+{
+       if [ `uname` == SunOS ]; then
+               echo '-lcurses'
+       else
+               echo '-lncurses'
+       fi
+}
+
+# Where is ncurses.h?
+ccflags()
+{
+       if [ -f /usr/include/ncurses/ncurses.h ]; then
+               echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
+       elif [ -f /usr/include/ncurses/curses.h ]; then
+               echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
+       elif [ -f /usr/include/ncurses.h ]; then
+               echo '-DCURSES_LOC="<ncurses.h>"'
+       else
+               echo '-DCURSES_LOC="<curses.h>"'
+       fi
+}
+
+compiler=""
+# Check if we can link to ncurses
+check() {
+       echo "main() {}" | $compiler -xc -
+       if [ $? != 0 ]; then
+               echo " *** Unable to find the ncurses libraries."          1>&2
+               echo " *** make menuconfig require the ncurses libraries"  1>&2
+               echo " *** "                                               1>&2
+               echo " *** Install ncurses (ncurses-devel) and try again"  1>&2
+               echo " *** "                                               1>&2
+               exit 1
+       fi
+}
+
+usage() {
+       printf "Usage: $0 [-check compiler options|-header|-library]\n"
+}
+
+if [ $# == 0 ]; then
+       usage
+       exit 1
+fi
+
+case "$1" in
+       "-check")
+               shift
+               compiler="$@"
+               check
+               ;;
+       "-ccflags")
+               ccflags
+               ;;
+       "-ldflags")
+               ldflags
+               ;;
+       "*")
+               usage
+               exit 1
+               ;;
+esac
index 2f45fd2969d09080c37e3b1b150179714c886602..9fd5f5b87d1e47cc160ec86fe7cf8aff7c4c091d 100755 (executable)
@@ -1405,6 +1405,7 @@ sub create_parameterlist($$$) {
     my $type;
     my $param;
 
+    # temporarily replace commas inside function pointer definition
     while ($args =~ /(\([^\),]+),/) {
         $args =~ s/(\([^\),]+),/$1#/g;
     }
@@ -1465,11 +1466,10 @@ sub push_parameter($$$) {
        my $param_name = $param;
        $param_name =~ s/\[.*//;
 
-       if ($type eq "" && $param eq "...")
+       if ($type eq "" && $param =~ /\.\.\.$/)
        {
            $type="";
-           $param="...";
-           $parameterdescs{"..."} = "variable arguments";
+           $parameterdescs{$param} = "variable arguments";
        }
        elsif ($type eq "" && ($param eq "" or $param eq "void"))
        {
@@ -1477,7 +1477,11 @@ sub push_parameter($$$) {
            $param="void";
            $parameterdescs{void} = "no arguments";
        }
-       if (defined $type && $type && !defined $parameterdescs{$param_name}) {
+       # warn if parameter has no description
+       # (but ignore ones starting with # as these are no parameters
+       # but inline preprocessor statements
+       if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
+
            $parameterdescs{$param_name} = $undescribed;
 
            if (($type eq 'function') || ($type eq 'enum')) {
index e0eedffe565b4ed8a75c3a91002b7c31a8d63254..be97caf664bbf47bc6e7ff5e98cf5f6b297f2e62 100644 (file)
@@ -417,7 +417,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
                do_input(alias, id->sndbit, 0, SND_MAX);
        sprintf(alias + strlen(alias), "f*");
        if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT)
-               do_input(alias, id->ffbit, 0, SND_MAX);
+               do_input(alias, id->ffbit, 0, FF_MAX);
        sprintf(alias + strlen(alias), "w*");
        if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT)
                do_input(alias, id->swbit, 0, SW_MAX);
index c2d54148a91f403eb74b8b81f53a117d7100ef70..4ee6ab2135b30dc0678719f758868d7a2a220e62 100644 (file)
@@ -71,6 +71,11 @@ foreach $object (keys(%object)) {
 # printf("ignoring %d conglomerate(s)\n", $ignore);
 
 # printf("Scanning objects\n");
+
+# Keith Ownes <kaos@sgi.com> commented:
+# For our future {in}sanity, add a comment that this is the ppc .opd
+# section, not the ia64 .opd section.
+# ia64 .opd should not point to discarded sections.
 $errorcount = 0;
 foreach $object (keys(%object)) {
        my $from;
@@ -88,6 +93,7 @@ foreach $object (keys(%object)) {
                    ($from !~ /\.text\.exit$/ &&
                     $from !~ /\.exit\.text$/ &&
                     $from !~ /\.data\.exit$/ &&
+                    $from !~ /\.opd$/ &&
                     $from !~ /\.exit\.data$/ &&
                     $from !~ /\.altinstructions$/ &&
                     $from !~ /\.pdr$/ &&
index f54dac88cfd1d86b2cbcf7e35e8b3880f9fcfce0..9a23825218f20135eadd4b348e45de2b21a3d421 100644 (file)
@@ -17,6 +17,6 @@ if head=`git rev-parse --verify HEAD 2>/dev/null`; then
 
        # Are there uncommitted changes?
        if git diff-files | read dummy; then
-               printf '%s' -git_dirty
+               printf '%s' -dirty
        fi
 fi
index 44eb4d74908d196beafdda585590c80efb245503..8a764928ff4be967d49709121991f4691c0f21e1 100644 (file)
@@ -1712,11 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
                goto out;
        }
 
-       *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC);
+       *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC);
        if (!*names)
                goto err;
 
-       *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC);
+       *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
        if (!*values)
                goto err;
 
@@ -1724,7 +1724,7 @@ int security_get_bools(int *len, char ***names, int **values)
                size_t name_len;
                (*values)[i] = policydb.bool_val_to_struct[i]->state;
                name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
-               (*names)[i] = (char*)kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
+               (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
                if (!(*names)[i])
                        goto err;
                strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
index 202c7cf3e3282774937f577e355600fa6a0f3e67..f36ede827479aab96a7dd96ac6a31855bec1e630 100644 (file)
@@ -385,7 +385,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_cs5535audio_init(void)
 {
-       return pci_module_init(&driver);
+       return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_cs5535audio_exit(void)