summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2003-05-27 04:55:14 +1000
committerPaul Mackerras <paulus@samba.org>2003-05-27 04:55:14 +1000
commit927bc10f742f603ced09dae59c94be4c70b5e949 (patch)
tree1c55e3fcb149050f4a4b81144515d47f276730f5
parent95c39f479c9ff6e36348ffd99c71dde12e6bcf32 (diff)
parentdc2f9764e8784817355504b5a78bed08578e2d46 (diff)
Merge samba.org:/stuff/paulus/kernel/linux-2.5
into samba.org:/stuff/paulus/kernel/for-linus-ppc
-rw-r--r--CREDITS11
-rw-r--r--Documentation/Changes2
-rw-r--r--Documentation/iostats.txt148
-rw-r--r--Documentation/networking/generic-hdlc.txt6
-rw-r--r--Documentation/sysctl/vm.txt15
-rw-r--r--Documentation/vm/overcommit-accounting4
-rw-r--r--Makefile4
-rw-r--r--arch/alpha/mm/init.c2
-rw-r--r--arch/i386/kernel/apic.c2
-rw-r--r--arch/i386/kernel/apm.c19
-rw-r--r--arch/i386/kernel/mpparse.c4
-rw-r--r--arch/i386/kernel/srat.c3
-rw-r--r--arch/i386/mach-generic/bigsmp.c1
-rw-r--r--arch/i386/mach-generic/default.c1
-rw-r--r--arch/i386/mach-generic/summit.c1
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/m68k/amiga/amiints.c23
-rw-r--r--arch/m68k/amiga/cia.c5
-rw-r--r--arch/m68k/amiga/config.c8
-rw-r--r--arch/m68k/apollo/config.c15
-rw-r--r--arch/m68k/apollo/dn_ints.c13
-rw-r--r--arch/m68k/atari/ataints.c7
-rw-r--r--arch/m68k/atari/config.c4
-rw-r--r--arch/m68k/atari/stdma.c12
-rw-r--r--arch/m68k/atari/time.c2
-rw-r--r--arch/m68k/bvme6000/bvmeints.c18
-rw-r--r--arch/m68k/bvme6000/config.c17
-rw-r--r--arch/m68k/hp300/config.c2
-rw-r--r--arch/m68k/hp300/ints.c7
-rw-r--r--arch/m68k/hp300/ints.h2
-rw-r--r--arch/m68k/hp300/time.c8
-rw-r--r--arch/m68k/hp300/time.h2
-rw-r--r--arch/m68k/kernel/ints.c10
-rw-r--r--arch/m68k/kernel/ptrace.c11
-rw-r--r--arch/m68k/kernel/setup.c6
-rw-r--r--arch/m68k/kernel/sys_m68k.c6
-rw-r--r--arch/m68k/kernel/time.c3
-rw-r--r--arch/m68k/mac/baboon.c8
-rw-r--r--arch/m68k/mac/config.c8
-rw-r--r--arch/m68k/mac/iop.c6
-rw-r--r--arch/m68k/mac/macints.c15
-rw-r--r--arch/m68k/mac/oss.c20
-rw-r--r--arch/m68k/mac/psc.c8
-rw-r--r--arch/m68k/mac/via.c30
-rw-r--r--arch/m68k/mm/init.c2
-rw-r--r--arch/m68k/mvme147/147ints.c18
-rw-r--r--arch/m68k/mvme147/config.c14
-rw-r--r--arch/m68k/mvme16x/16xints.c18
-rw-r--r--arch/m68k/mvme16x/config.c17
-rw-r--r--arch/m68k/q40/config.c8
-rw-r--r--arch/m68k/q40/q40ints.c40
-rw-r--r--arch/m68k/sun3/config.c4
-rw-r--r--arch/m68k/sun3/sun3ints.c27
-rw-r--r--arch/m68k/sun3x/time.c2
-rw-r--r--arch/m68k/sun3x/time.h2
-rw-r--r--arch/mips/mm/init.c2
-rw-r--r--arch/mips64/mm/init.c2
-rw-r--r--arch/parisc/kernel/ioctl32.c1
-rw-r--r--arch/parisc/mm/init.c2
-rw-r--r--arch/ppc/mm/init.c2
-rw-r--r--arch/ppc64/boot/addnote.c1
-rw-r--r--arch/ppc64/kernel/align.c2
-rw-r--r--arch/ppc64/kernel/ioctl32.c2
-rw-r--r--arch/ppc64/kernel/misc.S10
-rw-r--r--arch/ppc64/kernel/prom.c5
-rw-r--r--arch/ppc64/kernel/setup.c4
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c94
-rw-r--r--arch/ppc64/kernel/traps.c5
-rw-r--r--arch/ppc64/kernel/xics.c5
-rw-r--r--arch/ppc64/mm/init.c2
-rw-r--r--arch/s390/mm/init.c2
-rw-r--r--arch/sh/mm/init.c2
-rw-r--r--arch/sparc/mm/init.c2
-rw-r--r--arch/sparc64/kernel/ioctl32.c1
-rw-r--r--arch/sparc64/mm/init.c2
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/x86_64/ia32/ia32_ioctl.c1
-rw-r--r--arch/x86_64/mm/init.c2
-rw-r--r--drivers/acorn/block/fd1772.c2
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/bus.c4
-rw-r--r--drivers/base/class.c4
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/map.c154
-rw-r--r--drivers/block/acsi.c5
-rw-r--r--drivers/block/acsi_slm.c5
-rw-r--r--drivers/block/amiflop.c8
-rw-r--r--drivers/block/ataflop.c17
-rw-r--r--drivers/block/cpqarray.c110
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/floppy98.c2
-rw-r--r--drivers/block/genhd.c122
-rw-r--r--drivers/block/paride/pg.c618
-rw-r--r--drivers/block/paride/pt.c1043
-rw-r--r--drivers/block/rd.c19
-rw-r--r--drivers/block/z2ram.c2
-rw-r--r--drivers/char/amiserial.c13
-rw-r--r--drivers/char/ser_a2232.c5
-rw-r--r--drivers/char/serial167.c22
-rw-r--r--drivers/char/tty_io.c210
-rw-r--r--drivers/char/vme_scc.c28
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/legacy/q40ide.c93
-rw-r--r--drivers/ide/pci/hpt366.c1
-rw-r--r--drivers/input/joystick/amijoy.c3
-rw-r--r--drivers/input/keyboard/amikbd.c16
-rw-r--r--drivers/input/mouse/amimouse.c4
-rw-r--r--drivers/macintosh/via-macii.c9
-rw-r--r--drivers/macintosh/via-maciisi.c7
-rw-r--r--drivers/macintosh/via-pmu68k.c5
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/media/video/bttv-cards.c2
-rw-r--r--drivers/media/video/cpia.c10
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c14
-rw-r--r--drivers/mtd/nftlcore.c2
-rw-r--r--drivers/net/82596.c7
-rw-r--r--drivers/net/apne.c9
-rw-r--r--drivers/net/atari_bionet.c4
-rw-r--r--drivers/net/atari_pamsnet.c6
-rw-r--r--drivers/net/ewrk3.c5
-rw-r--r--drivers/net/macmace.c12
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c7
-rw-r--r--drivers/net/sun3lance.c10
-rw-r--r--drivers/net/tulip/interrupt.c4
-rw-r--r--drivers/parport/parport_amiga.c3
-rw-r--r--drivers/parport/parport_atari.c3
-rw-r--r--drivers/parport/parport_mfc3.c3
-rw-r--r--drivers/pnp/isapnp/core.c7
-rw-r--r--drivers/pnp/quirks.c7
-rw-r--r--drivers/scsi/53c7xx.c12
-rw-r--r--drivers/scsi/a2091.c18
-rw-r--r--drivers/scsi/a3000.c23
-rw-r--r--drivers/scsi/atari_NCR5380.c6
-rw-r--r--drivers/scsi/atari_dma_emul.c8
-rw-r--r--drivers/scsi/atari_scsi.c10
-rw-r--r--drivers/scsi/gvp11.c17
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/mac_NCR5380.c4
-rw-r--r--drivers/scsi/mac_esp.c3
-rw-r--r--drivers/scsi/mvme147.c15
-rw-r--r--drivers/scsi/sun3_NCR5380.c6
-rw-r--r--drivers/scsi/sun3_scsi.c12
-rw-r--r--drivers/scsi/sun3_scsi_vme.c12
-rw-r--r--drivers/video/amifb.c81
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c16
-rw-r--r--drivers/video/console/fbcon.c1
-rw-r--r--fs/Kconfig22
-rw-r--r--fs/Makefile4
-rw-r--r--fs/adfs/super.c2
-rw-r--r--fs/affs/super.c2
-rw-r--r--fs/afs/kafstimod.c2
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/befs/linuxvfs.c2
-rw-r--r--fs/bfs/inode.c2
-rw-r--r--fs/char_dev.c386
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/coda/inode.c2
-rw-r--r--fs/compat.c1
-rw-r--r--fs/dcache.c9
-rw-r--r--fs/devpts/Makefile8
-rw-r--r--fs/devpts/inode.c15
-rw-r--r--fs/devpts/xattr.c214
-rw-r--r--fs/devpts/xattr.h59
-rw-r--r--fs/devpts/xattr_security.c42
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/exec.c38
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext3/super.c2
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/file_table.c4
-rw-r--r--fs/freevxfs/vxfs_super.c3
-rw-r--r--fs/fs-writeback.c3
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/inode.c58
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/jffs/inode-v23.c6
-rw-r--r--fs/jffs2/malloc.c3
-rw-r--r--fs/jffs2/super.c2
-rw-r--r--fs/jfs/super.c4
-rw-r--r--fs/mbcache.c2
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/nfs4xdr.c2
-rw-r--r--fs/ntfs/super.c6
-rw-r--r--fs/proc/base.c319
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/proc_misc.c1
-rw-r--r--fs/proc/root.c2
-rw-r--r--fs/qnx4/inode.c2
-rw-r--r--fs/readdir.c23
-rw-r--r--fs/reiserfs/dir.c1
-rw-r--r--fs/reiserfs/inode.c73
-rw-r--r--fs/reiserfs/ioctl.c62
-rw-r--r--fs/reiserfs/procfs.c6
-rw-r--r--fs/reiserfs/super.c24
-rw-r--r--fs/romfs/inode.c2
-rw-r--r--fs/smbfs/inode.c2
-rw-r--r--fs/sysv/inode.c3
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/ufs/super.c2
-rw-r--r--fs/xfs/linux/xfs_super.c3
-rw-r--r--include/acpi/actypes.h14
-rw-r--r--include/asm-arm/tlb.h4
-rw-r--r--include/asm-generic/tlb.h4
-rw-r--r--include/asm-i386/mach-bigsmp/mach_apic.h13
-rw-r--r--include/asm-i386/mach-bigsmp/mach_apicdef.h13
-rw-r--r--include/asm-i386/mach-default/mach_apic.h11
-rw-r--r--include/asm-i386/mach-default/mach_apicdef.h13
-rw-r--r--include/asm-i386/mach-numaq/mach_apic.h9
-rw-r--r--include/asm-i386/mach-numaq/mach_apicdef.h14
-rw-r--r--include/asm-i386/mach-summit/mach_apic.h13
-rw-r--r--include/asm-i386/mach-summit/mach_apicdef.h13
-rw-r--r--include/asm-i386/mach-visws/mach_apic.h8
-rw-r--r--include/asm-i386/mach-visws/mach_apicdef.h12
-rw-r--r--include/asm-i386/smp.h2
-rw-r--r--include/asm-m68k/atari_stdma.h3
-rw-r--r--include/asm-m68k/hdreg.h2
-rw-r--r--include/asm-m68k/ide.h119
-rw-r--r--include/asm-m68k/io.h32
-rw-r--r--include/asm-m68k/irq.h7
-rw-r--r--include/asm-m68k/machdep.h9
-rw-r--r--include/asm-m68k/macintosh.h3
-rw-r--r--include/asm-m68k/motorola_pgtable.h22
-rw-r--r--include/asm-m68k/pgtable.h19
-rw-r--r--include/asm-m68k/raw_io.h472
-rw-r--r--include/asm-m68k/sun3_pgtable.h6
-rw-r--r--include/asm-m68k/sun3ints.h8
-rw-r--r--include/asm-ppc/linux_logo.h24
-rw-r--r--include/asm-ppc64/compat.h1
-rw-r--r--include/asm-ppc64/pgtable.h9
-rw-r--r--include/asm-ppc64/signal.h3
-rw-r--r--include/linux/aio.h3
-rw-r--r--include/linux/cdev.h29
-rw-r--r--include/linux/eventpoll.h9
-rw-r--r--include/linux/fs.h9
-rw-r--r--include/linux/futex.h11
-rw-r--r--include/linux/genhd.h4
-rw-r--r--include/linux/hugetlb.h6
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/kobj_map.h12
-rw-r--r--include/linux/proc_fs.h2
-rw-r--r--include/linux/reiserfs_fs.h43
-rw-r--r--include/linux/reiserfs_fs_i.h3
-rw-r--r--include/linux/reiserfs_fs_sb.h5
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/linux/security.h89
-rw-r--r--include/linux/slab.h2
-rw-r--r--include/linux/string.h3
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/tty_driver.h2
-rw-r--r--include/net/sock.h2
-rw-r--r--init/Kconfig27
-rw-r--r--init/do_mounts_rd.c4
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/compat.c11
-rw-r--r--kernel/exit.c40
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/futex.c156
-rw-r--r--kernel/signal.c8
-rw-r--r--kernel/sys.c5
-rw-r--r--lib/string.c27
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/mmap.c23
-rw-r--r--mm/shmem.c2
-rw-r--r--mm/slab.c18
-rw-r--r--net/rxrpc/krxtimod.c2
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/sunrpc/sunrpc_syms.c2
-rw-r--r--security/dummy.c34
-rw-r--r--sound/Makefile1
-rw-r--r--sound/core/sgbuf.c1
-rw-r--r--sound/oss/cs46xx.c6
-rw-r--r--sound/oss/dmasound/dmasound.h120
-rw-r--r--sound/oss/dmasound/dmasound_atari.c2
-rw-r--r--sound/oss/dmasound/dmasound_core.c2
-rw-r--r--sound/oss/dmasound/dmasound_paula.c1
-rw-r--r--sound/oss/dmasound/dmasound_q40.c3
284 files changed, 4493 insertions, 2314 deletions
diff --git a/CREDITS b/CREDITS
index 6c28b5c72e1a..b933ee8b90ca 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2966,12 +2966,11 @@ S: Cliffwood, New Jersey 07721
S: USA
N: Manfred Spraul
-E: manfreds@colorfullife.com
-W: http://colorfullife.com/~manfreds
-D: major SysV IPC changes
-D: various bug fixes (mostly SMP code)
-S: Warburgring 67
-S: 66424 Homburg
+E: manfred@colorfullife.com
+W: http://www.colorfullife.com/~manfred
+D: Lots of tiny hacks. Larger improvments to SysV IPC msg,
+D: slab, pipe, select.
+S: 71701 Schwieberdingen
S: Germany
N: Andrew Stanley-Jones
diff --git a/Documentation/Changes b/Documentation/Changes
index d62f1be5365e..b90076cd5737 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -83,8 +83,6 @@ almost certainly bugs (mainly, but not exclusively, in the kernel) that
will need to be fixed in order to use these compilers. In any case, using
pgcc instead of plain gcc is just asking for trouble.
-gcc 2.91.66 (egcs-1.1.2) continues to be supported for SPARC64 requirements.
-
The Red Hat gcc 2.96 compiler subtree can also be used to build this tree.
You should ensure you use gcc-2.96-74 or later. gcc-2.96-54 will not build
the kernel correctly.
diff --git a/Documentation/iostats.txt b/Documentation/iostats.txt
new file mode 100644
index 000000000000..b711aa4e6bad
--- /dev/null
+++ b/Documentation/iostats.txt
@@ -0,0 +1,148 @@
+I/O statistics fields
+---------------
+
+Last modified 5/15/03
+
+In 2.4.20 (and some versions before, with patches), and 2.5.45,
+more extensive disk statistics were introduced to help measure disk
+activity. Tools such as sar and iostat typically interpret these and do
+the work for you, but in case you are interested in creating your own
+tools, the fields are explained here.
+
+In most versions of the 2.4 patch, the information is found as additional
+fields in /proc/partitions. In 2.5, the same information is found in
+two places: one is in the file /proc/diskstats (appears in 2.5.69 and
+beyond), and the other is within the sysfs file system, which must be
+mounted in order to obtain the information. Throughout this document
+we'll assume that sysfs is mounted on /sys, although of course it may
+be mounted anywhere. In 2.5, both /proc/diskstats and sysfs use the
+same source for the information and so should not differ.
+
+Here are examples of these different formats:
+
+2.4:
+ 3 0 39082680 hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
+ 3 1 9221278 hda1 35486 0 35496 38030 0 0 0 0 0 38030 38030
+
+
+2.5 sysfs:
+ 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
+ 35486 38030 38030 38030
+
+2.5 diskstats:
+ 3 0 hda 446216 784926 9550688 4382310 424847 312726 5922052 19310380 0 3376340 23705160
+ 3 1 hda1 35486 38030 38030 38030
+
+On 2.4 you might execute "grep 'hda ' /proc/partitions". On 2.5, you have
+a choice of "cat /sys/block/hda/stat" or "grep 'hda ' /proc/diskstats".
+The advantage of one over the other is that the sysfs choice works well
+if you are watching a known, small set of disks. /proc/diskstats may
+be a better choice if you are watching a large number of disks because
+you'll avoid the overhead of 50, 100, or 500 or more opens/closes with
+each snapshot of your disk statistics.
+
+In 2.4, the statistics fields are those after the device name. In
+the above example, the first field of statistics would be 446216.
+By contrast, in 2.5 if you look at /sys/block/hda/stat, you'll
+find just the eleven fields, beginning with 446216. If you look at
+/proc/diskstats, the eleven fields will be preceded by the major and
+minor device numbers, and device name. Each of these formats provide
+eleven fields of statistics, each meaning exactly the same things.
+All fields except field 9 are cumulative since boot. Field 9 should
+go to zero as I/Os complete; all others only increase. Yes, these are
+32 bit unsigned numbers, and on a very busy or long-lived system they
+may wrap. Applications should be prepared to deal with that; unless
+your observations are measured in large numbers of minutes or hours,
+they should not wrap twice before you notice them.
+
+Each set of stats only applies to the indicated device; if you want
+system-wide stats you'll have to find all the devices and sum them all up.
+
+Field 1 -- # of reads issued
+ This is the total number of reads completed successfully.
+Field 2 -- # of reads merged, field 6 -- # of writes merged
+ Reads and writes which are adjacent to each other may be merged for
+ efficiency. Thus two 4K reads may become one 8K read before it is
+ ultimately handed to the disk, and so it will be counted (and queued)
+ as only one I/O. This field lets you know how often this was done.
+Field 3 -- # of sectors read
+ This is the total number of sectors read successfully.
+Field 4 -- # of milliseconds spent reading
+ This is the total number of milliseconds spent by all reads (as
+ measured from __make_request() to end_that_request_last()).
+Field 5 -- # of writes completed
+ This is the total number of writes completed successfully.
+Field 7 -- # of sectors written
+ This is the total number of sectors written successfully.
+Field 8 -- # of milliseconds spent writing
+ This is the total number of milliseconds spent by all writes (as
+ measured from __make_request() to end_that_request_last()).
+Field 9 -- # of I/Os currently in progress
+ The only field that should go to zero. Incremented as requests are
+ given to appropriate request_queue_t and decremented as they finish.
+Field 10 -- # of milliseconds spent doing I/Os
+ This field is increases so long as field 9 is nonzero.
+Field 11 -- weighted # of milliseconds spent doing I/Os
+ This field is incremented at each I/O start, I/O completion, I/O
+ merge, or read of these stats by the number of I/Os in progress
+ (field 9) times the number of milliseconds spent doing I/O since the
+ last update of this field. This can provide an easy measure of both
+ I/O completion time and the backlog that may be accumulating.
+
+
+To avoid introducing performance bottlenecks, no locks are held while
+modifying these counters. This implies that minor inaccuracies may be
+introduced when changes collide, so (for instance) adding up all the
+read I/Os issued per partition should equal those made to the disks
+... but due to the lack of locking it may only be very close.
+
+In release 2.5.65 the 2.5 counters were made per-cpu, which made the lack
+of locking almost a non-issue. When the statistics are read, the per-cpu
+counters are summed (possibly overflowing the unsigned 32-bit variable
+they are summed to) and the result given to the user. There is no
+convenient user interface for accessing the per-cpu counters themselves.
+
+Disks vs Partitions
+-------------------
+
+There were significant changes between 2.4 and 2.5 in the I/O subsystem.
+As a result, some statistic information disappeared. The translation from
+a disk address relative to a partition to the disk address relative to
+the host disk happens much earlier. All merges and timings now happen
+at the disk level rather than at both the disk and partition level as
+in 2.4. Consequently, you'll see a different statistics output on 2.5 for
+partitions from that for disks. There are only *four* fields available
+for partitions on 2.5 machines. This is reflected in the examples above.
+
+Field 1 -- # of reads issued
+ This is the total number of reads issued to this partition.
+Field 2 -- # of sectors read
+ This is the total number of sectors requested to be read from this
+ partition.
+Field 3 -- # of reads issued
+ This is the total number of writes issued to this partition.
+Field 4 -- # of sectors read
+ This is the total number of sectors requested to be written to
+ this partition.
+
+Note that since the address is translated to a disk-relative one, and no
+record of the partition-relative address is kept, the subsequent success
+or failure of the read cannot be attributed to the partition. In other
+words, the number of reads for partitions is counted slightly before time
+of queuing for partitions, and at completion for whole disks. This is
+a subtle distinction that is probably uninteresting for most cases.
+
+Additional notes
+----------------
+
+In 2.5, sysfs is not mounted by default. Here's the line you'll want
+to add to your /etc/fstab:
+
+none /sys sysfs defaults 0 0
+
+
+In 2.5, at the same time that disk statistics appeared in sysfs, they were
+removed from /proc/stat. In 2.4, they appear in both /proc/partitions
+and /proc/stat.
+
+-- ricklind@us.ibm.com
diff --git a/Documentation/networking/generic-hdlc.txt b/Documentation/networking/generic-hdlc.txt
index 25dd993e0d3f..7d1dc6b884f3 100644
--- a/Documentation/networking/generic-hdlc.txt
+++ b/Documentation/networking/generic-hdlc.txt
@@ -38,8 +38,10 @@ Usually you want something like:
sethdlc hdlc0 cisco interval 10 timeout 25
or
sethdlc hdlc0 rs232 clock ext
- sethdlc fr lmi ansi
- sethdlc create 99
+ sethdlc hdlc0 fr lmi ansi
+ sethdlc hdlc0 create 99
+ ifconfig hdlc0 up
+ ifconfig pvc0 localIP pointopoint remoteIP
In Frame Relay mode, ifconfig master hdlc device up (without assigning
any IP address to it) before using pvc devices.
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index e6f8c613c879..df64c2899046 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -35,17 +35,20 @@ See Documentation/filesystems/proc.txt
overcommit_memory:
This value contains a flag that enables memory overcommitment.
-When this flag is 0, the kernel checks before each malloc()
-to see if there's enough memory left. If the flag is nonzero,
-the system pretends there's always enough memory.
+
+When this flag is 0, the kernel attempts to estimate the amount
+of free memory left when userspace requests more memory.
+
+When this flag is 1, the kernel pretends there is always enough
+memory until it actually runs out.
+
+When this flag is 2, the kernel uses a "strict overcommit"
+policy that attempts to prevent any overcommit of memory.
This feature can be very useful because there are a lot of
programs that malloc() huge amounts of memory "just-in-case"
and don't use much of it.
-A value of 2 introduces a new "strict overcommit" policy
-that attempts to prevent any overcommit of memory.
-
The default value is 0.
See Documentation/vm/overcommit-accounting and
diff --git a/Documentation/vm/overcommit-accounting b/Documentation/vm/overcommit-accounting
index b39221feaceb..e0fd0b8f037a 100644
--- a/Documentation/vm/overcommit-accounting
+++ b/Documentation/vm/overcommit-accounting
@@ -3,7 +3,9 @@ The Linux kernel supports three overcommit handling modes
0 - Heuristic overcommit handling. Obvious overcommits of
address space are refused. Used for a typical system. It
ensures a seriously wild allocation fails while allowing
- overcommit to reduce swap usage. This is the default.
+ overcommit to reduce swap usage. root is allowed to
+ allocate slighly more memory in this mode. This is the
+ default.
1 - No overcommit handling. Appropriate for some scientific
applications.
diff --git a/Makefile b/Makefile
index dd6caeb1a57d..6ebd875b0f3e 100644
--- a/Makefile
+++ b/Makefile
@@ -107,7 +107,7 @@ export KBUILD_MODULES KBUILD_BUILTIN KBUILD_VERBOSE KBUILD_CHECKSRC
# If it is set to "silent_", nothing wil be printed at all, since
# the variable $(silent_cmd_cc_o_c) doesn't exist.
-# For now, leave verbose as default
+# To put more focus on warnings, less verbose as default
ifdef V
ifeq ("$(origin V)", "command line")
@@ -115,7 +115,7 @@ ifdef V
endif
endif
ifndef KBUILD_VERBOSE
- KBUILD_VERBOSE = 1
+ KBUILD_VERBOSE = 0
endif
ifdef C
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index d310bcc70d54..e797ec2040ca 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -34,7 +34,7 @@
#include <asm/console.h>
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
extern void die_if_kernel(char *,struct pt_regs *,long);
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index a07a0c9cc7ed..065b097b584a 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -291,6 +291,8 @@ void __init init_bsp_APIC(void)
value = apic_read(APIC_SPIV);
value &= ~APIC_VECTOR_MASK;
value |= APIC_SPIV_APIC_ENABLED;
+
+ /* This bit is reserved on P4/Xeon and should be cleared */
if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 15))
value &= ~APIC_SPIV_FOCUS_DISABLED;
else
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 130787b49ef2..172f3f9a603d 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -512,9 +512,8 @@ static unsigned long apm_save_cpus(void)
{
unsigned long x = current->cpus_allowed;
/* Some bioses don't like being called from CPU != 0 */
- set_cpus_allowed(current, 1 << 0);
- if (unlikely(smp_processor_id() != 0))
- BUG();
+ set_cpus_allowed(current, 1UL << 0);
+ BUG_ON(smp_processor_id() != 0);
return x;
}
@@ -914,11 +913,8 @@ static void apm_power_off(void)
*/
#ifdef CONFIG_SMP
/* Some bioses don't like being called from CPU != 0 */
- if (smp_processor_id() != 0) {
- set_cpus_allowed(current, 1 << 0);
- if (unlikely(smp_processor_id() != 0))
- BUG();
- }
+ set_cpus_allowed(current, 1UL << 0);
+ BUG_ON(smp_processor_id() != 0);
#endif
if (apm_info.realmode_power_off)
{
@@ -1708,11 +1704,8 @@ static int apm(void *unused)
* Some bioses don't like being called from CPU != 0.
* Method suggested by Ingo Molnar.
*/
- if (smp_processor_id() != 0) {
- set_cpus_allowed(current, 1 << 0);
- if (unlikely(smp_processor_id() != 0))
- BUG();
- }
+ set_cpus_allowed(current, 1UL << 0);
+ BUG_ON(smp_processor_id() != 0);
#endif
if (apm_info.connection_version == 0) {
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 5e0276d43425..88e9ad4409df 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -171,7 +171,7 @@ void __init MP_processor_info (struct mpc_config_processor *m)
num_processors++;
- if (m->mpc_apicid > MAX_APICS) {
+ if (MAX_APICS - m->mpc_apicid <= 0) {
printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS);
--num_processors;
@@ -803,7 +803,7 @@ void __init mp_register_lapic (
struct mpc_config_processor processor;
int boot_cpu = 0;
- if (id >= MAX_APICS) {
+ if (MAX_APICS - id <= 0) {
printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
id, MAX_APICS);
return;
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 6b3a04248a65..10906732862b 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -312,7 +312,8 @@ void __init get_memcfg_from_srat(void)
if (rsdp_address->pointer_type == ACPI_PHYSICAL_POINTER) {
printk("%s: assigning address to rsdp\n", __FUNCTION__);
- rsdp = (struct acpi_table_rsdp *)rsdp_address->pointer.physical;
+ rsdp = (struct acpi_table_rsdp *)
+ (u32)rsdp_address->pointer.physical;
} else {
printk("%s: rsdp_address is not a physical pointer\n", __FUNCTION__);
return;
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c
index 13951aa60c18..59aa05f8ddc8 100644
--- a/arch/i386/mach-generic/bigsmp.c
+++ b/arch/i386/mach-generic/bigsmp.c
@@ -10,6 +10,7 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <asm/mach-bigsmp/mach_apic.h>
+#include <asm/mach-bigsmp/mach_apicdef.h>
#include <asm/mach-bigsmp/mach_ipi.h>
#include <asm/mach-default/mach_mpparse.h>
diff --git a/arch/i386/mach-generic/default.c b/arch/i386/mach-generic/default.c
index 01093057f8d2..013ea644ffda 100644
--- a/arch/i386/mach-generic/default.c
+++ b/arch/i386/mach-generic/default.c
@@ -10,6 +10,7 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <asm/mach-default/mach_apic.h>
+#include <asm/mach-default/mach_apicdef.h>
#include <asm/mach-default/mach_ipi.h>
#include <asm/mach-default/mach_mpparse.h>
diff --git a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c
index d4f573c67219..4176c5433893 100644
--- a/arch/i386/mach-generic/summit.c
+++ b/arch/i386/mach-generic/summit.c
@@ -10,6 +10,7 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <asm/mach-summit/mach_apic.h>
+#include <asm/mach-summit/mach_apicdef.h>
#include <asm/mach-summit/mach_ipi.h>
#include <asm/mach-summit/mach_mpparse.h>
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index c6516fcab692..d1ac5318f2d7 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -41,7 +41,7 @@
#include <asm/tlbflush.h>
#include <asm/sections.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn;
static int do_test_wp_bit(void);
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 160e3fd53834..582bacabf2a9 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -51,7 +51,7 @@
#include <asm/amipcmcia.h>
extern int cia_request_irq(struct ciabase *base,int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id);
extern void cia_init_IRQ(struct ciabase *base);
@@ -70,9 +70,10 @@ static const unsigned char ami_servers[AMI_STD_IRQS] = {
static short ami_ablecount[AMI_IRQS];
-static void ami_badint(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp)
{
num_spurious += 1;
+ return IRQ_NONE;
}
/*
@@ -183,7 +184,7 @@ static inline void amiga_delete_irq(irq_node_t **list, void *dev_id)
*/
int amiga_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
irq_node_t *node;
@@ -368,7 +369,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp)
* The builtin Amiga hardware interrupt handlers.
*/
-static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp)
{
unsigned short ints = custom.intreqr & custom.intenar;
@@ -389,9 +390,10 @@ static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
custom.intreq = IF_SOFT;
amiga_do_irq(IRQ_AMIGA_SOFT, fp);
}
+ return IRQ_HANDLED;
}
-static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp)
{
unsigned short ints = custom.intreqr & custom.intenar;
@@ -410,9 +412,10 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
/* if a vertical blank interrupt */
if (ints & IF_VERTB)
amiga_do_irq_list(IRQ_AMIGA_VERTB, fp);
+ return IRQ_HANDLED;
}
-static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp)
{
unsigned short ints = custom.intreqr & custom.intenar;
@@ -439,9 +442,10 @@ static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
custom.intreq = IF_AUD3;
amiga_do_irq(IRQ_AMIGA_AUD3, fp);
}
+ return IRQ_HANDLED;
}
-static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp)
{
unsigned short ints = custom.intreqr & custom.intenar;
@@ -456,14 +460,15 @@ static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
custom.intreq = IF_DSKSYN;
amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
}
+ return IRQ_HANDLED;
}
-static void ami_int7(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp)
{
panic ("level 7 interrupt received\n");
}
-void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
ami_badint, ami_int1, ami_badint, ami_int3,
ami_int4, ami_int5, ami_badint, ami_int7
};
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index bceff2e4c7c4..94e15e991b66 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -90,7 +90,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
}
int cia_request_irq(struct ciabase *base, unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
unsigned char mask;
@@ -120,7 +120,7 @@ void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id)
cia_able_irq(base, 1 << irq);
}
-static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp)
{
struct ciabase *base = (struct ciabase *)dev_id;
int mach_irq, i;
@@ -138,6 +138,7 @@ static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
ints >>= 1;
}
amiga_do_irq_list(base->server_irq, fp);
+ return IRQ_HANDLED;
}
void __init cia_init_IRQ(struct ciabase *base)
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index d97c7a26ac49..965894ecd5ae 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -71,12 +71,12 @@ static char amiga_model_name[13] = "Amiga ";
extern char m68k_debug_device[];
-static void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *));
+static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
/* amiga specific irq functions */
extern void amiga_init_IRQ (void);
-extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
+extern irqreturn_t (*amiga_default_handler[]) (int, void *, struct pt_regs *);
extern int amiga_request_irq (unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname,
void *dev_id);
extern void amiga_free_irq (unsigned int irq, void *dev_id);
@@ -491,7 +491,7 @@ void __init config_amiga(void)
static unsigned short jiffy_ticks;
-static void __init amiga_sched_init(void (*timer_routine)(int, void *,
+static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *,
struct pt_regs *))
{
static struct resource sched_res = {
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 461aa796b808..127d3af20831 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -26,9 +26,9 @@ u_long cpuctrl_physaddr;
u_long timer_physaddr;
u_long apollo_model;
-extern void dn_sched_init(void (*handler)(int,void *,struct pt_regs *));
+extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *));
extern void dn_init_IRQ(void);
-extern int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
extern void dn_free_irq(unsigned int irq, void *dev_id);
extern void dn_enable_irq(unsigned int);
extern void dn_disable_irq(unsigned int);
@@ -41,12 +41,12 @@ extern void dn_dummy_waitbut(void);
extern struct fb_info *dn_fb_init(long *);
extern void dn_dummy_debug_init(void);
extern void dn_dummy_video_setup(char *,int *);
-extern void dn_process_int(int irq, struct pt_regs *fp);
+extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp);
#ifdef CONFIG_HEARTBEAT
static void dn_heartbeat(int on);
#endif
-static void dn_timer_int(int irq,void *, struct pt_regs *);
-static void (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL;
+static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *);
+static irqreturn_t (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL;
static void dn_get_model(char *model);
static const char *apollo_models[] = {
"DN3000 (Otter)",
@@ -195,7 +195,7 @@ void config_apollo(void) {
}
-void dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) {
+irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) {
volatile unsigned char x;
@@ -204,9 +204,10 @@ void dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) {
x=*(volatile unsigned char *)(timer+3);
x=*(volatile unsigned char *)(timer+5);
+ return IRQ_HANDLED;
}
-void dn_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) {
+void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) {
/* program timer 1 */
*(volatile unsigned char *)(timer+3)=0x01;
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index e92391957e89..4445b8f35cf9 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -14,19 +14,20 @@
static irq_handler_t dn_irqs[16];
-void dn_process_int(int irq, struct pt_regs *fp) {
-
+irqreturn_t dn_process_int(int irq, struct pt_regs *fp)
+{
+ irqreturn_t res = IRQ_NONE;
if(dn_irqs[irq-160].handler) {
- dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
- }
- else {
+ res = dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
+ } else {
printk("spurious irq %d occurred\n",irq);
}
*(volatile unsigned char *)(pica)=0x20;
*(volatile unsigned char *)(picb)=0x20;
+ return res;
}
void dn_init_IRQ(void) {
@@ -42,7 +43,7 @@ void dn_init_IRQ(void) {
}
-int dn_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) {
+int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) {
if((irq<0) || (irq>15)) {
printk("Trying to request illegal IRQ\n");
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 86f74f772917..24af013a23c2 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -110,7 +110,7 @@
typedef void (*asm_irq_handler)(void);
struct irqhandler {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
void *dev_id;
};
@@ -404,12 +404,13 @@ void __init atari_init_IRQ(void)
}
-static void atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
+static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
{
irq_node_t *node;
for (node = (irq_node_t *)dev_id; node; node = node->next)
node->handler(irq, node->dev_id, fp);
+ return IRQ_HANDLED;
}
@@ -419,7 +420,7 @@ static void atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp )
* If the addition was successful, it returns 0.
*/
-int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
int vector;
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 8fa786dbd982..d926739dbe55 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -60,7 +60,7 @@ static int atari_get_hardware_list(char *buffer);
/* atari specific irq functions */
extern void atari_init_IRQ (void);
-extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
extern void atari_free_irq (unsigned int irq, void *dev_id);
extern void atari_enable_irq (unsigned int);
@@ -72,7 +72,7 @@ static void atari_heartbeat( int on );
#endif
/* atari specific timer functions (in time.c) */
-extern void atari_sched_init(void (*)(int, void *, struct pt_regs *));
+extern void atari_sched_init(irqreturn_t (*)(int, void *, struct pt_regs *));
extern unsigned long atari_gettimeoffset (void);
extern int atari_mste_hwclk (int, struct rtc_time *);
extern int atari_tt_hwclk (int, struct rtc_time *);
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index ec7230628c76..f221f1d2cf67 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -43,8 +43,8 @@
static int stdma_locked = 0; /* the semaphore */
/* int func to be called */
-static void (*stdma_isr)(int, void *, struct pt_regs *) = NULL;
-static void *stdma_isr_data = NULL; /* data passed to isr */
+static irqreturn_t (*stdma_isr)(int, void *, struct pt_regs *) = NULL;
+static void *stdma_isr_data = NULL; /* data passed to isr */
static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */
@@ -52,7 +52,7 @@ static DECLARE_WAIT_QUEUE_HEAD(stdma_wait); /* wait queue for ST-DMA */
/***************************** Prototypes *****************************/
-static void stdma_int (int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t stdma_int (int irq, void *dummy, struct pt_regs *fp);
/************************* End of Prototypes **************************/
@@ -74,7 +74,8 @@ static void stdma_int (int irq, void *dummy, struct pt_regs *fp);
*
*/
-void stdma_lock(void (*handler)(int, void *, struct pt_regs *), void *data)
+void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ void *data)
{
unsigned long flags;
@@ -187,8 +188,9 @@ void __init stdma_init(void)
*
*/
-static void stdma_int(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t stdma_int(int irq, void *dummy, struct pt_regs *fp)
{
if (stdma_isr)
(*stdma_isr)(irq, stdma_isr_data, fp);
+ return IRQ_HANDLED;
}
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 8a26073adb23..26e32176f7c2 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -20,7 +20,7 @@
#include <asm/rtc.h>
void __init
-atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+atari_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
/* set Timer C data Register */
mfp.tim_dt_c = INT_TICKS;
diff --git a/arch/m68k/bvme6000/bvmeints.c b/arch/m68k/bvme6000/bvmeints.c
index 4f2038c3d8b4..b853d776c2c9 100644
--- a/arch/m68k/bvme6000/bvmeints.c
+++ b/arch/m68k/bvme6000/bvmeints.c
@@ -21,14 +21,14 @@
#include <asm/irq.h>
#include <asm/traps.h>
-static void bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp);
/*
* This should ideally be 4 elements only, for speed.
*/
static struct {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
@@ -60,7 +60,7 @@ void bvme6000_init_IRQ (void)
}
int bvme6000_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq > 255) {
@@ -117,14 +117,15 @@ void bvme6000_free_irq(unsigned int irq, void *dev_id)
irq_tab[irq].devname = NULL;
}
-void bvme6000_process_int (unsigned long vec, struct pt_regs *fp)
+irqreturn_t bvme6000_process_int (unsigned long vec, struct pt_regs *fp)
{
- if (vec > 255)
+ if (vec > 255) {
printk ("bvme6000_process_int: Illegal vector %ld", vec);
- else
- {
+ return IRQ_NONE;
+ } else {
irq_tab[vec].count++;
irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp);
+ return IRQ_HANDLED;
}
}
@@ -142,9 +143,10 @@ int show_bvme6000_interrupts(struct seq_file *p, void *v)
}
-static void bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp)
{
printk ("Unknown interrupt 0x%02x\n", irq);
+ return IRQ_NONE;
}
void bvme6000_enable_irq (unsigned int irq)
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index 58771d3367be..78c34da58f31 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -36,7 +36,7 @@
#include <asm/machdep.h>
#include <asm/bvme6000hw.h>
-extern void bvme6000_process_int (int level, struct pt_regs *regs);
+extern irqreturn_t bvme6000_process_int (int level, struct pt_regs *regs);
extern void bvme6000_init_IRQ (void);
extern void bvme6000_free_irq (unsigned int, void *);
extern int show_bvme6000_interrupts(struct seq_file *, void *);
@@ -44,8 +44,8 @@ extern void bvme6000_enable_irq (unsigned int);
extern void bvme6000_disable_irq (unsigned int);
static void bvme6000_get_model(char *model);
static int bvme6000_get_hardware_list(char *buffer);
-extern int bvme6000_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
-extern void bvme6000_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int bvme6000_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
extern unsigned long bvme6000_gettimeoffset (void);
extern int bvme6000_hwclk (int, struct rtc_time *);
extern int bvme6000_set_clock_mmss (unsigned long);
@@ -59,7 +59,7 @@ static unsigned char bin2bcd (unsigned char b);
/* Save tick handler routine pointer, will point to do_timer() in
* kernel/sched.c, called via bvme6000_process_int() */
-static void (*tick_handler)(int, void *, struct pt_regs *);
+static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
int bvme6000_parse_bootinfo(const struct bi_record *bi)
@@ -159,7 +159,7 @@ void __init config_bvme6000(void)
}
-void bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
{
unsigned long *new = (unsigned long *)vectors;
unsigned long *old = (unsigned long *)0xf8000000;
@@ -172,17 +172,18 @@ void bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
*(new+9) = *(old+9); /* Trace */
*(new+47) = *(old+47); /* Trap #15 */
*(new+0x1f) = *(old+0x1f); /* ABORT switch */
+ return IRQ_HANDLED;
}
-static void bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp)
{
volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
unsigned char msr = rtc->msr & 0xc0;
rtc->msr = msr | 0x20; /* Ack the interrupt */
- tick_handler(irq, dev_id, fp);
+ return tick_handler(irq, dev_id, fp);
}
/*
@@ -194,7 +195,7 @@ static void bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp)
* so divide by 8 to get the microsecond result.
*/
-void bvme6000_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+void bvme6000_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
unsigned char msr = rtc->msr & 0xc0;
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
index 3b4862cfa60d..31dcf1a39754 100644
--- a/arch/m68k/hp300/config.c
+++ b/arch/m68k/hp300/config.c
@@ -23,7 +23,7 @@
#include "time.h"
extern void hp300_reset(void);
-extern void (*hp300_default_handler[])(int, void *, struct pt_regs *);
+extern irqreturn_t (*hp300_default_handler[])(int, void *, struct pt_regs *);
extern int show_hp300_interrupts(struct seq_file *, void *);
#ifdef CONFIG_HEARTBEAT
diff --git a/arch/m68k/hp300/ints.c b/arch/m68k/hp300/ints.c
index ed3775df804e..125259485881 100644
--- a/arch/m68k/hp300/ints.c
+++ b/arch/m68k/hp300/ints.c
@@ -42,7 +42,7 @@ static irq_node_t *hp300_irq_list[HP300_NUM_IRQS] = { [0 ... HP300_NUM_IRQS-1] =
static spinlock_t irqlist_lock;
/* This handler receives all interrupts, dispatching them to the registered handlers */
-static void hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp)
{
irq_node_t *t;
/* We just give every handler on the chain an opportunity to handle
@@ -54,9 +54,10 @@ static void hp300_int_handler(int irq, void *dev_id, struct pt_regs *fp)
* etc, in here. Note that currently we can't tell whether or not
* a handler handles the interrupt, though.
*/
+ return IRQ_HANDLED;
}
-void (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+irqreturn_t (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
hp300_int_handler, hp300_int_handler, hp300_int_handler, hp300_int_handler,
hp300_int_handler, hp300_int_handler, hp300_int_handler, NULL
};
@@ -70,7 +71,7 @@ void (*hp300_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
* matters (eg the dreaded FIFOless UART...)
*/
int hp300_request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
+ irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
irq_node_t *t, *n = new_irq_node();
diff --git a/arch/m68k/hp300/ints.h b/arch/m68k/hp300/ints.h
index 26cb8d07784a..8cfabe2f3840 100644
--- a/arch/m68k/hp300/ints.h
+++ b/arch/m68k/hp300/ints.h
@@ -2,7 +2,7 @@ extern void hp300_init_IRQ(void);
extern void (*hp300_handlers[8])(int, void *, struct pt_regs *);
extern void hp300_free_irq(unsigned int irq, void *dev_id);
extern int hp300_request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
+ irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
/* number of interrupts, includes 0 (what's that?) */
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index aa38ffc717ac..ca11f146cf60 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -36,13 +36,13 @@
#define INTVAL ((10000 / 4) - 1)
-static void hp300_tick(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hp300_tick(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long tmp;
- void (*vector)(int, void *, struct pt_regs *) = dev_id;
+ irqreturn_t (*vector)(int, void *, struct pt_regs *) = dev_id;
in_8(CLOCKBASE + CLKSR);
asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
- vector(irq, NULL, regs);
+ return vector(irq, NULL, regs);
}
unsigned long hp300_gettimeoffset(void)
@@ -61,7 +61,7 @@ unsigned long hp300_gettimeoffset(void)
return (USECS_PER_JIFFY * ticks) / INTVAL;
}
-void __init hp300_sched_init(void (*vector)(int, void *, struct pt_regs *))
+void __init hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
{
out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */
out_8(CLOCKBASE + CLKCR1, 0x1); /* reset */
diff --git a/arch/m68k/hp300/time.h b/arch/m68k/hp300/time.h
index a081903ee6ac..8ef9987b49ab 100644
--- a/arch/m68k/hp300/time.h
+++ b/arch/m68k/hp300/time.h
@@ -1,4 +1,4 @@
-extern void hp300_sched_init(void (*vector)(int, void *, struct pt_regs *));
+extern void hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *));
extern unsigned long hp300_gettimeoffset (void);
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index b3da5f4912d4..9c41b72cb124 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -60,14 +60,14 @@ static irq_node_t nodes[NUM_IRQ_NODES];
static void dummy_enable_irq(unsigned int irq);
static void dummy_disable_irq(unsigned int irq);
static int dummy_request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
+ irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
static void dummy_free_irq(unsigned int irq, void *dev_id);
void (*enable_irq) (unsigned int) = dummy_enable_irq;
void (*disable_irq) (unsigned int) = dummy_disable_irq;
-int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+int (*mach_request_irq) (unsigned int, irqreturn_t (*)(int, void *, struct pt_regs *),
unsigned long, const char *, void *) = dummy_request_irq;
void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq;
@@ -121,7 +121,7 @@ irq_node_t *new_irq_node(void)
* include/asm/irq.h.
*/
int request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
+ irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
return mach_request_irq(irq, handler, flags, devname, dev_id);
@@ -133,7 +133,7 @@ void free_irq(unsigned int irq, void *dev_id)
}
int sys_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq < IRQ1 || irq > IRQ7) {
@@ -215,7 +215,7 @@ static void dummy_disable_irq(unsigned int irq)
}
static int dummy_request_irq(unsigned int irq,
- void (*handler) (int, void *, struct pt_regs *),
+ irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
printk("calling uninitialized request_irq()\n");
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index f6522a41b6e9..210972916f88 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -135,14 +135,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_attach(child);
goto out_tsk;
}
- ret = -ESRCH;
- if (!(child->ptrace & PT_PTRACED))
- goto out_tsk;
- if (child->state != TASK_STOPPED) {
- if (request != PTRACE_KILL)
- goto out_tsk;
- }
- if (child->parent != current)
+
+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
+ if (ret < 0)
goto out_tsk;
switch (request) {
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 349ffcc96dce..06374834c95a 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -67,14 +67,14 @@ char saved_command_line[CL_SIZE];
char m68k_debug_device[6] = "";
-void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
+void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
/* machine dependent irq functions */
void (*mach_init_IRQ) (void) __initdata = NULL;
-void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
void (*mach_get_model) (char *model) = NULL;
int (*mach_get_hardware_list) (char *buffer) = NULL;
int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
-void (*mach_process_int) (int, struct pt_regs *) = NULL;
+irqreturn_t (*mach_process_int) (int, struct pt_regs *) = NULL;
/* machine dependent timer functions */
unsigned long (*mach_gettimeoffset) (void);
int (*mach_hwclk) (int, struct rtc_time*) = NULL;
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index e5e1bffbd917..02c34dd74947 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -202,7 +202,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
return sys_semctl (first, second, third, fourth);
}
default:
- return -EINVAL;
+ return -ENOSYS;
}
if (call <= MSGCTL)
switch (call) {
@@ -233,7 +233,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
return sys_msgctl (first, second,
(struct msqid_ds *) ptr);
default:
- return -EINVAL;
+ return -ENOSYS;
}
if (call <= SHMCTL)
switch (call) {
@@ -256,7 +256,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
return sys_shmctl (first, second,
(struct shmid_ds *) ptr);
default:
- return -EINVAL;
+ return -ENOSYS;
}
return -EINVAL;
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 0768ec110f48..20eb0fac4ad3 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -57,7 +57,7 @@ static inline void do_profile (unsigned long pc)
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
-static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
{
do_timer(regs);
@@ -87,6 +87,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
}
}
#endif /* CONFIG_HEARTBEAT */
+ return IRQ_HANDLED;
}
void time_init(void)
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index 88303d8aaa4c..dd424e495689 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -25,7 +25,7 @@
int baboon_present,baboon_active;
volatile struct baboon *baboon;
-void baboon_irq(int, void *, struct pt_regs *);
+irqreturn_t baboon_irq(int, void *, struct pt_regs *);
#if 0
extern int macide_ack_intr(struct ata_channel *);
@@ -64,7 +64,7 @@ void __init baboon_register_interrupts(void)
* Baboon interrupt handler. This works a lot like a VIA.
*/
-void baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int irq_bit,i;
unsigned char events;
@@ -75,7 +75,8 @@ void baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
(uint) baboon->mb_status, baboon_active);
#endif
- if (!(events = baboon->mb_ifr & 0x07)) return;
+ if (!(events = baboon->mb_ifr & 0x07))
+ return IRQ_NONE;
for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) {
if (events & irq_bit/* & baboon_active*/) {
@@ -90,6 +91,7 @@ void baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
/* for now we need to smash all interrupts */
baboon->mb_ifr &= ~events;
#endif
+ return IRQ_HANDLED;
}
void baboon_irq_enable(int irq) {
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 17ce0248fbfe..b478da2b8f1c 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -72,7 +72,7 @@ extern int show_mac_interrupts(struct seq_file *, void *);
extern void iop_preinit(void);
extern void iop_init(void);
extern void via_init(void);
-extern void via_init_clock(void (*func)(int, void *, struct pt_regs *));
+extern void via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *));
extern void via_flush_cache(void);
extern void oss_init(void);
extern void psc_init(void);
@@ -94,7 +94,7 @@ void mac_bang(int irq, void *vector, struct pt_regs *p)
mac_reset();
}
-static void mac_sched_init(void (*vector)(int, void *, struct pt_regs *))
+static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
{
via_init_clock(vector);
}
@@ -106,9 +106,9 @@ void mac_waitbut (void)
}
#endif
-extern void mac_default_handler(int, void *, struct pt_regs *);
+extern irqreturn_t mac_default_handler(int, void *, struct pt_regs *);
-void (*mac_handlers[8])(int, void *, struct pt_regs *)=
+irqreturn_t (*mac_handlers[8])(int, void *, struct pt_regs *)=
{
mac_default_handler,
mac_default_handler,
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 01777ff73a14..7badee848229 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -153,7 +153,7 @@ static struct iop_msg iop_msg_pool[NUM_IOP_MSGS];
static struct iop_msg *iop_send_queue[NUM_IOPS][NUM_IOP_CHAN];
static struct listener iop_listeners[NUM_IOPS][NUM_IOP_CHAN];
-void iop_ism_irq(int, void *, struct pt_regs *);
+irqreturn_t iop_ism_irq(int, void *, struct pt_regs *);
extern void oss_irq_enable(int);
@@ -585,7 +585,7 @@ __u8 *iop_compare_code(uint iop_num, __u8 *code_start,
* Handle an ISM IOP interrupt
*/
-void iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
{
uint iop_num = (uint) dev_id;
volatile struct mac_iop *iop = iop_base[iop_num];
@@ -636,7 +636,7 @@ void iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
printk("\n");
#endif
}
-
+ return IRQ_HANDLED;
}
#ifdef CONFIG_PROC_FS
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index dff6526bdebd..488d63bc7314 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -217,10 +217,9 @@ static void scc_irq_disable(int);
* console_loglevel determines NMI handler function
*/
-extern void mac_bang(int, void *, struct pt_regs *);
-
-void mac_nmi_handler(int, void *, struct pt_regs *);
-void mac_debug_handler(int, void *, struct pt_regs *);
+extern irqreturn_t mac_bang(int, void *, struct pt_regs *);
+irqreturn_t mac_nmi_handler(int, void *, struct pt_regs *);
+irqreturn_t mac_debug_handler(int, void *, struct pt_regs *);
/* #define DEBUG_MACINTS */
@@ -499,7 +498,7 @@ int mac_irq_pending( unsigned int irq )
*/
int mac_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
irq_node_t *node;
@@ -647,18 +646,19 @@ void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
static int num_debug[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
{
if (num_debug[irq] < 10) {
printk("DEBUG: Unexpected IRQ %d\n", irq);
num_debug[irq]++;
}
+ return IRQ_HANDLED;
}
static int in_nmi = 0;
static volatile int nmi_hold = 0;
-void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
{
int i;
/*
@@ -703,6 +703,7 @@ void mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
#endif
}
in_nmi--;
+ return IRQ_HANDLED;
}
/*
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index f391716485f7..6016a07bc445 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -30,11 +30,11 @@
int oss_present;
volatile struct mac_oss *oss;
-void oss_irq(int, void *, struct pt_regs *);
-void oss_nubus_irq(int, void *, struct pt_regs *);
+irqreturn_t oss_irq(int, void *, struct pt_regs *);
+irqreturn_t oss_nubus_irq(int, void *, struct pt_regs *);
-extern void via1_irq(int, void *, struct pt_regs *);
-extern void mac_scc_dispatch(int, void *, struct pt_regs *);
+extern irqreturn_t via1_irq(int, void *, struct pt_regs *);
+extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *);
/*
* Initialize the OSS
@@ -92,12 +92,13 @@ void __init oss_nubus_init(void)
* and SCSI; everything else is routed to its own autovector IRQ.
*/
-void oss_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int events;
events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI);
- if (!events) return;
+ if (!events)
+ return IRQ_NONE;
#ifdef DEBUG_IRQS
if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) {
@@ -118,6 +119,7 @@ void oss_irq(int irq, void *dev_id, struct pt_regs *regs)
} else {
/* FIXME: error check here? */
}
+ return IRQ_HANDLED;
}
/*
@@ -126,12 +128,13 @@ void oss_irq(int irq, void *dev_id, struct pt_regs *regs)
* Unlike the VIA/RBV this is on its own autovector interrupt level.
*/
-void oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int events, irq_bit, i;
events = oss->irq_pending & OSS_IP_NUBUS;
- if (!events) return;
+ if (!events)
+ return IRQ_NONE;
#ifdef DEBUG_NUBUS_INT
if (console_loglevel > 7) {
@@ -148,6 +151,7 @@ void oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
oss->irq_level[i] = OSS_IRQLEV_NUBUS;
}
}
+ return IRQ_HANDLED;
}
/*
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 2b5c2ad78634..34a847437201 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -30,7 +30,7 @@
int psc_present;
volatile __u8 *psc;
-void psc_irq(int, void *, struct pt_regs *);
+irqreturn_t psc_irq(int, void *, struct pt_regs *);
/*
* Debugging dump, used in various places to see what's going on.
@@ -131,7 +131,7 @@ void __init psc_register_interrupts(void)
* PSC interrupt handler. It's a lot like the VIA interrupt handler.
*/
-void psc_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t psc_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int pIFR = pIFRbase + ((int) dev_id);
int pIER = pIERbase + ((int) dev_id);
@@ -147,7 +147,8 @@ void psc_irq(int irq, void *dev_id, struct pt_regs *regs)
#endif
events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF;
- if (!events) return;
+ if (!events)
+ return IRQ_NONE;
for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) {
if (events & irq_bit) {
@@ -157,6 +158,7 @@ void psc_irq(int irq, void *dev_id, struct pt_regs *regs)
psc_write_byte(pIER, irq_bit | 0x80);
}
}
+ return IRQ_HANDLED;
}
void psc_irq_enable(int irq) {
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 5b43e574046d..d5d9a305e4cf 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -65,15 +65,15 @@ static int gIER,gIFR,gBufA,gBufB;
static int nubus_active = 0;
void via_debug_dump(void);
-void via1_irq(int, void *, struct pt_regs *);
-void via2_irq(int, void *, struct pt_regs *);
-void via_nubus_irq(int, void *, struct pt_regs *);
+irqreturn_t via1_irq(int, void *, struct pt_regs *);
+irqreturn_t via2_irq(int, void *, struct pt_regs *);
+irqreturn_t via_nubus_irq(int, void *, struct pt_regs *);
void via_irq_enable(int irq);
void via_irq_disable(int irq);
void via_irq_clear(int irq);
-extern void mac_bang(int, void *, struct pt_regs *);
-extern void mac_scc_dispatch(int, void *, struct pt_regs *);
+extern irqreturn_t mac_bang(int, void *, struct pt_regs *);
+extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *);
extern int oss_present;
/*
@@ -243,7 +243,7 @@ void __init via_init(void)
* Start the 100 Hz clock
*/
-void __init via_init_clock(void (*func)(int, void *, struct pt_regs *))
+void __init via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *))
{
via1[vACR] |= 0x40;
via1[vT1LL] = MAC_CLOCK_LOW;
@@ -423,13 +423,14 @@ void __init via_nubus_init(void)
* the machspec interrupt number after clearing the interrupt.
*/
-void via1_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int irq_bit, i;
unsigned char events, mask;
mask = via1[vIER] & 0x7F;
- if (!(events = via1[vIFR] & mask)) return;
+ if (!(events = via1[vIFR] & mask))
+ return IRQ_NONE;
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
if (events & irq_bit) {
@@ -453,15 +454,17 @@ void via1_irq(int irq, void *dev_id, struct pt_regs *regs)
via_irq_enable(IRQ_MAC_NUBUS);
}
#endif
+ return IRQ_HANDLED;
}
-void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int irq_bit, i;
unsigned char events, mask;
mask = via2[gIER] & 0x7F;
- if (!(events = via2[gIFR] & mask)) return;
+ if (!(events = via2[gIFR] & mask))
+ return IRQ_NONE;
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
if (events & irq_bit) {
@@ -470,6 +473,7 @@ void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
via2[gIFR] = irq_bit | rbv_clear;
via2[gIER] = irq_bit | 0x80;
}
+ return IRQ_HANDLED;
}
/*
@@ -477,12 +481,13 @@ void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
* VIA2 dispatcher as a fast interrupt handler.
*/
-void via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
{
int irq_bit, i;
unsigned char events;
- if (!(events = ~via2[gBufA] & nubus_active)) return;
+ if (!(events = ~via2[gBufA] & nubus_active))
+ return IRQ_NONE;
for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) {
if (events & irq_bit) {
@@ -491,6 +496,7 @@ void via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
via_irq_enable(NUBUS_SOURCE_BASE + i);
}
}
+ return IRQ_HANDLED;
}
void via_irq_enable(int irq) {
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 26688cebc6f6..fd1d4b19da16 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -33,7 +33,7 @@
#endif
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/*
* ZERO_PAGE is a special page that is used for zero-initialized
diff --git a/arch/m68k/mvme147/147ints.c b/arch/m68k/mvme147/147ints.c
index d58edccba3cd..69a744ee35a3 100644
--- a/arch/m68k/mvme147/147ints.c
+++ b/arch/m68k/mvme147/147ints.c
@@ -21,14 +21,14 @@
#include <asm/irq.h>
#include <asm/traps.h>
-static void mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp);
/*
* This should ideally be 4 elements only, for speed.
*/
static struct {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
@@ -60,7 +60,7 @@ void mvme147_init_IRQ (void)
}
int mvme147_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq > 255) {
@@ -102,14 +102,15 @@ void mvme147_free_irq(unsigned int irq, void *dev_id)
irq_tab[irq].devname = NULL;
}
-void mvme147_process_int (unsigned long vec, struct pt_regs *fp)
+irqreturn_t mvme147_process_int (unsigned long vec, struct pt_regs *fp)
{
- if (vec > 255)
+ if (vec > 255) {
printk ("mvme147_process_int: Illegal vector %ld\n", vec);
- else
- {
+ return IRQ_NONE;
+ } else {
irq_tab[vec].count++;
irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp);
+ return IRQ_HANDLED;
}
}
@@ -127,9 +128,10 @@ int show_mvme147_interrupts (struct seq_file *p, void *v)
}
-static void mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp)
{
printk ("Unknown interrupt 0x%02x\n", irq);
+ return IRQ_NONE;
}
void mvme147_enable_irq (unsigned int irq)
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 5f5342a2a67f..a84400e94e1f 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -36,7 +36,7 @@
#include <asm/mvme147hw.h>
-extern void mvme147_process_int (int level, struct pt_regs *regs);
+extern irqreturn_t mvme147_process_int (int level, struct pt_regs *regs);
extern void mvme147_init_IRQ (void);
extern void mvme147_free_irq (unsigned int, void *);
extern int show_mvme147_interrupts (struct seq_file *, void *);
@@ -44,8 +44,8 @@ extern void mvme147_enable_irq (unsigned int);
extern void mvme147_disable_irq (unsigned int);
static void mvme147_get_model(char *model);
static int mvme147_get_hardware_list(char *buffer);
-extern int mvme147_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
-extern void mvme147_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int mvme147_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
extern unsigned long mvme147_gettimeoffset (void);
extern int mvme147_hwclk (int, struct rtc_time *);
extern int mvme147_set_clock_mmss (unsigned long);
@@ -58,7 +58,7 @@ static int bcd2int (unsigned char b);
/* Save tick handler routine pointer, will point to do_timer() in
* kernel/sched.c, called via mvme147_process_int() */
-void (*tick_handler)(int, void *, struct pt_regs *);
+irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
int mvme147_parse_bootinfo(const struct bi_record *bi)
@@ -118,15 +118,15 @@ void __init config_mvme147(void)
/* Using pcc tick timer 1 */
-static void mvme147_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme147_timer_int (int irq, void *dev_id, struct pt_regs *fp)
{
m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
- tick_handler(irq, dev_id, fp);
+ return tick_handler(irq, dev_id, fp);
}
-void mvme147_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+void mvme147_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
tick_handler = timer_routine;
request_irq (PCC_IRQ_TIMER1, mvme147_timer_int,
diff --git a/arch/m68k/mvme16x/16xints.c b/arch/m68k/mvme16x/16xints.c
index 198d01a684e4..1b3b478a9da4 100644
--- a/arch/m68k/mvme16x/16xints.c
+++ b/arch/m68k/mvme16x/16xints.c
@@ -20,14 +20,14 @@
#include <asm/ptrace.h>
#include <asm/irq.h>
-static void mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp);
/*
* This should ideally be 4 elements only, for speed.
*/
static struct {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
@@ -60,7 +60,7 @@ void mvme16x_init_IRQ (void)
}
int mvme16x_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
if (irq < 64 || irq > 255) {
@@ -104,14 +104,15 @@ void mvme16x_free_irq(unsigned int irq, void *dev_id)
irq_tab[irq-64].devname = NULL;
}
-void mvme16x_process_int (unsigned long vec, struct pt_regs *fp)
+irqreturn_t mvme16x_process_int (unsigned long vec, struct pt_regs *fp)
{
- if (vec < 64 || vec > 255)
+ if (vec < 64 || vec > 255) {
printk ("mvme16x_process_int: Illegal vector %ld", vec);
- else
- {
+ return IRQ_NONE;
+ } else {
irq_tab[vec-64].count++;
irq_tab[vec-64].handler(vec, irq_tab[vec-64].dev_id, fp);
+ return IRQ_HANDLED;
}
}
@@ -129,9 +130,10 @@ int show_mvme16x_interrupts (struct seq_file *p, void *v)
}
-static void mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp)
{
printk ("Unknown interrupt 0x%02x\n", irq);
+ return IRQ_NONE;
}
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index 713c18b54c7e..79182f1c8865 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -40,7 +40,7 @@ extern t_bdid mvme_bdid;
static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
-extern void mvme16x_process_int (int level, struct pt_regs *regs);
+extern irqreturn_t mvme16x_process_int (int level, struct pt_regs *regs);
extern void mvme16x_init_IRQ (void);
extern void mvme16x_free_irq (unsigned int, void *);
extern int show_mvme16x_interrupts (struct seq_file *, void *);
@@ -48,8 +48,8 @@ extern void mvme16x_enable_irq (unsigned int);
extern void mvme16x_disable_irq (unsigned int);
static void mvme16x_get_model(char *model);
static int mvme16x_get_hardware_list(char *buffer);
-extern int mvme16x_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
-extern void mvme16x_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int mvme16x_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
extern unsigned long mvme16x_gettimeoffset (void);
extern int mvme16x_hwclk (int, struct rtc_time *);
extern int mvme16x_set_clock_mmss (unsigned long);
@@ -61,7 +61,7 @@ int bcd2int (unsigned char b);
/* Save tick handler routine pointer, will point to do_timer() in
* kernel/sched.c, called via mvme16x_process_int() */
-static void (*tick_handler)(int, void *, struct pt_regs *);
+static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
unsigned short mvme16x_config;
@@ -193,7 +193,7 @@ void __init config_mvme16x(void)
}
}
-static void mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
{
p_bdid p = &mvme_bdid;
unsigned long *new = (unsigned long *)vectors;
@@ -218,15 +218,16 @@ static void mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
*(new+0x5e) = *(old+0x5e); /* ABORT switch */
else
*(new+0x6e) = *(old+0x6e); /* ABORT switch */
+ return IRQ_HANDLED;
}
-static void mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp)
{
*(volatile unsigned char *)0xfff4201b |= 8;
- tick_handler(irq, dev_id, fp);
+ return tick_handler(irq, dev_id, fp);
}
-void mvme16x_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+void mvme16x_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
p_bdid p = &mvme_bdid;
int irq;
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 9e5ca227cf49..6e68c49fd0a8 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -39,8 +39,8 @@
extern void floppy_setup(char *str, int *ints);
-extern void q40_process_int (int level, struct pt_regs *regs);
-extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
+extern irqreturn_t q40_process_int (int level, struct pt_regs *regs);
+extern irqreturn_t (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
extern void q40_init_IRQ (void);
extern void q40_free_irq (unsigned int, void *);
extern int show_q40_interrupts (struct seq_file *, void *);
@@ -48,8 +48,8 @@ extern void q40_enable_irq (unsigned int);
extern void q40_disable_irq (unsigned int);
static void q40_get_model(char *model);
static int q40_get_hardware_list(char *buffer);
-extern int q40_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
-extern void q40_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int q40_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
extern unsigned long q40_gettimeoffset (void);
extern int q40_hwclk (int, struct rtc_time *);
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 8f51ac0ed65e..8126c03f1f81 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -43,19 +43,19 @@
extern int ints_inited;
-void q40_irq2_handler (int, void *, struct pt_regs *fp);
+irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp);
-extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);
+extern irqreturn_t (*q40_sys_default_handler[]) (int, void *, struct pt_regs *);
-static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp);
-static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs);
+static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t sys_default_handler(int lev, void *dev_id, struct pt_regs *regs);
#define DEVNAME_SIZE 24
static struct q40_irq_node {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
/* struct q40_irq_node *next;*/
@@ -106,7 +106,7 @@ void q40_init_IRQ (void)
}
int q40_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
/*printk("q40_request_irq %d, %s\n",irq,devname);*/
@@ -198,9 +198,10 @@ void q40_free_irq(unsigned int irq, void *dev_id)
}
-void q40_process_int (int level, struct pt_regs *fp)
+irqreturn_t q40_process_int (int level, struct pt_regs *fp)
{
printk("unexpected interrupt %x\n",level);
+ return IRQ_HANDLED;
}
/*
@@ -231,9 +232,9 @@ void q40_mksound(unsigned int hz, unsigned int ticks)
sound_ticks=ticks<<1;
}
-static void (*q40_timer_routine)(int, void *, struct pt_regs *);
+static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *);
-static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
+static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs)
{
ql_ticks = ql_ticks ? 0 : 1;
if (sound_ticks)
@@ -244,12 +245,12 @@ static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
*DAC_RIGHT=sval;
}
- if (ql_ticks) return;
-
- q40_timer_routine(irq, dev, regs);
+ if (!ql_ticks)
+ q40_timer_routine(irq, dev, regs);
+ return IRQ_HANDLED;
}
-void q40_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
int timer_irq;
@@ -312,7 +313,7 @@ static int aliased_irq=0; /* how many times inside handler ?*/
/* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
-void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
+irqreturn_t q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
{
unsigned mir, mer;
int irq,i;
@@ -378,7 +379,7 @@ void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
#endif
}
// used to do 'goto repeat;' her, this delayed bh processing too long
- return;
+ return IRQ_HANDLED;
}
}
if (mer && ccleirq>0 && !aliased_irq)
@@ -390,6 +391,7 @@ void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
irq_tab[Q40_IRQ_KEYBOARD].count++;
irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
}
+ return IRQ_HANDLED;
}
int show_q40_interrupts (struct seq_file *p, void *v)
@@ -409,16 +411,18 @@ int show_q40_interrupts (struct seq_file *p, void *v)
}
-static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
{
printk ("Unknown q40 interrupt 0x%02x\n", irq);
+ return IRQ_NONE;
}
-static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
{
printk ("Uninitialised interrupt level %d\n", lev);
+ return IRQ_NONE;
}
- void (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
+ irqreturn_t (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
};
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index caf8a22d2498..2750c674d730 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -37,7 +37,7 @@ char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
extern unsigned long sun3_gettimeoffset(void);
extern int show_sun3_interrupts (struct seq_file *, void *);
-extern void sun3_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
extern void sun3_get_model (char* model);
extern void idprom_init (void);
extern int sun3_hwclk(int set, struct rtc_time *t);
@@ -174,7 +174,7 @@ void __init config_sun3(void)
sun3_bootmem_alloc(memory_start, memory_end);
}
-void __init sun3_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
+void __init sun3_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
{
sun3_disable_interrupts();
intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 99a129fb59f6..63fb4135a8f9 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -18,7 +18,7 @@
#include <linux/seq_file.h>
extern void sun3_leds (unsigned char);
-static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp);
void sun3_disable_interrupts(void)
{
@@ -64,15 +64,16 @@ inline void sun3_do_irq(int irq, struct pt_regs *fp)
*sun3_intreg |= (1<<irq);
}
-static void sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
{
sun3_do_irq(irq,fp);
if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 2000))
sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%16000)
/2000]);
+ return IRQ_HANDLED;
}
-static void sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
{
kstat_cpu(0).irqs[SYS_IRQS + irq]++;
#ifdef CONFIG_SUN3
@@ -87,11 +88,12 @@ static void sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
if(!(kstat_cpu(0).irqs[SYS_IRQS + irq] % 20))
sun3_leds(led_pattern[(kstat_cpu(0).irqs[SYS_IRQS+irq]%160)
/20]);
+ return IRQ_HANDLED;
}
/* handle requested ints, excepting 5 and 7, which always do the same
thing */
-void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+irqreturn_t (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
sun3_inthandle, sun3_inthandle, sun3_inthandle, sun3_inthandle,
sun3_inthandle, sun3_int5, sun3_inthandle, sun3_int7
};
@@ -99,10 +101,10 @@ void (*sun3_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
static const char *dev_names[SYS_IRQS] = { NULL, NULL, NULL, NULL,
NULL, "timer", NULL, "int7 handler" };
static void *dev_ids[SYS_IRQS];
-static void (*sun3_inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+static irqreturn_t (*sun3_inthandler[SYS_IRQS])(int, void *, struct pt_regs *) = {
NULL, NULL, NULL, NULL, NULL, sun3_int5, NULL, sun3_int7
};
-static void (*sun3_vechandler[SUN3_INT_VECS])(int, void *, struct pt_regs *);
+static irqreturn_t (*sun3_vechandler[SUN3_INT_VECS])(int, void *, struct pt_regs *);
static void *vec_ids[SUN3_INT_VECS];
static const char *vec_names[SUN3_INT_VECS];
static int vec_ints[SUN3_INT_VECS];
@@ -124,7 +126,7 @@ int show_sun3_interrupts(struct seq_file *p, void *v)
return 0;
}
-static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
{
if(sun3_inthandler[irq] == NULL)
panic ("bad interrupt %d received (id %p)\n",irq, dev_id);
@@ -133,11 +135,13 @@ static void sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp)
*sun3_intreg &= ~(1<<irq);
sun3_inthandler[irq](irq, dev_ids[irq], fp);
+ return IRQ_HANDLED;
}
-static void sun3_vec255(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_vec255(int irq, void *dev_id, struct pt_regs *fp)
{
// intersil_clear();
+ return IRQ_HANDLED;
}
void sun3_init_IRQ(void)
@@ -159,7 +163,7 @@ void sun3_init_IRQ(void)
sun3_vechandler[191] = sun3_vec255;
}
-int sun3_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+int sun3_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
@@ -228,7 +232,7 @@ void sun3_free_irq(unsigned int irq, void *dev_id)
}
}
-void sun3_process_int(int irq, struct pt_regs *regs)
+irqreturn_t sun3_process_int(int irq, struct pt_regs *regs)
{
if((irq >= 64) && (irq <= 255)) {
@@ -239,8 +243,7 @@ void sun3_process_int(int irq, struct pt_regs *regs)
panic ("bad interrupt vector %d received\n",irq);
vec_ints[vec]++;
- sun3_vechandler[vec](irq, vec_ids[vec], regs);
- return;
+ return sun3_vechandler[vec](irq, vec_ids[vec], regs);
} else {
panic("sun3_process_int: unable to handle interrupt vector %d\n",
irq);
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
index b9b334e0db7f..d475410e6db2 100644
--- a/arch/m68k/sun3x/time.c
+++ b/arch/m68k/sun3x/time.c
@@ -90,7 +90,7 @@ static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
}
#endif
-void __init sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *))
+void __init sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
{
sun3_disable_interrupts();
diff --git a/arch/m68k/sun3x/time.h b/arch/m68k/sun3x/time.h
index ad8c9fce76b7..e7e43b4ec4a1 100644
--- a/arch/m68k/sun3x/time.h
+++ b/arch/m68k/sun3x/time.h
@@ -3,7 +3,7 @@
extern int sun3x_hwclk(int set, struct rtc_time *t);
unsigned long sun3x_gettimeoffset (void);
-void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *));
+void sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *));
struct mostek_dt {
volatile unsigned char csr;
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 9e0f962e634d..a0cae9182737 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -42,7 +42,7 @@
#include <asm/mmu_context.h>
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
extern void prom_free_prom_memory(void);
diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c
index 4f7fe2cf6726..ea3c81e438c6 100644
--- a/arch/mips64/mm/init.c
+++ b/arch/mips64/mm/init.c
@@ -35,7 +35,7 @@
#include <asm/mmu_context.h>
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
void pgd_init(unsigned long page)
{
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index a3688aaac0bf..2c6f64552ab2 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -53,6 +53,7 @@
#include <linux/pci.h>
#include <linux/serial.h>
#include <linux/watchdog.h>
+#include <net/sock.h> /* siocdevprivate_ioctl */
#include <scsi/scsi.h>
/* Ugly hack. */
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 665e3461e374..93aa656bb8b2 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -23,7 +23,7 @@
#include <asm/tlb.h>
#include <asm/pdc_chassis.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
extern char _text; /* start of kernel code, defined by linker */
extern int data_start;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 9cf80494865a..4af189635f1a 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -53,7 +53,7 @@
#endif
#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long total_memory;
unsigned long total_lowmem;
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c
index 34fa17f47c1d..66ff8103bf4d 100644
--- a/arch/ppc64/boot/addnote.c
+++ b/arch/ppc64/boot/addnote.c
@@ -14,6 +14,7 @@
* Usage: addnote zImage
*/
#include <stdio.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
diff --git a/arch/ppc64/kernel/align.c b/arch/ppc64/kernel/align.c
index b2f846d08a78..37932d7c6b52 100644
--- a/arch/ppc64/kernel/align.c
+++ b/arch/ppc64/kernel/align.c
@@ -21,6 +21,8 @@
#include <asm/system.h>
#include <asm/cache.h>
+void disable_kernel_fp(void); /* asm function from head.S */
+
struct aligninfo {
unsigned char len;
unsigned char flags;
diff --git a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
index b504e47bbcac..5562991be802 100644
--- a/arch/ppc64/kernel/ioctl32.c
+++ b/arch/ppc64/kernel/ioctl32.c
@@ -685,7 +685,7 @@ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return -EFAULT;
if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
return -EFAULT;
- data64 = A(data32);
+ data64 = (void __user *)A(data32);
u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index 19573605448c..720fc3f5a4bb 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -735,11 +735,11 @@ _GLOBAL(sys_call_table32)
.llong .sys_ni_syscall
.llong .sys_ni_syscall /* 225 - reserved for tux */
.llong .sys32_sendfile64
- .llong .sys_ni_syscall /* reserved for sys_io_setup */
- .llong .sys_ni_syscall /* reserved for sys_io_destroy */
- .llong .sys_ni_syscall /* reserved for sys_io_getevents */
- .llong .sys_ni_syscall /* 230 - reserved for sys_io_submit */
- .llong .sys_ni_syscall /* reserved for sys_io_cancel */
+ .llong .sys32_io_setup
+ .llong .sys_io_destroy
+ .llong .sys32_io_getevents
+ .llong .sys32_io_submit
+ .llong .sys_io_cancel
.llong .sys_set_tid_address
.llong .ppc32_fadvise64
.llong .sys_exit_group
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 9dfa355ea906..e596e361be3c 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -1060,12 +1060,11 @@ unsigned long __init
prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
unsigned long r6, unsigned long r7)
{
- int chrp = 0;
unsigned long mem;
- ihandle prom_mmu, prom_op, prom_root, prom_cpu;
+ ihandle prom_root, prom_cpu;
phandle cpu_pkg;
unsigned long offset = reloc_offset();
- long l, sz;
+ long l;
char *p, *d;
unsigned long phys;
u32 getprop_rval;
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index f178fa9538a9..8b33cf97deb5 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -193,9 +193,9 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
printk("naca = 0x%p\n", naca);
printk("naca->pftSize = 0x%lx\n", naca->pftSize);
printk("naca->debug_switch = 0x%lx\n", naca->debug_switch);
- printk("naca->interrupt_controller = 0x%d\n", naca->interrupt_controller);
+ printk("naca->interrupt_controller = 0x%ld\n", naca->interrupt_controller);
printk("systemcf = 0x%p\n", systemcfg);
- printk("systemcfg->processorCount = 0x%x\n", systemcfg->processorCount);
+ printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount);
printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
printk("systemcfg->dCacheL1LineSize = 0x%x\n", systemcfg->dCacheL1LineSize);
printk("systemcfg->iCacheL1LineSize = 0x%x\n", systemcfg->iCacheL1LineSize);
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 63a9bc173b3a..66077d35a9b9 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -32,6 +32,7 @@
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
+#include <linux/aio.h>
#include <linux/nfs_fs.h>
#include <linux/smb_fs.h>
#include <linux/smb_mount.h>
@@ -58,6 +59,7 @@
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/ptrace.h>
+#include <linux/aio_abi.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -2643,6 +2645,98 @@ unsigned long sys32_mmap2(unsigned long addr, size_t len,
return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
}
+extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx);
+
+long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p)
+{
+ long ret;
+ aio_context_t ctx64;
+ mm_segment_t oldfs = get_fs();
+
+ if (get_user((u32)ctx64, ctx32p))
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+ ret = sys_io_setup(nr_reqs, &ctx64);
+ set_fs(oldfs);
+
+ /* truncating is ok because it's a user address */
+ if (!ret)
+ ret = put_user((u32)ctx64, ctx32p);
+
+ return ret;
+}
+
+long sys_io_getevents(aio_context_t ctx_id, long min_nr, long nr,
+ struct io_event *events, struct timespec *timeout);
+
+long sys32_io_getevents(aio_context_t ctx_id, u32 min_nr, u32 nr,
+ struct io_event *events, struct compat_timespec *t32)
+{
+ struct timespec t;
+ long ret;
+ mm_segment_t oldfs = get_fs();
+
+ if (t32) {
+ if (get_user(t.tv_sec, &t32->tv_sec) ||
+ __get_user(t.tv_nsec, &t32->tv_nsec))
+ return -EFAULT;
+ }
+
+ if (verify_area(VERIFY_WRITE, events, nr * sizeof(*events)))
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+ /* sign extend min_nr and nr */
+ ret = sys_io_getevents(ctx_id, (int)min_nr, (int)nr, events,
+ t32 ? &t : NULL);
+ set_fs(oldfs);
+
+ return ret;
+}
+
+long sys32_io_submit(aio_context_t ctx_id, u32 number, u32 *iocbpp)
+{
+ struct kioctx *ctx;
+ long ret = 0;
+ int i;
+ int nr = (int)number; /* sign extend */
+
+ if (unlikely(nr < 0))
+ return -EINVAL;
+
+ if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(u32)))))
+ return -EFAULT;
+
+ ctx = lookup_ioctx(ctx_id);
+ if (unlikely(!ctx)) {
+ pr_debug("EINVAL: io_submit: invalid context id\n");
+ return -EINVAL;
+ }
+
+ for (i=0; i<nr; i++) {
+ struct iocb tmp;
+ u32 *user_iocb;
+
+ if (unlikely(__get_user((u32)(long)user_iocb, iocbpp + i))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ if (unlikely(copy_from_user(&tmp, user_iocb, sizeof(tmp)))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = io_submit_one(ctx, (struct iocb *)user_iocb, &tmp);
+ if (ret)
+ break;
+ }
+
+ put_ioctx(ctx);
+ return i ? i : ret;
+}
+
/*
* long long munging:
* The 32 bit ABI passes long longs in an odd even register pair.
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index d7adaf568392..e350c14fc32a 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -346,10 +346,11 @@ ProgramCheckException(struct pt_regs *regs)
}
}
- void
+void
KernelFPUnavailableException(struct pt_regs *regs)
{
- printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n",
+ printk("Illegal floating point used in kernel "
+ "(task=0x%p, pc=0x%016lx, trap=0x%08lx)\n",
current, regs->nip, regs->trap);
panic("Unrecoverable FP Unavailable Exception in Kernel");
}
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index 58dcf9895078..2226ec69d8a6 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -25,6 +25,7 @@
#include <asm/xics.h>
#include <asm/ppcdebug.h>
#include <asm/hvcall.h>
+#include <asm/machdep.h>
#include "i8259.h"
@@ -322,11 +323,9 @@ extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int handled = 0;
ops->qirr_info(cpu, 0xff);
while (xics_ipi_message[cpu].value) {
- handled = 1;
if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
&xics_ipi_message[cpu].value)) {
mb();
@@ -352,7 +351,7 @@ irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
}
#endif
}
- return IRQ_RETVAL(handled);
+ return IRQ_HANDLED;
}
void xics_cause_IPI(int cpu)
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index 028aa5ae355e..32352bf454a8 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -93,7 +93,7 @@ unsigned long __max_memory;
/* This is declared as we are using the more or less generic
* include/asm-ppc64/tlb.h file -- tgall
*/
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
void show_mem(void)
{
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 364632f03460..6262a3c3afea 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -38,7 +38,7 @@
#include <asm/tlb.h>
#include <asm/tlbflush.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index c04a1e29f2c6..7bb7b260743d 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -36,7 +36,7 @@
#include <asm/io.h>
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/*
* Cache of MMU context last used.
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index bcfc43ba05f8..191d05fc979c 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -32,7 +32,7 @@
#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */
#include <asm/tlb.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long *sparc_valid_addr_bitmap;
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 5047b4112580..9ca4a0875d19 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -56,6 +56,7 @@
#include <linux/rtc.h>
#include <linux/pci.h>
#include <linux/dm-ioctl.h>
+#include <net/sock.h> /* siocdevprivate_ioctl */
#include <scsi/scsi.h>
/* Ugly hack. */
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index e037f7186dc0..4ab276183379 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -36,7 +36,7 @@
#include <asm/tlb.h>
#include <asm/spitfire.h>
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
extern void device_scan(void);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index f5b9b0dac448..9d3ae3fffdaf 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -45,7 +45,7 @@ extern char __init_begin, __init_end;
extern long physmem_size;
/* Not changed by UML */
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/* Changed during early boot */
int kmalloc_ok = 0;
diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
index fa2efa500c0f..53613d0f8a9e 100644
--- a/arch/x86_64/ia32/ia32_ioctl.c
+++ b/arch/x86_64/ia32/ia32_ioctl.c
@@ -61,6 +61,7 @@
#include <linux/if_tun.h>
#include <linux/dirent.h>
#include <linux/ctype.h>
+#include <net/sock.h> /* siocdevprivate_ioctl */
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/rfcomm.h>
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index cd589916e0ac..dee5a42a2e9f 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -41,7 +41,7 @@
#define Dprintk(x...)
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/*
* NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
index 0d2a8cba9fa3..124351950b34 100644
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -1513,7 +1513,7 @@ static struct block_device_operations floppy_fops =
.revalidate_disk= floppy_revalidate,
};
-static struct gendisk *floppy_find(dev_t dev, int *part, void *data)
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{
int drive = *part & 3;
if ((*part >> 2) > NUM_DISK_TYPES || drive >= FD_MAX_UNITS)
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 354a9789d29d..800228c16081 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -2,5 +2,5 @@
obj-y := core.o sys.o interface.o power.o bus.o \
driver.o class.o platform.o \
- cpu.o firmware.o init.o
+ cpu.o firmware.o init.o map.o
obj-$(CONFIG_NUMA) += node.o memblk.o
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 2c16f5972898..9d4e16eea0de 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -431,7 +431,7 @@ int bus_add_driver(struct device_driver * drv)
if (bus) {
pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
- strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
+ strlcpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
drv->kobj.kset = &bus->drivers;
if ((error = kobject_register(&drv->kobj))) {
@@ -540,7 +540,7 @@ struct bus_type * find_bus(char * name)
*/
int bus_register(struct bus_type * bus)
{
- strncpy(bus->subsys.kset.kobj.name,bus->name,KOBJ_NAME_LEN);
+ strlcpy(bus->subsys.kset.kobj.name,bus->name,KOBJ_NAME_LEN);
subsys_set_kset(bus,bus_subsys);
subsystem_register(&bus->subsys);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 4e43e97a8a70..bbb9d26a04bb 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -88,7 +88,7 @@ int class_register(struct class * cls)
INIT_LIST_HEAD(&cls->children);
INIT_LIST_HEAD(&cls->interfaces);
- strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
+ strlcpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
subsys_set_kset(cls,class_subsys);
subsystem_register(&cls->subsys);
@@ -258,7 +258,7 @@ int class_device_add(struct class_device *class_dev)
class_dev->class_id);
/* first, register with generic layer. */
- strncpy(class_dev->kobj.name, class_dev->class_id, KOBJ_NAME_LEN);
+ strlcpy(class_dev->kobj.name, class_dev->class_id, KOBJ_NAME_LEN);
kobj_set_kset_s(class_dev, class_obj_subsys);
if (parent)
class_dev->kobj.parent = &parent->subsys.kset.kobj;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index ad47099bc858..4069f77715a9 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -211,7 +211,7 @@ int device_add(struct device *dev)
dev->bus_id, dev->name);
/* first, register with generic layer. */
- strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
+ strlcpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
if (parent)
dev->kobj.parent = &parent->kobj;
diff --git a/drivers/base/map.c b/drivers/base/map.c
new file mode 100644
index 000000000000..0fc8e3a10756
--- /dev/null
+++ b/drivers/base/map.c
@@ -0,0 +1,154 @@
+/*
+ * linux/drivers/base/map.c
+ *
+ * (C) Copyright Al Viro 2002,2003
+ * Released under GPL v2.
+ *
+ * NOTE: data structure needs to be changed. It works, but for large dev_t
+ * it will be too slow. It is isolated, though, so these changes will be
+ * local to that file.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kdev_t.h>
+#include <linux/kobject.h>
+#include <linux/kobj_map.h>
+
+struct kobj_map {
+ struct probe {
+ struct probe *next;
+ dev_t dev;
+ unsigned long range;
+ struct module *owner;
+ kobj_probe_t *get;
+ int (*lock)(dev_t, void *);
+ void *data;
+ } *probes[255];
+ struct rw_semaphore *sem;
+};
+
+static inline int dev_to_index(dev_t dev)
+{
+ return MAJOR(dev) % 255;
+}
+
+int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
+ struct module *module, kobj_probe_t *probe,
+ int (*lock)(dev_t, void *), void *data)
+{
+ unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
+ unsigned index = MAJOR(dev);
+ unsigned i;
+ struct probe *p;
+
+ if (n > 255)
+ n = 255;
+
+ p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);
+
+ if (p == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < n; i++, p++) {
+ p->owner = module;
+ p->get = probe;
+ p->lock = lock;
+ p->dev = dev;
+ p->range = range;
+ p->data = data;
+ }
+ down_write(domain->sem);
+ for (i = 0, p -= n; i < n; i++, p++, index++) {
+ struct probe **s = &domain->probes[index % 255];
+ while (*s && (*s)->range < range)
+ s = &(*s)->next;
+ p->next = *s;
+ *s = p;
+ }
+ up_write(domain->sem);
+ return 0;
+}
+
+void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
+{
+ unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
+ unsigned index = MAJOR(dev);
+ unsigned i;
+ struct probe *found = NULL;
+
+ if (n > 255)
+ n = 255;
+
+ down_write(domain->sem);
+ for (i = 0; i < n; i++, index++) {
+ struct probe **s;
+ for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
+ struct probe *p = *s;
+ if (p->dev == dev && p->range == range) {
+ *s = p->next;
+ if (!found)
+ found = p;
+ break;
+ }
+ }
+ }
+ up_write(domain->sem);
+ kfree(found);
+}
+
+struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
+{
+ struct kobject *kobj;
+ struct probe *p;
+ unsigned best = ~0U;
+
+retry:
+ down_read(domain->sem);
+ for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
+ struct kobject *(*probe)(dev_t, int *, void *);
+ struct module *owner;
+ void *data;
+
+ if (p->dev > dev || p->dev + p->range - 1 < dev)
+ continue;
+ if (p->range - 1 >= best)
+ break;
+ if (!try_module_get(p->owner))
+ continue;
+ owner = p->owner;
+ data = p->data;
+ probe = p->get;
+ best = p->range - 1;
+ *index = dev - p->dev;
+ if (p->lock && p->lock(dev, data) < 0) {
+ module_put(owner);
+ continue;
+ }
+ up_read(domain->sem);
+ kobj = probe(dev, index, data);
+ /* Currently ->owner protects _only_ ->probe() itself. */
+ module_put(owner);
+ if (kobj)
+ return kobj;
+ goto retry;
+ }
+ up_read(domain->sem);
+ return NULL;
+}
+
+struct kobj_map *kobj_map_init(kobj_probe_t *base_probe,
+ struct subsystem *s)
+{
+ struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
+ struct probe *base = kmalloc(sizeof(struct probe), GFP_KERNEL);
+ int i;
+ memset(base, 0, sizeof(struct probe));
+ base->dev = 1;
+ base->range = ~0;
+ base->get = base_probe;
+ for (i = 0; i < 255; i++)
+ p->probes[i] = base;
+ p->sem = &s->rwsem;
+ return p;
+}
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 02651681338b..d3078f393d6f 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -348,7 +348,7 @@ static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
rwflag, int enable);
static int acsi_reqsense( char *buffer, int targ, int lun);
static void acsi_print_error(const unsigned char *errblk, int struct acsi_info_struct *aip);
-static void acsi_interrupt (int irq, void *data, struct pt_regs *fp);
+static irqreturn_t acsi_interrupt (int irq, void *data, struct pt_regs *fp);
static void unexpected_acsi_interrupt( void );
static void bad_rw_intr( void );
static void read_intr( void );
@@ -728,7 +728,7 @@ static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struc
*
*******************************************************************/
-static void acsi_interrupt(int irq, void *data, struct pt_regs *fp )
+static irqreturn_t acsi_interrupt(int irq, void *data, struct pt_regs *fp )
{ void (*acsi_irq_handler)(void) = do_acsi;
@@ -738,6 +738,7 @@ static void acsi_interrupt(int irq, void *data, struct pt_regs *fp )
if (!acsi_irq_handler)
acsi_irq_handler = unexpected_acsi_interrupt;
acsi_irq_handler();
+ return IRQ_HANDLED;
}
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 70dc69bb75ce..3a21119c3ebd 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -247,7 +247,7 @@ static int slm_getstats( char *buffer, int device );
static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
*ppos );
static void start_print( int device );
-static void slm_interrupt(int irc, void *data, struct pt_regs *fp);
+static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp);
static void slm_test_ready( unsigned long dummy );
static void set_dma_addr( unsigned long paddr );
static unsigned long get_dma_addr( void );
@@ -455,7 +455,7 @@ static void start_print( int device )
/* Only called when an error happened or at the end of a page */
-static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
+static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp)
{ unsigned long addr;
int stat;
@@ -476,6 +476,7 @@ static void slm_interrupt(int irc, void *data, struct pt_regs *fp)
wake_up( &print_wait );
stdma_release();
ENABLE_IRQ();
+ return IRQ_HANDLED;
}
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 2e470c6b9195..9ad4b95a11f1 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -216,10 +216,11 @@ static int fd_device[4] = { 0, 0, 0, 0 };
/* Milliseconds timer */
-static void ms_isr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t ms_isr(int irq, void *dummy, struct pt_regs *fp)
{
ms_busy = -1;
wake_up(&ms_wait);
+ return IRQ_HANDLED;
}
/* all waits are queued up
@@ -576,7 +577,7 @@ static unsigned long fd_get_drive_id(int drive)
return (id);
}
-static void fd_block_done(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t fd_block_done(int irq, void *dummy, struct pt_regs *fp)
{
if (block_flag)
custom.dsklen = 0x4000;
@@ -591,6 +592,7 @@ static void fd_block_done(int irq, void *dummy, struct pt_regs *fp)
block_flag = 0;
wake_up (&wait_fd_block);
}
+ return IRQ_HANDLED;
}
static void raw_read(int drive)
@@ -1728,7 +1730,7 @@ static int __init fd_probe_drives(void)
return -ENOMEM;
}
-static struct gendisk *floppy_find(dev_t dev, int *part, void *data)
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{
int drive = *part & 3;
if (unit[drive].type->code == FD_NODRIVE)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 4301d4b80345..ee058e3af72f 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -364,7 +364,7 @@ static void fd_motor_off_timer( unsigned long dummy );
static void check_change( unsigned long dummy );
static __inline__ void set_head_settle_flag( void );
static __inline__ int get_head_settle_flag( void );
-static void floppy_irq (int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp);
static void fd_error( void );
static int do_format(int drive, int type, struct atari_format_descr *desc);
static void do_fd_action( int drive );
@@ -597,7 +597,7 @@ static __inline__ int get_head_settle_flag( void )
static void (*FloppyIRQHandler)( int status ) = NULL;
-static void floppy_irq (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp)
{
unsigned char status;
void (*handler)( int );
@@ -613,6 +613,7 @@ static void floppy_irq (int irq, void *dummy, struct pt_regs *fp)
else {
DPRINT(("FDC irq, no handler\n"));
}
+ return IRQ_HANDLED;
}
@@ -1570,7 +1571,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
*/
/* get the parameters from user space */
- if (p->ref != 1 && p->ref != -1)
+ if (floppy->ref != 1 && floppy->ref != -1)
return -EBUSY;
if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))
return -EFAULT;
@@ -1617,7 +1618,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
printk (KERN_INFO "floppy%d: setting %s %p!\n",
drive, dtp->name, dtp);
UDT = dtp;
- set_capacity(p->disk, UDT->blocks);
+ set_capacity(floppy->disk, UDT->blocks);
if (cmd == FDDEFPRM) {
/* save settings as permanent default type */
@@ -1663,7 +1664,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
}
UDT = dtp;
- set_capacity(p->disk, UDT->blocks);
+ set_capacity(floppy->disk, UDT->blocks);
return 0;
case FDMSGON:
@@ -1677,7 +1678,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
case FDFMTBEG:
return 0;
case FDFMTTRK:
- if (p->ref != 1 && p->ref != -1)
+ if (floppy->ref != 1 && floppy->ref != -1)
return -EBUSY;
if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))
return -EFAULT;
@@ -1686,7 +1687,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
UDT = NULL;
/* MSch: invalidate default_params */
default_params[drive].blocks = 0;
- set_capacity(p->disk, MAX_DISK_SIZE * 2);
+ set_capacity(floppy->disk, MAX_DISK_SIZE * 2);
case FDFMTEND:
case FDFLUSH:
/* invalidate the buffer track to force a reread */
@@ -1895,7 +1896,7 @@ static struct block_device_operations floppy_fops = {
.revalidate_disk= floppy_revalidate,
};
-static struct gendisk *floppy_find(dev_t dev, int *part, void *data)
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{
int drive = *part & 3;
int type = *part >> 2;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index b78eea8c0a73..d18ef9356fa6 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -134,7 +134,7 @@ static int sendcmd(
static int ida_open(struct inode *inode, struct file *filep);
static int ida_release(struct inode *inode, struct file *filep);
static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
-static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io);
+static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
static void do_ida_request(request_queue_t *q);
static void start_io(ctlr_info_t *h);
@@ -147,7 +147,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout);
static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
static void ida_timer(unsigned long tdata);
static int ida_revalidate(struct gendisk *disk);
-static int revalidate_allvol(kdev_t dev);
+static int revalidate_allvol(ctlr_info_t *host);
#ifdef CONFIG_PROC_FS
static void ida_procinit(int i);
@@ -158,6 +158,17 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset,
int length, int *eof, void *data) { return 0;}
#endif
+static inline drv_info_t *get_drv(struct gendisk *disk)
+{
+ return disk->private_data;
+}
+
+static inline ctlr_info_t *get_host(struct gendisk *disk)
+{
+ return disk->queue->queuedata;
+}
+
+
static struct block_device_operations ida_fops = {
.owner = THIS_MODULE,
.open = ida_open,
@@ -401,7 +412,7 @@ static int __init cpqarray_init(void)
disk->major = COMPAQ_SMART2_MAJOR + i;
disk->first_minor = j<<NWD_SHIFT;
disk->fops = &ida_fops;
- if (!drv->nr_blks)
+ if (j && !drv->nr_blks)
continue;
hba[i]->queue.hardsect_size = drv->blk_size;
set_capacity(disk, drv->nr_blks);
@@ -704,27 +715,23 @@ DBGINFO(
*/
static int ida_open(struct inode *inode, struct file *filep)
{
- int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
- int dsk = minor(inode->i_rdev) >> NWD_SHIFT;
-
- DBGINFO(printk("ida_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk) );
- if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
- return -ENXIO;
+ drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+ ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+ DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name));
/*
* Root is allowed to open raw volume zero even if it's not configured
* so array config can still work. I don't think I really like this,
* but I'm already using way to many device nodes to claim another one
* for "raw controller".
*/
- if (!hba[ctlr]->drv[dsk].nr_blks) {
+ if (!drv->nr_blks) {
if (!capable(CAP_SYS_RAWIO))
return -ENXIO;
- /* Huh??? */
- if (capable(CAP_SYS_ADMIN) && minor(inode->i_rdev) != 0)
+ if (!capable(CAP_SYS_ADMIN) && drv != host->drv)
return -ENXIO;
}
- hba[ctlr]->usage_count++;
+ host->usage_count++;
return 0;
}
@@ -733,8 +740,8 @@ static int ida_open(struct inode *inode, struct file *filep)
*/
static int ida_release(struct inode *inode, struct file *filep)
{
- int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
- hba[ctlr]->usage_count--;
+ ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
+ host->usage_count--;
return 0;
}
@@ -1015,8 +1022,8 @@ static void ida_timer(unsigned long tdata)
*/
static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
{
- int ctlr = major(inode->i_rdev) - COMPAQ_SMART2_MAJOR;
- int dsk = minor(inode->i_rdev) >> NWD_SHIFT;
+ drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
+ ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
int error;
int diskinfo[4];
struct hd_geometry *geo = (struct hd_geometry *)arg;
@@ -1025,14 +1032,14 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
switch(cmd) {
case HDIO_GETGEO:
- if (hba[ctlr]->drv[dsk].cylinders) {
- diskinfo[0] = hba[ctlr]->drv[dsk].heads;
- diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
- diskinfo[2] = hba[ctlr]->drv[dsk].cylinders;
+ if (drv->cylinders) {
+ diskinfo[0] = drv->heads;
+ diskinfo[1] = drv->sectors;
+ diskinfo[2] = drv->cylinders;
} else {
diskinfo[0] = 0xff;
diskinfo[1] = 0x3f;
- diskinfo[2] = hba[ctlr]->drv[dsk].nr_blks / (0xff*0x3f);
+ diskinfo[2] = drv->nr_blks / (0xff*0x3f);
}
put_user(diskinfo[0], &geo->heads);
put_user(diskinfo[1], &geo->sectors);
@@ -1040,23 +1047,24 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
put_user(get_start_sect(inode->i_bdev), &geo->start);
return 0;
case IDAGETDRVINFO:
- if (copy_to_user(&io->c.drv, &hba[ctlr]->drv[dsk],
- sizeof(drv_info_t)))
+ if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
return -EFAULT;
return 0;
case IDAPASSTHRU:
if (!capable(CAP_SYS_RAWIO)) return -EPERM;
if (copy_from_user(&my_io, io, sizeof(my_io)))
return -EFAULT;
- error = ida_ctlr_ioctl(ctlr, dsk, &my_io);
+ error = ida_ctlr_ioctl(host, drv - host->drv, &my_io);
if (error) return error;
return copy_to_user(io, &my_io, sizeof(my_io)) ? -EFAULT : 0;
case IDAGETCTLRSIG:
if (!arg) return -EINVAL;
- put_user(hba[ctlr]->ctlr_sig, (int*)arg);
+ put_user(host->ctlr_sig, (int*)arg);
return 0;
case IDAREVALIDATEVOLS:
- return revalidate_allvol(inode->i_rdev);
+ if (minor(inode->i_rdev) != 0)
+ return -ENXIO;
+ return revalidate_allvol(host);
case IDADRIVERVERSION:
if (!arg) return -EINVAL;
put_user(DRIVER_VERSION, (unsigned long*)arg);
@@ -1067,9 +1075,9 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
ida_pci_info_struct pciinfo;
if (!arg) return -EINVAL;
- pciinfo.bus = hba[ctlr]->pci_dev->bus->number;
- pciinfo.dev_fn = hba[ctlr]->pci_dev->devfn;
- pciinfo.board_id = hba[ctlr]->board_id;
+ pciinfo.bus = host->pci_dev->bus->number;
+ pciinfo.dev_fn = host->pci_dev->devfn;
+ pciinfo.board_id = host->board_id;
if(copy_to_user((void *) arg, &pciinfo,
sizeof( ida_pci_info_struct)))
return -EFAULT;
@@ -1091,9 +1099,9 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
* any serious sanity checking on the arguments. Doing an IDA_WRITE_MEDIA and
* putting a 64M buffer in the sglist is probably a *bad* idea.
*/
-static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
+static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io)
{
- ctlr_info_t *h = hba[ctlr];
+ int ctlr = h->ctlr;
cmdlist_t *c;
void *p = NULL;
unsigned long flags;
@@ -1387,59 +1395,57 @@ DBG(
* particualar logical volume (instead of all of them on a particular
* controller).
*/
-static int revalidate_allvol(kdev_t dev)
+static int revalidate_allvol(ctlr_info_t *host)
{
- int ctlr, i;
+ int ctlr = host->ctlr;
+ int i;
unsigned long flags;
- if (minor(dev) != 0)
- return -ENXIO;
-
- ctlr = major(dev) - COMPAQ_SMART2_MAJOR;
-
spin_lock_irqsave(IDA_LOCK(ctlr), flags);
- if (hba[ctlr]->usage_count > 1) {
+ if (host->usage_count > 1) {
spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
printk(KERN_WARNING "cpqarray: Device busy for volume"
- " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
+ " revalidation (usage=%d)\n", host->usage_count);
return -EBUSY;
}
- hba[ctlr]->usage_count++;
+ host->usage_count++;
spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
/*
* Set the partition and block size structures for all volumes
* on this controller to zero. We will reread all of this data
*/
- for (i = 0; i < NWD; i++) {
+ set_capacity(ida_gendisk[ctlr][0], 0);
+ for (i = 1; i < NWD; i++) {
struct gendisk *disk = ida_gendisk[ctlr][i];
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
}
- memset(hba[ctlr]->drv, 0, sizeof(drv_info_t)*NWD);
+ memset(host->drv, 0, sizeof(drv_info_t)*NWD);
/*
* Tell the array controller not to give us any interrupts while
* we check the new geometry. Then turn interrupts back on when
* we're done.
*/
- hba[ctlr]->access.set_intr_mask(hba[ctlr], 0);
+ host->access.set_intr_mask(host, 0);
getgeometry(ctlr);
- hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY);
+ host->access.set_intr_mask(host, FIFO_NOT_EMPTY);
for(i=0; i<NWD; i++) {
struct gendisk *disk = ida_gendisk[ctlr][i];
- drv_info_t *drv = &hba[ctlr]->drv[i];
- if (!drv->nr_blks)
+ drv_info_t *drv = &host->drv[i];
+ if (i && !drv->nr_blks)
continue;
- hba[ctlr]->queue.hardsect_size = drv->blk_size;
+ host->queue.hardsect_size = drv->blk_size;
set_capacity(disk, drv->nr_blks);
- disk->queue = &hba[ctlr]->queue;
+ disk->queue = &host->queue;
disk->private_data = drv;
- add_disk(disk);
+ if (i)
+ add_disk(disk);
}
- hba[ctlr]->usage_count--;
+ host->usage_count--;
return 0;
}
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 1ba0019f493a..ca2332522f9a 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4212,7 +4212,7 @@ static struct platform_device floppy_device = {
},
};
-static struct gendisk *floppy_find(dev_t dev, int *part, void *data)
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{
int drive = (*part&3) | ((*part&0x80) >> 5);
if (drive >= N_DRIVE ||
diff --git a/drivers/block/floppy98.c b/drivers/block/floppy98.c
index 226b0cee8a20..18b12fd309a9 100644
--- a/drivers/block/floppy98.c
+++ b/drivers/block/floppy98.c
@@ -4246,7 +4246,7 @@ static struct platform_device floppy_device = {
},
};
-static struct gendisk *floppy_find(dev_t dev, int *part, void *data)
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
{
int drive = (*part&3) | ((*part&0x80) >> 5);
if (drive >= N_DRIVE ||
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 232f7bc0b40f..ebfecee2f69e 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -13,13 +13,14 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/kmod.h>
+#include <linux/kobj_map.h>
#define MAX_PROBE_HASH 255 /* random */
static struct subsystem block_subsys;
/*
- * Can be merged with blk_probe or deleted altogether. Later.
+ * Can be deleted altogether. Later.
*
* Modified under both block_subsys.rwsem and major_names_lock.
*/
@@ -31,27 +32,12 @@ static struct blk_major_name {
static spinlock_t major_names_lock = SPIN_LOCK_UNLOCKED;
-static struct blk_probe {
- struct blk_probe *next;
- dev_t dev;
- unsigned long range;
- struct module *owner;
- struct gendisk *(*get)(dev_t dev, int *part, void *data);
- int (*lock)(dev_t, void *);
- void *data;
-} *probes[MAX_PROBE_HASH];
-
/* index in the above - for now: assume no multimajor ranges */
static inline int major_to_index(int major)
{
return major % MAX_PROBE_HASH;
}
-static inline int dev_to_index(dev_t dev)
-{
- return major_to_index(MAJOR(dev));
-}
-
/* get block device names in somewhat random order */
int get_blkdev_list(char *p)
{
@@ -156,59 +142,32 @@ int unregister_blkdev(unsigned int major, const char *name)
return ret;
}
+static struct kobj_map *bdev_map;
+
/*
* Register device numbers dev..(dev+range-1)
* range must be nonzero
* The hash chain is sorted on range, so that subranges can override.
*/
void blk_register_region(dev_t dev, unsigned long range, struct module *module,
- struct gendisk *(*probe)(dev_t, int *, void *),
+ struct kobject *(*probe)(dev_t, int *, void *),
int (*lock)(dev_t, void *), void *data)
{
- int index = dev_to_index(dev);
- struct blk_probe *p = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
- struct blk_probe **s;
-
- if (p == NULL)
- return;
-
- p->owner = module;
- p->get = probe;
- p->lock = lock;
- p->dev = dev;
- p->range = range;
- p->data = data;
- down_write(&block_subsys.rwsem);
- for (s = &probes[index]; *s && (*s)->range < range; s = &(*s)->next)
- ;
- p->next = *s;
- *s = p;
- up_write(&block_subsys.rwsem);
+ kobj_map(bdev_map, dev, range, module, probe, lock, data);
}
void blk_unregister_region(dev_t dev, unsigned long range)
{
- int index = dev_to_index(dev);
- struct blk_probe **s;
-
- down_write(&block_subsys.rwsem);
- for (s = &probes[index]; *s; s = &(*s)->next) {
- struct blk_probe *p = *s;
- if (p->dev == dev && p->range == range) {
- *s = p->next;
- kfree(p);
- break;
- }
- }
- up_write(&block_subsys.rwsem);
+ kobj_unmap(bdev_map, dev, range);
}
EXPORT_SYMBOL(blk_register_region);
EXPORT_SYMBOL(blk_unregister_region);
-static struct gendisk *exact_match(dev_t dev, int *part, void *data)
+static struct kobject *exact_match(dev_t dev, int *part, void *data)
{
- return data;
+ struct gendisk *p = data;
+ return &p->kobj;
}
static int exact_lock(dev_t dev, void *data)
@@ -246,6 +205,8 @@ void unlink_gendisk(struct gendisk *disk)
disk->minors);
}
+#define to_disk(obj) container_of(obj,struct gendisk,kobj)
+
/**
* get_gendisk - get partitioning information for a given device
* @dev: device to get partitioning information for
@@ -253,46 +214,10 @@ void unlink_gendisk(struct gendisk *disk)
* This function gets the structure containing partitioning
* information for the given device @dev.
*/
-struct gendisk *
-get_gendisk(dev_t dev, int *part)
+struct gendisk *get_gendisk(dev_t dev, int *part)
{
- int index = dev_to_index(dev);
- struct gendisk *disk;
- struct blk_probe *p;
- unsigned best = ~0U;
-
-retry:
- down_read(&block_subsys.rwsem);
- for (p = probes[index]; p; p = p->next) {
- struct gendisk *(*probe)(dev_t, int *, void *);
- struct module *owner;
- void *data;
-
- if (p->dev > dev || p->dev + p->range - 1 < dev)
- continue;
- if (p->range - 1 >= best)
- break;
- if (!try_module_get(p->owner))
- continue;
- owner = p->owner;
- data = p->data;
- probe = p->get;
- best = p->range - 1;
- *part = dev - p->dev;
- if (p->lock && p->lock(dev, data) < 0) {
- module_put(owner);
- continue;
- }
- up_read(&block_subsys.rwsem);
- disk = probe(dev, part, data);
- /* Currently ->owner protects _only_ ->probe() itself. */
- module_put(owner);
- if (disk)
- return disk;
- goto retry; /* this terminates: best decreases */
- }
- up_read(&block_subsys.rwsem);
- return NULL;
+ struct kobject *kobj = kobj_lookup(bdev_map, dev, part);
+ return kobj ? to_disk(kobj) : NULL;
}
#ifdef CONFIG_PROC_FS
@@ -365,7 +290,7 @@ struct seq_operations partitions_op = {
extern int blk_dev_init(void);
-static struct gendisk *base_probe(dev_t dev, int *part, void *data)
+static struct kobject *base_probe(dev_t dev, int *part, void *data)
{
request_module("block-major-%d", MAJOR(dev));
return NULL;
@@ -373,14 +298,7 @@ static struct gendisk *base_probe(dev_t dev, int *part, void *data)
int __init device_init(void)
{
- struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
- int i;
- memset(base, 0, sizeof(struct blk_probe));
- base->dev = 1;
- base->range = ~0; /* range 1 .. ~0 */
- base->get = base_probe;
- for (i = 0; i < MAX_PROBE_HASH; i++)
- probes[i] = base; /* must remain last in chain */
+ bdev_map = kobj_map_init(base_probe, &block_subsys);
blk_dev_init();
subsystem_register(&block_subsys);
return 0;
@@ -394,8 +312,6 @@ subsys_initcall(device_init);
* kobject & sysfs bindings for block devices
*/
-#define to_disk(obj) container_of(obj,struct gendisk,kobj)
-
struct disk_attribute {
struct attribute attr;
ssize_t (*show)(struct gendisk *, char *);
@@ -632,7 +548,7 @@ struct gendisk *alloc_disk(int minors)
return disk;
}
-struct gendisk *get_disk(struct gendisk *disk)
+struct kobject *get_disk(struct gendisk *disk)
{
struct module *owner;
struct kobject *kobj;
@@ -647,7 +563,7 @@ struct gendisk *get_disk(struct gendisk *disk)
module_put(owner);
return NULL;
}
- return to_disk(kobj);
+ return kobj;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index ef225d2e6685..b6e854b8613a 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -136,31 +136,23 @@
*/
-static int verbose = 0;
-static int major = PG_MAJOR;
-static char *name = PG_NAME;
-static int disable = 0;
+static int verbose = 0;
+static int major = PG_MAJOR;
+static char *name = PG_NAME;
+static int disable = 0;
-static int drive0[6] = {0,0,0,-1,-1,-1};
-static int drive1[6] = {0,0,0,-1,-1,-1};
-static int drive2[6] = {0,0,0,-1,-1,-1};
-static int drive3[6] = {0,0,0,-1,-1,-1};
+static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
-static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
+static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
static int pg_drive_count;
-#define D_PRT 0
-#define D_PRO 1
-#define D_UNI 2
-#define D_MOD 3
-#define D_SLV 4
-#define D_DLY 5
-
-#define DU (*drives[unit])
+enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
/* end of parameters */
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
@@ -176,30 +168,32 @@ static int pg_drive_count;
#include "setup.h"
-static STT pg_stt[5] = {{"drive0",6,drive0},
- {"drive1",6,drive1},
- {"drive2",6,drive2},
- {"drive3",6,drive3},
- {"disable",1,&disable}};
-
-void pg_setup( char *str, int *ints)
+static STT pg_stt[5] = {
+ {"drive0", 6, drive0},
+ {"drive1", 6, drive1},
+ {"drive2", 6, drive2},
+ {"drive3", 6, drive3},
+ {"disable", 1, &disable}
+};
-{ generic_setup(pg_stt,5,str);
+void pg_setup(char *str, int *ints)
+{
+ generic_setup(pg_stt, 5, str);
}
#endif
-MODULE_PARM(verbose,"i");
-MODULE_PARM(major,"i");
-MODULE_PARM(name,"s");
-MODULE_PARM(drive0,"1-6i");
-MODULE_PARM(drive1,"1-6i");
-MODULE_PARM(drive2,"1-6i");
-MODULE_PARM(drive3,"1-6i");
+MODULE_PARM(verbose, "i");
+MODULE_PARM(major, "i");
+MODULE_PARM(name, "s");
+MODULE_PARM(drive0, "1-6i");
+MODULE_PARM(drive1, "1-6i");
+MODULE_PARM(drive2, "1-6i");
+MODULE_PARM(drive3, "1-6i");
#include "paride.h"
-#define PG_SPIN_DEL 50 /* spin delay in micro-seconds */
+#define PG_SPIN_DEL 50 /* spin delay in micro-seconds */
#define PG_SPIN 200
#define PG_TMO HZ
#define PG_RESET_TMO 10*HZ
@@ -216,91 +210,101 @@ MODULE_PARM(drive3,"1-6i");
#define ATAPI_IDENTIFY 0x12
static int pg_open(struct inode *inode, struct file *file);
-static int pg_release (struct inode *inode, struct file *file);
-static ssize_t pg_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos);
-static ssize_t pg_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos);
+static int pg_release(struct inode *inode, struct file *file);
+static ssize_t pg_read(struct file *filp, char *buf,
+ size_t count, loff_t * ppos);
+static ssize_t pg_write(struct file *filp, const char *buf,
+ size_t count, loff_t * ppos);
static int pg_detect(void);
-static int pg_identify (int unit, int log);
-
#define PG_NAMELEN 8
-struct pg_unit {
- struct pi_adapter pia; /* interface to paride layer */
+struct pg {
+ struct pi_adapter pia; /* interface to paride layer */
struct pi_adapter *pi;
- int busy; /* write done, read expected */
- int start; /* jiffies at command start */
- int dlen; /* transfer size requested */
- unsigned long timeout; /* timeout requested */
- int status; /* last sense key */
- int drive; /* drive */
- unsigned long access; /* count of active opens ... */
- int present; /* device present ? */
+ int busy; /* write done, read expected */
+ int start; /* jiffies at command start */
+ int dlen; /* transfer size requested */
+ unsigned long timeout; /* timeout requested */
+ int status; /* last sense key */
+ int drive; /* drive */
+ unsigned long access; /* count of active opens ... */
+ int present; /* device present ? */
char *bufptr;
- char name[PG_NAMELEN]; /* pg0, pg1, ... */
+ char name[PG_NAMELEN]; /* pg0, pg1, ... */
};
-struct pg_unit pg[PG_UNITS];
-
-/* 'unit' must be defined in all functions - either as a local or a param */
+struct pg devices[PG_UNITS];
-#define PG pg[unit]
-#define PI PG.pi
+static int pg_identify(struct pg *dev, int log);
-static char pg_scratch[512]; /* scratch block buffer */
+static char pg_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
static struct file_operations pg_fops = {
- .owner = THIS_MODULE,
- .read = pg_read,
- .write = pg_write,
- .open = pg_open,
- .release = pg_release,
+ .owner = THIS_MODULE,
+ .read = pg_read,
+ .write = pg_write,
+ .open = pg_open,
+ .release = pg_release,
};
-void pg_init_units( void )
-
-{ int unit, j;
+static void pg_init_units(void)
+{
+ int unit;
pg_drive_count = 0;
- for (unit=0;unit<PG_UNITS;unit++) {
- PG.pi = & PG.pia;
- set_bit( 0, &PG.access );
- PG.busy = 0;
- PG.present = 0;
- PG.bufptr = NULL;
- PG.drive = DU[D_SLV];
- j = 0;
- while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
- PG.name[j++] = '0' + unit;
- PG.name[j] = 0;
- if (DU[D_PRT]) pg_drive_count++;
+ for (unit = 0; unit < PG_UNITS; unit++) {
+ int *parm = *drives[unit];
+ struct pg *dev = &devices[unit];
+ dev->pi = &dev->pia;
+ set_bit(0, &dev->access);
+ dev->busy = 0;
+ dev->present = 0;
+ dev->bufptr = NULL;
+ dev->drive = parm[D_SLV];
+ snprintf(dev->name, PG_NAMELEN, "%s%c", name, 'a'+unit);
+ if (parm[D_PRT])
+ pg_drive_count++;
}
-}
+}
-#define WR(c,r,v) pi_write_regr(PI,c,r,v)
-#define RR(c,r) (pi_read_regr(PI,c,r))
+static inline int status_reg(struct pg *dev)
+{
+ return pi_read_regr(dev->pi, 1, 6);
+}
-#define DRIVE (0xa0+0x10*PG.drive)
+static inline int read_reg(struct pg *dev, int reg)
+{
+ return pi_read_regr(dev->pi, 0, reg);
+}
-static void pg_sleep( int cs )
+static inline void write_reg(struct pg *dev, int reg, int val)
+{
+ pi_write_regr(dev->pi, 0, reg, val);
+}
+
+static inline u8 DRIVE(struct pg *dev)
+{
+ return 0xa0+0x10*dev->drive;
+}
-{ current->state = TASK_INTERRUPTIBLE;
+static void pg_sleep(int cs)
+{
+ current->state = TASK_INTERRUPTIBLE;
schedule_timeout(cs);
}
-static int pg_wait(int unit, int go, int stop, unsigned long tmo, char *msg)
+static int pg_wait(struct pg *dev, int go, int stop, unsigned long tmo, char *msg)
{
int j, r, e, s, p, to;
- PG.status = 0;
+ dev->status = 0;
j = 0;
- while ((((r=RR(1,6))&go) || (stop&&(!(r&stop))))
- && time_before(jiffies,tmo)) {
+ while ((((r = status_reg(dev)) & go) || (stop && (!(r & stop))))
+ && time_before(jiffies, tmo)) {
if (j++ < PG_SPIN)
udelay(PG_SPIN_DEL);
else
@@ -309,325 +313,349 @@ static int pg_wait(int unit, int go, int stop, unsigned long tmo, char *msg)
to = time_after_eq(jiffies, tmo);
- if ((r&(STAT_ERR&stop)) || to) {
- s = RR(0,7);
- e = RR(0,1);
- p = RR(0,2);
+ if ((r & (STAT_ERR & stop)) || to) {
+ s = read_reg(dev, 7);
+ e = read_reg(dev, 1);
+ p = read_reg(dev, 2);
if (verbose > 1)
printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
- PG.name, msg, s, e, p, to ? " timeout" : "");
+ dev->name, msg, s, e, p, to ? " timeout" : "");
if (to)
e |= 0x100;
- PG.status = (e >> 4) & 0xff;
+ dev->status = (e >> 4) & 0xff;
return -1;
}
return 0;
}
-static int pg_command(int unit, char *cmd, int dlen, unsigned long tmo)
+static int pg_command(struct pg *dev, char *cmd, int dlen, unsigned long tmo)
{
int k;
- pi_connect(PI);
+ pi_connect(dev->pi);
- WR(0,6,DRIVE);
+ write_reg(dev, 6, DRIVE(dev));
- if (pg_wait(unit, STAT_BUSY|STAT_DRQ, 0, tmo, "before command")) {
- pi_disconnect(PI);
- return -1;
- }
+ if (pg_wait(dev, STAT_BUSY | STAT_DRQ, 0, tmo, "before command"))
+ goto fail;
- WR(0,4,dlen % 256);
- WR(0,5,dlen / 256);
- WR(0,7,0xa0); /* ATAPI packet command */
+ write_reg(dev, 4, dlen % 256);
+ write_reg(dev, 5, dlen / 256);
+ write_reg(dev, 7, 0xa0); /* ATAPI packet command */
- if (pg_wait(unit, STAT_BUSY, STAT_DRQ, tmo, "command DRQ")) {
- pi_disconnect(PI);
- return -1;
- }
+ if (pg_wait(dev, STAT_BUSY, STAT_DRQ, tmo, "command DRQ"))
+ goto fail;
- if (RR(0,2) != 1) {
- printk("%s: command phase error\n",PG.name);
- pi_disconnect(PI);
- return -1;
+ if (read_reg(dev, 2) != 1) {
+ printk("%s: command phase error\n", dev->name);
+ goto fail;
}
- pi_write_block(PI,cmd,12);
+ pi_write_block(dev->pi, cmd, 12);
if (verbose > 1) {
- printk("%s: Command sent, dlen=%d packet= ", PG.name,dlen);
- for (k=0;k<12;k++) printk("%02x ",cmd[k]&0xff);
+ printk("%s: Command sent, dlen=%d packet= ", dev->name, dlen);
+ for (k = 0; k < 12; k++)
+ printk("%02x ", cmd[k] & 0xff);
printk("\n");
}
return 0;
+fail:
+ pi_disconnect(dev->pi);
+ return -1;
}
-static int pg_completion(int unit, char *buf, unsigned long tmo)
+static int pg_completion(struct pg *dev, char *buf, unsigned long tmo)
{
int r, d, n, p;
- r = pg_wait(unit, STAT_BUSY, STAT_DRQ|STAT_READY|STAT_ERR,
+ r = pg_wait(dev, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
tmo, "completion");
- PG.dlen = 0;
+ dev->dlen = 0;
- while (RR(0,7)&STAT_DRQ) {
- d = (RR(0,4)+256*RR(0,5));
- n = ((d+3)&0xfffc);
- p = RR(0,2)&3;
+ while (read_reg(dev, 7) & STAT_DRQ) {
+ d = (read_reg(dev, 4) + 256 * read_reg(dev, 5));
+ n = ((d + 3) & 0xfffc);
+ p = read_reg(dev, 2) & 3;
if (p == 0)
- pi_write_block(PI,buf,n);
+ pi_write_block(dev->pi, buf, n);
if (p == 2)
- pi_read_block(PI,buf,n);
+ pi_read_block(dev->pi, buf, n);
if (verbose > 1)
- printk("%s: %s %d bytes\n", PG.name,
- p?"Read":"Write", n);
- PG.dlen += (1-p)*d;
+ printk("%s: %s %d bytes\n", dev->name,
+ p ? "Read" : "Write", n);
+ dev->dlen += (1 - p) * d;
buf += d;
- r = pg_wait(unit, STAT_BUSY, STAT_DRQ|STAT_READY|STAT_ERR,
+ r = pg_wait(dev, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
tmo, "completion");
}
- pi_disconnect(PI);
+ pi_disconnect(dev->pi);
return r;
}
-static int pg_reset( int unit )
-
-{ int i, k, flg;
- int expect[5] = {1,1,1,0x14,0xeb};
+static int pg_reset(struct pg *dev)
+{
+ int i, k, err;
+ int expect[5] = { 1, 1, 1, 0x14, 0xeb };
+ int got[5];
- pi_connect(PI);
- WR(0,6,DRIVE);
- WR(0,7,8);
+ pi_connect(dev->pi);
+ write_reg(dev, 6, DRIVE(dev));
+ write_reg(dev, 7, 8);
- pg_sleep(20*HZ/1000);
+ pg_sleep(20 * HZ / 1000);
k = 0;
- while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
+ while ((k++ < PG_RESET_TMO) && (status_reg(dev) & STAT_BUSY))
pg_sleep(1);
- flg = 1;
- for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
+ for (i = 0; i < 5; i++)
+ got[i] = read_reg(dev, i + 1);
+
+ err = memcmp(expect, got, sizeof(got)) ? -1 : 0;
if (verbose) {
- printk("%s: Reset (%d) signature = ",PG.name,k);
- for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
- if (!flg) printk(" (incorrect)");
+ printk("%s: Reset (%d) signature = ", dev->name, k);
+ for (i = 0; i < 5; i++)
+ printk("%3x", got[i]);
+ if (err)
+ printk(" (incorrect)");
printk("\n");
}
-
- pi_disconnect(PI);
- return flg-1;
-}
-
-static void xs( char *buf, char *targ, int offs, int len )
-{ int j,k,l;
-
- j=0; l=0;
- for (k=0;k<len;k++)
- if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
- l=targ[j++]=buf[k+offs];
- if (l==0x20) j--;
- targ[j]=0;
+ pi_disconnect(dev->pi);
+ return err;
}
-static int pg_identify( int unit, int log )
+static void xs(char *buf, char *targ, int len)
+{
+ char l = '\0';
+ int k;
-{ int s;
- char *ms[2] = {"master","slave"};
- char mf[10], id[18];
- char id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
- char buf[36];
+ for (k = 0; k < len; k++) {
+ char c = *buf++;
+ if (c != ' ' || c != l)
+ l = *targ++ = c;
+ }
+ if (l == ' ')
+ targ--;
+ *targ = '\0';
+}
- s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
- if (s) return -1;
- s = pg_completion(unit,buf,jiffies+PG_TMO);
- if (s) return -1;
+static int pg_identify(struct pg *dev, int log)
+{
+ int s;
+ char *ms[2] = { "master", "slave" };
+ char mf[10], id[18];
+ char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
+ char buf[36];
+
+ s = pg_command(dev, id_cmd, 36, jiffies + PG_TMO);
+ if (s)
+ return -1;
+ s = pg_completion(dev, buf, jiffies + PG_TMO);
+ if (s)
+ return -1;
if (log) {
- xs(buf,mf,8,8);
- xs(buf,id,16,16);
- printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
+ xs(buf + 8, mf, 8);
+ xs(buf + 16, id, 16);
+ printk("%s: %s %s, %s\n", dev->name, mf, id, ms[dev->drive]);
}
return 0;
}
-static int pg_probe( int unit )
-
-/* returns 0, with id set if drive is detected
- -1, if drive detection failed
-*/
-
-{ if (PG.drive == -1) {
- for (PG.drive=0;PG.drive<=1;PG.drive++)
- if (!pg_reset(unit)) return pg_identify(unit,1);
+/*
+ * returns 0, with id set if drive is detected
+ * -1, if drive detection failed
+ */
+static int pg_probe(struct pg *dev)
+{
+ if (dev->drive == -1) {
+ for (dev->drive = 0; dev->drive <= 1; dev->drive++)
+ if (!pg_reset(dev))
+ return pg_identify(dev, 1);
} else {
- if (!pg_reset(unit)) return pg_identify(unit,1);
+ if (!pg_reset(dev))
+ return pg_identify(dev, 1);
}
- return -1;
+ return -1;
}
-static int pg_detect( void )
-
-{ int k, unit;
+static int pg_detect(void)
+{
+ struct pg *dev = &devices[0];
+ int k, unit;
- printk("%s: %s version %s, major %d\n",
- name,name,PG_VERSION,major);
+ printk("%s: %s version %s, major %d\n", name, name, PG_VERSION, major);
k = 0;
if (pg_drive_count == 0) {
- unit = 0;
- if (pi_init(PI,1,-1,-1,-1,-1,-1,pg_scratch,
- PI_PG,verbose,PG.name)) {
- if (!pg_probe(unit)) {
- PG.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- } else for (unit=0;unit<PG_UNITS;unit++) if (DU[D_PRT])
- if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
- DU[D_PRO],DU[D_DLY],pg_scratch,PI_PG,verbose,
- PG.name)) {
- if (!pg_probe(unit)) {
- PG.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- if (k) return 0;
-
- printk("%s: No ATAPI device detected\n",name);
+ if (pi_init(dev->pi, 1, -1, -1, -1, -1, -1, pg_scratch,
+ PI_PG, verbose, dev->name)) {
+ if (!pg_probe(dev)) {
+ dev->present = 1;
+ k++;
+ } else
+ pi_release(dev->pi);
+ }
+
+ } else
+ for (unit = 0; unit < PG_UNITS; unit++, dev++) {
+ int *parm = *drives[unit];
+ if (!parm[D_PRT])
+ continue;
+ if (pi_init(dev->pi, 0, parm[D_PRT], parm[D_MOD],
+ parm[D_UNI], parm[D_PRO], parm[D_DLY],
+ pg_scratch, PI_PG, verbose, dev->name)) {
+ if (!pg_probe(dev)) {
+ dev->present = 1;
+ k++;
+ } else
+ pi_release(dev->pi);
+ }
+ }
+
+ if (k)
+ return 0;
+
+ printk("%s: No ATAPI device detected\n", name);
return -1;
}
#define DEVICE_NR(dev) (minor(dev) & 0x7F)
-static int pg_open (struct inode *inode, struct file *file)
-
-{ int unit = DEVICE_NR(inode->i_rdev);
+static int pg_open(struct inode *inode, struct file *file)
+{
+ int unit = DEVICE_NR(inode->i_rdev);
+ struct pg *dev = &devices[unit];
- if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
+ if ((unit >= PG_UNITS) || (!dev->present))
+ return -ENODEV;
- if ( test_and_set_bit(0, &PG.access) ) {
+ if (test_and_set_bit(0, &dev->access))
return -EBUSY;
- }
- if (PG.busy) {
- pg_reset(unit);
- PG.busy = 0;
+ if (dev->busy) {
+ pg_reset(dev);
+ dev->busy = 0;
}
- pg_identify(unit,(verbose>1));
+ pg_identify(dev, (verbose > 1));
-
- PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL);
- if (PG.bufptr == NULL) {
- clear_bit( 0, &PG.access ) ;
- printk("%s: buffer allocation failed\n",PG.name);
+ dev->bufptr = kmalloc(PG_MAX_DATA, GFP_KERNEL);
+ if (dev->bufptr == NULL) {
+ clear_bit(0, &dev->access);
+ printk("%s: buffer allocation failed\n", dev->name);
return -ENOMEM;
}
+ file->private_data = dev;
+
return 0;
}
-static int pg_release (struct inode *inode, struct file *file)
+static int pg_release(struct inode *inode, struct file *file)
{
- int unit = DEVICE_NR(inode->i_rdev);
+ struct pg *dev = file->private_data;
- if ( unit >= PG_UNITS || !test_bit(0,&PG.access) )
- return -EINVAL;
-
- clear_bit( 0, &PG.access);
-
- kfree(PG.bufptr);
- PG.bufptr = NULL;
+ kfree(dev->bufptr);
+ dev->bufptr = NULL;
+ clear_bit(0, &dev->access);
return 0;
-
}
-static ssize_t pg_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos)
+static ssize_t pg_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+ struct pg *dev = filp->private_data;
+ struct pg_write_hdr hdr;
+ int hs = sizeof (hdr);
-{ struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino->i_rdev);
- struct pg_write_hdr hdr;
- int hs = sizeof(hdr);
+ if (dev->busy)
+ return -EBUSY;
+ if (count < hs)
+ return -EINVAL;
- if (PG.busy) return -EBUSY;
- if (count < hs) return -EINVAL;
-
- if (copy_from_user((char *)&hdr, buf, hs))
+ if (copy_from_user((char *) &hdr, buf, hs))
return -EFAULT;
- if (hdr.magic != PG_MAGIC) return -EINVAL;
- if (hdr.dlen > PG_MAX_DATA) return -EINVAL;
- if ((count - hs) > PG_MAX_DATA) return -EINVAL;
+ if (hdr.magic != PG_MAGIC)
+ return -EINVAL;
+ if (hdr.dlen > PG_MAX_DATA)
+ return -EINVAL;
+ if ((count - hs) > PG_MAX_DATA)
+ return -EINVAL;
if (hdr.func == PG_RESET) {
- if (count != hs) return -EINVAL;
- if (pg_reset(unit)) return -EIO;
+ if (count != hs)
+ return -EINVAL;
+ if (pg_reset(dev))
+ return -EIO;
return count;
}
- if (hdr.func != PG_COMMAND) return -EINVAL;
+ if (hdr.func != PG_COMMAND)
+ return -EINVAL;
- PG.start = jiffies;
- PG.timeout = hdr.timeout*HZ + HZ/2 + jiffies;
+ dev->start = jiffies;
+ dev->timeout = hdr.timeout * HZ + HZ / 2 + jiffies;
- if (pg_command(unit,hdr.packet,hdr.dlen,jiffies+PG_TMO)) {
- if (PG.status & 0x10) return -ETIME;
+ if (pg_command(dev, hdr.packet, hdr.dlen, jiffies + PG_TMO)) {
+ if (dev->status & 0x10)
+ return -ETIME;
return -EIO;
}
- PG.busy = 1;
+ dev->busy = 1;
- if (copy_from_user(PG.bufptr, buf + hs, count - hs))
+ if (copy_from_user(dev->bufptr, buf + hs, count - hs))
return -EFAULT;
return count;
}
-static ssize_t pg_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos)
-
-{ struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino->i_rdev);
- struct pg_read_hdr hdr;
- int hs = sizeof(hdr);
- int copy;
+static ssize_t pg_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+ struct pg *dev = filp->private_data;
+ struct pg_read_hdr hdr;
+ int hs = sizeof (hdr);
+ int copy;
- if (!PG.busy) return -EINVAL;
- if (count < hs) return -EINVAL;
+ if (!dev->busy)
+ return -EINVAL;
+ if (count < hs)
+ return -EINVAL;
- PG.busy = 0;
+ dev->busy = 0;
- if (pg_completion(unit,PG.bufptr,PG.timeout))
- if (PG.status & 0x10) return -ETIME;
+ if (pg_completion(dev, dev->bufptr, dev->timeout))
+ if (dev->status & 0x10)
+ return -ETIME;
hdr.magic = PG_MAGIC;
- hdr.dlen = PG.dlen;
+ hdr.dlen = dev->dlen;
copy = 0;
if (hdr.dlen < 0) {
hdr.dlen = -1 * hdr.dlen;
copy = hdr.dlen;
- if (copy > (count - hs)) copy = count - hs;
+ if (copy > (count - hs))
+ copy = count - hs;
}
- hdr.duration = (jiffies - PG.start + HZ/2) / HZ;
- hdr.scsi = PG.status & 0x0f;
+ hdr.duration = (jiffies - dev->start + HZ / 2) / HZ;
+ hdr.scsi = dev->status & 0x0f;
- if (copy_to_user(buf, (char *)&hdr, hs))
+ if (copy_to_user(buf, (char *) &hdr, hs))
return -EFAULT;
if (copy > 0)
- if (copy_to_user(buf+hs,PG.bufptr,copy))
+ if (copy_to_user(buf + hs, dev->bufptr, copy))
return -EFAULT;
- return copy+hs;
+ return copy + hs;
}
static int __init pg_init(void)
@@ -642,19 +670,24 @@ static int __init pg_init(void)
if (pg_detect())
return -1;
- if (register_chrdev(major,name,&pg_fops)) {
- printk("pg_init: unable to get major number %d\n",
- major);
- for (unit=0;unit<PG_UNITS;unit++)
- if (PG.present) pi_release(PI);
+ if (register_chrdev(major, name, &pg_fops)) {
+ printk("pg_init: unable to get major number %d\n", major);
+ for (unit = 0; unit < PG_UNITS; unit++) {
+ struct pg *dev = &devices[unit];
+ if (dev->present)
+ pi_release(dev->pi);
+ }
return -1;
}
- devfs_mk_dir ("pg");
- for (unit=0; unit<PG_UNITS; unit++)
- if (PG.present) {
+ devfs_mk_dir("pg");
+ for (unit = 0; unit < PG_UNITS; unit++) {
+ struct pg *dev = &devices[unit];
+ if (dev->present) {
devfs_mk_cdev(MKDEV(major, unit),
- S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u", unit);
+ S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
+ unit);
}
+ }
return 0;
}
@@ -662,15 +695,20 @@ static void __exit pg_exit(void)
{
int unit;
- for (unit=0; unit<PG_UNITS; unit++)
- if (PG.present)
+ for (unit = 0; unit < PG_UNITS; unit++) {
+ struct pg *dev = &devices[unit];
+ if (dev->present)
devfs_remove("pg/%u", unit);
+ }
- devfs_remove ("pg");
- unregister_chrdev(major,name);
+ devfs_remove("pg");
+ unregister_chrdev(major, name);
- for (unit=0;unit<PG_UNITS;unit++)
- if (PG.present) pi_release(PI);
+ for (unit = 0; unit < PG_UNITS; unit++) {
+ struct pg *dev = &devices[unit];
+ if (dev->present)
+ pi_release(dev->pi);
+ }
}
MODULE_LICENSE("GPL");
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index c9541f651087..c2145ac9da66 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -115,17 +115,17 @@
*/
-static int verbose = 0;
-static int major = PT_MAJOR;
-static char *name = PT_NAME;
-static int disable = 0;
+static int verbose = 0;
+static int major = PT_MAJOR;
+static char *name = PT_NAME;
+static int disable = 0;
-static int drive0[6] = {0,0,0,-1,-1,-1};
-static int drive1[6] = {0,0,0,-1,-1,-1};
-static int drive2[6] = {0,0,0,-1,-1,-1};
-static int drive3[6] = {0,0,0,-1,-1,-1};
+static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
+static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
-static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
+static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
static int pt_drive_count;
#define D_PRT 0
@@ -139,7 +139,6 @@ static int pt_drive_count;
/* end of parameters */
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
@@ -154,37 +153,40 @@ static int pt_drive_count;
#include "setup.h"
-static STT pt_stt[5] = {{"drive0",6,drive0},
- {"drive1",6,drive1},
- {"drive2",6,drive2},
- {"drive3",6,drive3},
- {"disable",1,&disable}};
-
-void pt_setup( char *str, int *ints)
+static STT pt_stt[5] = {
+ {"drive0", 6, drive0},
+ {"drive1", 6, drive1},
+ {"drive2", 6, drive2},
+ {"drive3", 6, drive3},
+ {"disable", 1, &disable}
+};
-{ generic_setup(pt_stt,5,str);
+void
+pt_setup(char *str, int *ints)
+{
+ generic_setup(pt_stt, 5, str);
}
#endif
-MODULE_PARM(verbose,"i");
-MODULE_PARM(major,"i");
-MODULE_PARM(name,"s");
-MODULE_PARM(drive0,"1-6i");
-MODULE_PARM(drive1,"1-6i");
-MODULE_PARM(drive2,"1-6i");
-MODULE_PARM(drive3,"1-6i");
+MODULE_PARM(verbose, "i");
+MODULE_PARM(major, "i");
+MODULE_PARM(name, "s");
+MODULE_PARM(drive0, "1-6i");
+MODULE_PARM(drive1, "1-6i");
+MODULE_PARM(drive2, "1-6i");
+MODULE_PARM(drive3, "1-6i");
#include "paride.h"
#define PT_MAX_RETRIES 5
-#define PT_TMO 3000 /* interrupt timeout in jiffies */
-#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
-#define PT_RESET_TMO 30 /* 30 seconds */
-#define PT_READY_TMO 60 /* 60 seconds */
-#define PT_REWIND_TMO 1200 /* 20 minutes */
+#define PT_TMO 3000 /* interrupt timeout in jiffies */
+#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
+#define PT_RESET_TMO 30 /* 30 seconds */
+#define PT_READY_TMO 60 /* 60 seconds */
+#define PT_REWIND_TMO 1200 /* 20 minutes */
-#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
+#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
#define STAT_ERR 0x00001
#define STAT_INDEX 0x00002
@@ -207,16 +209,16 @@ MODULE_PARM(drive3,"1-6i");
#define ATAPI_LOG_SENSE 0x4d
static int pt_open(struct inode *inode, struct file *file);
-static int pt_ioctl(struct inode *inode,struct file *file,
- unsigned int cmd, unsigned long arg);
-static int pt_release (struct inode *inode, struct file *file);
-static ssize_t pt_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos);
-static ssize_t pt_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos);
+static int pt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static int pt_release(struct inode *inode, struct file *file);
+static ssize_t pt_read(struct file *filp, char *buf,
+ size_t count, loff_t * ppos);
+static ssize_t pt_write(struct file *filp, const char *buf,
+ size_t count, loff_t * ppos);
static int pt_detect(void);
-static int pt_identify (int unit);
+static int pt_identify(int unit);
/* bits in PT.flags */
@@ -231,18 +233,18 @@ static int pt_identify (int unit);
#define PT_BUFSIZE 16384
struct pt_unit {
- struct pi_adapter pia; /* interface to paride layer */
+ struct pi_adapter pia; /* interface to paride layer */
struct pi_adapter *pi;
- int flags; /* various state flags */
- int last_sense; /* result of last request sense */
- int drive; /* drive */
- atomic_t available; /* 1 if access is available 0 otherwise */
- int bs; /* block size */
- int capacity; /* Size of tape in KB */
- int present; /* device present ? */
+ int flags; /* various state flags */
+ int last_sense; /* result of last request sense */
+ int drive; /* drive */
+ atomic_t available; /* 1 if access is available 0 otherwise */
+ int bs; /* block size */
+ int capacity; /* Size of tape in KB */
+ int present; /* device present ? */
char *bufptr;
- char name[PT_NAMELEN]; /* pf0, pf1, ... */
- };
+ char name[PT_NAMELEN]; /* pf0, pf1, ... */
+};
struct pt_unit pt[PT_UNITS];
@@ -251,641 +253,718 @@ struct pt_unit pt[PT_UNITS];
#define PT pt[unit]
#define PI PT.pi
-static char pt_scratch[512]; /* scratch block buffer */
+static char pt_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
static struct file_operations pt_fops = {
- .owner = THIS_MODULE,
- .read = pt_read,
- .write = pt_write,
- .ioctl = pt_ioctl,
- .open = pt_open,
- .release = pt_release,
+ .owner = THIS_MODULE,
+ .read = pt_read,
+ .write = pt_write,
+ .ioctl = pt_ioctl,
+ .open = pt_open,
+ .release = pt_release,
};
-void pt_init_units( void )
-
-{ int unit, j;
+static void pt_init_units(void)
+{
+ int unit, j;
- pt_drive_count = 0;
- for (unit=0;unit<PT_UNITS;unit++) {
- PT.pi = & PT.pia;
- atomic_set( &PT.available, 1 );
- PT.flags = 0;
+ pt_drive_count = 0;
+ for (unit = 0; unit < PT_UNITS; unit++) {
+ PT.pi = &PT.pia;
+ atomic_set(&PT.available, 1);
+ PT.flags = 0;
PT.last_sense = 0;
- PT.present = 0;
+ PT.present = 0;
PT.bufptr = NULL;
PT.drive = DU[D_SLV];
- j = 0;
- while ((j < PT_NAMELEN-2) && (PT.name[j]=name[j])) j++;
- PT.name[j++] = '0' + unit;
- PT.name[j] = 0;
- if (DU[D_PRT]) pt_drive_count++;
- }
+ j = 0;
+ while ((j < PT_NAMELEN - 2) && (PT.name[j] = name[j]))
+ j++;
+ PT.name[j++] = '0' + unit;
+ PT.name[j] = 0;
+ if (DU[D_PRT])
+ pt_drive_count++;
+ }
}
-#define WR(c,r,v) pi_write_regr(PI,c,r,v)
-#define RR(c,r) (pi_read_regr(PI,c,r))
-
-#define DRIVE (0xa0+0x10*PT.drive)
-
-static int pt_wait( int unit, int go, int stop, char * fun, char * msg )
-
-{ int j, r, e, s, p;
-
- j = 0;
- while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PT_SPIN))
- udelay(PT_SPIN_DEL);
-
- if ((r&(STAT_ERR&stop))||(j>=PT_SPIN)) {
- s = RR(0,7);
- e = RR(0,1);
- p = RR(0,2);
- if (j >= PT_SPIN) e |= 0x100;
- if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
- " loop=%d phase=%d\n",
- PT.name,fun,msg,r,s,e,j,p);
- return (e<<8)+s;
- }
- return 0;
+static inline int status_reg(int unit)
+{
+ return pi_read_regr(PI, 1, 6);
}
-static int pt_command( int unit, char * cmd, int dlen, char * fun )
+static inline int read_reg(int unit, int reg)
+{
+ return pi_read_regr(PI, 0, reg);
+}
-{ pi_connect(PI);
+static inline void write_reg(int unit, int reg, int val)
+{
+ pi_write_regr(PI, 0, reg, val);
+}
- WR(0,6,DRIVE);
+#define DRIVE (0xa0+0x10*PT.drive)
- if (pt_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
- pi_disconnect(PI);
- return -1;
- }
+static int pt_wait(int unit, int go, int stop, char *fun, char *msg)
+{
+ int j, r, e, s, p;
+
+ j = 0;
+ while ((((r = status_reg(unit)) & go) || (stop && (!(r & stop))))
+ && (j++ < PT_SPIN))
+ udelay(PT_SPIN_DEL);
+
+ if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
+ s = read_reg(unit, 7);
+ e = read_reg(unit, 1);
+ p = read_reg(unit, 2);
+ if (j >= PT_SPIN)
+ e |= 0x100;
+ if (fun)
+ printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
+ " loop=%d phase=%d\n",
+ PT.name, fun, msg, r, s, e, j, p);
+ return (e << 8) + s;
+ }
+ return 0;
+}
- WR(0,4,dlen % 256);
- WR(0,5,dlen / 256);
- WR(0,7,0xa0); /* ATAPI packet command */
+static int pt_command(int unit, char *cmd, int dlen, char *fun)
+{
+ pi_connect(PI);
- if (pt_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
- pi_disconnect(PI);
- return -1;
- }
+ write_reg(unit, 6, DRIVE);
- if (RR(0,2) != 1) {
- printk("%s: %s: command phase error\n",PT.name,fun);
- pi_disconnect(PI);
- return -1;
- }
+ if (pt_wait(unit, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) {
+ pi_disconnect(PI);
+ return -1;
+ }
- pi_write_block(PI,cmd,12);
+ write_reg(unit, 4, dlen % 256);
+ write_reg(unit, 5, dlen / 256);
+ write_reg(unit, 7, 0xa0); /* ATAPI packet command */
- return 0;
-}
+ if (pt_wait(unit, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) {
+ pi_disconnect(PI);
+ return -1;
+ }
-static int pt_completion( int unit, char * buf, char * fun )
+ if (read_reg(unit, 2) != 1) {
+ printk("%s: %s: command phase error\n", PT.name, fun);
+ pi_disconnect(PI);
+ return -1;
+ }
-{ int r, s, n, p;
+ pi_write_block(PI, cmd, 12);
- r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
- fun,"completion");
+ return 0;
+}
- if (RR(0,7)&STAT_DRQ) {
- n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
- p = RR(0,2)&3;
- if (p == 0) pi_write_block(PI,buf,n);
- if (p == 2) pi_read_block(PI,buf,n);
- }
+static int pt_completion(int unit, char *buf, char *fun)
+{
+ int r, s, n, p;
+
+ r = pt_wait(unit, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR,
+ fun, "completion");
+
+ if (read_reg(unit, 7) & STAT_DRQ) {
+ n = (((read_reg(unit, 4) + 256 * read_reg(unit, 5)) +
+ 3) & 0xfffc);
+ p = read_reg(unit, 2) & 3;
+ if (p == 0)
+ pi_write_block(PI, buf, n);
+ if (p == 2)
+ pi_read_block(PI, buf, n);
+ }
- s = pt_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
+ s = pt_wait(unit, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done");
- pi_disconnect(PI);
+ pi_disconnect(PI);
- return (r?r:s);
+ return (r ? r : s);
}
-static void pt_req_sense( int unit, int quiet )
-
-{ char rs_cmd[12] = { ATAPI_REQ_SENSE,0,0,0,16,0,0,0,0,0,0,0 };
- char buf[16];
- int r;
+static void pt_req_sense(int unit, int quiet)
+{
+ char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
+ char buf[16];
+ int r;
- r = pt_command(unit,rs_cmd,16,"Request sense");
- mdelay(1);
- if (!r) pt_completion(unit,buf,"Request sense");
+ r = pt_command(unit, rs_cmd, 16, "Request sense");
+ mdelay(1);
+ if (!r)
+ pt_completion(unit, buf, "Request sense");
PT.last_sense = -1;
- if (!r) {
- if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
- PT.name,buf[2]&0xf,buf[12],buf[13]);
- PT.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
- | ((buf[13]&0xff)<<16) ;
- }
+ if (!r) {
+ if (!quiet)
+ printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
+ PT.name, buf[2] & 0xf, buf[12], buf[13]);
+ PT.last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8)
+ | ((buf[13] & 0xff) << 16);
+ }
}
-static int pt_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
+static int pt_atapi(int unit, char *cmd, int dlen, char *buf, char *fun)
+{
+ int r;
-{ int r;
+ r = pt_command(unit, cmd, dlen, fun);
+ mdelay(1);
+ if (!r)
+ r = pt_completion(unit, buf, fun);
+ if (r)
+ pt_req_sense(unit, !fun);
- r = pt_command(unit,cmd,dlen,fun);
- mdelay(1);
- if (!r) r = pt_completion(unit,buf,fun);
- if (r) pt_req_sense(unit,!fun);
-
- return r;
+ return r;
}
-static void pt_sleep( int cs )
-
-{ current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(cs);
+static void pt_sleep(int cs)
+{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(cs);
}
-static int pt_poll_dsc( int unit, int pause, int tmo, char *msg )
-
-{ int k, e, s;
+static int pt_poll_dsc(int unit, int pause, int tmo, char *msg)
+{
+ int k, e, s;
- k = 0; e = 0; s = 0;
+ k = 0;
+ e = 0;
+ s = 0;
while (k < tmo) {
pt_sleep(pause);
k++;
pi_connect(PI);
- WR(0,6,DRIVE);
- s = RR(0,7);
- e = RR(0,1);
+ write_reg(unit, 6, DRIVE);
+ s = read_reg(unit, 7);
+ e = read_reg(unit, 1);
pi_disconnect(PI);
- if (s & (STAT_ERR|STAT_SEEK)) break;
+ if (s & (STAT_ERR | STAT_SEEK))
+ break;
}
if ((k >= tmo) || (s & STAT_ERR)) {
- if (k >= tmo) printk("%s: %s DSC timeout\n",PT.name,msg);
- else printk("%s: %s stat=0x%x err=0x%x\n",PT.name,msg,s,e);
- pt_req_sense(unit,0);
- return 0;
+ if (k >= tmo)
+ printk("%s: %s DSC timeout\n", PT.name, msg);
+ else
+ printk("%s: %s stat=0x%x err=0x%x\n", PT.name, msg, s,
+ e);
+ pt_req_sense(unit, 0);
+ return 0;
}
return 1;
}
-static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun)
-
-{ if (pt_command(unit,cmd,0,fun)) {
- pt_req_sense(unit,0);
+static void pt_media_access_cmd(int unit, int tmo, char *cmd, char *fun)
+{
+ if (pt_command(unit, cmd, 0, fun)) {
+ pt_req_sense(unit, 0);
return;
}
pi_disconnect(PI);
- pt_poll_dsc(unit,HZ,tmo,fun);
+ pt_poll_dsc(unit, HZ, tmo, fun);
}
-static void pt_rewind( int unit )
-
-{ char rw_cmd[12] = {ATAPI_REWIND,0,0,0,0,0,0,0,0,0,0,0};
+static void pt_rewind(int unit)
+{
+ char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- pt_media_access_cmd(unit,PT_REWIND_TMO,rw_cmd,"rewind");
+ pt_media_access_cmd(unit, PT_REWIND_TMO, rw_cmd, "rewind");
}
-static void pt_write_fm( int unit )
-
-{ char wm_cmd[12] = {ATAPI_WFM,0,0,0,1,0,0,0,0,0,0,0};
+static void pt_write_fm(int unit)
+{
+ char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
- pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
+ pt_media_access_cmd(unit, PT_TMO, wm_cmd, "write filemark");
}
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
-static int pt_reset( int unit )
-
-{ int i, k, flg;
- int expect[5] = {1,1,1,0x14,0xeb};
+static int pt_reset(int unit)
+{
+ int i, k, flg;
+ int expect[5] = { 1, 1, 1, 0x14, 0xeb };
pi_connect(PI);
- WR(0,6,DRIVE);
- WR(0,7,8);
+ write_reg(unit, 6, DRIVE);
+ write_reg(unit, 7, 8);
- pt_sleep(20*HZ/1000);
+ pt_sleep(20 * HZ / 1000);
- k = 0;
- while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))
- pt_sleep(HZ/10);
+ k = 0;
+ while ((k++ < PT_RESET_TMO) && (status_reg(unit) & STAT_BUSY))
+ pt_sleep(HZ / 10);
flg = 1;
- for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
+ for (i = 0; i < 5; i++)
+ flg &= (read_reg(unit, i + 1) == expect[i]);
if (verbose) {
- printk("%s: Reset (%d) signature = ",PT.name,k);
- for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
- if (!flg) printk(" (incorrect)");
+ printk("%s: Reset (%d) signature = ", PT.name, k);
+ for (i = 0; i < 5; i++)
+ printk("%3x", read_reg(unit, i + 1));
+ if (!flg)
+ printk(" (incorrect)");
printk("\n");
}
-
+
pi_disconnect(PI);
- return flg-1;
+ return flg - 1;
}
-static int pt_ready_wait( int unit, int tmo )
-
-{ char tr_cmd[12] = {ATAPI_TEST_READY,0,0,0,0,0,0,0,0,0,0,0};
- int k, p;
+static int pt_ready_wait(int unit, int tmo)
+{
+ char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int k, p;
k = 0;
while (k < tmo) {
- PT.last_sense = 0;
- pt_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
- p = PT.last_sense;
- if (!p) return 0;
- if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
- k++;
- pt_sleep(HZ);
+ PT.last_sense = 0;
+ pt_atapi(unit, tr_cmd, 0, NULL, DBMSG("test unit ready"));
+ p = PT.last_sense;
+ if (!p)
+ return 0;
+ if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
+ return p;
+ k++;
+ pt_sleep(HZ);
}
return 0x000020; /* timeout */
}
-static void xs( char *buf, char *targ, int offs, int len )
-
-{ int j,k,l;
-
- j=0; l=0;
- for (k=0;k<len;k++)
- if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
- l=targ[j++]=buf[k+offs];
- if (l==0x20) j--;
- targ[j]=0;
+static void xs(char *buf, char *targ, int offs, int len)
+{
+ int j, k, l;
+
+ j = 0;
+ l = 0;
+ for (k = 0; k < len; k++)
+ if ((buf[k + offs] != 0x20) || (buf[k + offs] != l))
+ l = targ[j++] = buf[k + offs];
+ if (l == 0x20)
+ j--;
+ targ[j] = 0;
}
-static int xn( char *buf, int offs, int size )
-
-{ int v,k;
+static int xn(char *buf, int offs, int size)
+{
+ int v, k;
- v=0;
- for(k=0;k<size;k++) v=v*256+(buf[k+offs]&0xff);
+ v = 0;
+ for (k = 0; k < size; k++)
+ v = v * 256 + (buf[k + offs] & 0xff);
return v;
}
-static int pt_identify( int unit )
-
-{ int dt, s;
- char *ms[2] = {"master","slave"};
- char mf[10], id[18];
- char id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
- char ms_cmd[12] = { ATAPI_MODE_SENSE,0,0x2a,0,36,0,0,0,0,0,0,0};
- char ls_cmd[12] = { ATAPI_LOG_SENSE,0,0x71,0,0,0,0,0,36,0,0,0};
- char buf[36];
-
- s = pt_atapi(unit,id_cmd,36,buf,"identify");
- if (s) return -1;
+static int pt_identify(int unit)
+{
+ int dt, s;
+ char *ms[2] = { "master", "slave" };
+ char mf[10], id[18];
+ char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
+ char ms_cmd[12] =
+ { ATAPI_MODE_SENSE, 0, 0x2a, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
+ char ls_cmd[12] =
+ { ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 };
+ char buf[36];
+
+ s = pt_atapi(unit, id_cmd, 36, buf, "identify");
+ if (s)
+ return -1;
dt = buf[0] & 0x1f;
if (dt != 1) {
- if (verbose)
- printk("%s: Drive %d, unsupported type %d\n",
- PT.name,PT.drive,dt);
- return -1;
- }
+ if (verbose)
+ printk("%s: Drive %d, unsupported type %d\n",
+ PT.name, PT.drive, dt);
+ return -1;
+ }
- xs(buf,mf,8,8);
- xs(buf,id,16,16);
+ xs(buf, mf, 8, 8);
+ xs(buf, id, 16, 16);
PT.flags = 0;
PT.capacity = 0;
PT.bs = 0;
- if (!pt_ready_wait(unit,PT_READY_TMO)) PT.flags |= PT_MEDIA;
+ if (!pt_ready_wait(unit, PT_READY_TMO))
+ PT.flags |= PT_MEDIA;
- if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) {
- if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK;
- PT.bs = xn(buf,10,2);
+ if (!pt_atapi(unit, ms_cmd, 36, buf, "mode sense")) {
+ if (!(buf[2] & 0x80))
+ PT.flags |= PT_WRITE_OK;
+ PT.bs = xn(buf, 10, 2);
}
- if (!pt_atapi(unit,ls_cmd,36,buf,"log sense"))
- PT.capacity = xn(buf,24,4);
+ if (!pt_atapi(unit, ls_cmd, 36, buf, "log sense"))
+ PT.capacity = xn(buf, 24, 4);
- printk("%s: %s %s, %s",
- PT.name,mf,id,ms[PT.drive]);
- if (!(PT.flags & PT_MEDIA))
- printk(", no media\n");
- else { if (!(PT.flags & PT_WRITE_OK)) printk(", RO");
- printk(", blocksize %d, %d MB\n",
- PT.bs,PT.capacity/1024);
- }
+ printk("%s: %s %s, %s", PT.name, mf, id, ms[PT.drive]);
+ if (!(PT.flags & PT_MEDIA))
+ printk(", no media\n");
+ else {
+ if (!(PT.flags & PT_WRITE_OK))
+ printk(", RO");
+ printk(", blocksize %d, %d MB\n", PT.bs, PT.capacity / 1024);
+ }
return 0;
}
-static int pt_probe( int unit )
-
-/* returns 0, with id set if drive is detected
- -1, if drive detection failed
-*/
-{ if (PT.drive == -1) {
- for (PT.drive=0;PT.drive<=1;PT.drive++)
- if (!pt_reset(unit)) return pt_identify(unit);
+/*
+ * returns 0, with id set if drive is detected
+ * -1, if drive detection failed
+ */
+static int pt_probe(int unit)
+{
+ if (PT.drive == -1) {
+ for (PT.drive = 0; PT.drive <= 1; PT.drive++)
+ if (!pt_reset(unit))
+ return pt_identify(unit);
} else {
- if (!pt_reset(unit)) return pt_identify(unit);
+ if (!pt_reset(unit))
+ return pt_identify(unit);
}
- return -1;
+ return -1;
}
-static int pt_detect( void )
-
-{ int k, unit;
+static int pt_detect(void)
+{
+ int k, unit;
- printk("%s: %s version %s, major %d\n",
- name,name,PT_VERSION,major);
+ printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
k = 0;
if (pt_drive_count == 0) {
- unit = 0;
- if (pi_init(PI,1,-1,-1,-1,-1,-1,pt_scratch,
- PI_PT,verbose,PT.name)) {
- if (!pt_probe(unit)) {
- PT.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- } else for (unit=0;unit<PT_UNITS;unit++) if (DU[D_PRT])
- if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
- DU[D_PRO],DU[D_DLY],pt_scratch,PI_PT,verbose,
- PT.name)) {
- if (!pt_probe(unit)) {
- PT.present = 1;
- k++;
- } else pi_release(PI);
- }
-
- if (k) return 0;
-
- printk("%s: No ATAPI tape drive detected\n",name);
+ unit = 0;
+ if (pi_init(PI, 1, -1, -1, -1, -1, -1, pt_scratch,
+ PI_PT, verbose, PT.name)) {
+ if (!pt_probe(unit)) {
+ PT.present = 1;
+ k++;
+ } else
+ pi_release(PI);
+ }
+
+ } else
+ for (unit = 0; unit < PT_UNITS; unit++)
+ if (DU[D_PRT])
+ if (pi_init
+ (PI, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI],
+ DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT,
+ verbose, PT.name)) {
+ if (!pt_probe(unit)) {
+ PT.present = 1;
+ k++;
+ } else
+ pi_release(PI);
+ }
+
+ if (k)
+ return 0;
+
+ printk("%s: No ATAPI tape drive detected\n", name);
return -1;
}
#define DEVICE_NR(dev) (minor(dev) & 0x7F)
-static int pt_open (struct inode *inode, struct file *file)
-
-{ int unit = DEVICE_NR(inode->i_rdev);
+static int pt_open(struct inode *inode, struct file *file)
+{
+ int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;
+ if ((unit >= PT_UNITS) || (!PT.present))
+ return -ENODEV;
- if ( !atomic_dec_and_test(&PT.available) ) {
- atomic_inc( &PT.available );
+ if (!atomic_dec_and_test(&PT.available)) {
+ atomic_inc(&PT.available);
return -EBUSY;
}
pt_identify(unit);
if (!PT.flags & PT_MEDIA) {
- atomic_inc( &PT.available );
+ atomic_inc(&PT.available);
return -ENODEV;
- }
+ }
- if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
- atomic_inc( &PT.available );
+ if ((!PT.flags & PT_WRITE_OK) && (file->f_mode & 2)) {
+ atomic_inc(&PT.available);
return -EROFS;
- }
+ }
if (!(minor(inode->i_rdev) & 128))
PT.flags |= PT_REWIND;
- PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
+ PT.bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL);
if (PT.bufptr == NULL) {
- atomic_inc( &PT.available );
- printk("%s: buffer allocation failed\n",PT.name);
+ atomic_inc(&PT.available);
+ printk("%s: buffer allocation failed\n", PT.name);
return -ENOMEM;
}
- return 0;
+ return 0;
}
-static int pt_ioctl(struct inode *inode,struct file *file,
- unsigned int cmd, unsigned long arg)
+static int pt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
int unit;
struct mtop mtop;
- unit = DEVICE_NR(inode->i_rdev);
- if (unit >= PT_UNITS)
+ unit = DEVICE_NR(inode->i_rdev);
+ if (unit >= PT_UNITS)
return -EINVAL;
- if (!PT.present)
+ if (!PT.present)
return -ENODEV;
- switch (cmd) {
- case MTIOCTOP:
- if (copy_from_user((char *)&mtop, (char *)arg,
- sizeof(struct mtop))) return -EFAULT;
+ switch (cmd) {
+ case MTIOCTOP:
+ if (copy_from_user((char *) &mtop, (char *) arg,
+ sizeof (struct mtop)))
+ return -EFAULT;
switch (mtop.mt_op) {
- case MTREW:
+ case MTREW:
pt_rewind(unit);
return 0;
- case MTWEOF:
+ case MTWEOF:
pt_write_fm(unit);
return 0;
- default:
- printk("%s: Unimplemented mt_op %d\n",PT.name,
- mtop.mt_op);
+ default:
+ printk("%s: Unimplemented mt_op %d\n", PT.name,
+ mtop.mt_op);
return -EINVAL;
}
- default:
- printk("%s: Unimplemented ioctl 0x%x\n",PT.name,cmd);
- return -EINVAL;
+ default:
+ printk("%s: Unimplemented ioctl 0x%x\n", PT.name, cmd);
+ return -EINVAL;
- }
+ }
}
-
-static int pt_release (struct inode *inode, struct file *file)
+static int
+pt_release(struct inode *inode, struct file *file)
{
- int unit = DEVICE_NR(inode->i_rdev);
+ int unit = DEVICE_NR(inode->i_rdev);
- if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1))
- return -EINVAL;
+ if ((unit >= PT_UNITS) || (atomic_read(&PT.available) > 1))
+ return -EINVAL;
- if (PT.flags & PT_WRITING) pt_write_fm(unit);
+ if (PT.flags & PT_WRITING)
+ pt_write_fm(unit);
- if (PT.flags & PT_REWIND) pt_rewind(unit);
+ if (PT.flags & PT_REWIND)
+ pt_rewind(unit);
kfree(PT.bufptr);
PT.bufptr = NULL;
- atomic_inc( &PT.available );
-
+ atomic_inc(&PT.available);
+
return 0;
}
-static ssize_t pt_read(struct file * filp, char * buf,
- size_t count, loff_t *ppos)
+static ssize_t pt_read(struct file *filp, char *buf, size_t count, loff_t * ppos)
{
- struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino->i_rdev);
- char rd_cmd[12] = {ATAPI_READ_6,1,0,0,0,0,0,0,0,0,0,0};
- int k, n, r, p, s, t, b;
-
- if (!(PT.flags & (PT_READING|PT_WRITING))) {
- PT.flags |= PT_READING;
- if (pt_atapi(unit,rd_cmd,0,NULL,"start read-ahead"))
+ struct inode *ino = filp->f_dentry->d_inode;
+ int unit = DEVICE_NR(ino->i_rdev);
+ char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int k, n, r, p, s, t, b;
+
+ if (!(PT.flags & (PT_READING | PT_WRITING))) {
+ PT.flags |= PT_READING;
+ if (pt_atapi(unit, rd_cmd, 0, NULL, "start read-ahead"))
return -EIO;
- } else if (PT.flags & PT_WRITING) return -EIO;
+ } else if (PT.flags & PT_WRITING)
+ return -EIO;
- if (PT.flags & PT_EOF) return 0;
+ if (PT.flags & PT_EOF)
+ return 0;
t = 0;
while (count > 0) {
- if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"read")) return -EIO;
-
- n = count;
- if (n > 32768) n = 32768; /* max per command */
- b = (n-1+PT.bs)/PT.bs;
- n = b*PT.bs; /* rounded up to even block */
-
- rd_cmd[4] = b;
-
- r = pt_command(unit,rd_cmd,n,"read");
-
- mdelay(1);
-
- if (r) {
- pt_req_sense(unit,0);
- return -EIO;
- }
-
- while (1) {
+ if (!pt_poll_dsc(unit, HZ / 100, PT_TMO, "read"))
+ return -EIO;
- r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
- DBMSG("read DRQ"),"");
+ n = count;
+ if (n > 32768)
+ n = 32768; /* max per command */
+ b = (n - 1 + PT.bs) / PT.bs;
+ n = b * PT.bs; /* rounded up to even block */
- if (r & STAT_SENSE) {
- pi_disconnect(PI);
- pt_req_sense(unit,0);
- return -EIO;
- }
+ rd_cmd[4] = b;
- if (r) PT.flags |= PT_EOF;
+ r = pt_command(unit, rd_cmd, n, "read");
- s = RR(0,7);
+ mdelay(1);
- if (!(s & STAT_DRQ)) break;
+ if (r) {
+ pt_req_sense(unit, 0);
+ return -EIO;
+ }
- n = (RR(0,4)+256*RR(0,5));
- p = (RR(0,2)&3);
- if (p != 2) {
- pi_disconnect(PI);
- printk("%s: Phase error on read: %d\n",PT.name,p);
- return -EIO;
- }
+ while (1) {
+
+ r = pt_wait(unit, STAT_BUSY,
+ STAT_DRQ | STAT_ERR | STAT_READY,
+ DBMSG("read DRQ"), "");
+
+ if (r & STAT_SENSE) {
+ pi_disconnect(PI);
+ pt_req_sense(unit, 0);
+ return -EIO;
+ }
+
+ if (r)
+ PT.flags |= PT_EOF;
+
+ s = read_reg(unit, 7);
+
+ if (!(s & STAT_DRQ))
+ break;
+
+ n = (read_reg(unit, 4) + 256 * read_reg(unit, 5));
+ p = (read_reg(unit, 2) & 3);
+ if (p != 2) {
+ pi_disconnect(PI);
+ printk("%s: Phase error on read: %d\n", PT.name,
+ p);
+ return -EIO;
+ }
+
+ while (n > 0) {
+ k = n;
+ if (k > PT_BUFSIZE)
+ k = PT_BUFSIZE;
+ pi_read_block(PI, PT.bufptr, k);
+ n -= k;
+ b = k;
+ if (b > count)
+ b = count;
+ if (copy_to_user(buf + t, PT.bufptr, b)) {
+ pi_disconnect(PI);
+ return -EFAULT;
+ }
+ t += b;
+ count -= b;
+ }
- while (n > 0) {
- k = n;
- if (k > PT_BUFSIZE) k = PT_BUFSIZE;
- pi_read_block(PI,PT.bufptr,k);
- n -= k;
- b = k;
- if (b > count) b = count;
- if (copy_to_user(buf + t, PT.bufptr, b)) {
- pi_disconnect(PI);
- return -EFAULT;
- }
- t += b;
- count -= b;
- }
-
- }
- pi_disconnect(PI);
- if (PT.flags & PT_EOF) break;
+ }
+ pi_disconnect(PI);
+ if (PT.flags & PT_EOF)
+ break;
}
return t;
}
-static ssize_t pt_write(struct file * filp, const char * buf,
- size_t count, loff_t *ppos)
+static ssize_t pt_write(struct file *filp, const char *buf, size_t count, loff_t * ppos)
{
- struct inode *ino = filp->f_dentry->d_inode;
- int unit = DEVICE_NR(ino->i_rdev);
- char wr_cmd[12] = {ATAPI_WRITE_6,1,0,0,0,0,0,0,0,0,0,0};
- int k, n, r, p, s, t, b;
+ struct inode *ino = filp->f_dentry->d_inode;
+ int unit = DEVICE_NR(ino->i_rdev);
+ char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int k, n, r, p, s, t, b;
- if (!(PT.flags & PT_WRITE_OK)) return -EROFS;
+ if (!(PT.flags & PT_WRITE_OK))
+ return -EROFS;
- if (!(PT.flags & (PT_READING|PT_WRITING))) {
- PT.flags |= PT_WRITING;
- if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode"))
- return -EIO;
- } else if (PT.flags&PT_READING) return -EIO;
+ if (!(PT.flags & (PT_READING | PT_WRITING))) {
+ PT.flags |= PT_WRITING;
+ if (pt_atapi
+ (unit, wr_cmd, 0, NULL, "start buffer-available mode"))
+ return -EIO;
+ } else if (PT.flags & PT_READING)
+ return -EIO;
- if (PT.flags & PT_EOF) return -ENOSPC;
+ if (PT.flags & PT_EOF)
+ return -ENOSPC;
t = 0;
while (count > 0) {
- if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"write")) return -EIO;
-
- n = count;
- if (n > 32768) n = 32768; /* max per command */
- b = (n-1+PT.bs)/PT.bs;
- n = b*PT.bs; /* rounded up to even block */
-
- wr_cmd[4] = b;
-
- r = pt_command(unit,wr_cmd,n,"write");
-
- mdelay(1);
-
- if (r) { /* error delivering command only */
- pt_req_sense(unit,0);
- return -EIO;
- }
-
- while (1) {
+ if (!pt_poll_dsc(unit, HZ / 100, PT_TMO, "write"))
+ return -EIO;
- r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
- DBMSG("write DRQ"),NULL);
+ n = count;
+ if (n > 32768)
+ n = 32768; /* max per command */
+ b = (n - 1 + PT.bs) / PT.bs;
+ n = b * PT.bs; /* rounded up to even block */
- if (r & STAT_SENSE) {
- pi_disconnect(PI);
- pt_req_sense(unit,0);
- return -EIO;
- }
+ wr_cmd[4] = b;
- if (r) PT.flags |= PT_EOF;
+ r = pt_command(unit, wr_cmd, n, "write");
- s = RR(0,7);
+ mdelay(1);
- if (!(s & STAT_DRQ)) break;
+ if (r) { /* error delivering command only */
+ pt_req_sense(unit, 0);
+ return -EIO;
+ }
- n = (RR(0,4)+256*RR(0,5));
- p = (RR(0,2)&3);
- if (p != 0) {
- pi_disconnect(PI);
- printk("%s: Phase error on write: %d \n",PT.name,p);
- return -EIO;
- }
+ while (1) {
+
+ r = pt_wait(unit, STAT_BUSY,
+ STAT_DRQ | STAT_ERR | STAT_READY,
+ DBMSG("write DRQ"), NULL);
+
+ if (r & STAT_SENSE) {
+ pi_disconnect(PI);
+ pt_req_sense(unit, 0);
+ return -EIO;
+ }
+
+ if (r)
+ PT.flags |= PT_EOF;
+
+ s = read_reg(unit, 7);
+
+ if (!(s & STAT_DRQ))
+ break;
+
+ n = (read_reg(unit, 4) + 256 * read_reg(unit, 5));
+ p = (read_reg(unit, 2) & 3);
+ if (p != 0) {
+ pi_disconnect(PI);
+ printk("%s: Phase error on write: %d \n",
+ PT.name, p);
+ return -EIO;
+ }
+
+ while (n > 0) {
+ k = n;
+ if (k > PT_BUFSIZE)
+ k = PT_BUFSIZE;
+ b = k;
+ if (b > count)
+ b = count;
+ if (copy_from_user(PT.bufptr, buf + t, b)) {
+ pi_disconnect(PI);
+ return -EFAULT;
+ }
+ pi_write_block(PI, PT.bufptr, k);
+ t += b;
+ count -= b;
+ n -= k;
+ }
- while (n > 0) {
- k = n;
- if (k > PT_BUFSIZE) k = PT_BUFSIZE;
- b = k;
- if (b > count) b = count;
- if (copy_from_user(PT.bufptr, buf + t, b)) {
- pi_disconnect(PI);
- return -EFAULT;
- }
- pi_write_block(PI,PT.bufptr,k);
- t += b;
- count -= b;
- n -= k;
- }
-
- }
- pi_disconnect(PI);
- if (PT.flags & PT_EOF) break;
+ }
+ pi_disconnect(PI);
+ if (PT.flags & PT_EOF)
+ break;
}
return t;
@@ -903,23 +982,23 @@ static int __init pt_init(void)
if (pt_detect())
return -1;
- if (register_chrdev(major,name,&pt_fops)) {
- printk("pt_init: unable to get major number %d\n",
- major);
- for (unit=0;unit<PT_UNITS;unit++)
- if (PT.present) pi_release(PI);
+ if (register_chrdev(major, name, &pt_fops)) {
+ printk("pt_init: unable to get major number %d\n", major);
+ for (unit = 0; unit < PT_UNITS; unit++)
+ if (PT.present)
+ pi_release(PI);
return -1;
}
- devfs_mk_dir ("pt");
- for (unit=0;unit<PT_UNITS;unit++)
+ devfs_mk_dir("pt");
+ for (unit = 0; unit < PT_UNITS; unit++)
if (PT.present) {
devfs_mk_cdev(MKDEV(major, unit),
- S_IFCHR | S_IRUSR | S_IWUSR,
- "pt/%d", unit);
+ S_IFCHR | S_IRUSR | S_IWUSR,
+ "pt/%d", unit);
devfs_mk_cdev(MKDEV(major, unit + 128),
- S_IFCHR | S_IRUSR | S_IWUSR,
- "pt/%dn", unit);
+ S_IFCHR | S_IRUSR | S_IWUSR,
+ "pt/%dn", unit);
}
return 0;
}
@@ -927,14 +1006,14 @@ static int __init pt_init(void)
static void __exit pt_exit(void)
{
int unit;
- for (unit=0;unit<PT_UNITS;unit++)
+ for (unit = 0; unit < PT_UNITS; unit++)
if (PT.present) {
devfs_remove("pt/%d", unit);
devfs_remove("pt/%dn", unit);
}
devfs_remove("pt");
- unregister_chrdev(major,name);
- for (unit=0;unit<PT_UNITS;unit++)
+ unregister_chrdev(major, name);
+ for (unit = 0; unit < PT_UNITS; unit++)
if (PT.present)
pi_release(PI);
}
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 3a8c264f2c72..0509a67c2eb8 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -67,6 +67,7 @@
static struct gendisk *rd_disks[NUM_RAMDISKS];
static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
+static struct request_queue *rd_queue;
/*
* Parameters for the boot-loading of the RAM disk. These are set by
@@ -308,12 +309,11 @@ static void __exit rd_cleanup (void)
del_gendisk(rd_disks[i]);
put_disk(rd_disks[i]);
}
-
+ kfree(rd_queue);
devfs_remove("rd");
unregister_blkdev(RAMDISK_MAJOR, "ramdisk" );
}
-static struct request_queue rd_queue;
/* This is the registration and initialization section of the RAM disk driver */
static int __init rd_init (void)
{
@@ -333,23 +333,28 @@ static int __init rd_init (void)
goto out;
}
+ rd_queue = kmalloc(NUM_RAMDISKS * sizeof(struct request_queue),
+ GFP_KERNEL);
+ if (!rd_queue)
+ goto out;
+ memset(rd_queue, 0, NUM_RAMDISKS * sizeof(struct request_queue));
if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) {
err = -EIO;
- goto out;
+ goto out_queue;
}
- blk_queue_make_request(&rd_queue, &rd_make_request);
-
devfs_mk_dir("rd");
for (i = 0; i < NUM_RAMDISKS; i++) {
struct gendisk *disk = rd_disks[i];
+ blk_queue_make_request(&rd_queue[i], &rd_make_request);
+
/* rd_size is given in kB */
disk->major = RAMDISK_MAJOR;
disk->first_minor = i;
disk->fops = &rd_bd_op;
- disk->queue = &rd_queue;
+ disk->queue = &rd_queue[i];
sprintf(disk->disk_name, "ram%d", i);
sprintf(disk->devfs_name, "rd/%d", i);
set_capacity(disk, rd_size * 2);
@@ -362,6 +367,8 @@ static int __init rd_init (void)
NUM_RAMDISKS, rd_size, rd_blocksize);
return 0;
+out_queue:
+ kfree(rd_queue);
out:
while (i--)
put_disk(rd_disks[i]);
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 08689f222de8..5ec7675c3622 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -322,7 +322,7 @@ static struct block_device_operations z2_fops =
.release = z2_release,
};
-static struct gendisk *z2_find(dev_t dev, int *part, void *data)
+static struct kobject *z2_find(dev_t dev, int *part, void *data)
{
*part = 0;
return get_disk(z2ram_gendisk);
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index c717872fad83..e0c7f3eeefc0 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -490,7 +490,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
}
}
-static void ser_vbl_int( int irq, void *data, struct pt_regs *regs)
+static irqreturn_t ser_vbl_int( int irq, void *data, struct pt_regs *regs)
{
/* vbl is just a periodic interrupt we tie into to update modem status */
struct async_struct * info = IRQ_ports;
@@ -500,9 +500,10 @@ static void ser_vbl_int( int irq, void *data, struct pt_regs *regs)
*/
if(info->IER & UART_IER_MSI)
check_modem_status(info);
+ return IRQ_HANDLED;
}
-static void ser_rx_int(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ser_rx_int(int irq, void *dev_id, struct pt_regs * regs)
{
struct async_struct * info;
@@ -512,16 +513,17 @@ static void ser_rx_int(int irq, void *dev_id, struct pt_regs * regs)
info = IRQ_ports;
if (!info || !info->tty)
- return;
+ return IRQ_NONE;
receive_chars(info);
info->last_active = jiffies;
#ifdef SERIAL_DEBUG_INTR
printk("end.\n");
#endif
+ return IRQ_HANDLED;
}
-static void ser_tx_int(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ser_tx_int(int irq, void *dev_id, struct pt_regs * regs)
{
struct async_struct * info;
@@ -532,7 +534,7 @@ static void ser_tx_int(int irq, void *dev_id, struct pt_regs * regs)
info = IRQ_ports;
if (!info || !info->tty)
- return;
+ return IRQ_NONE;
transmit_chars(info);
info->last_active = jiffies;
@@ -540,6 +542,7 @@ static void ser_tx_int(int irq, void *dev_id, struct pt_regs * regs)
printk("end.\n");
#endif
}
+ return IRQ_HANDLED;
}
/*
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index ff6dce969e03..8562ec717c0d 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -116,7 +116,7 @@ static __inline__ volatile struct a2232memory *a2232mem (unsigned int board);
static __inline__ void a2232_receive_char( struct a2232_port *port,
int ch, int err );
/* The interrupt service routine */
-static void a2232_vbl_inter(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp);
/* Initialize the port structures */
static void a2232_init_portstructs(void);
/* Initialize and register TTY drivers. */
@@ -533,7 +533,7 @@ static __inline__ void a2232_receive_char( struct a2232_port *port,
tty_flip_buffer_push(tty);
}
-static void a2232_vbl_inter(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp)
{
#if A2232_IOBUFLEN != 256
#error "Re-Implement a2232_vbl_inter()!"
@@ -673,6 +673,7 @@ int ch, err, n, p;
} // if events in CD queue
} // for every completely initialized A2232 board
+ return IRQ_HANDLED;
}
static void a2232_init_portstructs(void)
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 41ecc17b806d..7fa5e22827de 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -400,7 +400,7 @@ cy_sched_event(struct cyclades_port *info, int event)
whenever the card wants its hand held--chars
received, out buffer empty, modem change, etc.
*/
-static void
+static irqreturn_t
cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
{
struct tty_struct *tty;
@@ -418,7 +418,7 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
/* This is a receive timeout interrupt, ignore it */
base_addr[CyREOIR] = CyNOTRANS;
- return;
+ return IRQ_HANDLED;
}
/* Read a byte of data if there is any - assume the error
@@ -432,13 +432,13 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
/* if there is nowhere to put the data, discard it */
if(info->tty == 0) {
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
- return;
+ return IRQ_HANDLED;
}
else { /* there is an open port for this data */
tty = info->tty;
if(err & info->ignore_status_mask){
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
- return;
+ return IRQ_HANDLED;
}
if (tty->flip.count < TTY_FLIPBUF_SIZE){
tty->flip.count++;
@@ -488,9 +488,10 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
queue_task(&tty->flip.tqueue, &tq_timer);
/* end of service */
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
} /* cy_rxerr_interrupt */
-static void
+static irqreturn_t
cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
{
struct cyclades_port *info;
@@ -543,9 +544,10 @@ cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
}
}
base_addr[CyMEOIR] = 0;
+ return IRQ_HANDLED;
} /* cy_modem_interrupt */
-static void
+static irqreturn_t
cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
{
struct cyclades_port *info;
@@ -569,7 +571,7 @@ cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
if( (channel < 0) || (NR_PORTS <= channel) ){
base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
base_addr[CyTEOIR] = CyNOTRANS;
- return;
+ return IRQ_HANDLED;
}
info->last_active = jiffies;
if(info->tty == 0){
@@ -578,7 +580,7 @@ cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
}
base_addr[CyTEOIR] = CyNOTRANS;
- return;
+ return IRQ_HANDLED;
}
/* load the on-chip space available for outbound data */
@@ -662,9 +664,10 @@ cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
}
base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
} /* cy_tx_interrupt */
-static void
+static irqreturn_t
cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
{
struct tty_struct *tty;
@@ -722,6 +725,7 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
}
/* end of service */
base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
} /* cy_rx_interrupt */
/*
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 01278bf90344..62bcbcac3aa9 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -132,12 +132,6 @@ extern struct tty_driver pts_driver; /* Unix98 pty slaves; for /dev/ptmx */
extern void disable_early_printk(void);
-/*
- * redirect is the pseudo-tty that console output
- * is redirected to if asked by TIOCCONS.
- */
-static struct tty_struct *redirect;
-
static void initialize_tty_struct(struct tty_struct *tty);
static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
@@ -400,6 +394,8 @@ static struct file_operations hung_up_tty_fops = {
.release = tty_release,
};
+static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED;
+static struct file *redirect;
/*
* This can be called by the "eventd" kernel thread. That is process synchronous,
* but doesn't hold any locks, so we need to make sure we have the appropriate
@@ -409,7 +405,7 @@ void do_tty_hangup(void *data)
{
struct tty_struct *tty = (struct tty_struct *) data;
struct file * cons_filp = NULL;
- struct file *filp;
+ struct file *filp, *f = NULL;
struct task_struct *p;
struct pid *pid;
int closecount = 0, n;
@@ -419,6 +415,15 @@ void do_tty_hangup(void *data)
/* inuse_filps is protected by the single kernel lock */
lock_kernel();
+
+ spin_lock(&redirect_lock);
+ if (redirect && redirect->private_data == tty) {
+ f = redirect;
+ redirect = NULL;
+ }
+ spin_unlock(&redirect_lock);
+ if (f)
+ fput(f);
check_tty_count(tty, "do_tty_hangup");
file_list_lock();
@@ -726,39 +731,40 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count,
{
int is_console;
struct tty_struct * tty;
- struct inode *inode;
-
- /* Can't seek (pwrite) on ttys. */
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
+ struct inode *inode = file->f_dentry->d_inode;
/*
* For now, we redirect writes from /dev/console as
* well as /dev/tty0.
*/
- inode = file->f_dentry->d_inode;
is_console = IS_SYSCONS_DEV(inode->i_rdev) ||
IS_CONSOLE_DEV(inode->i_rdev);
- if (is_console && redirect)
- tty = redirect;
- else
- tty = (struct tty_struct *)file->private_data;
+ /* Can't seek (pwrite) on ttys. */
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+
+ if (is_console) {
+ struct file *p = NULL;
+
+ spin_lock(&redirect_lock);
+ if (redirect) {
+ get_file(redirect);
+ p = redirect;
+ }
+ spin_unlock(&redirect_lock);
+
+ if (p) {
+ ssize_t res = vfs_write(p, buf, count, &p->f_pos);
+ fput(p);
+ return res;
+ }
+ }
+
+ tty = (struct tty_struct *)file->private_data;
if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
return -EIO;
if (!tty || !tty->driver->write || (test_bit(TTY_IO_ERROR, &tty->flags)))
return -EIO;
-#if 0
- if (!is_console && L_TOSTOP(tty) && (tty->pgrp > 0) &&
- (current->tty == tty) && (tty->pgrp != current->pgrp)) {
- if (is_orphaned_pgrp(current->pgrp))
- return -EIO;
- if (!is_ignored(SIGTTOU)) {
- (void) kill_pg(current->pgrp, SIGTTOU, 1);
- return -ERESTARTSYS;
- }
- }
-#endif
if (!tty->ldisc.write)
return -EIO;
return do_tty_write(tty->ldisc.write, tty, file,
@@ -1221,7 +1227,7 @@ static void release_dev(struct file * filp)
/*
* If _either_ side is closing, make sure there aren't any
* processes that still think tty or o_tty is their controlling
- * tty. Also, clear redirect if it points to either tty.
+ * tty.
*/
if (tty_closing || o_tty_closing) {
struct task_struct *p;
@@ -1235,9 +1241,6 @@ static void release_dev(struct file * filp)
for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
p->tty = NULL;
read_unlock(&tasklist_lock);
-
- if (redirect == tty || (o_tty && redirect == o_tty))
- redirect = NULL;
}
/* check whether both sides are closing ... */
@@ -1526,19 +1529,29 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
return 0;
}
-static int tioccons(struct inode *inode,
- struct tty_struct *tty, struct tty_struct *real_tty)
+static int tioccons(struct inode *inode, struct file *file)
{
if (IS_SYSCONS_DEV(inode->i_rdev) ||
IS_CONSOLE_DEV(inode->i_rdev)) {
+ struct file *f;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ spin_lock(&redirect_lock);
+ f = redirect;
redirect = NULL;
+ spin_unlock(&redirect_lock);
+ if (f)
+ fput(f);
return 0;
}
- if (redirect)
+ spin_lock(&redirect_lock);
+ if (redirect) {
+ spin_unlock(&redirect_lock);
return -EBUSY;
- redirect = real_tty;
+ }
+ get_file(file);
+ redirect = file;
+ spin_unlock(&redirect_lock);
return 0;
}
@@ -1786,7 +1799,7 @@ int tty_ioctl(struct inode * inode, struct file * file,
case TIOCSWINSZ:
return tiocswinsz(tty, real_tty, (struct winsize *) arg);
case TIOCCONS:
- return tioccons(inode, tty, real_tty);
+ return real_tty!=tty ? -EINVAL : tioccons(inode, file);
case FIONBIO:
return fionbio(file, (int *) arg);
case TIOCEXCL:
@@ -2113,7 +2126,7 @@ static spinlock_t tty_dev_list_lock = SPIN_LOCK_UNLOCKED;
static ssize_t show_dev(struct class_device *class_dev, char *buf)
{
struct tty_dev *tty_dev = to_tty_dev(class_dev);
- return sprintf(buf, "%04x\n", tty_dev->dev);
+ return sprintf(buf, "%04lx\n", (unsigned long)tty_dev->dev);
}
static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
@@ -2229,53 +2242,7 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)
EXPORT_SYMBOL(tty_register_device);
EXPORT_SYMBOL(tty_unregister_device);
-/* that should be handled by register_chrdev_region() */
-static int get_range(struct tty_driver *driver)
-{
- dev_t from = MKDEV(driver->major, driver->minor_start);
- dev_t to = from + driver->num;
- dev_t n, next;
- int error = 0;
-
- for (n = from; MAJOR(n) < MAJOR(to); n = next) {
- next = MKDEV(MAJOR(n)+1, 0);
- error = register_chrdev_region(MAJOR(n), MINOR(n),
- next - n, driver->name, &tty_fops);
- if (error)
- goto fail;
- }
- if (n != to)
- error = register_chrdev_region(MAJOR(n), MINOR(n),
- to - n, driver->name, &tty_fops);
- if (!error)
- return 0;
-fail:
- to = n;
- for (n = from; MAJOR(n) < MAJOR(to); n = next) {
- next = MKDEV(MAJOR(n)+1, 0);
- unregister_chrdev_region(MAJOR(n), MINOR(n),
- next - n, driver->name);
- }
- return error;
-}
-
-/* that should be handled by unregister_chrdev_region() */
-static void put_range(struct tty_driver *driver)
-{
- dev_t from = MKDEV(driver->major, driver->minor_start);
- dev_t to = from + driver->num;
- dev_t n, next;
-
- for (n = from; MAJOR(n) < MAJOR(to); n = next) {
- next = MKDEV(MAJOR(n)+1, 0);
- unregister_chrdev_region(MAJOR(n), MINOR(n),
- next - n, driver->name);
- }
- if (n != to)
- unregister_chrdev_region(MAJOR(n), MINOR(n),
- to - n, driver->name);
-}
-
+static struct kobject tty_kobj = {.name = "tty"};
/*
* Called by a tty driver to register itself.
*/
@@ -2283,21 +2250,40 @@ int tty_register_driver(struct tty_driver *driver)
{
int error;
int i;
+ dev_t dev;
+ char *s;
if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
if (!driver->major) {
- error = register_chrdev_region(0, driver->minor_start,
- driver->num, driver->name, &tty_fops);
- if (error > 0)
- driver->major = error;
+ error = alloc_chrdev_region(&dev, driver->num,
+ (char*)driver->name);
+ if (!error) {
+ driver->major = MAJOR(dev);
+ driver->minor_start = MINOR(dev);
+ }
} else {
- error = get_range(driver);
+ dev = MKDEV(driver->major, driver->minor_start);
+ error = register_chrdev_region(dev, driver->num,
+ (char*)driver->name);
}
if (error < 0)
return error;
+ driver->cdev.kobj.parent = &tty_kobj;
+ strcpy(driver->cdev.kobj.name, driver->name);
+ for (s = strchr(driver->cdev.kobj.name, '/'); s; s = strchr(s, '/'))
+ *s = '!';
+ cdev_init(&driver->cdev, &tty_fops);
+ driver->cdev.owner = driver->owner;
+ error = cdev_add(&driver->cdev, dev, driver->num);
+ if (error) {
+ kobject_del(&driver->cdev.kobj);
+ unregister_chrdev_region(dev, driver->num);
+ return error;
+ }
+
if (!driver->put_char)
driver->put_char = tty_default_put_char;
@@ -2308,7 +2294,7 @@ int tty_register_driver(struct tty_driver *driver)
tty_register_device(driver, i, NULL);
}
proc_tty_register_driver(driver);
- return error;
+ return 0;
}
/*
@@ -2322,7 +2308,9 @@ int tty_unregister_driver(struct tty_driver *driver)
if (*driver->refcount)
return -EBUSY;
- put_range(driver);
+ cdev_unmap(MKDEV(driver->major, driver->minor_start), driver->num);
+ unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
+ driver->num);
list_del(&driver->tty_drivers);
@@ -2346,6 +2334,7 @@ int tty_unregister_driver(struct tty_driver *driver)
tty_unregister_device(driver, i);
}
proc_tty_unregister_driver(driver);
+ cdev_del(&driver->cdev);
return 0;
}
@@ -2392,6 +2381,14 @@ static int __init tty_class_init(void)
}
postcore_initcall(tty_class_init);
+
+static struct cdev tty_cdev, console_cdev;
+#ifdef CONFIG_UNIX98_PTYS
+static struct cdev ptmx_cdev;
+#endif
+#ifdef CONFIG_VT
+static struct cdev vc0_cdev;
+#endif
/*
* Ok, now we can initialize the rest of the tty devices and can count
@@ -2399,29 +2396,40 @@ postcore_initcall(tty_class_init);
*/
void __init tty_init(void)
{
- if (register_chrdev_region(TTYAUX_MAJOR, 0, 1,
- "/dev/tty", &tty_fops) < 0)
+ strcpy(tty_cdev.kobj.name, "dev.tty");
+ cdev_init(&tty_cdev, &tty_fops);
+ if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
+ register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
panic("Couldn't register /dev/tty driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
tty_add_class_device ("tty", MKDEV(TTYAUX_MAJOR, 0), NULL);
- if (register_chrdev_region(TTYAUX_MAJOR, 1, 1,
- "/dev/console", &tty_fops) < 0)
+ strcpy(console_cdev.kobj.name, "dev.console");
+ cdev_init(&console_cdev, &tty_fops);
+ if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
+ register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
panic("Couldn't register /dev/console driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
tty_add_class_device ("console", MKDEV(TTYAUX_MAJOR, 1), NULL);
+ tty_kobj.kset = tty_cdev.kobj.kset;
+ kobject_register(&tty_kobj);
+
#ifdef CONFIG_UNIX98_PTYS
- if (register_chrdev_region(TTYAUX_MAJOR, 2, 1,
- "/dev/ptmx", &tty_fops) < 0)
+ strcpy(ptmx_cdev.kobj.name, "dev.ptmx");
+ cdev_init(&ptmx_cdev, &tty_fops);
+ if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
+ register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
panic("Couldn't register /dev/ptmx driver\n");
devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
tty_add_class_device ("ptmx", MKDEV(TTYAUX_MAJOR, 2), NULL);
#endif
#ifdef CONFIG_VT
- if (register_chrdev_region(TTY_MAJOR, 0, 1,
- "/dev/vc/0", &tty_fops) < 0)
+ strcpy(vc0_cdev.kobj.name, "dev.vc0");
+ cdev_init(&vc0_cdev, &tty_fops);
+ if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
+ register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
panic("Couldn't register /dev/tty0 driver\n");
devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
tty_add_class_device ("tty0", MKDEV(TTY_MAJOR, 0), NULL);
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index c2bed745cef4..83aa0d7388f1 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -83,10 +83,10 @@ static int scc_ioctl(struct tty_struct * tty, struct file * filp,
unsigned int cmd, unsigned long arg);
static void scc_throttle(struct tty_struct *tty);
static void scc_unthrottle(struct tty_struct *tty);
-static void scc_tx_int(int irq, void *data, struct pt_regs *fp);
-static void scc_rx_int(int irq, void *data, struct pt_regs *fp);
-static void scc_stat_int(int irq, void *data, struct pt_regs *fp);
-static void scc_spcond_int(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp);
static void scc_setsignals(struct scc_port *port, int dtr, int rts);
static void scc_break_ctl(struct tty_struct *tty, int break_state);
@@ -448,7 +448,7 @@ int vme_scc_init(void)
* Interrupt handlers
*--------------------------------------------------------------------------*/
-static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp)
{
unsigned char ch;
struct scc_port *port = data;
@@ -459,7 +459,7 @@ static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
if (!tty) {
printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
- return;
+ return IRQ_HANDLED;
}
if (tty->flip.count < TTY_FLIPBUF_SIZE) {
*tty->flip.char_buf_ptr = ch;
@@ -476,16 +476,17 @@ static void scc_rx_int(int irq, void *data, struct pt_regs *fp)
if (SCCread(INT_PENDING_REG) &
(port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
scc_spcond_int (irq, data, fp);
- return;
+ return IRQ_HANDLED;
}
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
tty_flip_buffer_push(tty);
+ return IRQ_HANDLED;
}
-static void scc_spcond_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp)
{
struct scc_port *port = data;
struct tty_struct *tty = port->gs.tty;
@@ -498,7 +499,7 @@ static void scc_spcond_int(int irq, void *data, struct pt_regs *fp)
printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
SCCwrite(COMMAND_REG, CR_ERROR_RESET);
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
- return;
+ return IRQ_HANDLED;
}
do {
stat = SCCread(SPCOND_STATUS_REG);
@@ -532,10 +533,11 @@ static void scc_spcond_int(int irq, void *data, struct pt_regs *fp)
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
tty_flip_buffer_push(tty);
+ return IRQ_HANDLED;
}
-static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp)
{
struct scc_port *port = data;
SCC_ACCESS_INIT(port);
@@ -545,7 +547,7 @@ static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
- return;
+ return IRQ_HANDLED;
}
while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) {
if (port->x_char) {
@@ -577,10 +579,11 @@ static void scc_tx_int(int irq, void *data, struct pt_regs *fp)
}
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ return IRQ_HANDLED;
}
-static void scc_stat_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp)
{
struct scc_port *port = data;
unsigned channel = port->channel;
@@ -612,6 +615,7 @@ static void scc_stat_int(int irq, void *data, struct pt_regs *fp)
}
SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ return IRQ_HANDLED;
}
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 72df917205ab..dfdef28c9397 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -155,7 +155,7 @@ static void ide_outl (u32 val, unsigned long port)
static void ide_outsl (unsigned long port, void *addr, u32 count)
{
- return outsl(port, addr, count);
+ outsl(port, addr, count);
}
void default_hwif_iops (ide_hwif_t *hwif)
@@ -391,7 +391,7 @@ void atapi_input_bytes (ide_drive_t *drive, void *buffer, u32 bytecount)
insw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI || CONFIG_Q40 */
hwif->ata_input_data(drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
hwif->INSW(IDE_DATA_REG, ((u8 *)buffer)+(bytecount & ~0x03), 1);
@@ -410,7 +410,7 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, u32 bytecount)
outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI || CONFIG_Q40 */
hwif->ata_output_data(drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
hwif->OUTSW(IDE_DATA_REG, ((u8*)buffer)+(bytecount & ~0x03), 1);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 6d29292e5c4b..8034df6b7e15 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1226,7 +1226,7 @@ static int ata_lock(dev_t dev, void *data)
return 0;
}
-struct gendisk *ata_probe(dev_t dev, int *part, void *data)
+struct kobject *ata_probe(dev_t dev, int *part, void *data)
{
ide_hwif_t *hwif = data;
int unit = *part >> PARTN_BITS;
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 0647b999912b..2a78b792f7fb 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -31,7 +31,7 @@
#define PCIDE_BASE5 0x1e0
#define PCIDE_BASE6 0x160
-static const q40ide_ioreg_t pcide_bases[Q40IDE_NUM_HWIFS] = {
+static const unsigned long pcide_bases[Q40IDE_NUM_HWIFS] = {
PCIDE_BASE1, PCIDE_BASE2, /* PCIDE_BASE3, PCIDE_BASE4 , PCIDE_BASE5,
PCIDE_BASE6 */
};
@@ -41,23 +41,21 @@ static const q40ide_ioreg_t pcide_bases[Q40IDE_NUM_HWIFS] = {
* Offsets from one of the above bases
*/
+/* used to do addr translation here but it is easier to do in setup ports */
+/*#define IDE_OFF_B(x) ((unsigned long)Q40_ISA_IO_B((IDE_##x##_OFFSET)))*/
-/* HD_DATA was redefined in asm-m68k/ide.h */
-#undef HD_DATA
-#define HD_DATA 0x1f0
-
-
-#define PCIDE_REG(x) ((q40ide_ioreg_t)(HD_##x-PCIDE_BASE1))
+#define IDE_OFF_B(x) ((unsigned long)((IDE_##x##_OFFSET)))
+#define IDE_OFF_W(x) ((unsigned long)((IDE_##x##_OFFSET)))
static const int pcide_offsets[IDE_NR_PORTS] = {
- PCIDE_REG(DATA), PCIDE_REG(ERROR), PCIDE_REG(NSECTOR), PCIDE_REG(SECTOR),
- PCIDE_REG(LCYL), PCIDE_REG(HCYL), PCIDE_REG(CURRENT), PCIDE_REG(STATUS),
- PCIDE_REG(CMD)
+ IDE_OFF_W(DATA), IDE_OFF_B(ERROR), IDE_OFF_B(NSECTOR), IDE_OFF_B(SECTOR),
+ IDE_OFF_B(LCYL), IDE_OFF_B(HCYL), 6 /*IDE_OFF_B(CURRENT)*/, IDE_OFF_B(STATUS),
+ 518/*IDE_OFF(CMD)*/
};
-static int q40ide_default_irq(q40ide_ioreg_t base)
+static int q40ide_default_irq(unsigned long base)
{
- switch (base) {
+ switch (base) {
case 0x1f0: return 14;
case 0x170: return 15;
case 0x1e8: return 11;
@@ -67,14 +65,58 @@ static int q40ide_default_irq(q40ide_ioreg_t base)
}
+/*
+ * This is very similar to ide_setup_ports except that addresses
+ * are pretranslated for q40 ISA access
+ */
+void q40_ide_setup_ports ( hw_regs_t *hw,
+ unsigned long base, int *offsets,
+ unsigned long ctrl, unsigned long intr,
+ ide_ack_intr_t *ack_intr,
+/*
+ * ide_io_ops_t *iops,
+ */
+ int irq)
+{
+ int i;
+
+ for (i = 0; i < IDE_NR_PORTS; i++) {
+ /* BIG FAT WARNING:
+ assumption: only DATA port is ever used in 16 bit mode */
+ if ( i==0 )
+ hw->io_ports[i] = Q40_ISA_IO_W(base + offsets[i]);
+ else
+ hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
+ }
+
+ hw->irq = irq;
+ hw->dma = NO_DMA;
+ hw->ack_intr = ack_intr;
+/*
+ * hw->iops = iops;
+ */
+}
- /*
- * Probe for Q40 IDE interfaces
- */
+
+
+/*
+ * the static array is needed to have the name reported in /proc/ioports,
+ * hwif->name unfortunately isn´t available yet
+ */
+static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
+ "ide0", "ide1"
+};
+
+/*
+ * Probe for Q40 IDE interfaces
+ */
void q40ide_init(void)
{
int i;
+ ide_hwif_t *hwif;
+ int index;
+ const char *name;
if (!MACH_IS_Q40)
return ;
@@ -82,12 +124,27 @@ void q40ide_init(void)
for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
hw_regs_t hw;
- ide_setup_ports(&hw,(unsigned long) pcide_bases[i], (int *)pcide_offsets,
+ name = q40_ide_names[i];
+ if (!request_region(pcide_bases[i], 8, name)) {
+ printk("could not reserve ports %lx-%lx for %s\n",
+ pcide_bases[i],pcide_bases[i]+8,name);
+ continue;
+ }
+ if (!request_region(pcide_bases[i]+0x206, 1, name)) {
+ printk("could not reserve port %lx for %s\n",
+ pcide_bases[i]+0x206,name);
+ release_region(pcide_bases[i], 8);
+ continue;
+ }
+ q40_ide_setup_ports(&hw,(unsigned long) pcide_bases[i], (int *)pcide_offsets,
pcide_bases[i]+0x206,
0, NULL,
-// pcide_iops,
+// m68kide_iops,
q40ide_default_irq(pcide_bases[i]));
- ide_register_hw(&hw, NULL);
+ index = ide_register_hw(&hw, &hwif);
+ // **FIXME**
+ if (index != -1)
+ hwif->mmio = 2;
}
}
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index ccd51cd20bbc..88fcd5895ee1 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1105,7 +1105,6 @@ static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d)
(findev->device == dev->device) &&
((findev->devfn - dev->devfn) == 1) &&
(PCI_FUNC(findev->devfn) & 1)) {
- u8 irq = 0, irq2 = 0;
if (findev->irq != dev->irq) {
/* FIXME: we need a core pci_set_interrupt() */
findev->irq = dev->irq;
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index 7dd5ce20f4ce..c84662f60ba1 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -52,7 +52,7 @@ static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
static char *amijoy_name = "Amiga joystick";
-static void amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
int i, data = 0, button = 0;
@@ -74,6 +74,7 @@ static void amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
input_sync(amijoy_dev + i);
}
+ return IRQ_HANDLED;
}
static int amijoy_open(struct input_dev *dev)
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index e1832cc082e8..4357ca9393d2 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -71,7 +71,7 @@ static struct input_dev amikbd_dev;
static char *amikbd_name = "Amiga keyboard";
static char *amikbd_phys = "amikbd/input0";
-static void amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
unsigned char scancode, down;
@@ -93,16 +93,14 @@ static void amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
input_report_key(&amikbd_dev, scancode, 1);
input_report_key(&amikbd_dev, scancode, 0);
input_sync(&amikbd_dev);
- return;
+ } else {
+ input_report_key(&amikbd_dev, scancode, down);
+ input_sync(&amikbd_dev);
}
+ } else /* scancodes >= 0x78 are error codes */
+ printk(amikbd_messages[scancode - 0x78]);
- input_report_key(&amikbd_dev, scancode, down);
- input_sync(&amikbd_dev);
-
- return;
- }
-
- printk(amikbd_messages[scancode - 0x78]); /* scancodes >= 0x78 are error codes */
+ return IRQ_HANDLED;
}
static int __init amikbd_init(void)
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index 05bf73dbf86d..7baa09cca7c5 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -40,7 +40,7 @@ static struct input_dev amimouse_dev;
static char *amimouse_name = "Amiga mouse";
static char *amimouse_phys = "amimouse/input0";
-static void amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
unsigned short joy0dat, potgor;
int nx, ny, dx, dy;
@@ -73,6 +73,8 @@ static void amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
input_report_key(&amimouse_dev, BTN_RIGHT, potgor & 0x0400);
input_sync(&amimouse_dev);
+
+ return IRQ_HANDLED;
}
static int amimouse_open(struct input_dev *dev)
diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 0aa34eebe478..0ec692e60851 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -77,7 +77,7 @@ static volatile unsigned char *via;
static int macii_init_via(void);
static void macii_start(void);
-static void macii_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs);
static void macii_retransmit(int);
static void macii_queue_poll(void);
@@ -151,7 +151,7 @@ int macii_init(void)
if (err) return err;
err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB",
- macii_interrupt);
+ macii_interrupt);
if (err) return err;
macii_state = idle;
@@ -410,7 +410,7 @@ static void macii_start(void)
* Note: As of 21/10/97, the MacII ADB part works including timeout detection
* and retransmit (Talk to the last active device).
*/
-void macii_interrupt(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs)
{
int x, adbdir;
unsigned long flags;
@@ -423,7 +423,7 @@ void macii_interrupt(int irq, void *arg, struct pt_regs *regs)
if (driver_running) {
local_irq_restore(flags);
- return;
+ return IRQ_NONE;
}
driver_running = 1;
@@ -649,4 +649,5 @@ void macii_interrupt(int irq, void *arg, struct pt_regs *regs)
/* reset mutex and interrupts */
driver_running = 0;
local_irq_restore(flags);
+ return IRQ_HANDLED;
}
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
index 162ce3f2acd0..a1966975d58f 100644
--- a/drivers/macintosh/via-maciisi.c
+++ b/drivers/macintosh/via-maciisi.c
@@ -84,7 +84,7 @@ static int maciisi_init(void);
static int maciisi_send_request(struct adb_request* req, int sync);
static void maciisi_sync(struct adb_request *req);
static int maciisi_write(struct adb_request* req);
-static void maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
+static irqreturn_t maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
static int maciisi_init_via(void);
static void maciisi_poll(void);
@@ -414,7 +414,7 @@ maciisi_poll(void)
/* Shift register interrupt - this is *supposed* to mean that the
register is either full or empty. In practice, I have no idea what
it means :( */
-static void
+static irqreturn_t
maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
{
int status;
@@ -436,7 +436,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
/* Shouldn't happen, we hope */
printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
local_irq_restore(flags);
- return;
+ return IRQ_NONE;
}
/* Clear the interrupt */
@@ -635,6 +635,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
}
local_irq_restore(flags);
+ return IRQ_HANDLED;
}
static void
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index ea592973e28f..9c7c90529222 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -107,7 +107,7 @@ struct notifier_block *sleep_notifier_list;
static int pmu_probe(void);
static int pmu_init(void);
static void pmu_start(void);
-static void pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
static int pmu_send_request(struct adb_request *req, int sync);
static int pmu_autopoll(int devs);
void pmu_poll(void);
@@ -572,7 +572,7 @@ pmu_poll()
local_irq_restore(flags);
}
-static void
+static irqreturn_t
pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct adb_request *req;
@@ -688,6 +688,7 @@ finish:
printk("pmu_interrupt: exit state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
#endif
+ return IRQ_HANDLED;
}
static void
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3840a5fbebb5..205f3d77fa8c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1438,7 +1438,7 @@ abort:
}
-static struct gendisk *md_probe(dev_t dev, int *part, void *data)
+static struct kobject *md_probe(dev_t dev, int *part, void *data)
{
static DECLARE_MUTEX(disks_sem);
int unit = MINOR(dev);
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 29ef3a9048fb..bcc6c06c4335 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2671,7 +2671,7 @@ int bus_in(struct bttv *btv, int bit)
static int tea5757_read(struct bttv *btv)
{
int value = 0;
- long timeout;
+ unsigned long timeout;
int i;
/* better safe than sorry */
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 1ba683ffc674..e317e8977019 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -2427,10 +2427,20 @@ static void set_flicker(struct cam_params *params, volatile u32 *command_flags,
#define FIRMWARE_VERSION(x,y) (params->version.firmwareVersion == (x) && \
params->version.firmwareRevision == (y))
/* define for compgain calculation */
+#if 0
#define COMPGAIN(base, curexp, newexp) \
(u8) ((((float) base - 128.0) * ((float) curexp / (float) newexp)) + 128.5)
#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
(u16)((float)curexp * (float)(u8)(curcomp + 128) / (float)(u8)(basecomp - 128))
+#else
+ /* equivalent functions without floating point math */
+#define COMPGAIN(base, curexp, newexp) \
+ (u8)(128 + (((u32)(2*(base-128)*curexp + newexp)) / (2* newexp)) )
+#define EXP_FROM_COMP(basecomp, curcomp, curexp) \
+ (u16)(((u32)(curexp * (u8)(curcomp + 128)) / (u8)(basecomp - 128)))
+#endif
+
+
int currentexp = params->exposure.coarseExpLo +
params->exposure.coarseExpHi*256;
int startexp;
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 1010f7443e95..61c734da84b4 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -596,16 +596,18 @@ static struct {
static void board_flyvideo(struct saa7134_dev *dev)
{
u32 value;
- int index;
saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
#if 0
- index = (value & 0x1f00) >> 8;
- printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
- dev->name, value, fly_list[index].model,
- fly_list[index].tuner_type);
- dev->tuner_type = fly_list[index].tuner_type;
+ {
+ int index = (value & 0x1f00) >> 8;
+ printk(KERN_INFO "%s: flyvideo: gpio is 0x%x "
+ "[model=%s,tuner=%d]\n",
+ dev->name, value, fly_list[index].model,
+ fly_list[index].tuner_type);
+ dev->tuner_type = fly_list[index].tuner_type;
+ }
#else
printk(KERN_INFO "%s: flyvideo: gpio is 0x%x\n",
dev->name, value);
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index 7e9414f6263e..6b5ab7bd56db 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -862,7 +862,7 @@ void nftl_request(struct request_queue *q)
}
}
-static struct gendisk *nftl_probe(dev_t dev, int *part, void *data)
+static struct kobject *nftl_probe(dev_t dev, int *part, void *data)
{
request_module("docprobe");
return NULL;
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 67e6f30f8c4c..30e52920c91e 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -501,7 +501,7 @@ static void i596_display_data(struct net_device *dev)
#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i596_error(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
#ifdef ENABLE_MVME16x_NET
@@ -522,6 +522,7 @@ static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
#endif
printk(KERN_ERR "%s: Error interrupt\n", dev->name);
i596_display_data(dev);
+ return IRQ_HANDLED;
}
#endif
@@ -1004,13 +1005,13 @@ static int i596_open(struct net_device *dev)
DEB(DEB_OPEN,printk(KERN_DEBUG "%s: i596_open() irq %d.\n", dev->name, dev->irq));
- if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
+ if (request_irq(dev->irq, i596_interrupt, 0, "i82596", dev)) {
printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
return -EAGAIN;
}
#ifdef ENABLE_MVME16x_NET
if (MACH_IS_MVME16x) {
- if (request_irq(0x56, &i596_error, 0, "i82596_error", dev))
+ if (request_irq(0x56, i596_error, 0, "i82596_error", dev))
return -EAGAIN;
}
#endif
diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index 7d9f45f7e2d9..d455b1e5fe41 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -85,7 +85,7 @@ static void apne_block_input(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
static void apne_block_output(struct net_device *dev, const int count,
const unsigned char *buf, const int start_page);
-static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int init_pcmcia(void);
@@ -511,18 +511,18 @@ apne_block_output(struct net_device *dev, int count,
return;
}
-static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char pcmcia_intreq;
if (!(gayle.inten & GAYLE_IRQ_IRQ))
- return;
+ return IRQ_NONE;
pcmcia_intreq = pcmcia_get_intreq();
if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) {
pcmcia_ack_int(pcmcia_intreq);
- return;
+ return IRQ_NONE;
}
if (ei_debug > 3)
printk("pcmcia intreq = %x\n", pcmcia_intreq);
@@ -530,6 +530,7 @@ static void apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ei_interrupt(irq, dev_id, regs);
pcmcia_ack_int(pcmcia_get_intreq());
pcmcia_enable_irq();
+ return IRQ_HANDLED;
}
#ifdef MODULE
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index f35bce5b05bd..36d5392c448e 100644
--- a/drivers/net/atari_bionet.c
+++ b/drivers/net/atari_bionet.c
@@ -221,9 +221,9 @@ gsend:
return c;
}
-static void
+static irqreturn_t
bionet_intr(int irq, void *data, struct pt_regs *fp) {
- return;
+ return IRQ_HANDLED;
}
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 95d6640fabd5..fb8d9ee5df8d 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -167,7 +167,7 @@ static int pamsnet_close(struct net_device *dev);
static struct net_device_stats *net_get_stats(struct net_device *dev);
static void pamsnet_tick(unsigned long);
-static void pamsnet_intr(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp);
static struct timer_list pamsnet_timer = TIMER_INITIALIZER(amsnet_tick, 0, 0);
@@ -494,13 +494,13 @@ bad:
return (ret);
}
-static void
+static irqreturn_t
pamsnet_intr(irq, data, fp)
int irq;
void *data;
struct pt_regs *fp;
{
- return;
+ return IRQ_HANDLED;
}
/* receivepkt() loads a packet to a given buffer and returns its length */
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index bbe6abd5187e..99bb5e96366a 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -1968,7 +1968,10 @@ static int ewrk3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case EWRK3_GET_STATS: { /* Get the driver statistics */
struct ewrk3_stats *tmp_stats =
kmalloc(sizeof(lp->pktStats), GFP_KERNEL);
- if (!tmp_stats) return -ENOMEM;
+ if (!tmp_stats) {
+ status = -ENOMEM;
+ break;
+ }
spin_lock_irqsave(&lp->hw_lock, flags);
memcpy(tmp_stats, &lp->pktStats, sizeof(lp->pktStats));
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index beb3a8cc7376..e06740d11531 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -77,8 +77,8 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
static struct net_device_stats *mace_stats(struct net_device *dev);
static void mace_set_multicast(struct net_device *dev);
static int mace_set_address(struct net_device *dev, void *addr);
-static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
static void mace_tx_timeout(struct net_device *dev);
/* Bit-reverse one byte of an ethernet hardware address. */
@@ -561,7 +561,7 @@ static void mace_recv_interrupt(struct net_device *dev)
* Process the chip interrupt
*/
-static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
struct mace_data *mp = (struct mace_data *) dev->priv;
@@ -577,6 +577,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (ir & RCVINT) {
mace_recv_interrupt(dev);
}
+ return IRQ_HANDLED;
}
static void mace_tx_timeout(struct net_device *dev)
@@ -632,7 +633,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
* The PSC has passed us a DMA interrupt event.
*/
-static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_id;
struct mace_data *mp = (struct mace_data *) dev->priv;
@@ -643,7 +644,7 @@ static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
/* Not sure what this does */
while ((baka = psc_read_long(PSC_MYSTERY)) != psc_read_long(PSC_MYSTERY));
- if (!(baka & 0x60000000)) return;
+ if (!(baka & 0x60000000)) return IRQ_NONE;
/*
* Process the read queue
@@ -691,6 +692,7 @@ static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
mp->tx_count++;
netif_wake_queue(dev);
}
+ return IRQ_HANDLED;
}
MODULE_LICENSE("GPL");
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 4e11f8805044..81459c1e6fe3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1305,14 +1305,14 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
u_char saved_page;
unsigned bytes_rcvd;
unsigned int_status, eth_status, rx_status, tx_status;
- unsigned rsr, pktlen, handled = 1;
+ unsigned rsr, pktlen;
ulong start_ticks = jiffies; /* fixme: jiffies rollover every 497 days
* is this something to worry about?
* -- on a laptop?
*/
if (!netif_device_present(dev))
- return IRQ_NONE;
+ return IRQ_HANDLED;
ioaddr = dev->base_addr;
if (lp->mohawk) { /* must disable the interrupt */
@@ -1330,7 +1330,6 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
loop_entry:
if (int_status == 0xff) { /* card may be ejected */
DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
- handled = 0;
goto leave;
}
eth_status = GetByte(XIRCREG_ESR);
@@ -1515,7 +1514,7 @@ xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* force an interrupt with this command:
* PutByte(XIRCREG_CR, EnableIntr|ForceIntr);
*/
- return IRQ_RETVAL(handled);
+ return IRQ_HANDLED;
} /* xirc2ps_interrupt */
/*====================================================================*/
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 72e80026e8f8..5bfad9ba4a8a 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -238,7 +238,7 @@ static int lance_probe( struct net_device *dev);
static int lance_open( struct net_device *dev );
static void lance_init_ring( struct net_device *dev );
static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
-static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
+static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
static int lance_rx( struct net_device *dev );
static int lance_close( struct net_device *dev );
static struct net_device_stats *lance_get_stats( struct net_device *dev );
@@ -620,7 +620,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
/* The LANCE interrupt handler. */
-static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
{
struct net_device *dev = dev_id;
struct lance_private *lp = dev->priv;
@@ -629,7 +629,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
if (dev == NULL) {
DPRINTK( 1, ( "lance_interrupt(): invalid dev_id\n" ));
- return;
+ return IRQ_NONE;
}
if (in_interrupt)
@@ -688,7 +688,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
REGA(CSR3) = CSR3_BSWP;
lance_init_ring(dev);
REGA(CSR0) = CSR0_STRT | CSR0_INEA;
- return;
+ return IRQ_HANDLED;
}
} else if(head->flag & (TMD1_ENP | TMD1_STP)) {
@@ -743,7 +743,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
dev->name, DREG ));
in_interrupt = 0;
- return;
+ return IRQ_HANDLED;
}
/* get packet, toss into skbuff */
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 0a5f6d9b84d2..694692b6393d 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -194,10 +194,10 @@ static int tulip_rx(struct net_device *dev)
if (tp->rx_buffers[entry].mapping !=
le32_to_cpu(tp->rx_ring[entry].buffer1)) {
printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
- "do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
+ "do not match in tulip_rx: %08x vs. %Lx %p / %p.\n",
dev->name,
le32_to_cpu(tp->rx_ring[entry].buffer1),
- tp->rx_buffers[entry].mapping,
+ (u64)tp->rx_buffers[entry].mapping,
skb->head, temp);
}
#endif
diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c
index 44a5e154756c..2dd959a4e005 100644
--- a/drivers/parport/parport_amiga.c
+++ b/drivers/parport/parport_amiga.c
@@ -138,9 +138,10 @@ static unsigned char amiga_read_status(struct parport *p)
}
/* as this ports irq handling is already done, we use a generic funktion */
-static void amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
parport_generic_irq(irq, (struct parport *) dev_id, regs);
+ return IRQ_HANDLED;
}
static void amiga_enable_irq(struct parport *p)
diff --git a/drivers/parport/parport_atari.c b/drivers/parport/parport_atari.c
index bf32c8d3684a..1fd616d120ee 100644
--- a/drivers/parport/parport_atari.c
+++ b/drivers/parport/parport_atari.c
@@ -103,10 +103,11 @@ parport_atari_restore_state(struct parport *p, struct parport_state *s)
{
}
-static void
+static irqreturn_t
parport_atari_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
parport_generic_irq(irq, (struct parport *) dev_id, regs);
+ return IRQ_HANDLED;
}
static void
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index 350f96ff0c71..8dcc3c650974 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -211,7 +211,7 @@ static void mfc3_change_mode( struct parport *p, int m)
static int use_cnt = 0;
-static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int i;
@@ -221,6 +221,7 @@ static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
dummy = pia(this_port[i])->pprb; /* clear irq bit */
parport_generic_irq(irq, this_port[i], regs);
}
+ return IRQ_HANDLED;
}
static void mfc3_enable_irq(struct parport *p)
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 867b31dc3d00..938ff30019c3 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -419,11 +419,12 @@ static void __init isapnp_skip_bytes(int count)
static void isapnp_parse_id(struct pnp_dev * dev, unsigned short vendor, unsigned short device)
{
- struct pnp_id * id = isapnp_alloc(sizeof(struct pnp_id));
- if (!id)
- return;
+ struct pnp_id * id;
if (!dev)
return;
+ id = isapnp_alloc(sizeof(struct pnp_id));
+ if (!id)
+ return;
sprintf(id->id, "%c%c%c%x%x%x%x",
'A' + ((vendor >> 2) & 0x3f) - 1,
'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 4ea00c186153..dcb4570cd657 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/slab.h>
#ifdef CONFIG_PNP_DEBUG
#define DEBUG
@@ -39,9 +40,13 @@ static void quirk_awe32_resources(struct pnp_dev *dev)
*/
for ( ; res ; res = res->dep ) {
port2 = pnp_alloc(sizeof(struct pnp_port));
+ if (!port2)
+ return;
port3 = pnp_alloc(sizeof(struct pnp_port));
- if (!port2 || !port3)
+ if (!port3) {
+ kfree(port2);
return;
+ }
port = res->port;
memcpy(port2, port, sizeof(struct pnp_port));
memcpy(port3, port, sizeof(struct pnp_port));
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 208eabcf23b8..64c2b3424f45 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -322,7 +322,7 @@ static int shutdown (struct Scsi_Host *host);
static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
static int disable (struct Scsi_Host *host);
static int NCR53c7xx_run_tests (struct Scsi_Host *host);
-static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
static void NCR53c7x0_intfly (struct Scsi_Host *host);
static int ncr_halt (struct Scsi_Host *host);
static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
@@ -4226,7 +4226,7 @@ restart:
}
/*
- * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
+ * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
*
* Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
* the same IRQ line.
@@ -4239,14 +4239,16 @@ restart:
* script interrupt handler will call back to this function.
*/
-static void
-NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
+static irqreturn_t
+NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
+{
NCR53c7x0_local_declare();
struct Scsi_Host *host; /* Host we are looking at */
unsigned char istat; /* Values of interrupt regs */
struct NCR53c7x0_hostdata *hostdata; /* host->hostdata[0] */
struct NCR53c7x0_cmd *cmd; /* command which halted */
u32 *dsa; /* DSA */
+ int handled = 0;
#ifdef NCR_DEBUG
char buf[80]; /* Debugging sprintf buffer */
@@ -4263,6 +4265,7 @@ NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
*/
while ((istat = NCR53c7x0_read8(hostdata->istat)) & (ISTAT_SIP|ISTAT_DIP)) {
+ handled = 1;
hostdata->dsp_changed = 0;
hostdata->dstat_valid = 0;
hostdata->state = STATE_HALTED;
@@ -4347,6 +4350,7 @@ NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
}
}
}
+ return IRQ_HANDLED;
}
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index bf82d0b2df1b..e8cb31564efc 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -28,11 +28,13 @@
static struct Scsi_Host *first_instance = NULL;
static Scsi_Host_Template *a2091_template;
-static void a2091_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t a2091_intr (int irq, void *dummy, struct pt_regs *fp)
{
unsigned long flags;
unsigned int status;
struct Scsi_Host *instance;
+ int handled = 0;
+
for (instance = first_instance; instance &&
instance->hostt == a2091_template; instance = instance->next)
{
@@ -44,8 +46,10 @@ static void a2091_intr (int irq, void *dummy, struct pt_regs *fp)
spin_lock_irqsave(&instance->host_lock, flags);
wd33c93_intr (instance);
spin_unlock_irqrestore(&instance->host_lock, flags);
+ handled = 1;
}
}
+ return IRQ_RETVAL(handled);
}
static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
@@ -229,6 +233,13 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
return num_a2091;
}
+static int a2091_bus_reset(Scsi_Cmnd *cmd)
+{
+ /* FIXME perform bus-specific reset */
+ wd33c93_host_reset(cmd);
+ return SUCCESS;
+}
+
#define HOSTS_C
static Scsi_Host_Template driver_template = {
@@ -237,8 +248,9 @@ static Scsi_Host_Template driver_template = {
.detect = a2091_detect,
.release = a2091_release,
.queuecommand = wd33c93_queuecommand,
- .abort = wd33c93_abort,
- .reset = wd33c93_reset,
+ .eh_abort_handler = wd33c93_abort,
+ .eh_bus_reset_handler = a2091_bus_reset,
+ .eh_host_reset_handler = wd33c93_host_reset,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index a6a56c9014f2..073c406344e7 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -27,21 +27,22 @@
static struct Scsi_Host *a3000_host = NULL;
-static void a3000_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t a3000_intr (int irq, void *dummy, struct pt_regs *fp)
{
unsigned long flags;
unsigned int status = DMA(a3000_host)->ISTR;
if (!(status & ISTR_INT_P))
- return;
+ return IRQ_NONE;
if (status & ISTR_INTS)
{
spin_lock_irqsave(&a3000_host->host_lock, flags);
wd33c93_intr (a3000_host);
spin_unlock_irqrestore(&a3000_host->host_lock, flags);
- } else
- printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n",
- status);
+ return IRQ_HANDLED;
+ }
+ printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status);
+ return IRQ_NONE;
}
static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
@@ -205,6 +206,13 @@ fail_register:
return 0;
}
+static int a3000_bus_reset(Scsi_Cmnd *cmd)
+{
+ /* FIXME perform bus-specific reset */
+ wd33c93_host_reset(cmd);
+ return SUCCESS;
+}
+
#define HOSTS_C
static Scsi_Host_Template driver_template = {
@@ -213,8 +221,9 @@ static Scsi_Host_Template driver_template = {
.detect = a3000_detect,
.release = a3000_release,
.queuecommand = wd33c93_queuecommand,
- .abort = wd33c93_abort,
- .reset = wd33c93_reset,
+ .eh_abort_handler = wd33c93_abort,
+ .eh_bus_reset_handler = a3000_bus_reset,
+ .eh_host_reset_handler = wd33c93_host_reset,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 387a14db1fa9..015ebd6ed487 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -1267,10 +1267,10 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
*
*/
-static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
{
struct Scsi_Host *instance = first_instance;
- int done = 1;
+ int done = 1, handled = 0;
unsigned char basr;
INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
@@ -1329,6 +1329,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
}
} /* if !(SELECTION || PARITY) */
+ handled = 1;
} /* BASR & IRQ */
else {
printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
@@ -1342,6 +1343,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
/* Put a call to NCR5380_main() on the queue... */
queue_main();
}
+ return IRQ_RETVAL(handled);
}
#ifdef NCR5380_STATS
diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c
index 55c19c40f6bf..7026045527fd 100644
--- a/drivers/scsi/atari_dma_emul.c
+++ b/drivers/scsi/atari_dma_emul.c
@@ -138,7 +138,7 @@ static inline void set_restdata_reg(unsigned char *cur_addr)
* increased with one.
*/
-static void hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
{
unsigned long dma_base;
register unsigned long dma_cnt asm ("d3");
@@ -166,7 +166,7 @@ static void hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
if ((tt_scsi_dma.dma_ctrl & 2) == 0)
{
atari_enable_irq(IRQ_TT_MFP_SCSI);
- return;
+ return IRQ_HANDLED;
}
if (dma_cnt == 0)
@@ -174,7 +174,7 @@ static void hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
printk(KERN_NOTICE "DMA emulation: count is zero.\n");
tt_scsi_dma.dma_ctrl &= 0xfd; /* DMA ready. */
atari_enable_irq(IRQ_TT_MFP_SCSI);
- return;
+ return IRQ_HANDLED;
}
/*
@@ -338,7 +338,7 @@ scsi_end:
atari_enable_irq(IRQ_TT_MFP_SCSI);
- return;
+ return IRQ_HANDLED;
scsi_bus_error:
/*
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index 17dfa0835bfb..dffe97ee6ad6 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -195,8 +195,8 @@ static int falcon_classify_cmd( Scsi_Cmnd *cmd );
static unsigned long atari_dma_xfer_len( unsigned long wanted_len,
Scsi_Cmnd *cmd, int write_flag );
#endif
-static void scsi_tt_intr( int irq, void *dummy, struct pt_regs *fp);
-static void scsi_falcon_intr( int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_tt_intr( int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_falcon_intr( int irq, void *dummy, struct pt_regs *fp);
static void falcon_release_lock_if_possible( struct NCR5380_hostdata *
hostdata );
static void falcon_get_lock( void );
@@ -315,7 +315,7 @@ static void scsi_dma_buserr (int irq, void *dummy, struct pt_regs *fp)
#endif
-static void scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
{
#ifdef REAL_DMA
int dma_stat;
@@ -403,10 +403,11 @@ static void scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
/* To be sure the int is not masked */
atari_enable_irq( IRQ_TT_MFP_SCSI );
#endif
+ return IRQ_HANDLED;
}
-static void scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp)
{
#ifdef REAL_DMA
int dma_stat;
@@ -463,6 +464,7 @@ static void scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp)
#endif /* REAL_DMA */
NCR5380_intr (0, 0, 0);
+ return IRQ_HANDLED;
}
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index f3ec633166a6..cbfba8bf3cd0 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -28,11 +28,12 @@
static struct Scsi_Host *first_instance = NULL;
static Scsi_Host_Template *gvp11_template;
-static void gvp11_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t gvp11_intr (int irq, void *dummy, struct pt_regs *fp)
{
unsigned long flags;
unsigned int status;
struct Scsi_Host *instance;
+ int handled = 0;
for (instance = first_instance; instance &&
instance->hostt == gvp11_template; instance = instance->next)
@@ -44,7 +45,9 @@ static void gvp11_intr (int irq, void *dummy, struct pt_regs *fp)
spin_lock_irqsave(&instance->host_lock, flags);
wd33c93_intr (instance);
spin_unlock_irqrestore(&instance->host_lock, flags);
+ handled = 1;
}
+ return IRQ_RETVAL(handled);
}
static int gvp11_xfer_mask = 0;
@@ -352,6 +355,13 @@ release:
return num_gvp11;
}
+static int gvp11_bus_reset(Scsi_Cmnd *cmd)
+{
+ /* FIXME perform bus-specific reset */
+ wd33c93_host_reset(cmd);
+ return SUCCESS;
+}
+
#define HOSTS_C
@@ -363,8 +373,9 @@ static Scsi_Host_Template driver_template = {
.detect = gvp11_detect,
.release = gvp11_release,
.queuecommand = wd33c93_queuecommand,
- .abort = wd33c93_abort,
- .reset = wd33c93_reset,
+ .eh_abort_handler = wd33c93_abort,
+ .eh_bus_reset_handler = gvp11_bus_reset,
+ .eh_host_reset_handler = wd33c93_host_reset,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 9a567d97e5d2..a2a06a77813f 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -27,6 +27,7 @@
* hosts currently present in the system.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/blk.h>
#include <linux/kernel.h>
diff --git a/drivers/scsi/mac_NCR5380.c b/drivers/scsi/mac_NCR5380.c
index 81e94a695e5e..9069b5ab3321 100644
--- a/drivers/scsi/mac_NCR5380.c
+++ b/drivers/scsi/mac_NCR5380.c
@@ -1274,7 +1274,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
{
struct Scsi_Host *instance = first_instance;
- int done = 1;
+ int done = 1, handled = 0;
unsigned char basr;
INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
@@ -1333,6 +1333,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
}
} /* if !(SELECTION || PARITY) */
+ handled = 1;
} /* BASR & IRQ */
else {
printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
@@ -1346,6 +1347,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
/* Put a call to NCR5380_main() on the queue... */
queue_main();
}
+ return IRQ_RETVAL(handled);
}
#ifdef NCR5380_STATS
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index cc01741d1416..d5db95619dd0 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -142,9 +142,10 @@ void fake_intr(int irq, void *dev_id, struct pt_regs *pregs)
mac_esp_intr(irq, dev_id, pregs);
}
-void fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
+irqreturn_t fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
{
printk("mac_esp: got drq\n");
+ return IRQ_HANDLED;
}
#define DRIVER_SETUP
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 5f081518ddce..e7c6d9cb450c 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -21,12 +21,13 @@
static struct Scsi_Host *mvme147_host = NULL;
-static void mvme147_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t mvme147_intr (int irq, void *dummy, struct pt_regs *fp)
{
if (irq == MVME147_IRQ_SCSI_PORT)
wd33c93_intr (mvme147_host);
else
m147_pcc->dma_intr = 0x89; /* Ack and enable ints */
+ return IRQ_HANDLED;
}
static int dma_setup (Scsi_Cmnd *cmd, int dir_in)
@@ -112,6 +113,13 @@ int mvme147_detect(Scsi_Host_Template *tpnt)
return 0;
}
+static int mvme147_bus_reset(Scsi_Cmnd *cmd)
+{
+ /* FIXME perform bus-specific reset */
+ wd33c93_host_reset(cmd);
+ return SUCCESS;
+}
+
#define HOSTS_C
#include "mvme147.h"
@@ -122,8 +130,9 @@ static Scsi_Host_Template driver_template = {
.detect = mvme147_detect,
.release = mvme147_release,
.queuecommand = wd33c93_queuecommand,
- .abort = wd33c93_abort,
- .reset = wd33c93_reset,
+ .eh_abort_handler = wd33c93_abort,
+ .eh_bus_reset_handler = mvme147_bus_reset,
+ .eh_host_reset_handler = wd33c93_host_reset,
.can_queue = CAN_QUEUE,
.this_id = 7,
.sg_tablesize = SG_ALL,
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 89d3b02c8a05..f1416975840d 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -1255,10 +1255,10 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
*
*/
-static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
{
struct Scsi_Host *instance = first_instance;
- int done = 1;
+ int done = 1, handled = 0;
unsigned char basr;
INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
@@ -1320,6 +1320,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
#endif
}
} /* if !(SELECTION || PARITY) */
+ handled = 1;
} /* BASR & IRQ */
else {
@@ -1337,6 +1338,7 @@ static void NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
/* Put a call to NCR5380_main() on the queue... */
queue_main();
}
+ return IRQ_RETVAL(handled);
}
#ifdef NCR5380_STATS
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c
index 01b99713e437..f1fea9a416f3 100644
--- a/drivers/scsi/sun3_scsi.c
+++ b/drivers/scsi/sun3_scsi.c
@@ -102,7 +102,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
#define ENABLE_IRQ() enable_irq( IRQ_SUN3_SCSI );
-static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
static inline unsigned char sun3scsi_read(int reg);
static inline void sun3scsi_write(int reg, int value);
@@ -373,9 +373,10 @@ const char * sun3scsi_info (struct Scsi_Host *spnt) {
// safe bits for the CSR
#define CSR_GOOD 0x060f
-static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
{
unsigned short csr = dregs->csr;
+ int handled = 0;
if(csr & ~CSR_GOOD) {
if(csr & CSR_DMA_BUSERR) {
@@ -385,10 +386,15 @@ static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
if(csr & CSR_DMA_CONFLICT) {
printk("scsi%d: dma conflict\n", default_instance->host_no);
}
+ handled = 1;
}
- if(csr & (CSR_SDB_INT | CSR_DMA_INT))
+ if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
NCR5380_intr(irq, dummy, fp);
+ handled = 1;
+ }
+
+ return IRQ_RETVAL(handled);
}
/*
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c
index 28efb3ea4586..0fba9fec29d3 100644
--- a/drivers/scsi/sun3_scsi_vme.c
+++ b/drivers/scsi/sun3_scsi_vme.c
@@ -67,7 +67,7 @@ extern int sun3_map_test(unsigned long, char *);
#define ENABLE_IRQ()
-static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
static inline unsigned char sun3scsi_read(int reg);
static inline void sun3scsi_write(int reg, int value);
@@ -342,9 +342,10 @@ static const char * sun3scsi_info (struct Scsi_Host *spnt) {
// safe bits for the CSR
#define CSR_GOOD 0x060f
-static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
{
unsigned short csr = dregs->csr;
+ int handled = 0;
dregs->csr &= ~CSR_DMA_ENABLE;
@@ -368,10 +369,15 @@ static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
if(csr & CSR_DMA_CONFLICT) {
printk("scsi%d: dma conflict\n", default_instance->host_no);
}
+ handled = 1;
}
- if(csr & (CSR_SDB_INT | CSR_DMA_INT))
+ if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
NCR5380_intr(irq, dummy, fp);
+ handled = 1;
+ }
+
+ return IRQ_RETVAL(handled);
}
/*
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 6eb80fd1a24d..bc60a8e781be 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1123,9 +1123,12 @@ static int amifb_setcolreg(unsigned regno, unsigned red, unsigned green,
static int amifb_blank(int blank, struct fb_info *info);
static int amifb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
-static void amifb_fillrect(struct fb_info *info, struct fb_fillrect *rect);
-static void amifb_copyarea(struct fb_info *info, struct fb_copyarea *region);
-static void amifb_imageblit(struct fb_info *info, struct fb_image *image);
+static void amifb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect);
+static void amifb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *region);
+static void amifb_imageblit(struct fb_info *info,
+ const struct fb_image *image);
static int amifb_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg,
struct fb_info *info);
@@ -1949,11 +1952,13 @@ static inline void xor_one_line(int bpp, unsigned long next_plane,
}
-static void amifb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+static void amifb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
{
struct amifb_par *par = (struct amifb_par *)info->par;
int dst_idx, x2, y2;
unsigned long *dst;
+ u32 width, height;
if (!rect->width || !rect->height)
return;
@@ -1966,25 +1971,24 @@ static void amifb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
y2 = rect->dy + rect->height;
x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
- rect->width = x2 - rect->dx;
- rect->height = y2 - rect->dy;
+ width = x2 - rect->dx;
+ height = y2 - rect->dy;
dst = (unsigned long *)
((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
dst_idx += rect->dy*par->next_line*8+rect->dx;
- while (rect->height--) {
+ while (height--) {
switch (rect->rop) {
case ROP_COPY:
fill_one_line(info->var.bits_per_pixel,
- par->next_plane, dst, dst_idx,
- rect->width, rect->color);
+ par->next_plane, dst, dst_idx, width,
+ rect->color);
break;
case ROP_XOR:
- xor_one_line(info->var.bits_per_pixel,
- par->next_plane, dst, dst_idx,
- rect->width, rect->color);
+ xor_one_line(info->var.bits_per_pixel, par->next_plane,
+ dst, dst_idx, width, rect->color);
break;
}
dst_idx += par->next_line*8;
@@ -2026,47 +2030,38 @@ static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
}
-static void amifb_copyarea(struct fb_info *info, struct fb_copyarea *area)
+static void amifb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
{
struct amifb_par *par = (struct amifb_par *)info->par;
- int x2, y2, old_dx, old_dy;
+ int x2, y2;
+ u32 dx, dy, sx, sy, width, height;
unsigned long *dst, *src;
- int dst_idx, src_idx, height;
+ int dst_idx, src_idx;
int rev_copy = 0;
/* clip the destination */
- old_dx = area->dx;
- old_dy = area->dy;
-
- /*
- * We could use hardware clipping but on many cards you get around
- * hardware clipping by writing to framebuffer directly.
- */
x2 = area->dx + area->width;
y2 = area->dy + area->height;
- area->dx = area->dx > 0 ? area->dx : 0;
- area->dy = area->dy > 0 ? area->dy : 0;
+ dx = area->dx > 0 ? area->dx : 0;
+ dy = area->dy > 0 ? area->dy : 0;
x2 = x2 < info->var.xres_virtual ? x2 : info->var.xres_virtual;
y2 = y2 < info->var.yres_virtual ? y2 : info->var.yres_virtual;
- area->width = x2 - area->dx;
- area->height = y2 - area->dy;
-
- /* update sx1,sy1 */
- area->sx += (area->dx - old_dx);
- area->sy += (area->dy - old_dy);
+ width = x2 - dx;
+ height = y2 - dy;
- height = area->height;
+ /* update sx,sy */
+ sx = area->sx + (dx - area->dx);
+ sy = area->sy + (dy - area->dy);
/* the source must be completely inside the virtual screen */
- if (area->sx < 0 || area->sy < 0 ||
- (area->sx + area->width) > info->var.xres_virtual ||
- (area->sy + area->height) > info->var.yres_virtual)
+ if (sx < 0 || sy < 0 || (sx + width) > info->var.xres_virtual ||
+ (sy + height) > info->var.yres_virtual)
return;
- if (area->dy > area->sy ||
- (area->dy == area->sy && area->dx > area->sx)) {
- area->dy += area->height;
- area->sy += area->height;
+ if (dy > sy || (dy == sy && dx > sx)) {
+ dy += height;
+ sy += height;
rev_copy = 1;
}
dst = (unsigned long *)
@@ -2074,21 +2069,21 @@ static void amifb_copyarea(struct fb_info *info, struct fb_copyarea *area)
src = dst;
dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
src_idx = dst_idx;
- dst_idx += area->dy*par->next_line*8+area->dx;
- src_idx += area->sy*par->next_line*8+area->sx;
+ dst_idx += dy*par->next_line*8+dx;
+ src_idx += sy*par->next_line*8+sx;
if (rev_copy) {
while (height--) {
dst_idx -= par->next_line*8;
src_idx -= par->next_line*8;
copy_one_line_rev(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
- src_idx, area->width);
+ src_idx, width);
}
} else {
while (height--) {
copy_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
- src_idx, area->width);
+ src_idx, width);
dst_idx += par->next_line*8;
src_idx += par->next_line*8;
}
@@ -2125,7 +2120,7 @@ static inline void expand_one_line(int bpp, unsigned long next_plane,
}
-static void amifb_imageblit(struct fb_info *info, struct fb_image *image)
+static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct amifb_par *par = (struct amifb_par *)info->par;
int x2, y2;
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index b7d16c494a32..add29728e767 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -1182,7 +1182,7 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
par->HBB = gend2 - par->HHT - 2;
#if 0
/* One more Videl constraint: data fetch of two lines must not overlap */
- if (par->HDB & 0x200 && par->HDB & ~0x200 - par->HDE <= 5) {
+ if ((par->HDB & 0x200) && (par->HDB & ~0x200) - par->HDE <= 5) {
/* if this happens increase margins, decrease hfreq. */
}
#endif
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 1ce04c3fa002..48ad78cde05e 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2318,15 +2318,25 @@ int __init atyfb_init(void)
return -ENOMEM;
}
memset(info, 0, sizeof(struct fb_info));
- info->fix = atyfb_fix;
+
+ default_par = kmalloc(sizeof(struct atyfb_par), GFP_ATOMIC);
+ if (!default_par) {
+ printk
+ ("atyfb_init: can't alloc atyfb_par\n");
+ kfree(info);
+ return -ENXIO;
+ }
+ memset(default_par, 0, sizeof(struct atyfb_par));
+
+ info->fix = atyfb_fix;
/*
* Map the video memory (physical address given) to somewhere in the
* kernel address space.
*/
- info->screen_base = (unsigned long)ioremap(phys_vmembase[m64_num],
+ info->screen_base = ioremap(phys_vmembase[m64_num],
phys_size[m64_num]);
- info->fix.smem_start = info->screen_base; /* Fake! */
+ info->fix.smem_start = (unsigned long)info->screen_base; /* Fake! */
default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
0x10000) + 0xFC00ul;
info->fix.mmio_start = default_par->ati_regbase; /* Fake! */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 54f2a88de44d..dff229fe7a20 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -187,6 +187,7 @@ static int vbl_detected;
static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
{
vbl_detected++;
+ return IRQ_HANDLED;
}
#endif
diff --git a/fs/Kconfig b/fs/Kconfig
index 5102d45e6466..493fb86f5d32 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -827,6 +827,28 @@ config DEVPTS_FS
Note that the experimental "/dev file system support"
(CONFIG_DEVFS_FS) is a more general facility.
+config DEVPTS_FS_XATTR
+ bool "/dev/pts Extended Attributes"
+ depends on DEVPTS_FS
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+config DEVPTS_FS_SECURITY
+ bool "/dev/pts Security Labels"
+ depends on DEVPTS_FS_XATTR
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the /dev/pts filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
+
config TMPFS
bool "Virtual memory file system support (former shm fs)"
help
diff --git a/fs/Makefile b/fs/Makefile
index 0462ed4d42db..7bf93d805a00 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,9 @@ obj-y := open.o read_write.o file_table.o buffer.o \
namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
dcache.o inode.o attr.o bad_inode.o file.o dnotify.o \
filesystems.o namespace.o seq_file.o xattr.o libfs.o \
- fs-writeback.o mpage.o direct-io.o aio.o eventpoll.o
+ fs-writeback.o mpage.o direct-io.o aio.o
+
+obj-$(CONFIG_EPOLL) += eventpoll.o
obj-$(CONFIG_COMPAT) += compat.o
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index bc3e040de140..14def9ef7385 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -234,7 +234,7 @@ static int init_inodecache(void)
{
adfs_inode_cachep = kmem_cache_create("adfs_inode_cache",
sizeof(struct adfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (adfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 7d6295a8c27f..f3e7aad77c4a 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -115,7 +115,7 @@ static int init_inodecache(void)
{
affs_inode_cachep = kmem_cache_create("affs_inode_cache",
sizeof(struct affs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (affs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
index 0f5a6508290c..084b1f9b1c56 100644
--- a/fs/afs/kafstimod.c
+++ b/fs/afs/kafstimod.c
@@ -83,7 +83,7 @@ static int kafstimod(void *arg)
for (;;) {
unsigned long jif;
- signed long timeout;
+ unsigned long timeout;
/* deal with the server being asked to die */
if (kafstimod_die) {
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 9a0bcf351e13..0e4603081774 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -81,7 +81,7 @@ int __init afs_fs_init(void)
afs_inode_cachep = kmem_cache_create("afs_inode_cache",
sizeof(afs_vnode_t),
0,
- SLAB_HWCACHE_ALIGN,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
afs_i_init_once,
NULL);
if (!afs_inode_cachep) {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 8fff0ea711d9..c2d5ca4d16f2 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -430,7 +430,7 @@ befs_init_inodecache(void)
{
befs_inode_cachep = kmem_cache_create("befs_inode_cache",
sizeof (struct befs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (befs_inode_cachep == NULL) {
printk(KERN_ERR "befs_init_inodecache: "
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 0a41ab302781..0aeab591b8cf 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -243,7 +243,7 @@ static int init_inodecache(void)
{
bfs_inode_cachep = kmem_cache_create("bfs_inode_cache",
sizeof(struct bfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (bfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 2621ba46bf9d..5b340702bdd2 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -17,10 +17,16 @@
#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/kobject.h>
+#include <linux/kobj_map.h>
+#include <linux/cdev.h>
+
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
+static struct kobj_map *cdev_map;
+
#define MAX_PROBE_HASH 255 /* random */
static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
@@ -32,6 +38,7 @@ static struct char_device_struct {
int minorct;
const char *name;
struct file_operations *fops;
+ struct cdev *cdev; /* will die */
} *chrdevs[MAX_PROBE_HASH];
/* index in the above */
@@ -60,59 +67,6 @@ int get_chrdev_list(char *page)
}
/*
- * Return the function table of a device, if present.
- * Increment the reference count of module in question.
- */
-static struct file_operations *
-lookup_chrfops(unsigned int major, unsigned int minor)
-{
- struct char_device_struct *cd;
- struct file_operations *ret = NULL;
- int i;
-
- i = major_to_index(major);
-
- read_lock(&chrdevs_lock);
- for (cd = chrdevs[i]; cd; cd = cd->next) {
- if (major == cd->major &&
- minor - cd->baseminor < cd->minorct) {
- ret = fops_get(cd->fops);
- break;
- }
- }
- read_unlock(&chrdevs_lock);
-
- return ret;
-}
-
-/*
- * Return the function table of a device, if present.
- * Load the driver if needed.
- * Increment the reference count of module in question.
- */
-static struct file_operations *
-get_chrfops(unsigned int major, unsigned int minor)
-{
- struct file_operations *ret = NULL;
-
- if (!major)
- return NULL;
-
- ret = lookup_chrfops(major, minor);
-
-#ifdef CONFIG_KMOD
- if (!ret) {
- request_module("char-major-%d", major);
-
- read_lock(&chrdevs_lock);
- ret = lookup_chrfops(major, minor);
- read_unlock(&chrdevs_lock);
- }
-#endif
- return ret;
-}
-
-/*
* Register a single major with a specified minor range.
*
* If major == 0 this functions will dynamically allocate a major and return
@@ -123,9 +77,9 @@ get_chrfops(unsigned int major, unsigned int minor)
*
* Returns a -ve errno on failure.
*/
-int register_chrdev_region(unsigned int major, unsigned int baseminor,
- int minorct, const char *name,
- struct file_operations *fops)
+static struct char_device_struct *
+__register_chrdev_region(unsigned int major, unsigned int baseminor,
+ int minorct, const char *name)
{
struct char_device_struct *cd, **cp;
int ret = 0;
@@ -133,7 +87,7 @@ int register_chrdev_region(unsigned int major, unsigned int baseminor,
cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL);
if (cd == NULL)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
write_lock_irq(&chrdevs_lock);
@@ -156,7 +110,6 @@ int register_chrdev_region(unsigned int major, unsigned int baseminor,
cd->baseminor = baseminor;
cd->minorct = minorct;
cd->name = name;
- cd->fops = fops;
i = major_to_index(major);
@@ -167,32 +120,23 @@ int register_chrdev_region(unsigned int major, unsigned int baseminor,
if (*cp && (*cp)->major == major &&
(*cp)->baseminor < baseminor + minorct) {
ret = -EBUSY;
- } else {
- cd->next = *cp;
- *cp = cd;
+ goto out;
}
+ cd->next = *cp;
+ *cp = cd;
+ write_unlock_irq(&chrdevs_lock);
+ return cd;
out:
write_unlock_irq(&chrdevs_lock);
- if (ret < 0)
- kfree(cd);
- return ret;
-}
-
-int register_chrdev(unsigned int major, const char *name,
- struct file_operations *fops)
-{
- return register_chrdev_region(major, 0, 256, name, fops);
+ kfree(cd);
+ return ERR_PTR(ret);
}
-/* todo: make void - error printk here */
-int unregister_chrdev_region(unsigned int major, unsigned int baseminor,
- int minorct, const char *name)
+static struct char_device_struct *
+__unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
{
- struct char_device_struct *cd, **cp;
- int ret = 0;
- int i;
-
- i = major_to_index(major);
+ struct char_device_struct *cd = NULL, **cp;
+ int i = major_to_index(major);
write_lock_irq(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
@@ -200,42 +144,179 @@ int unregister_chrdev_region(unsigned int major, unsigned int baseminor,
(*cp)->baseminor == baseminor &&
(*cp)->minorct == minorct)
break;
- if (!*cp || strcmp((*cp)->name, name))
- ret = -EINVAL;
- else {
+ if (*cp) {
cd = *cp;
*cp = cd->next;
- kfree(cd);
}
write_unlock_irq(&chrdevs_lock);
+ return cd;
+}
- return ret;
+int register_chrdev_region(dev_t from, unsigned count, char *name)
+{
+ struct char_device_struct *cd;
+ dev_t to = from + count;
+ dev_t n, next;
+
+ for (n = from; n < to; n = next) {
+ next = MKDEV(MAJOR(n)+1, 0);
+ if (next > to)
+ next = to;
+ cd = __register_chrdev_region(MAJOR(n), MINOR(n),
+ next - n, name);
+ if (IS_ERR(cd))
+ goto fail;
+ }
+ return 0;
+fail:
+ to = n;
+ for (n = from; n < to; n = next) {
+ next = MKDEV(MAJOR(n)+1, 0);
+ kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
+ }
+ return PTR_ERR(cd);
+}
+
+int alloc_chrdev_region(dev_t *dev, unsigned count, char *name)
+{
+ struct char_device_struct *cd;
+ cd = __register_chrdev_region(0, 0, count, name);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+ *dev = MKDEV(cd->major, cd->baseminor);
+ return 0;
+}
+
+int register_chrdev(unsigned int major, const char *name,
+ struct file_operations *fops)
+{
+ struct char_device_struct *cd;
+ struct cdev *cdev;
+ char *s;
+ int err = -ENOMEM;
+
+ cd = __register_chrdev_region(major, 0, 256, name);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+
+ cdev = cdev_alloc();
+ if (!cdev)
+ goto out2;
+
+ cdev->owner = fops->owner;
+ cdev->ops = fops;
+ strcpy(cdev->kobj.name, name);
+ for (s = strchr(cdev->kobj.name, '/'); s; s = strchr(s, '/'))
+ *s = '!';
+
+ err = cdev_add(cdev, MKDEV(cd->major, 0), 256);
+ if (err)
+ goto out;
+
+ cd->cdev = cdev;
+
+ return major ? 0 : cd->major;
+out:
+ kobject_put(&cdev->kobj);
+out2:
+ __unregister_chrdev_region(cd->major, 0, 256);
+ return err;
+}
+
+void unregister_chrdev_region(dev_t from, unsigned count)
+{
+ dev_t to = from + count;
+ dev_t n, next;
+
+ for (n = from; n < to; n = next) {
+ next = MKDEV(MAJOR(n)+1, 0);
+ if (next > to)
+ next = to;
+ kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
+ }
}
int unregister_chrdev(unsigned int major, const char *name)
{
- return unregister_chrdev_region(major, 0, 256, name);
+ struct char_device_struct *cd;
+ cdev_unmap(MKDEV(major, 0), 256);
+ cd = __unregister_chrdev_region(major, 0, 256);
+ if (cd && cd->cdev)
+ cdev_del(cd->cdev);
+ kfree(cd);
+ return 0;
}
+static spinlock_t cdev_lock = SPIN_LOCK_UNLOCKED;
/*
* Called every time a character special file is opened
*/
int chrdev_open(struct inode * inode, struct file * filp)
{
- int ret = -ENODEV;
-
- filp->f_op = get_chrfops(major(inode->i_rdev), minor(inode->i_rdev));
- if (filp->f_op) {
- ret = 0;
- if (filp->f_op->open != NULL) {
- lock_kernel();
- ret = filp->f_op->open(inode,filp);
- unlock_kernel();
- }
+ struct cdev *p;
+ struct cdev *new = NULL;
+ int ret = 0;
+
+ spin_lock(&cdev_lock);
+ p = inode->i_cdev;
+ if (!p) {
+ struct kobject *kobj;
+ int idx;
+ spin_unlock(&cdev_lock);
+ kobj = kobj_lookup(cdev_map, kdev_t_to_nr(inode->i_rdev), &idx);
+ if (!kobj)
+ return -ENODEV;
+ new = container_of(kobj, struct cdev, kobj);
+ spin_lock(&cdev_lock);
+ p = inode->i_cdev;
+ if (!p) {
+ inode->i_cdev = p = new;
+ inode->i_cindex = idx;
+ list_add(&inode->i_devices, &p->list);
+ new = NULL;
+ } else if (!cdev_get(p))
+ ret = -ENODEV;
+ } else if (!cdev_get(p))
+ ret = -ENODEV;
+ spin_unlock(&cdev_lock);
+ cdev_put(new);
+ if (ret)
+ return ret;
+ filp->f_op = fops_get(p->ops);
+ if (!filp->f_op) {
+ cdev_put(p);
+ return -ENODEV;
}
+ if (filp->f_op->open) {
+ lock_kernel();
+ ret = filp->f_op->open(inode,filp);
+ unlock_kernel();
+ }
+ if (ret)
+ cdev_put(p);
return ret;
}
+void cd_forget(struct inode *inode)
+{
+ spin_lock(&cdev_lock);
+ list_del_init(&inode->i_devices);
+ inode->i_cdev = NULL;
+ spin_unlock(&cdev_lock);
+}
+
+void cdev_purge(struct cdev *cdev)
+{
+ spin_lock(&cdev_lock);
+ while (!list_empty(&cdev->list)) {
+ struct inode *inode;
+ inode = container_of(cdev->list.next, struct inode, i_devices);
+ list_del_init(&inode->i_devices);
+ inode->i_cdev = NULL;
+ }
+ spin_unlock(&cdev_lock);
+}
+
/*
* Dummy default file-operations: the only thing this does
* is contain the open that then fills in the correct operations
@@ -265,3 +346,120 @@ const char *cdevname(kdev_t dev)
return buffer;
}
+
+static struct kobject *exact_match(dev_t dev, int *part, void *data)
+{
+ struct cdev *p = data;
+ return &p->kobj;
+}
+
+static int exact_lock(dev_t dev, void *data)
+{
+ struct cdev *p = data;
+ return cdev_get(p) ? 0 : -1;
+}
+
+int cdev_add(struct cdev *p, dev_t dev, unsigned count)
+{
+ int err = kobject_add(&p->kobj);
+ if (err)
+ return err;
+ return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
+}
+
+void cdev_unmap(dev_t dev, unsigned count)
+{
+ kobj_unmap(cdev_map, dev, count);
+}
+
+void cdev_del(struct cdev *p)
+{
+ kobject_del(&p->kobj);
+ kobject_put(&p->kobj);
+}
+
+struct kobject *cdev_get(struct cdev *p)
+{
+ struct module *owner = p->owner;
+ struct kobject *kobj;
+
+ if (owner && !try_module_get(owner))
+ return NULL;
+ kobj = kobject_get(&p->kobj);
+ if (!kobj)
+ module_put(owner);
+ return kobj;
+}
+
+void cdev_put(struct cdev *p)
+{
+ if (p) {
+ kobject_put(&p->kobj);
+ module_put(p->owner);
+ }
+}
+
+static decl_subsys(cdev, NULL, NULL);
+
+static void cdev_default_release(struct kobject *kobj)
+{
+ struct cdev *p = container_of(kobj, struct cdev, kobj);
+ cdev_purge(p);
+}
+
+static void cdev_dynamic_release(struct kobject *kobj)
+{
+ struct cdev *p = container_of(kobj, struct cdev, kobj);
+ cdev_purge(p);
+ kfree(p);
+}
+
+static struct kobj_type ktype_cdev_default = {
+ .release = cdev_default_release,
+};
+
+static struct kobj_type ktype_cdev_dynamic = {
+ .release = cdev_dynamic_release,
+};
+
+static struct kset kset_dynamic = {
+ .subsys = &cdev_subsys,
+ .kobj = {.name = "major",},
+ .ktype = &ktype_cdev_dynamic,
+};
+
+struct cdev *cdev_alloc(void)
+{
+ struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL);
+ if (p) {
+ memset(p, 0, sizeof(struct cdev));
+ p->kobj.kset = &kset_dynamic;
+ INIT_LIST_HEAD(&p->list);
+ kobject_init(&p->kobj);
+ }
+ return p;
+}
+
+void cdev_init(struct cdev *cdev, struct file_operations *fops)
+{
+ INIT_LIST_HEAD(&cdev->list);
+ kobj_set_kset_s(cdev, cdev_subsys);
+ cdev->kobj.ktype = &ktype_cdev_default;
+ kobject_init(&cdev->kobj);
+ cdev->ops = fops;
+}
+
+static struct kobject *base_probe(dev_t dev, int *part, void *data)
+{
+ char name[30];
+ sprintf(name, "char-major-%d", MAJOR(dev));
+ request_module(name);
+ return NULL;
+}
+
+void __init chrdev_init(void)
+{
+ subsystem_register(&cdev_subsys);
+ kset_register(&kset_dynamic);
+ cdev_map = kobj_map_init(base_probe, &cdev_subsys);
+}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 91b1224589b6..d6244d17f236 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -359,7 +359,7 @@ cifs_init_inodecache(void)
{
cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
sizeof (struct cifsInodeInfo),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
cifs_init_once, NULL);
if (cifs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 690806872b10..2728e039f86a 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -70,7 +70,7 @@ int coda_init_inodecache(void)
{
coda_inode_cachep = kmem_cache_create("coda_inode_cache",
sizeof(struct coda_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN||SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (coda_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/compat.c b/fs/compat.c
index 1a834ba4d1a3..89e58e2f720d 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -31,6 +31,7 @@
#include <linux/smp_lock.h>
#include <linux/ctype.h>
#include <linux/module.h>
+#include <net/sock.h> /* siocdevprivate_ioctl */
#include <asm/uaccess.h>
diff --git a/fs/dcache.c b/fs/dcache.c
index 4bbd819d97cf..178328944ce7 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1272,8 +1272,9 @@ void d_move(struct dentry * dentry, struct dentry * target)
* @buflen: buffer length
*
* Convert a dentry into an ASCII path name. If the entry has been deleted
- * the string " (deleted)" is appended. Note that this is ambiguous. Returns
- * the buffer.
+ * the string " (deleted)" is appended. Note that this is ambiguous.
+ *
+ * Returns the buffer or an error code if the path was too long.
*
* "buflen" should be positive. Caller holds the dcache_lock.
*/
@@ -1552,7 +1553,7 @@ static void __init dcache_init(unsigned long mempages)
dentry_cache = kmem_cache_create("dentry_cache",
sizeof(struct dentry),
0,
- SLAB_HWCACHE_ALIGN,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
NULL, NULL);
if (!dentry_cache)
panic("Cannot create dentry cache");
@@ -1606,6 +1607,7 @@ kmem_cache_t *filp_cachep;
EXPORT_SYMBOL(d_genocide);
extern void bdev_cache_init(void);
+extern void chrdev_init(void);
void __init vfs_caches_init(unsigned long mempages)
{
@@ -1626,4 +1628,5 @@ void __init vfs_caches_init(unsigned long mempages)
files_init(mempages);
mnt_init(mempages);
bdev_cache_init();
+ chrdev_init();
}
diff --git a/fs/devpts/Makefile b/fs/devpts/Makefile
index 2619351cd55c..f47e29c13987 100644
--- a/fs/devpts/Makefile
+++ b/fs/devpts/Makefile
@@ -5,3 +5,11 @@
obj-$(CONFIG_DEVPTS_FS) += devpts.o
devpts-objs := inode.o
+
+ifeq ($(CONFIG_DEVPTS_FS_XATTR),y)
+devpts-objs += xattr.o
+endif
+
+ifeq ($(CONFIG_DEVPTS_FS_SECURITY),y)
+devpts-objs += xattr_security.o
+endif
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 377eb7107d6b..3f871c1fa42a 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -16,6 +16,7 @@
#include <linux/sched.h>
#include <linux/namei.h>
#include <linux/mount.h>
+#include "xattr.h"
#define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -130,6 +131,13 @@ static struct dentry *get_node(int num)
return lookup_one_len(s, root, sprintf(s, "%d", num));
}
+static struct inode_operations devpts_file_inode_operations = {
+ .setxattr = devpts_setxattr,
+ .getxattr = devpts_getxattr,
+ .listxattr = devpts_listxattr,
+ .removexattr = devpts_removexattr,
+};
+
void devpts_pty_new(int number, dev_t device)
{
struct dentry *dentry;
@@ -142,6 +150,7 @@ void devpts_pty_new(int number, dev_t device)
inode->i_gid = config.setgid ? config.gid : current->fsgid;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
init_special_inode(inode, S_IFCHR|config.mode, device);
+ inode->i_op = &devpts_file_inode_operations;
dentry = get_node(number);
if (!IS_ERR(dentry) && !dentry->d_inode)
@@ -167,7 +176,10 @@ void devpts_pty_kill(int number)
static int __init init_devpts_fs(void)
{
- int err = register_filesystem(&devpts_fs_type);
+ int err = init_devpts_xattr();
+ if (err)
+ return err;
+ err = register_filesystem(&devpts_fs_type);
if (!err) {
devpts_mnt = kern_mount(&devpts_fs_type);
err = PTR_ERR(devpts_mnt);
@@ -181,6 +193,7 @@ static void __exit exit_devpts_fs(void)
{
unregister_filesystem(&devpts_fs_type);
mntput(devpts_mnt);
+ exit_devpts_xattr();
}
module_init(init_devpts_fs)
diff --git a/fs/devpts/xattr.c b/fs/devpts/xattr.c
new file mode 100644
index 000000000000..db7e15c4fc30
--- /dev/null
+++ b/fs/devpts/xattr.c
@@ -0,0 +1,214 @@
+/*
+ File: fs/devpts/xattr.c
+
+ Derived from fs/ext3/xattr.c, changed in the following ways:
+ drop everything related to persistent storage of EAs
+ pass dentry rather than inode to internal methods
+ only presently define a handler for security modules
+*/
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/semaphore.h>
+#include "xattr.h"
+
+static struct devpts_xattr_handler *devpts_xattr_handlers[DEVPTS_XATTR_INDEX_MAX];
+static rwlock_t devpts_handler_lock = RW_LOCK_UNLOCKED;
+
+int
+devpts_xattr_register(int name_index, struct devpts_xattr_handler *handler)
+{
+ int error = -EINVAL;
+
+ if (name_index > 0 && name_index <= DEVPTS_XATTR_INDEX_MAX) {
+ write_lock(&devpts_handler_lock);
+ if (!devpts_xattr_handlers[name_index-1]) {
+ devpts_xattr_handlers[name_index-1] = handler;
+ error = 0;
+ }
+ write_unlock(&devpts_handler_lock);
+ }
+ return error;
+}
+
+void
+devpts_xattr_unregister(int name_index, struct devpts_xattr_handler *handler)
+{
+ if (name_index > 0 || name_index <= DEVPTS_XATTR_INDEX_MAX) {
+ write_lock(&devpts_handler_lock);
+ devpts_xattr_handlers[name_index-1] = NULL;
+ write_unlock(&devpts_handler_lock);
+ }
+}
+
+static inline const char *
+strcmp_prefix(const char *a, const char *a_prefix)
+{
+ while (*a_prefix && *a == *a_prefix) {
+ a++;
+ a_prefix++;
+ }
+ return *a_prefix ? NULL : a;
+}
+
+/*
+ * Decode the extended attribute name, and translate it into
+ * the name_index and name suffix.
+ */
+static inline struct devpts_xattr_handler *
+devpts_xattr_resolve_name(const char **name)
+{
+ struct devpts_xattr_handler *handler = NULL;
+ int i;
+
+ if (!*name)
+ return NULL;
+ read_lock(&devpts_handler_lock);
+ for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
+ if (devpts_xattr_handlers[i]) {
+ const char *n = strcmp_prefix(*name,
+ devpts_xattr_handlers[i]->prefix);
+ if (n) {
+ handler = devpts_xattr_handlers[i];
+ *name = n;
+ break;
+ }
+ }
+ }
+ read_unlock(&devpts_handler_lock);
+ return handler;
+}
+
+static inline struct devpts_xattr_handler *
+devpts_xattr_handler(int name_index)
+{
+ struct devpts_xattr_handler *handler = NULL;
+ if (name_index > 0 && name_index <= DEVPTS_XATTR_INDEX_MAX) {
+ read_lock(&devpts_handler_lock);
+ handler = devpts_xattr_handlers[name_index-1];
+ read_unlock(&devpts_handler_lock);
+ }
+ return handler;
+}
+
+/*
+ * Inode operation getxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+ssize_t
+devpts_getxattr(struct dentry *dentry, const char *name,
+ void *buffer, size_t size)
+{
+ struct devpts_xattr_handler *handler;
+
+ handler = devpts_xattr_resolve_name(&name);
+ if (!handler)
+ return -EOPNOTSUPP;
+ return handler->get(dentry, name, buffer, size);
+}
+
+/*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+ssize_t
+devpts_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
+{
+ struct devpts_xattr_handler *handler = NULL;
+ int i, error = 0;
+ unsigned int size = 0;
+ char *buf;
+
+ read_lock(&devpts_handler_lock);
+
+ for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
+ handler = devpts_xattr_handlers[i];
+ if (handler)
+ size += handler->list(dentry, NULL);
+ }
+
+ if (!buffer) {
+ error = size;
+ goto out;
+ } else {
+ error = -ERANGE;
+ if (size > buffer_size)
+ goto out;
+ }
+
+ buf = buffer;
+ for (i=0; i<DEVPTS_XATTR_INDEX_MAX; i++) {
+ handler = devpts_xattr_handlers[i];
+ if (handler)
+ buf += handler->list(dentry, buf);
+ }
+ error = size;
+
+out:
+ read_unlock(&devpts_handler_lock);
+ return size;
+}
+
+/*
+ * Inode operation setxattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+int
+devpts_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ struct devpts_xattr_handler *handler;
+
+ if (size == 0)
+ value = ""; /* empty EA, do not remove */
+ handler = devpts_xattr_resolve_name(&name);
+ if (!handler)
+ return -EOPNOTSUPP;
+ return handler->set(dentry, name, value, size, flags);
+}
+
+/*
+ * Inode operation removexattr()
+ *
+ * dentry->d_inode->i_sem down
+ */
+int
+devpts_removexattr(struct dentry *dentry, const char *name)
+{
+ struct devpts_xattr_handler *handler;
+
+ handler = devpts_xattr_resolve_name(&name);
+ if (!handler)
+ return -EOPNOTSUPP;
+ return handler->set(dentry, name, NULL, 0, XATTR_REPLACE);
+}
+
+int __init
+init_devpts_xattr(void)
+{
+#ifdef CONFIG_DEVPTS_FS_SECURITY
+ int err;
+
+ err = devpts_xattr_register(DEVPTS_XATTR_INDEX_SECURITY,
+ &devpts_xattr_security_handler);
+ if (err)
+ return err;
+#endif
+
+ return 0;
+}
+
+void
+exit_devpts_xattr(void)
+{
+#ifdef CONFIG_DEVPTS_FS_SECURITY
+ devpts_xattr_unregister(DEVPTS_XATTR_INDEX_SECURITY,
+ &devpts_xattr_security_handler);
+#endif
+
+}
diff --git a/fs/devpts/xattr.h b/fs/devpts/xattr.h
new file mode 100644
index 000000000000..ecd74a0986a6
--- /dev/null
+++ b/fs/devpts/xattr.h
@@ -0,0 +1,59 @@
+/*
+ File: fs/devpts/xattr.h
+
+ Derived from fs/ext3/xattr.h, changed in the following ways:
+ drop everything related to persistent storage of EAs
+ pass dentry rather than inode to internal methods
+ only presently define a handler for security modules
+*/
+
+#include <linux/config.h>
+#include <linux/xattr.h>
+
+/* Name indexes */
+#define DEVPTS_XATTR_INDEX_MAX 10
+#define DEVPTS_XATTR_INDEX_SECURITY 1
+
+# ifdef CONFIG_DEVPTS_FS_XATTR
+
+struct devpts_xattr_handler {
+ char *prefix;
+ size_t (*list)(struct dentry *dentry, char *buffer);
+ int (*get)(struct dentry *dentry, const char *name, void *buffer,
+ size_t size);
+ int (*set)(struct dentry *dentry, const char *name, const void *buffer,
+ size_t size, int flags);
+};
+
+extern int devpts_xattr_register(int, struct devpts_xattr_handler *);
+extern void devpts_xattr_unregister(int, struct devpts_xattr_handler *);
+
+extern int devpts_setxattr(struct dentry *, const char *, const void *, size_t, int);
+extern ssize_t devpts_getxattr(struct dentry *, const char *, void *, size_t);
+extern ssize_t devpts_listxattr(struct dentry *, char *, size_t);
+extern int devpts_removexattr(struct dentry *, const char *);
+
+extern int init_devpts_xattr(void);
+extern void exit_devpts_xattr(void);
+
+# else /* CONFIG_DEVPTS_FS_XATTR */
+# define devpts_setxattr NULL
+# define devpts_getxattr NULL
+# define devpts_listxattr NULL
+# define devpts_removexattr NULL
+
+static inline int
+init_devpts_xattr(void)
+{
+ return 0;
+}
+
+static inline void
+exit_devpts_xattr(void)
+{
+}
+
+# endif /* CONFIG_DEVPTS_FS_XATTR */
+
+extern struct devpts_xattr_handler devpts_xattr_security_handler;
+
diff --git a/fs/devpts/xattr_security.c b/fs/devpts/xattr_security.c
new file mode 100644
index 000000000000..b7c9b7cac1b0
--- /dev/null
+++ b/fs/devpts/xattr_security.c
@@ -0,0 +1,42 @@
+/*
+ * File: fs/devpts/xattr_security.c
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/security.h>
+#include "xattr.h"
+
+#define XATTR_SECURITY_PREFIX "security."
+
+static size_t
+devpts_xattr_security_list(struct dentry *dentry, char *buffer)
+{
+ return security_inode_listsecurity(dentry, buffer);
+}
+
+static int
+devpts_xattr_security_get(struct dentry *dentry, const char *name,
+ void *buffer, size_t size)
+{
+ if (strcmp(name, "") == 0)
+ return -EINVAL;
+ return security_inode_getsecurity(dentry, name, buffer, size);
+}
+
+static int
+devpts_xattr_security_set(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ if (strcmp(name, "") == 0)
+ return -EINVAL;
+ return security_inode_setsecurity(dentry, name, value, size, flags);
+}
+
+struct devpts_xattr_handler devpts_xattr_security_handler = {
+ .prefix = XATTR_SECURITY_PREFIX,
+ .list = devpts_xattr_security_list,
+ .get = devpts_xattr_security_get,
+ .set = devpts_xattr_security_set,
+};
diff --git a/fs/dquot.c b/fs/dquot.c
index edda8c2009d6..6ee5cd6af648 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1383,7 +1383,7 @@ static int __init dquot_init(void)
dquot_cachep = kmem_cache_create("dquot",
sizeof(struct dquot), sizeof(unsigned long) * 4,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (!dquot_cachep)
panic("Cannot create dquot SLAB cache");
diff --git a/fs/efs/super.c b/fs/efs/super.c
index f0ece23a28c3..21be0cb8cb50 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -58,7 +58,7 @@ static int init_inodecache(void)
{
efs_inode_cachep = kmem_cache_create("efs_inode_cache",
sizeof(struct efs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN||SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (efs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/exec.c b/fs/exec.c
index e214e30ca525..d84c9a2c4b8f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -529,30 +529,6 @@ static int exec_mmap(struct mm_struct *mm)
return 0;
}
-static struct dentry *clean_proc_dentry(struct task_struct *p)
-{
- struct dentry *proc_dentry = p->proc_dentry;
-
- if (proc_dentry) {
- spin_lock(&dcache_lock);
- if (!d_unhashed(proc_dentry)) {
- dget_locked(proc_dentry);
- __d_drop(proc_dentry);
- } else
- proc_dentry = NULL;
- spin_unlock(&dcache_lock);
- }
- return proc_dentry;
-}
-
-static inline void put_proc_dentry(struct dentry *dentry)
-{
- if (dentry) {
- shrink_dcache_parent(dentry);
- dput(dentry);
- }
-}
-
/*
* This function makes sure the current process has its own signal table,
* so that flush_signal_handlers can later reset the handlers without
@@ -633,6 +609,7 @@ static inline int de_thread(struct task_struct *tsk)
count = 1;
while (atomic_read(&oldsig->count) > count) {
oldsig->group_exit_task = current;
+ oldsig->notify_count = count;
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(lock);
schedule();
@@ -660,9 +637,11 @@ static inline int de_thread(struct task_struct *tsk)
while (leader->state != TASK_ZOMBIE)
yield();
+ spin_lock(&leader->proc_lock);
+ spin_lock(&current->proc_lock);
+ proc_dentry1 = proc_pid_unhash(current);
+ proc_dentry2 = proc_pid_unhash(leader);
write_lock_irq(&tasklist_lock);
- proc_dentry1 = clean_proc_dentry(current);
- proc_dentry2 = clean_proc_dentry(leader);
if (leader->tgid != current->tgid)
BUG();
@@ -702,9 +681,10 @@ static inline int de_thread(struct task_struct *tsk)
state = leader->state;
write_unlock_irq(&tasklist_lock);
-
- put_proc_dentry(proc_dentry1);
- put_proc_dentry(proc_dentry2);
+ spin_unlock(&leader->proc_lock);
+ spin_unlock(&current->proc_lock);
+ proc_pid_flush(proc_dentry1);
+ proc_pid_flush(proc_dentry2);
if (state != TASK_ZOMBIE)
BUG();
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 7d8e178b44af..dc7ced597149 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -185,7 +185,7 @@ static int init_inodecache(void)
{
ext2_inode_cachep = kmem_cache_create("ext2_inode_cache",
sizeof(struct ext2_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (ext2_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 8c72318360b7..6d27c23210b8 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -529,7 +529,7 @@ static int init_inodecache(void)
{
ext3_inode_cachep = kmem_cache_create("ext3_inode_cache",
sizeof(struct ext3_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (ext3_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 282c0c22db6f..a6d740b59426 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -697,7 +697,7 @@ int __init fat_init_inodecache(void)
{
fat_inode_cachep = kmem_cache_create("fat_inode_cache",
sizeof(struct msdos_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (fat_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/file_table.c b/fs/file_table.c
index 6762d46ceaa0..0e6e6bb82979 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -15,7 +15,7 @@
#include <linux/security.h>
#include <linux/eventpoll.h>
#include <linux/mount.h>
-
+#include <linux/cdev.h>
/* sysctl tunables... */
struct files_stat_struct files_stat = {
@@ -166,6 +166,8 @@ void __fput(struct file *file)
if (file->f_op && file->f_op->release)
file->f_op->release(inode, file);
security_file_free(file);
+ if (unlikely(inode->i_cdev != NULL))
+ cdev_put(inode->i_cdev);
fops_put(file->f_op);
if (file->f_mode & FMODE_WRITE)
put_write_access(inode);
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 9733ee2d1d6a..c3d3f301ba20 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -247,7 +247,8 @@ static int __init
vxfs_init(void)
{
vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
- sizeof(struct vxfs_inode_info), 0, 0, NULL, NULL);
+ sizeof(struct vxfs_inode_info), 0,
+ SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (vxfs_inode_cachep)
return (register_filesystem(&vxfs_fs_type));
return -ENOMEM;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 28e47bf7d5ab..74e717cb5f37 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -90,7 +90,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
* Only add valid (hashed) inodes to the superblock's
* dirty list. Add blockdev inodes as well.
*/
- if (hlist_unhashed(&inode->i_hash) && !S_ISBLK(inode->i_mode))
+ if ((hlist_unhashed(&inode->i_hash) || (inode->i_state & (I_FREEING|I_CLEAR)))
+ && !S_ISBLK(inode->i_mode))
goto out;
/*
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 89195405b3d2..f93f0e78789b 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -72,7 +72,7 @@ static int init_inodecache(void)
{
hfs_inode_cachep = kmem_cache_create("hfs_inode_cache",
sizeof(struct hfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (hfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 79a57406e602..aaa088d8601c 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -191,7 +191,7 @@ static int init_inodecache(void)
{
hpfs_inode_cachep = kmem_cache_create("hpfs_inode_cache",
sizeof(struct hpfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (hpfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/inode.c b/fs/inode.c
index 9440ffe76b08..2725851f6202 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -18,6 +18,7 @@
#include <linux/hash.h>
#include <linux/swap.h>
#include <linux/security.h>
+#include <linux/cdev.h>
/*
* This is needed for the following functions:
@@ -128,6 +129,7 @@ static struct inode *alloc_inode(struct super_block *sb)
memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
inode->i_pipe = NULL;
inode->i_bdev = NULL;
+ inode->i_cdev = NULL;
inode->i_rdev = to_kdev_t(0);
inode->i_security = NULL;
if (security_inode_alloc(inode)) {
@@ -241,6 +243,8 @@ void clear_inode(struct inode *inode)
inode->i_sb->s_op->clear_inode(inode);
if (inode->i_bdev)
bd_forget(inode);
+ if (inode->i_cdev)
+ cd_forget(inode);
inode->i_state = I_CLEAR;
}
@@ -466,6 +470,7 @@ static int shrink_icache_memory(int nr, unsigned int gfp_mask)
return inodes_stat.nr_unused;
}
+static void __wait_on_freeing_inode(struct inode *inode);
/*
* Called with the inode lock held.
* NOTE: we are not increasing the inode-refcount, you must call __iget()
@@ -477,6 +482,7 @@ static struct inode * find_inode(struct super_block * sb, struct hlist_head *hea
struct hlist_node *node;
struct inode * inode = NULL;
+repeat:
hlist_for_each (node, head) {
prefetch(node->next);
inode = hlist_entry(node, struct inode, i_hash);
@@ -484,6 +490,10 @@ static struct inode * find_inode(struct super_block * sb, struct hlist_head *hea
continue;
if (!test(inode, data))
continue;
+ if (inode->i_state & (I_FREEING|I_CLEAR)) {
+ __wait_on_freeing_inode(inode);
+ goto repeat;
+ }
break;
}
return node ? inode : NULL;
@@ -498,6 +508,7 @@ static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head
struct hlist_node *node;
struct inode * inode = NULL;
+repeat:
hlist_for_each (node, head) {
prefetch(node->next);
inode = list_entry(node, struct inode, i_hash);
@@ -505,6 +516,10 @@ static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head
continue;
if (inode->i_sb != sb)
continue;
+ if (inode->i_state & (I_FREEING|I_CLEAR)) {
+ __wait_on_freeing_inode(inode);
+ goto repeat;
+ }
break;
}
return node ? inode : NULL;
@@ -933,11 +948,22 @@ void remove_inode_hash(struct inode *inode)
spin_unlock(&inode_lock);
}
+/*
+ * Tell the filesystem that this inode is no longer of any interest and should
+ * be completely destroyed.
+ *
+ * We leave the inode in the inode hash table until *after* the filesystem's
+ * ->delete_inode completes. This ensures that an iget (such as nfsd might
+ * instigate) will always find up-to-date information either in the hash or on
+ * disk.
+ *
+ * I_FREEING is set so that no-one will take a new reference to the inode while
+ * it is being deleted.
+ */
void generic_delete_inode(struct inode *inode)
{
struct super_operations *op = inode->i_sb->s_op;
- hlist_del_init(&inode->i_hash);
list_del_init(&inode->i_list);
inode->i_state|=I_FREEING;
inodes_stat.nr_inodes--;
@@ -956,6 +982,10 @@ void generic_delete_inode(struct inode *inode)
delete(inode);
} else
clear_inode(inode);
+ spin_lock(&inode_lock);
+ hlist_del_init(&inode->i_hash);
+ spin_unlock(&inode_lock);
+ wake_up_inode(inode);
if (inode->i_state != I_CLEAR)
BUG();
destroy_inode(inode);
@@ -1229,6 +1259,32 @@ repeat:
__set_current_state(TASK_RUNNING);
}
+/*
+ * If we try to find an inode in the inode hash while it is being deleted, we
+ * have to wait until the filesystem completes its deletion before reporting
+ * that it isn't found. This is because iget will immediately call
+ * ->read_inode, and we want to be sure that evidence of the deletion is found
+ * by ->read_inode.
+ *
+ * This call might return early if an inode which shares the waitq is woken up.
+ * This is most easily handled by the caller which will loop around again
+ * looking for the inode.
+ *
+ * This is called with inode_lock held.
+ */
+static void __wait_on_freeing_inode(struct inode *inode)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ wait_queue_head_t *wq = i_waitq_head(inode);
+
+ add_wait_queue(wq, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ spin_unlock(&inode_lock);
+ schedule();
+ remove_wait_queue(wq, &wait);
+ spin_lock(&inode_lock);
+}
+
void wake_up_inode(struct inode *inode)
{
wait_queue_head_t *wq = i_waitq_head(inode);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 54cff6f1b0df..9c47f2565297 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -105,7 +105,7 @@ static int init_inodecache(void)
{
isofs_inode_cachep = kmem_cache_create("isofs_inode_cache",
sizeof(struct iso_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (isofs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 376962a24161..e74ce5fc40f8 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1806,9 +1806,11 @@ init_jffs_fs(void)
jffs_proc_root = proc_mkdir("jffs", proc_root_fs);
#endif
fm_cache = kmem_cache_create("jffs_fm", sizeof(struct jffs_fm),
- 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+ NULL, NULL);
node_cache = kmem_cache_create("jffs_node",sizeof(struct jffs_node),
- 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+ NULL, NULL);
return register_filesystem(&jffs_fs_type);
}
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 23985b4efed1..f8b7ba5a46d8 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -73,7 +73,8 @@ int __init jffs2_create_slab_caches(void)
inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
sizeof(struct jffs2_inode_cache),
- 0, JFFS2_SLAB_POISON, NULL, NULL);
+ 0, JFFS2_SLAB_POISON|SLAB_RECLAIM_ACCOUNT,
+ NULL, NULL);
if (inode_cache_slab)
return 0;
err:
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 614c984ecf4f..bce925b6c9ab 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -299,7 +299,7 @@ static int __init init_jffs2_fs(void)
jffs2_inode_cachep = kmem_cache_create("jffs2_i",
sizeof(struct jffs2_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
jffs2_i_init_once, NULL);
if (!jffs2_inode_cachep) {
printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n");
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 166df3331657..84ddb9e25483 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -444,8 +444,8 @@ static int __init init_jfs_fs(void)
int rc;
jfs_inode_cachep =
- kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, 0,
- init_once, NULL);
+ kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0,
+ SLAB_RECLAIM_ACCOUNT, init_once, NULL);
if (jfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/mbcache.c b/fs/mbcache.c
index 3dff3a5e65b0..dbc4443e6949 100644
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -265,7 +265,7 @@ mb_cache_create(const char *name, struct mb_cache_op *cache_op,
INIT_LIST_HEAD(&cache->c_indexes_hash[m][n]);
}
cache->c_entry_cache = kmem_cache_create(name, entry_size, 0,
- 0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL);
+ SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (!cache->c_entry_cache)
goto fail;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index ec5c8bffed08..aaaa4d9c3664 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -79,7 +79,7 @@ static int init_inodecache(void)
{
minix_inode_cachep = kmem_cache_create("minix_inode_cache",
sizeof(struct minix_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (minix_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/namespace.c b/fs/namespace.c
index 09238867b43b..0174d8400c9d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -486,9 +486,11 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
if (err)
goto out_unlock;
+ err = -ENOENT;
spin_lock(&dcache_lock);
if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) {
struct list_head head;
+
attach_mnt(mnt, nd);
list_add_tail(&head, &mnt->mnt_list);
list_splice(&head, current->namespace->list.prev);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index f8039a1683d1..9de41ad18cbf 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -72,7 +72,7 @@ static int init_inodecache(void)
{
ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
sizeof(struct ncp_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (ncp_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a0569d609554..b97f81b911a1 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1571,7 +1571,7 @@ int nfs_init_inodecache(void)
{
nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
sizeof(struct nfs_inode),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (nfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 91d90ee6f581..2d8cfbda8698 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -361,7 +361,7 @@ encode_attrs(struct xdr_stream *xdr, struct iattr *iap,
*q++ = htonl(len);
status = 0;
-out:
+/* out: */
return status;
}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index cb3aeea03410..24afa0afcb3d 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1715,7 +1715,8 @@ static int __init init_ntfs_fs(void)
}
ntfs_inode_cache = kmem_cache_create(ntfs_inode_cache_name,
- sizeof(ntfs_inode), 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+ sizeof(ntfs_inode), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, NULL, NULL);
if (!ntfs_inode_cache) {
printk(KERN_CRIT "NTFS: Failed to create %s!\n",
ntfs_inode_cache_name);
@@ -1723,7 +1724,8 @@ static int __init init_ntfs_fs(void)
}
ntfs_big_inode_cache = kmem_cache_create(ntfs_big_inode_cache_name,
- sizeof(big_ntfs_inode), 0, SLAB_HWCACHE_ALIGN,
+ sizeof(big_ntfs_inode), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
ntfs_big_inode_init_once, NULL);
if (!ntfs_big_inode_cache) {
printk(KERN_CRIT "NTFS: Failed to create %s!\n",
diff --git a/fs/proc/base.c b/fs/proc/base.c
index cad41397fd3f..04fd16864aff 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -58,6 +58,13 @@ enum pid_directory_inos {
PROC_PID_MAPS,
PROC_PID_MOUNTS,
PROC_PID_WCHAN,
+#ifdef CONFIG_SECURITY
+ PROC_PID_ATTR,
+ PROC_PID_ATTR_CURRENT,
+ PROC_PID_ATTR_PREV,
+ PROC_PID_ATTR_EXEC,
+ PROC_PID_ATTR_FSCREATE,
+#endif
PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
};
@@ -82,11 +89,23 @@ static struct pid_entry base_stuff[] = {
E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_PID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_SECURITY
+ E(PROC_PID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
+#endif
#ifdef CONFIG_KALLSYMS
E(PROC_PID_WCHAN, "wchan", S_IFREG|S_IRUGO),
#endif
{0,0,NULL,0}
};
+#ifdef CONFIG_SECURITY
+static struct pid_entry attr_stuff[] = {
+ E(PROC_PID_ATTR_CURRENT, "current", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_PID_ATTR_PREV, "prev", S_IFREG|S_IRUGO),
+ E(PROC_PID_ATTR_EXEC, "exec", S_IFREG|S_IRUGO|S_IWUGO),
+ E(PROC_PID_ATTR_FSCREATE, "fscreate", S_IFREG|S_IRUGO|S_IWUGO),
+ {0,0,NULL,0}
+};
+#endif
#undef E
static inline struct task_struct *proc_task(struct inode *inode)
@@ -411,8 +430,10 @@ static ssize_t proc_info_read(struct file * file, char * buf,
if (count + *ppos > length)
count = length - *ppos;
end = count + *ppos;
- copy_to_user(buf, (char *) page + *ppos, count);
- *ppos = end;
+ if (copy_to_user(buf, (char *) page + *ppos, count))
+ count = -EFAULT;
+ else
+ *ppos = end;
free_page(page);
return count;
}
@@ -624,6 +645,12 @@ static struct inode_operations proc_pid_link_inode_operations = {
.follow_link = proc_pid_follow_link
};
+static int pid_alive(struct task_struct *p)
+{
+ BUG_ON(p->pids[PIDTYPE_PID].pidptr != &p->pids[PIDTYPE_PID].pid);
+ return atomic_read(&p->pids[PIDTYPE_PID].pid.count);
+}
+
#define NUMBUF 10
static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
@@ -635,6 +662,9 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
char buf[NUMBUF];
struct files_struct * files;
+ retval = -ENOENT;
+ if (!pid_alive(p))
+ goto out;
retval = 0;
pid = p->pid;
@@ -689,58 +719,68 @@ out:
return retval;
}
-static int proc_base_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
+static int proc_pident_readdir(struct file *filp,
+ void *dirent, filldir_t filldir,
+ struct pid_entry *ents, unsigned int nents)
{
int i;
int pid;
- struct inode *inode = filp->f_dentry->d_inode;
+ struct dentry *dentry = filp->f_dentry;
+ struct inode *inode = dentry->d_inode;
struct pid_entry *p;
- int ret = 0;
+ ino_t ino;
+ int ret;
- lock_kernel();
+ ret = -ENOENT;
+ if (!pid_alive(proc_task(inode)))
+ goto out;
+ ret = 0;
pid = proc_task(inode)->pid;
- if (!pid) {
- ret = -ENOENT;
- goto out;
- }
i = filp->f_pos;
switch (i) {
- case 0:
- if (filldir(dirent, ".", 1, i, inode->i_ino, DT_DIR) < 0)
- goto out;
- i++;
- filp->f_pos++;
- /* fall through */
- case 1:
- if (filldir(dirent, "..", 2, i, PROC_ROOT_INO, DT_DIR) < 0)
+ case 0:
+ ino = inode->i_ino;
+ if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ case 1:
+ ino = parent_ino(dentry);
+ if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+ goto out;
+ i++;
+ filp->f_pos++;
+ /* fall through */
+ default:
+ i -= 2;
+ if (i >= nents) {
+ ret = 1;
+ goto out;
+ }
+ p = ents + i;
+ while (p->name) {
+ if (filldir(dirent, p->name, p->len, filp->f_pos,
+ fake_ino(pid, p->type), p->mode >> 12) < 0)
goto out;
- i++;
filp->f_pos++;
- /* fall through */
- default:
- i -= 2;
- if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) {
- ret = 1;
- goto out;
- }
- p = base_stuff + i;
- while (p->name) {
- if (filldir(dirent, p->name, p->len, filp->f_pos,
- fake_ino(pid, p->type), p->mode >> 12) < 0)
- goto out;
- filp->f_pos++;
- p++;
- }
+ p++;
+ }
}
ret = 1;
out:
- unlock_kernel();
return ret;
}
+static int proc_base_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ base_stuff,ARRAY_SIZE(base_stuff));
+}
+
/* building an inode */
static int task_dumpable(struct task_struct *task)
@@ -774,7 +814,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_ino = fake_ino(task->pid, ino);
- if (!task->pid)
+ if (!pid_alive(task))
goto out_unlock;
/*
@@ -789,6 +829,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
inode->i_uid = task->euid;
inode->i_gid = task->egid;
}
+ security_task_to_inode(task, inode);
out:
return inode;
@@ -808,7 +849,7 @@ out_unlock:
*/
static int pid_revalidate(struct dentry * dentry, int flags)
{
- if (proc_task(dentry->d_inode)->pid)
+ if (pid_alive(proc_task(dentry->d_inode)))
return 1;
d_drop(dentry);
return 0;
@@ -842,18 +883,23 @@ static int pid_fd_revalidate(struct dentry * dentry, int flags)
static void pid_base_iput(struct dentry *dentry, struct inode *inode)
{
struct task_struct *task = proc_task(inode);
- write_lock_irq(&tasklist_lock);
+ spin_lock(&task->proc_lock);
if (task->proc_dentry == dentry)
task->proc_dentry = NULL;
- write_unlock_irq(&tasklist_lock);
+ spin_unlock(&task->proc_lock);
iput(inode);
}
static int pid_delete_dentry(struct dentry * dentry)
{
- return proc_task(dentry->d_inode)->pid == 0;
+ /* Is the task we represent dead?
+ * If so, then don't put the dentry on the lru list,
+ * kill it immediately.
+ */
+ return !pid_alive(proc_task(dentry->d_inode));
}
+
static struct dentry_operations pid_fd_dentry_operations =
{
.d_revalidate = pid_fd_revalidate,
@@ -909,6 +955,8 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
if (fd == ~0U)
goto out;
+ if (!pid_alive(task))
+ goto out;
inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
if (!inode)
@@ -937,8 +985,6 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
ei->op.proc_get_link = proc_fd_link;
dentry->d_op = &pid_fd_dentry_operations;
d_add(dentry, inode);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
return NULL;
out_unlock2:
@@ -963,8 +1009,86 @@ static struct inode_operations proc_fd_inode_operations = {
.permission = proc_permission,
};
+#ifdef CONFIG_SECURITY
+static ssize_t proc_pid_attr_read(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ unsigned long page;
+ ssize_t length;
+ ssize_t end;
+ struct task_struct *task = proc_task(inode);
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+ if (!(page = __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ length = security_getprocattr(task,
+ (char*)file->f_dentry->d_name.name,
+ (void*)page, count);
+ if (length < 0) {
+ free_page(page);
+ return length;
+ }
+ /* Static 4kB (or whatever) block capacity */
+ if (*ppos >= length) {
+ free_page(page);
+ return 0;
+ }
+ if (count + *ppos > length)
+ count = length - *ppos;
+ end = count + *ppos;
+ if (copy_to_user(buf, (char *) page + *ppos, count))
+ count = -EFAULT;
+ else
+ *ppos = end;
+ free_page(page);
+ return count;
+}
+
+static ssize_t proc_pid_attr_write(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
+{
+ struct inode * inode = file->f_dentry->d_inode;
+ char *page;
+ ssize_t length;
+ struct task_struct *task = proc_task(inode);
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+ if (*ppos != 0) {
+ /* No partial writes. */
+ return -EINVAL;
+ }
+ page = (char*)__get_free_page(GFP_USER);
+ if (!page)
+ return -ENOMEM;
+ length = -EFAULT;
+ if (copy_from_user(page, buf, count))
+ goto out;
+
+ length = security_setprocattr(task,
+ (char*)file->f_dentry->d_name.name,
+ (void*)page, count);
+out:
+ free_page((unsigned long) page);
+ return length;
+}
+
+static struct file_operations proc_pid_attr_operations = {
+ .read = proc_pid_attr_read,
+ .write = proc_pid_attr_write,
+};
+
+static struct file_operations proc_attr_operations;
+static struct inode_operations proc_attr_inode_operations;
+#endif
+
/* SMP-safe */
-static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *proc_pident_lookup(struct inode *dir,
+ struct dentry *dentry,
+ struct pid_entry *ents)
{
struct inode *inode;
int error;
@@ -975,7 +1099,10 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
error = -ENOENT;
inode = NULL;
- for (p = base_stuff; p->name; p++) {
+ if (!pid_alive(task))
+ goto out;
+
+ for (p = ents; p->name; p++) {
if (p->len != dentry->d_name.len)
continue;
if (!memcmp(dentry->d_name.name, p->name, p->len))
@@ -1043,6 +1170,19 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
case PROC_PID_MOUNTS:
inode->i_fop = &proc_mounts_operations;
break;
+#ifdef CONFIG_SECURITY
+ case PROC_PID_ATTR:
+ inode->i_nlink = 2;
+ inode->i_op = &proc_attr_inode_operations;
+ inode->i_fop = &proc_attr_operations;
+ break;
+ case PROC_PID_ATTR_CURRENT:
+ case PROC_PID_ATTR_PREV:
+ case PROC_PID_ATTR_EXEC:
+ case PROC_PID_ATTR_FSCREATE:
+ inode->i_fop = &proc_pid_attr_operations;
+ break;
+#endif
#ifdef CONFIG_KALLSYMS
case PROC_PID_WCHAN:
inode->i_fop = &proc_info_file_operations;
@@ -1056,14 +1196,16 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
}
dentry->d_op = &pid_dentry_operations;
d_add(dentry, inode);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
return NULL;
out:
return ERR_PTR(error);
}
+static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry){
+ return proc_pident_lookup(dir, dentry, base_stuff);
+}
+
static struct file_operations proc_base_operations = {
.read = generic_read_dir,
.readdir = proc_base_readdir,
@@ -1073,6 +1215,28 @@ static struct inode_operations proc_base_inode_operations = {
.lookup = proc_base_lookup,
};
+#ifdef CONFIG_SECURITY
+static int proc_attr_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+{
+ return proc_pident_readdir(filp,dirent,filldir,
+ attr_stuff,ARRAY_SIZE(attr_stuff));
+}
+
+static struct file_operations proc_attr_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_attr_readdir,
+};
+
+static struct dentry *proc_attr_lookup(struct inode *dir, struct dentry *dentry){
+ return proc_pident_lookup(dir, dentry, attr_stuff);
+}
+
+static struct inode_operations proc_attr_inode_operations = {
+ .lookup = proc_attr_lookup,
+};
+#endif
+
/*
* /proc/self:
*/
@@ -1095,6 +1259,55 @@ static struct inode_operations proc_self_inode_operations = {
.follow_link = proc_self_follow_link,
};
+/**
+ * proc_pid_unhash - Unhash /proc/<pid> entry from the dcache.
+ * @p: task that should be flushed.
+ *
+ * Drops the /proc/<pid> dcache entry from the hash chains.
+ *
+ * Dropping /proc/<pid> entries and detach_pid must be synchroneous,
+ * otherwise e.g. /proc/<pid>/exe might point to the wrong executable,
+ * if the pid value is immediately reused. This is enforced by
+ * - caller must acquire spin_lock(p->proc_lock)
+ * - must be called before detach_pid()
+ * - proc_pid_lookup acquires proc_lock, and checks that
+ * the target is not dead by looking at the attach count
+ * of PIDTYPE_PID.
+ */
+
+struct dentry *proc_pid_unhash(struct task_struct *p)
+{
+ struct dentry *proc_dentry;
+
+ proc_dentry = p->proc_dentry;
+ if (proc_dentry != NULL) {
+
+ spin_lock(&dcache_lock);
+ if (!d_unhashed(proc_dentry)) {
+ dget_locked(proc_dentry);
+ __d_drop(proc_dentry);
+ } else
+ proc_dentry = NULL;
+ spin_unlock(&dcache_lock);
+ }
+ return proc_dentry;
+}
+
+/**
+ * proc_pid_flush - recover memory used by stale /proc/<pid>/x entries
+ * @proc_entry: directoy to prune.
+ *
+ * Shrink the /proc directory that was used by the just killed thread.
+ */
+
+void proc_pid_flush(struct dentry *proc_dentry)
+{
+ if(proc_dentry != NULL) {
+ shrink_dcache_parent(proc_dentry);
+ dput(proc_dentry);
+ }
+}
+
/* SMP-safe */
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
{
@@ -1143,12 +1356,12 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
inode->i_flags|=S_IMMUTABLE;
dentry->d_op = &pid_base_dentry_operations;
+
+ spin_lock(&task->proc_lock);
+ task->proc_dentry = dentry;
d_add(dentry, inode);
- read_lock(&tasklist_lock);
- proc_task(dentry->d_inode)->proc_dentry = dentry;
- read_unlock(&tasklist_lock);
- if (!proc_task(dentry->d_inode)->pid)
- d_drop(dentry);
+ spin_unlock(&task->proc_lock);
+
return NULL;
out:
return ERR_PTR(-ENOENT);
@@ -1171,7 +1384,7 @@ static int get_pid_list(int index, unsigned int *pids)
read_lock(&tasklist_lock);
for_each_process(p) {
int pid = p->pid;
- if (!pid)
+ if (!pid_alive(p))
continue;
if (--index >= 0)
continue;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 146556c6d507..ec0bc6aadd2c 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -121,7 +121,7 @@ int __init proc_init_inodecache(void)
{
proc_inode_cachep = kmem_cache_create("proc_inode_cache",
sizeof(struct proc_inode),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (proc_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a39ade29cbf3..439226c79daf 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -485,7 +485,6 @@ static int cmdline_read_proc(char *page, char **start, off_t off,
int len;
len = sprintf(page, "%s\n", saved_command_line);
- len = strlen(page);
return proc_calc_metrics(page, start, off, count, eof, len);
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index c4d71953bc6a..d49f353378df 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -110,9 +110,9 @@ static int proc_root_readdir(struct file * filp,
}
filp->f_pos = FIRST_PROCESS_ENTRY;
}
+ unlock_kernel();
ret = proc_pid_readdir(filp, dirent, filldir);
- unlock_kernel();
return ret;
}
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index caac9561ab80..8c6a4dc19cd4 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -540,7 +540,7 @@ static int init_inodecache(void)
{
qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",
sizeof(struct qnx4_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (qnx4_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/readdir.c b/fs/readdir.c
index 68975a079b7c..5261c81859d6 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -59,7 +59,7 @@ struct old_linux_dirent {
struct readdir_callback {
struct old_linux_dirent __user * dirent;
- int count;
+ int result;
};
static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
@@ -68,21 +68,24 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset
struct readdir_callback * buf = (struct readdir_callback *) __buf;
struct old_linux_dirent __user * dirent;
- if (buf->count)
+ if (buf->result)
return -EINVAL;
- buf->count++;
+ buf->result++;
dirent = buf->dirent;
if (!access_ok(VERIFY_WRITE, (unsigned long)dirent,
(unsigned long)(dirent->d_name + namlen + 1) -
(unsigned long)dirent))
- return -EFAULT;
+ goto efault;
if ( __put_user(ino, &dirent->d_ino) ||
__put_user(offset, &dirent->d_offset) ||
__put_user(namlen, &dirent->d_namlen) ||
__copy_to_user(dirent->d_name, name, namlen) ||
__put_user(0, dirent->d_name + namlen))
- return -EFAULT;
+ goto efault;
return 0;
+efault:
+ buf->result = -EFAULT;
+ return -EFAULT;
}
asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count)
@@ -96,12 +99,12 @@ asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * di
if (!file)
goto out;
- buf.count = 0;
+ buf.result = 0;
buf.dirent = dirent;
error = vfs_readdir(file, fillonedir, &buf);
if (error >= 0)
- error = buf.count;
+ error = buf.result;
fput(file);
out:
@@ -144,7 +147,6 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
goto efault;
}
dirent = buf->current_dir;
- buf->previous = dirent;
if (__put_user(ino, &dirent->d_ino))
goto efault;
if (__put_user(reclen, &dirent->d_reclen))
@@ -153,11 +155,13 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
goto efault;
if (__put_user(0, dirent->d_name + namlen))
goto efault;
+ buf->previous = dirent;
((char *) dirent) += reclen;
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
efault:
+ buf->error = -EFAULT;
return -EFAULT;
}
@@ -225,7 +229,6 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
goto efault;
}
dirent = buf->current_dir;
- buf->previous = dirent;
if (__put_user(ino, &dirent->d_ino))
goto efault;
if (__put_user(0, &dirent->d_off))
@@ -238,11 +241,13 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
goto efault;
if (__put_user(0, dirent->d_name + namlen))
goto efault;
+ buf->previous = dirent;
((char *) dirent) += reclen;
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
efault:
+ buf->error = -EFAULT;
return -EFAULT;
}
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index a779d856d6bc..cbc26ddb5c90 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -21,6 +21,7 @@ struct file_operations reiserfs_dir_operations = {
.read = generic_read_dir,
.readdir = reiserfs_readdir,
.fsync = reiserfs_dir_fsync,
+ .ioctl = reiserfs_ioctl,
};
int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 53caf4f460d0..31adb5bfe7d8 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -918,8 +918,6 @@ static void init_inode (struct inode * inode, struct path * path)
REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0;
- /* nopack = 0, by default */
- REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
if (stat_data_v1 (ih)) {
struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
@@ -954,6 +952,9 @@ static void init_inode (struct inode * inode, struct path * path)
rdev = sd_v1_rdev(sd);
REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd);
+ /* nopack is initially zero for v1 objects. For v2 objects,
+ nopack is initialised from sd_attrs */
+ REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
} else {
// new stat data found, but object may have old items
// (directories and symlinks)
@@ -983,6 +984,10 @@ static void init_inode (struct inode * inode, struct path * path)
set_inode_item_key_version (inode, KEY_FORMAT_3_6);
REISERFS_I(inode)->i_first_direct_byte = 0;
set_inode_sd_version (inode, STAT_DATA_V2);
+ /* read persistent inode attributes from sd and initalise
+ generic inode flags from them */
+ REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd );
+ sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode );
}
pathrelse (path);
@@ -1007,6 +1012,7 @@ static void init_inode (struct inode * inode, struct path * path)
static void inode2sd (void * sd, struct inode * inode)
{
struct stat_data * sd_v2 = (struct stat_data *)sd;
+ __u16 flags;
set_sd_v2_mode(sd_v2, inode->i_mode );
set_sd_v2_nlink(sd_v2, inode->i_nlink );
@@ -1017,13 +1023,13 @@ static void inode2sd (void * sd, struct inode * inode)
set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec );
set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
set_sd_v2_blocks(sd_v2, inode->i_blocks );
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) );
-}
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+ set_sd_v2_rdev(sd_v2, kdev_t_to_nr(inode->i_rdev) );
else
- {
- set_sd_v2_generation(sd_v2, inode->i_generation);
- }
+ set_sd_v2_generation(sd_v2, inode->i_generation);
+ flags = REISERFS_I(inode)->i_attrs;
+ i_attrs_to_sd_attrs( inode, &flags );
+ set_sd_v2_attrs( sd_v2, flags );
}
@@ -1553,6 +1559,10 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
/* uid and gid must already be set by the caller for quota init */
+ /* symlink cannot be immutable or append only, right? */
+ if( S_ISLNK( inode -> i_mode ) )
+ inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
+
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_size = i_size;
inode->i_blocks = (inode->i_size + 511) >> 9;
@@ -1565,6 +1575,9 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_trans_index = 0;
+ REISERFS_I(inode)->i_attrs =
+ REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
+ sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode );
if (old_format_only (sb))
make_le_item_head (&ih, 0, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
@@ -2210,6 +2223,50 @@ static int reiserfs_commit_write(struct file *f, struct page *page,
return ret ;
}
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
+{
+ if( reiserfs_attrs( inode -> i_sb ) ) {
+ if( sd_attrs & REISERFS_SYNC_FL )
+ inode -> i_flags |= S_SYNC;
+ else
+ inode -> i_flags &= ~S_SYNC;
+ if( sd_attrs & REISERFS_IMMUTABLE_FL )
+ inode -> i_flags |= S_IMMUTABLE;
+ else
+ inode -> i_flags &= ~S_IMMUTABLE;
+ if( sd_attrs & REISERFS_NOATIME_FL )
+ inode -> i_flags |= S_NOATIME;
+ else
+ inode -> i_flags &= ~S_NOATIME;
+ if( sd_attrs & REISERFS_NOTAIL_FL )
+ REISERFS_I(inode)->i_flags |= i_nopack_mask;
+ else
+ REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
+ }
+}
+
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
+{
+ if( reiserfs_attrs( inode -> i_sb ) ) {
+ if( inode -> i_flags & S_IMMUTABLE )
+ *sd_attrs |= REISERFS_IMMUTABLE_FL;
+ else
+ *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
+ if( inode -> i_flags & S_SYNC )
+ *sd_attrs |= REISERFS_SYNC_FL;
+ else
+ *sd_attrs &= ~REISERFS_SYNC_FL;
+ if( inode -> i_flags & S_NOATIME )
+ *sd_attrs |= REISERFS_NOATIME_FL;
+ else
+ *sd_attrs &= ~REISERFS_NOATIME_FL;
+ if( REISERFS_I(inode)->i_flags & i_nopack_mask )
+ *sd_attrs |= REISERFS_NOTAIL_FL;
+ else
+ *sd_attrs &= ~REISERFS_NOTAIL_FL;
+ }
+}
+
/*
* Returns 1 if the page's buffers were dropped. The page is locked.
*
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index bac3199b045d..92fac037519e 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -14,17 +14,70 @@
** supported commands:
** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
** and prevent packing file (argument arg has to be non-zero)
-** 2) That's all for a while ...
+** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
+** 3) That's all for a while ...
*/
int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg)
{
+ unsigned int flags;
+
switch (cmd) {
case REISERFS_IOC_UNPACK:
+ if( S_ISREG( inode -> i_mode ) ) {
if (arg)
return reiserfs_unpack (inode, filp);
+ else
+ return 0;
+ } else
+ return -ENOTTY;
+ /* following two cases are taken from fs/ext2/ioctl.c by Remy
+ Card (card@masi.ibp.fr) */
+ case REISERFS_IOC_GETFLAGS:
+ flags = REISERFS_I(inode) -> i_attrs;
+ i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
+ return put_user(flags, (int *) arg);
+ case REISERFS_IOC_SETFLAGS: {
+ if (IS_RDONLY(inode))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+
+ if (get_user(flags, (int *) arg))
+ return -EFAULT;
+
+ if ( ( flags & REISERFS_IMMUTABLE_FL ) &&
+ !capable( CAP_LINUX_IMMUTABLE ) )
+ return -EPERM;
- default:
+ if( ( flags & REISERFS_NOTAIL_FL ) &&
+ S_ISREG( inode -> i_mode ) ) {
+ int result;
+
+ result = reiserfs_unpack( inode, filp );
+ if( result )
+ return result;
+ }
+ sd_attrs_to_i_attrs( flags, inode );
+ REISERFS_I(inode) -> i_attrs = flags;
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ return 0;
+ }
+ case REISERFS_IOC_GETVERSION:
+ return put_user(inode->i_generation, (int *) arg);
+ case REISERFS_IOC_SETVERSION:
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EPERM;
+ if (IS_RDONLY(inode))
+ return -EROFS;
+ if (get_user(inode->i_generation, (int *) arg))
+ return -EFAULT;
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ return 0;
+ default:
return -ENOTTY;
}
}
@@ -32,7 +85,7 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
/*
** reiserfs_unpack
** Function try to convert tail from direct item into indirect.
-** It set up nopack attribute in the inode.u.reiserfs_i.nopack
+** It set up nopack attribute in the REISERFS_I(inode)->nopack
*/
int reiserfs_unpack (struct inode * inode, struct file * filp)
{
@@ -43,7 +96,8 @@ int reiserfs_unpack (struct inode * inode, struct file * filp)
unsigned long blocksize = inode->i_sb->s_blocksize ;
if (inode->i_size == 0) {
- return -EINVAL ;
+ REISERFS_I(inode)->i_flags |= i_nopack_mask;
+ return 0 ;
}
/* ioctl already done */
if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index a90e4b61d791..1789f8b201ba 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -350,6 +350,7 @@ int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
struct reiserfs_sb_info *sb_info;
struct reiserfs_super_block *rs;
int hash_code;
+ __u32 flags;
int len = 0;
sb = procinfo_prologue((int)data);
@@ -358,6 +359,7 @@ int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
sb_info = REISERFS_SB(sb);
rs = sb_info -> s_rs;
hash_code = DFL( s_hash_function_code );
+ flags = DJF( s_flags );
len += sprintf( &buffer[ len ],
"block_count: \t%i\n"
@@ -373,6 +375,7 @@ int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
"tree_height: \t%i\n"
"bmap_nr: \t%i\n"
"version: \t%i\n"
+ "flags: \t%x[%s]\n"
"reserved_for_journal: \t%i\n",
DFL( s_block_count ),
@@ -391,6 +394,9 @@ int reiserfs_on_disk_super_in_proc( char *buffer, char **start, off_t offset,
DF( s_tree_height ),
DF( s_bmap_nr ),
DF( s_version ),
+ flags,
+ ( flags & reiserfs_attrs_cleared )
+ ? "attrs_cleared" : "",
DF (s_reserved_for_journal));
procinfo_epilogue( sb );
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index a70cd0986486..ae31cff05cd1 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -440,7 +440,7 @@ static int init_inodecache(void)
{
reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache",
sizeof(struct reiserfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (reiserfs_inode_cachep == NULL)
return -ENOMEM;
@@ -708,6 +708,24 @@ for old setups still work */
return 1;
}
+static void handle_attrs( struct super_block *s )
+{
+ struct reiserfs_super_block * rs;
+
+ if( reiserfs_attrs( s ) ) {
+ rs = SB_DISK_SUPER_BLOCK (s);
+ if( old_format_only(s) ) {
+ reiserfs_warning( "reiserfs: cannot support attributes on 3.5.x disk format\n" );
+ REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+ return;
+ }
+ if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
+ reiserfs_warning( "reiserfs: cannot support attributes until flag is set in super-block\n" );
+ REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+ }
+ }
+}
+
static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
{
struct reiserfs_super_block * rs;
@@ -720,6 +738,8 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a
if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL))
return -EINVAL;
+ handle_attrs( s );
+
if(blocks) {
int rc = reiserfs_resize(s, blocks);
if (rc != 0)
@@ -1319,6 +1339,8 @@ static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
// mark hash in super block: it could be unset. overwrite should be ok
set_sb_hash_function_code( rs, function2code(sbi->s_hash_function ) );
+ handle_attrs( s );
+
reiserfs_proc_info_init( s );
reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
reiserfs_proc_register( s, "super", reiserfs_super_in_proc );
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index ee215f3e56fd..7355ce94e60c 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -578,7 +578,7 @@ static int init_inodecache(void)
{
romfs_inode_cachep = kmem_cache_create("romfs_inode_cache",
sizeof(struct romfs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (romfs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index d0c335625c14..74a424899996 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -79,7 +79,7 @@ static int init_inodecache(void)
{
smb_inode_cachep = kmem_cache_create("smb_inode_cache",
sizeof(struct smb_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (smb_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 0a8c81d23b71..d433042d358f 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -328,7 +328,8 @@ int __init sysv_init_icache(void)
{
sysv_inode_cachep = kmem_cache_create("sysv_inode_cache",
sizeof(struct sysv_inode_info), 0,
- SLAB_HWCACHE_ALIGN, init_once, NULL);
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+ init_once, NULL);
if (!sysv_inode_cachep)
return -ENOMEM;
return 0;
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 6fafb04f6a99..e95e09fda8a8 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -141,7 +141,7 @@ static int init_inodecache(void)
{
udf_inode_cachep = kmem_cache_create("udf_inode_cache",
sizeof(struct udf_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (udf_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 39282f551371..53029020b321 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1029,7 +1029,7 @@ static int init_inodecache(void)
{
ufs_inode_cachep = kmem_cache_create("ufs_inode_cache",
sizeof(struct ufs_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (ufs_inode_cachep == NULL)
return -ENOMEM;
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 7143735182e3..a6821a542818 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -329,7 +329,8 @@ STATIC int
init_inodecache( void )
{
linvfs_inode_cachep = kmem_cache_create("linvfs_icache",
- sizeof(vnode_t), 0, SLAB_HWCACHE_ALIGN,
+ sizeof(vnode_t), 0,
+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (linvfs_inode_cachep == NULL)
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 875bee2947a8..d077d7419682 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -51,10 +51,10 @@
/*
* Data type ranges
*/
-#define ACPI_UINT8_MAX (UINT8) 0xFF
-#define ACPI_UINT16_MAX (UINT16) 0xFFFF
-#define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF
-#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF
+#define ACPI_UINT8_MAX (~((UINT8) 0))
+#define ACPI_UINT16_MAX (~((UINT16) 0))
+#define ACPI_UINT32_MAX (~((UINT32) 0))
+#define ACPI_UINT64_MAX (~((UINT64) 0))
#define ACPI_ASCII_MAX 0x7F
@@ -313,7 +313,11 @@ typedef u32 acpi_integer;
typedef u64 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
-#define ACPI_MAX_BCD_VALUE 9999999999999999
+#if ACPI_MACHINE_WIDTH == 64
+#define ACPI_MAX_BCD_VALUE 9999999999999999UL
+#else
+#define ACPI_MAX_BCD_VALUE 9999999999999999ULL
+#endif
#define ACPI_MAX_BCD_DIGITS 16
#define ACPI_MAX_DECIMAL_DIGITS 19
diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
index f0ab134d99cf..1db148c2bde7 100644
--- a/include/asm-arm/tlb.h
+++ b/include/asm-arm/tlb.h
@@ -33,13 +33,13 @@ struct mmu_gather {
unsigned int avoided_flushes;
};
-extern struct mmu_gather mmu_gathers[NR_CPUS];
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
int cpu = smp_processor_id();
- struct mmu_gather *tlb = &mmu_gathers[cpu];
+ struct mmu_gather *tlb = &per_cpu(mmu_gathers, cpu);
tlb->mm = mm;
tlb->freed = 0;
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 486a4e77d476..368f65b64360 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -44,7 +44,7 @@ struct mmu_gather {
};
/* Users of the generic TLB shootdown code must declare this storage space. */
-extern struct mmu_gather mmu_gathers[NR_CPUS];
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
/* tlb_gather_mmu
* Return a pointer to an initialized struct mmu_gather.
@@ -52,7 +52,7 @@ extern struct mmu_gather mmu_gathers[NR_CPUS];
static inline struct mmu_gather *
tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
{
- struct mmu_gather *tlb = &mmu_gathers[smp_processor_id()];
+ struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
tlb->mm = mm;
diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
index 7b84277e526c..519571a84945 100644
--- a/include/asm-i386/mach-bigsmp/mach_apic.h
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h
@@ -1,5 +1,6 @@
#ifndef __ASM_MACH_APIC_H
#define __ASM_MACH_APIC_H
+#include <asm/smp.h>
#define SEQUENTIAL_APICID
#ifdef SEQUENTIAL_APICID
@@ -40,18 +41,10 @@ static inline unsigned long check_apicid_present(int bit)
#define apicid_cluster(apicid) (apicid & 0xF0)
-static inline unsigned get_apic_id(unsigned long x)
-{
- return (((x)>>24)&0x0F);
-}
-
-#define GET_APIC_ID(x) get_apic_id(x)
-
static inline unsigned long calculate_ldr(unsigned long old)
{
unsigned long id;
- id = xapic_phys_to_log_apicid(
- GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)));
+ id = xapic_phys_to_log_apicid(hard_smp_processor_id());
return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
}
@@ -135,8 +128,6 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
return (1);
}
-#define APIC_ID_MASK (0x0F<<24)
-
static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
{
int num_bits_set;
diff --git a/include/asm-i386/mach-bigsmp/mach_apicdef.h b/include/asm-i386/mach-bigsmp/mach_apicdef.h
new file mode 100644
index 000000000000..23e58b317c79
--- /dev/null
+++ b/include/asm-i386/mach-bigsmp/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0x0F<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0x0F);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h
index ad40d96b3824..f0d615e4a924 100644
--- a/include/asm-i386/mach-default/mach_apic.h
+++ b/include/asm-i386/mach-default/mach_apic.h
@@ -1,6 +1,8 @@
#ifndef __ASM_MACH_APIC_H
#define __ASM_MACH_APIC_H
+#include <mach_apicdef.h>
+
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
static inline unsigned long target_cpus(void)
@@ -105,15 +107,6 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map);
}
-#define APIC_ID_MASK (0xF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
- return (((x)>>24)&0xF);
-}
-
-#define GET_APIC_ID(x) get_apic_id(x)
-
static inline int apic_id_registered(void)
{
return (test_bit(GET_APIC_ID(apic_read(APIC_ID)),
diff --git a/include/asm-i386/mach-default/mach_apicdef.h b/include/asm-i386/mach-default/mach_apicdef.h
new file mode 100644
index 000000000000..7bcb350c3ee8
--- /dev/null
+++ b/include/asm-i386/mach-default/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0xF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0xF);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h
index d5160168908a..bdf7cc780cbe 100644
--- a/include/asm-i386/mach-numaq/mach_apic.h
+++ b/include/asm-i386/mach-numaq/mach_apic.h
@@ -107,15 +107,6 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
return (1);
}
-#define APIC_ID_MASK (0xF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
- return (((x)>>24)&0x0F);
-}
-
-#define GET_APIC_ID(x) get_apic_id(x)
-
static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
{
int num_bits_set;
diff --git a/include/asm-i386/mach-numaq/mach_apicdef.h b/include/asm-i386/mach-numaq/mach_apicdef.h
new file mode 100644
index 000000000000..bf439d0690f5
--- /dev/null
+++ b/include/asm-i386/mach-numaq/mach_apicdef.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+
+#define APIC_ID_MASK (0xF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0x0F);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index cc5a532f6c95..f576880b5343 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -2,6 +2,7 @@
#define __ASM_MACH_APIC_H
#include <linux/config.h>
+#include <asm/smp.h>
#ifdef CONFIG_X86_GENERICARCH
#define x86_summit 1 /* must be an constant expressiona for generic arch */
@@ -48,20 +49,12 @@ static inline unsigned long check_apicid_present(int bit)
extern u8 bios_cpu_apicid[];
-static inline unsigned get_apic_id(unsigned long x)
-{
- return (((x)>>24)&0xFF);
-}
-
-#define GET_APIC_ID(x) get_apic_id(x)
-
static inline void init_apic_ldr(void)
{
unsigned long val, id;
if (x86_summit)
- id = xapic_phys_to_log_apicid(
- GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)));
+ id = xapic_phys_to_log_apicid(hard_smp_processor_id());
else
id = 1UL << smp_processor_id();
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
@@ -143,8 +136,6 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map);
}
-#define APIC_ID_MASK (0xFF<<24)
-
static inline unsigned int cpu_mask_to_apicid (unsigned long cpumask)
{
int num_bits_set;
diff --git a/include/asm-i386/mach-summit/mach_apicdef.h b/include/asm-i386/mach-summit/mach_apicdef.h
new file mode 100644
index 000000000000..a58ab5a75c8c
--- /dev/null
+++ b/include/asm-i386/mach-summit/mach_apicdef.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0xFF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0xFF);
+}
+
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h
index c2681d88b3be..641c173d4f76 100644
--- a/include/asm-i386/mach-visws/mach_apic.h
+++ b/include/asm-i386/mach-visws/mach_apic.h
@@ -19,14 +19,6 @@
#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid))
#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
-#define APIC_ID_MASK (0xF<<24)
-
-static inline unsigned get_apic_id(unsigned long x)
-{
- return (((x)>>24)&0xF);
-}
-#define GET_APIC_ID(x) get_apic_id(x)
-
static inline int apic_id_registered(void)
{
return (test_bit(GET_APIC_ID(apic_read(APIC_ID)),
diff --git a/include/asm-i386/mach-visws/mach_apicdef.h b/include/asm-i386/mach-visws/mach_apicdef.h
new file mode 100644
index 000000000000..826cfa97d778
--- /dev/null
+++ b/include/asm-i386/mach-visws/mach_apicdef.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_MACH_APICDEF_H
+#define __ASM_MACH_APICDEF_H
+
+#define APIC_ID_MASK (0xF<<24)
+
+static inline unsigned get_apic_id(unsigned long x)
+{
+ return (((x)>>24)&0xF);
+}
+#define GET_APIC_ID(x) get_apic_id(x)
+
+#endif
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
index 67a5353fdb59..f72e82945a57 100644
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -91,7 +91,7 @@ extern inline int any_online_cpu(unsigned int mask)
#ifdef APIC_DEFINITION
extern int hard_smp_processor_id(void);
#else
-#include <mach_apic.h>
+#include <mach_apicdef.h>
static inline int hard_smp_processor_id(void)
{
/* we don't want to mark this access volatile - bad code generation */
diff --git a/include/asm-m68k/atari_stdma.h b/include/asm-m68k/atari_stdma.h
index ddc92e199ced..64f92880ce43 100644
--- a/include/asm-m68k/atari_stdma.h
+++ b/include/asm-m68k/atari_stdma.h
@@ -8,7 +8,8 @@
/***************************** Prototypes *****************************/
-void stdma_lock(void (*handler)(int, void *, struct pt_regs *), void *data);
+void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ void *data);
void stdma_release( void );
int stdma_others_waiting( void );
int stdma_islocked( void );
diff --git a/include/asm-m68k/hdreg.h b/include/asm-m68k/hdreg.h
index 16249bd892a4..214152b84ace 100644
--- a/include/asm-m68k/hdreg.h
+++ b/include/asm-m68k/hdreg.h
@@ -7,7 +7,5 @@
#ifndef _M68K_HDREG_H
#define _M68K_HDREG_H
-typedef unsigned int q40ide_ioreg_t;
-typedef unsigned char * ide_ioreg_t;
#endif /* _M68K_HDREG_H */
diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h
index 621be3adc24a..a9d0d84bc71d 100644
--- a/include/asm-m68k/ide.h
+++ b/include/asm-m68k/ide.h
@@ -51,12 +51,12 @@
#endif
-static __inline__ int ide_default_irq(ide_ioreg_t base)
+static __inline__ int ide_default_irq(unsigned long base)
{
return 0;
}
-static __inline__ ide_ioreg_t ide_default_io_base(int index)
+static __inline__ unsigned long ide_default_io_base(int index)
{
return 0;
}
@@ -66,7 +66,9 @@ static __inline__ ide_ioreg_t ide_default_io_base(int index)
* Set up a hw structure for a specified data port, control port and IRQ.
* This should follow whatever the default interface uses.
*/
-static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+static __inline__ void ide_init_hwif_ports(hw_regs_t *hw,
+ unsigned long data_port,
+ unsigned long ctrl_port, int *irq)
{
if (data_port || ctrl_port)
printk("ide_init_hwif_ports: must not be called\n");
@@ -80,72 +82,64 @@ static __inline__ void ide_init_default_hwifs(void)
{
}
-#undef SUPPORT_SLOW_DATA_PORTS
-#define SUPPORT_SLOW_DATA_PORTS 0
-
-/* this definition is used only on startup .. */
-#undef HD_DATA
-#define HD_DATA NULL
-
-
-/* get rid of defs from io.h - ide has its private and conflicting versions */
+/*
+ * Get rid of defs from io.h - ide has its private and conflicting versions
+ * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
+ * always use the `raw' MMIO versions
+ */
#undef inb
#undef inw
+#undef insw
+#undef inl
+#undef insl
#undef outb
#undef outw
-#undef inb_p
-#undef outb_p
-#undef insw
#undef outsw
-#undef insw_swapw
-#undef outsw_swapw
-
-/*
- * define IO method and translation,
- * so far only Q40 has ide-if on ISA
-*/
-#ifndef CONFIG_Q40
-
-#define ADDR_TRANS_B(_addr_) (_addr_)
-#define ADDR_TRANS_W(_addr_) (_addr_)
-
-#else
-
-#define ADDR_TRANS_B(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_B(_addr_)) : (_addr_))
-#define ADDR_TRANS_W(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
-#endif
-
-#define inb(p) in_8(ADDR_TRANS_B(p))
-#define inb_p(p) in_8(ADDR_TRANS_B(p))
-#define inw(p) in_be16(ADDR_TRANS_W(p))
-#define inw_p(p) in_be16(ADDR_TRANS_W(p))
-#define outb(v,p) out_8(ADDR_TRANS_B(p),v)
-#define outb_p(v,p) out_8(ADDR_TRANS_B(p),v)
-#define outw(v,p) out_be16(ADDR_TRANS_W(p),v)
-
-#define insw(port, buf, nr) raw_insw(ADDR_TRANS_W(port), buf, nr)
-#define outsw(port, buf, nr) raw_outsw(ADDR_TRANS_W(port), buf, nr)
-
-#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
-#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
-
-
+#undef outl
+#undef outsl
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+
+#define inb in_8
+#define inw in_be16
+#define insw(port, addr, n) raw_insw((u16 *)port, addr, n)
+#define inl in_be32
+#define insl(port, addr, n) raw_insl((u32 *)port, addr, n)
+#define outb(val, port) out_8(port, val)
+#define outw(val, port) out_be16(port, val)
+#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
+#define outl(val, port) out_be32(port, val)
+#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
+#define readb in_8
+#define readw in_be16
+#define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n)
+#define readl in_be32
+#define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n)
+#define writeb(val, port) out_8(port, val)
+#define writew(val, port) out_be16(port, val)
+#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
+#define writel(val, port) out_be32(port, val)
+#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
+#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n)
+#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n)
+#endif
-#define insl_swapw(data_reg, buffer, wcount) \
- insw_swapw(data_reg, buffer, (wcount)<<1)
-#define outsl_swapw(data_reg, buffer, wcount) \
- outsw_swapw(data_reg, buffer, (wcount)<<1)
-
-#define insw_swapw(port, buf, nr) raw_insw_swapw(ADDR_TRANS_W(port), buf, nr)
-#define outsw_swapw(port, buf, nr) raw_outsw_swapw(ADDR_TRANS_W(port),buf,nr)
-
-#endif /* CONFIG_ATARI || CONFIG_Q40 */
-#define ATA_ARCH_ACK_INTR
+/* Q40 and Atari have byteswapped IDE busses and since many interesting
+ * values in the identification string are text, chars and words they
+ * happened to be almost correct without swapping.. However *_capacity
+ * is needed for drives over 8 GB. RZ */
+#if defined(CONFIG_Q40) || defined(CONFIG_ATARI)
+#define M68K_IDE_SWAPW (MACH_IS_Q40 || MACH_IS_ATARI)
+#endif
#ifdef CONFIG_BLK_DEV_FALCON_IDE
-#define ATA_ARCH_LOCK
+#define IDE_ARCH_LOCK
extern int falconide_intr_lock;
@@ -161,7 +155,8 @@ static __inline__ void ide_release_lock (void)
}
}
-static __inline__ void ide_get_lock(void (*handler)(int, void *, struct pt_regs *), void *data)
+static __inline__ void
+ide_get_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), void *data)
{
if (MACH_IS_ATARI) {
if (falconide_intr_lock == 0) {
@@ -173,5 +168,9 @@ static __inline__ void ide_get_lock(void (*handler)(int, void *, struct pt_regs
}
}
#endif /* CONFIG_BLK_DEV_FALCON_IDE */
+
+#define IDE_ARCH_ACK_INTR
+#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+
#endif /* __KERNEL__ */
#endif /* _M68K_IDE_H */
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index 406a93da3f6b..371ad13151e3 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -120,66 +120,66 @@ extern int isa_sex;
* be compiled in so the case statement will be optimised away
*/
-static inline unsigned long isa_itb(long addr)
+static inline unsigned char *isa_itb(long addr)
{
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case Q40_ISA: return Q40_ISA_IO_B(addr);
+ case Q40_ISA: return (unsigned char *)Q40_ISA_IO_B(addr);
#endif
#ifdef CONFIG_GG2
- case GG2_ISA: return GG2_ISA_IO_B(addr);
+ case GG2_ISA: return (unsigned char *)GG2_ISA_IO_B(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case AG_ISA: return AG_ISA_IO_B(addr);
+ case AG_ISA: return (unsigned char *)AG_ISA_IO_B(addr);
#endif
default: return 0; /* avoid warnings, just in case */
}
}
-static inline unsigned long isa_itw(long addr)
+static inline unsigned short *isa_itw(long addr)
{
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case Q40_ISA: return Q40_ISA_IO_W(addr);
+ case Q40_ISA: return (unsigned short *)Q40_ISA_IO_W(addr);
#endif
#ifdef CONFIG_GG2
- case GG2_ISA: return GG2_ISA_IO_W(addr);
+ case GG2_ISA: return (unsigned short *)GG2_ISA_IO_W(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case AG_ISA: return AG_ISA_IO_W(addr);
+ case AG_ISA: return (unsigned short *)AG_ISA_IO_W(addr);
#endif
default: return 0; /* avoid warnings, just in case */
}
}
-static inline unsigned long isa_mtb(long addr)
+static inline unsigned char *isa_mtb(long addr)
{
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case Q40_ISA: return Q40_ISA_MEM_B(addr);
+ case Q40_ISA: return (unsigned char *)Q40_ISA_MEM_B(addr);
#endif
#ifdef CONFIG_GG2
- case GG2_ISA: return GG2_ISA_MEM_B(addr);
+ case GG2_ISA: return (unsigned char *)GG2_ISA_MEM_B(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case AG_ISA: return addr;
+ case AG_ISA: return (unsigned char *)addr;
#endif
default: return 0; /* avoid warnings, just in case */
}
}
-static inline unsigned long isa_mtw(long addr)
+static inline unsigned short *isa_mtw(long addr)
{
switch(ISA_TYPE)
{
#ifdef CONFIG_Q40
- case Q40_ISA: return Q40_ISA_MEM_W(addr);
+ case Q40_ISA: return (unsigned short *)Q40_ISA_MEM_W(addr);
#endif
#ifdef CONFIG_GG2
- case GG2_ISA: return GG2_ISA_MEM_W(addr);
+ case GG2_ISA: return (unsigned short *)GG2_ISA_MEM_W(addr);
#endif
#ifdef CONFIG_AMIGA_PCMCIA
- case AG_ISA: return addr;
+ case AG_ISA: return (unsigned short *)addr;
#endif
default: return 0; /* avoid warnings, just in case */
}
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h
index f8b2ed3255c7..1c7ec850126e 100644
--- a/include/asm-m68k/irq.h
+++ b/include/asm-m68k/irq.h
@@ -2,6 +2,7 @@
#define _M68K_IRQ_H_
#include <linux/config.h>
+#include <linux/interrupt.h>
/*
* # of m68k interrupts
@@ -76,7 +77,7 @@ extern void (*disable_irq)(unsigned int);
struct pt_regs;
extern int sys_request_irq(unsigned int,
- void (*)(int, void *, struct pt_regs *),
+ irqreturn_t (*)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
extern void sys_free_irq(unsigned int, void *);
@@ -98,7 +99,7 @@ extern void sys_free_irq(unsigned int, void *);
* interrupt source (if it supports chaining).
*/
typedef struct irq_node {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
@@ -109,7 +110,7 @@ typedef struct irq_node {
* This structure has only 4 elements for speed reasons
*/
typedef struct irq_handler {
- void (*handler)(int, void *, struct pt_regs *);
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
void *dev_id;
const char *devname;
diff --git a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h
index 62ad61c76fa0..a0dd5c47002c 100644
--- a/include/asm-m68k/machdep.h
+++ b/include/asm-m68k/machdep.h
@@ -2,6 +2,7 @@
#define _M68K_MACHDEP_H
#include <linux/seq_file.h>
+#include <linux/interrupt.h>
struct pt_regs;
struct mktime;
@@ -9,17 +10,17 @@ struct rtc_time;
struct rtc_pll_info;
struct buffer_head;
-extern void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
+extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *));
/* machine dependent irq functions */
extern void (*mach_init_IRQ) (void);
-extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
-extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
+extern int (*mach_request_irq) (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
extern void (*mach_get_model) (char *model);
extern int (*mach_get_hardware_list) (char *buffer);
extern int (*mach_get_irq_list) (struct seq_file *p, void *v);
-extern void (*mach_process_int) (int irq, struct pt_regs *fp);
+extern irqreturn_t (*mach_process_int) (int irq, struct pt_regs *fp);
/* machine dependent timer functions */
extern unsigned long (*mach_gettimeoffset)(void);
extern int (*mach_hwclk)(int, struct rtc_time*);
diff --git a/include/asm-m68k/macintosh.h b/include/asm-m68k/macintosh.h
index cbb1cb10cf73..ab762b103e21 100644
--- a/include/asm-m68k/macintosh.h
+++ b/include/asm-m68k/macintosh.h
@@ -2,6 +2,7 @@
#define __ASM_MACINTOSH_H
#include <linux/seq_file.h>
+#include <linux/interrupt.h>
/*
* Apple Macintoshisms
@@ -10,7 +11,7 @@
extern void mac_reset(void);
extern void mac_poweroff(void);
extern void mac_init_IRQ(void);
-extern int mac_request_irq (unsigned int, void (*)(int, void *,
+extern int mac_request_irq (unsigned int, irqreturn_t (*)(int, void *,
struct pt_regs *),
unsigned long, const char *, void *);
extern void mac_free_irq(unsigned int, void *);
diff --git a/include/asm-m68k/motorola_pgtable.h b/include/asm-m68k/motorola_pgtable.h
index 57991e6da957..73ddf2fcbb81 100644
--- a/include/asm-m68k/motorola_pgtable.h
+++ b/include/asm-m68k/motorola_pgtable.h
@@ -14,7 +14,7 @@
#define _PAGE_SUPER 0x080 /* 68040 supervisor only */
#define _PAGE_FAKE_SUPER 0x200 /* fake supervisor only on 680[23]0 */
#define _PAGE_GLOBAL040 0x400 /* 68040 global bit, used for kva descs */
-#define _PAGE_COW 0x800 /* implemented in software */
+#define _PAGE_FILE 0x800 /* pagecache or swap? */
#define _PAGE_NOCACHE030 0x040 /* 68030 no-cache mode */
#define _PAGE_NOCACHE 0x060 /* 68040 cache mode, non-serialized */
#define _PAGE_NOCACHE_S 0x040 /* 68040 no-cache mode, serialized */
@@ -159,6 +159,7 @@ extern inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RONLY);
extern inline int pte_exec(pte_t pte) { return 1; }
extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
extern 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; }
extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) |= _PAGE_RONLY; return pte; }
extern inline pte_t pte_rdprotect(pte_t pte) { return pte; }
@@ -255,6 +256,25 @@ static inline void cache_page(void *vaddr)
}
}
+#define PTE_FILE_MAX_BITS 29
+
+static inline unsigned long pte_to_pgoff(pte_t pte)
+{
+ return ((pte.pte >> 12) << 7) + ((pte.pte >> 2) & 0x1ff);
+}
+
+static inline pte_t pgoff_to_pte(inline unsigned off)
+{
+ pte_t pte = { ((off >> 7) << 12) + ((off & 0x1ff) << 2) + _PAGE_FILE };
+ return pte;
+}
+
+/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
+#define __swp_type(x) (((x).val >> 2) & 0x1ff)
+#define __swp_offset(x) ((x).val >> 12)
+#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 12) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
#endif /* !__ASSEMBLY__ */
#endif /* _MOTOROLA_PGTABLE_H */
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index 22632064a4ed..4fcccc01f1ca 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -136,25 +136,6 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma,
{
}
-#ifdef CONFIG_SUN3
-/* Macros to (de)construct the fake PTEs representing swap pages. */
-#define __swp_type(x) ((x).val & 0x7F)
-#define __swp_offset(x) (((x).val) >> 7)
-#define __swp_entry(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
-
-#else
-
-/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
-#define __swp_type(x) (((x).val >> 1) & 0xff)
-#define __swp_offset(x) ((x).val >> 10)
-#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
-#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
-
-#endif /* CONFIG_SUN3 */
-
#endif /* !__ASSEMBLY__ */
#define kern_addr_valid(addr) (1)
diff --git a/include/asm-m68k/raw_io.h b/include/asm-m68k/raw_io.h
index ca4868f1d42c..d0554c1e38d6 100644
--- a/include/asm-m68k/raw_io.h
+++ b/include/asm-m68k/raw_io.h
@@ -52,208 +52,290 @@ extern void __iounmap(void *addr, unsigned long size);
#define raw_outw(val,port) out_be16((port),(val))
#define raw_outl(val,port) out_be32((port),(val))
-#define raw_insb(port, buf, len) ({ \
- volatile unsigned char *_port = (volatile unsigned char *) (port); \
- unsigned char *_buf =(unsigned char *)(buf); \
- unsigned int _i,_len=(unsigned int)(len); \
- for(_i=0; _i< _len; _i++) \
- *_buf++=in_8(_port); \
- })
+static inline void raw_insb(volatile unsigned char *port, unsigned char *buf,
+ unsigned int len)
+{
+ unsigned int i;
-#define raw_outsb(port, buf, len) ({ \
- volatile unsigned char *_port = (volatile unsigned char *) (port); \
- unsigned char *_buf =(unsigned char *)(buf); \
- unsigned int _i,_len=(unsigned int)(len); \
- for( _i=0; _i< _len; _i++) \
- out_8(_port,*_buf++); \
- })
-
+ for (i = 0; i < len; i++)
+ *buf++ = in_8(port);
+}
-#define raw_insw(port, buf, nr) ({ \
- volatile unsigned char *_port = (volatile unsigned char *) (port); \
- unsigned char *_buf = (unsigned char *)(buf); \
- unsigned int _nr = (unsigned int)(nr); \
- unsigned long _tmp; \
- \
- if (_nr & 15) { \
- _tmp = (_nr & 15) - 1; \
- asm volatile ( \
- "1: movew %2@,%0@+; dbra %1,1b" \
- : "=a" (_buf), "=d" (_tmp) \
- : "a" (_port), "0" (_buf), \
- "1" (_tmp)); \
- } \
- if (_nr >> 4) { \
- _tmp = (_nr >> 4) - 1; \
- asm volatile ( \
- "1: " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "movew %2@,%0@+; " \
- "dbra %1,1b" \
- : "=a" (_buf), "=d" (_tmp) \
- : "a" (_port), "0" (_buf), \
- "1" (_tmp)); \
- } \
-})
+static inline void raw_outsb(volatile unsigned char *port,
+ const unsigned char *buf, unsigned int len)
+{
+ unsigned int i;
-#define raw_outsw(port, buf, nr) ({ \
- volatile unsigned char *_port = (volatile unsigned char *) (port); \
- unsigned char *_buf = (unsigned char *)(buf); \
- unsigned int _nr = (unsigned int)(nr); \
- unsigned long _tmp; \
- \
- if (_nr & 15) { \
- _tmp = (_nr & 15) - 1; \
- asm volatile ( \
- "1: movew %0@+,%2@; dbra %1,1b" \
- : "=a" (_buf), "=d" (_tmp) \
- : "a" (_port), "0" (_buf), \
- "1" (_tmp)); \
- } \
- if (_nr >> 4) { \
- _tmp = (_nr >> 4) - 1; \
- asm volatile ( \
- "1: " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "movew %0@+,%2@; " \
- "dbra %1,1b" \
- : "=a" (_buf), "=d" (_tmp) \
- : "a" (_port), "0" (_buf), \
- "1" (_tmp)); \
- } \
-})
+ for (i = 0; i < len; i++)
+ out_8(port, *buf++);
+}
+static inline void raw_insw(volatile unsigned short *port, unsigned short *buf,
+ unsigned int nr)
+{
+ unsigned int tmp;
-#define raw_insw_swapw(port, buf, nr) \
-({ if ((nr) % 8) \
- __asm__ __volatile__ \
- ("movel %0,%/a0; \
- movel %1,%/a1; \
- movel %2,%/d6; \
- subql #1,%/d6; \
- 1:movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- dbra %/d6,1b" \
- : \
- : "g" (port), "g" (buf), "g" (nr) \
- : "d0", "a0", "a1", "d6"); \
- else \
- __asm__ __volatile__ \
- ("movel %0,%/a0; \
- movel %1,%/a1; \
- movel %2,%/d6; \
- lsrl #3,%/d6; \
- subql #1,%/d6; \
- 1:movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- movew %/a0@,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a1@+; \
- dbra %/d6,1b" \
- : \
- : "g" (port), "g" (buf), "g" (nr) \
- : "d0", "a0", "a1", "d6"); \
-})
+ if (nr & 15) {
+ tmp = (nr & 15) - 1;
+ asm volatile (
+ "1: movew %2@,%0@+; dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+ if (nr >> 4) {
+ tmp = (nr >> 4) - 1;
+ asm volatile (
+ "1: "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "movew %2@,%0@+; "
+ "dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+}
+static inline void raw_outsw(volatile unsigned short *port,
+ const unsigned short *buf, unsigned int nr)
+{
+ unsigned int tmp;
-#define raw_outsw_swapw(port, buf, nr) \
-({ if ((nr) % 8) \
- __asm__ __volatile__ \
- ("movel %0,%/a0; \
- movel %1,%/a1; \
- movel %2,%/d6; \
- subql #1,%/d6; \
- 1:movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- dbra %/d6,1b" \
- : \
- : "g" (port), "g" (buf), "g" (nr) \
- : "d0", "a0", "a1", "d6"); \
- else \
- __asm__ __volatile__ \
- ("movel %0,%/a0; \
- movel %1,%/a1; \
- movel %2,%/d6; \
- lsrl #3,%/d6; \
- subql #1,%/d6; \
- 1:movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- movew %/a1@+,%/d0; \
- rolw #8,%/d0; \
- movew %/d0,%/a0@; \
- dbra %/d6,1b" \
- : \
- : "g" (port), "g" (buf), "g" (nr) \
- : "d0", "a0", "a1", "d6"); \
-})
+ if (nr & 15) {
+ tmp = (nr & 15) - 1;
+ asm volatile (
+ "1: movew %0@+,%2@; dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+ if (nr >> 4) {
+ tmp = (nr >> 4) - 1;
+ asm volatile (
+ "1: "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "movew %0@+,%2@; "
+ "dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+}
+
+static inline void raw_insl(volatile unsigned int *port, unsigned int *buf,
+ unsigned int nr)
+{
+ unsigned int tmp;
+
+ if (nr & 15) {
+ tmp = (nr & 15) - 1;
+ asm volatile (
+ "1: movel %2@,%0@+; dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+ if (nr >> 4) {
+ tmp = (nr >> 4) - 1;
+ asm volatile (
+ "1: "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "movel %2@,%0@+; "
+ "dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+}
+
+static inline void raw_outsl(volatile unsigned int *port,
+ const unsigned int *buf, unsigned int nr)
+{
+ unsigned int tmp;
+
+ if (nr & 15) {
+ tmp = (nr & 15) - 1;
+ asm volatile (
+ "1: movel %0@+,%2@; dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+ if (nr >> 4) {
+ tmp = (nr >> 4) - 1;
+ asm volatile (
+ "1: "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "movel %0@+,%2@; "
+ "dbra %1,1b"
+ : "=a" (buf), "=d" (tmp)
+ : "a" (port), "0" (buf),
+ "1" (tmp));
+ }
+}
+
+
+static inline void raw_insw_swapw(volatile unsigned short *port,
+ unsigned short *buf, unsigned int nr)
+{
+ if ((nr) % 8)
+ __asm__ __volatile__
+ ("\tmovel %0,%/a0\n\t"
+ "movel %1,%/a1\n\t"
+ "movel %2,%/d6\n\t"
+ "subql #1,%/d6\n"
+ "1:\tmovew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "dbra %/d6,1b"
+ :
+ : "g" (port), "g" (buf), "g" (nr)
+ : "d0", "a0", "a1", "d6");
+ else
+ __asm__ __volatile__
+ ("movel %0,%/a0\n\t"
+ "movel %1,%/a1\n\t"
+ "movel %2,%/d6\n\t"
+ "lsrl #3,%/d6\n\t"
+ "subql #1,%/d6\n"
+ "1:\tmovew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "movew %/a0@,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a1@+\n\t"
+ "dbra %/d6,1b"
+ :
+ : "g" (port), "g" (buf), "g" (nr)
+ : "d0", "a0", "a1", "d6");
+}
+
+static inline void raw_outsw_swapw(volatile unsigned short *port,
+ const unsigned short *buf, unsigned int nr)
+{
+ if ((nr) % 8)
+ __asm__ __volatile__
+ ("movel %0,%/a0\n\t"
+ "movel %1,%/a1\n\t"
+ "movel %2,%/d6\n\t"
+ "subql #1,%/d6\n"
+ "1:\tmovew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "dbra %/d6,1b"
+ :
+ : "g" (port), "g" (buf), "g" (nr)
+ : "d0", "a0", "a1", "d6");
+ else
+ __asm__ __volatile__
+ ("movel %0,%/a0\n\t"
+ "movel %1,%/a1\n\t"
+ "movel %2,%/d6\n\t"
+ "lsrl #3,%/d6\n\t"
+ "subql #1,%/d6\n"
+ "1:\tmovew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "movew %/a1@+,%/d0\n\t"
+ "rolw #8,%/d0\n\t"
+ "movew %/d0,%/a0@\n\t"
+ "dbra %/d6,1b"
+ :
+ : "g" (port), "g" (buf), "g" (nr)
+ : "d0", "a0", "a1", "d6");
+}
#endif /* __KERNEL__ */
diff --git a/include/asm-m68k/sun3_pgtable.h b/include/asm-m68k/sun3_pgtable.h
index 9667aa24fc2c..b4f70615613e 100644
--- a/include/asm-m68k/sun3_pgtable.h
+++ b/include/asm-m68k/sun3_pgtable.h
@@ -204,6 +204,12 @@ extern inline pmd_t *pmd_offset (pgd_t *pgd, unsigned long address)
#define pte_unmap(pte) kunmap(pte)
#define pte_unmap_nested(pte) kunmap(pte)
+/* Macros to (de)construct the fake PTEs representing swap pages. */
+#define __swp_type(x) ((x).val & 0x7F)
+#define __swp_offset(x) (((x).val) >> 7)
+#define __swp_entry(type,offset) ((swp_entry_t) { ((type) | ((offset) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
#endif /* !__ASSEMBLY__ */
#endif /* !_SUN3_PGTABLE_H */
diff --git a/include/asm-m68k/sun3ints.h b/include/asm-m68k/sun3ints.h
index 5ce63422c57a..fd838eb14213 100644
--- a/include/asm-m68k/sun3ints.h
+++ b/include/asm-m68k/sun3ints.h
@@ -26,17 +26,17 @@
void sun3_enable_irq(unsigned int irq);
void sun3_disable_irq(unsigned int irq);
int sun3_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id
);
extern void sun3_init_IRQ (void);
-extern void (*sun3_default_handler[]) (int, void *, struct pt_regs *);
-extern void (*sun3_inthandler[]) (int, void *, struct pt_regs *);
+extern irqreturn_t (*sun3_default_handler[]) (int, void *, struct pt_regs *);
+extern irqreturn_t (*sun3_inthandler[]) (int, void *, struct pt_regs *);
extern void sun3_free_irq (unsigned int irq, void *dev_id);
extern void sun3_enable_interrupts (void);
extern void sun3_disable_interrupts (void);
extern int show_sun3_interrupts(struct seq_file *, void *);
-extern void sun3_process_int(int, struct pt_regs *);
+extern irqreturn_t sun3_process_int(int, struct pt_regs *);
extern volatile unsigned char* sun3_intreg;
/* master list of VME vectors -- don't fuck with this */
diff --git a/include/asm-ppc/linux_logo.h b/include/asm-ppc/linux_logo.h
deleted file mode 100644
index e6dad37b9622..000000000000
--- a/include/asm-ppc/linux_logo.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * include/asm-ppc/linux_logo.h: A linux logo to be displayed on boot
- * (pinched from the sparc port).
- *
- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
- * values have to start from 0x20
- * (i.e. linux_logo_{red,green,blue}[0] is color 0x20)
- */
-#ifdef __KERNEL__
-
-#include <linux/init.h>
-
-#define linux_logo_banner "Linux/PPC version " UTS_RELEASE
-
-#define LINUX_LOGO_HEIGHT 80
-#define LINUX_LOGO_WIDTH 80
-
-#include <linux/linux_logo.h>
-
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
index cc54b6d83f4b..31e9ce210904 100644
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-ppc64/compat.h
@@ -4,6 +4,7 @@
* Architecture specific compatibility types
*/
#include <linux/types.h>
+#include <linux/sched.h>
#define COMPAT_USER_HZ 100
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
index 5f47f45bf03f..6f6a89e3cca4 100644
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -377,5 +377,14 @@ extern void hpte_init_iSeries(void);
typedef pte_t *pte_addr_t;
+long pSeries_lpar_hpte_insert(unsigned long hpte_group,
+ unsigned long va, unsigned long prpn,
+ int secondary, unsigned long hpteflags,
+ int bolted, int large);
+
+long pSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
+ unsigned long prpn, int secondary,
+ unsigned long hpteflags, int bolted, int large);
+
#endif /* __ASSEMBLY__ */
#endif /* _PPC64_PGTABLE_H */
diff --git a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
index 707e5d2ba609..9e66c0bc10aa 100644
--- a/include/asm-ppc64/signal.h
+++ b/include/asm-ppc64/signal.h
@@ -145,4 +145,7 @@ typedef struct sigaltstack {
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+struct pt_regs;
+int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+
#endif /* _ASMPPC64_SIGNAL_H */
diff --git a/include/linux/aio.h b/include/linux/aio.h
index a00ad7b7bf92..adbf5ea8bbe9 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -147,6 +147,9 @@ extern int FASTCALL(aio_complete(struct kiocb *iocb, long res, long res2));
extern void FASTCALL(__put_ioctx(struct kioctx *ctx));
struct mm_struct;
extern void FASTCALL(exit_aio(struct mm_struct *mm));
+extern struct kioctx *lookup_ioctx(unsigned long ctx_id);
+extern int FASTCALL(io_submit_one(struct kioctx *ctx,
+ struct iocb *user_iocb, struct iocb *iocb));
/* semi private, but used by the 32bit emulations: */
struct kioctx *lookup_ioctx(unsigned long ctx_id);
diff --git a/include/linux/cdev.h b/include/linux/cdev.h
new file mode 100644
index 000000000000..191c800fa127
--- /dev/null
+++ b/include/linux/cdev.h
@@ -0,0 +1,29 @@
+#ifndef _LINUX_CDEV_H
+#define _LINUX_CDEV_H
+#ifdef __KERNEL__
+
+struct cdev {
+ struct kobject kobj;
+ struct module *owner;
+ struct file_operations *ops;
+ struct list_head list;
+};
+
+void cdev_init(struct cdev *, struct file_operations *);
+
+struct cdev *cdev_alloc(void);
+
+void cdev_put(struct cdev *p);
+
+struct kobject *cdev_get(struct cdev *);
+
+int cdev_add(struct cdev *, dev_t, unsigned);
+
+void cdev_del(struct cdev *);
+
+void cdev_unmap(dev_t, unsigned);
+
+void cd_forget(struct inode *);
+
+#endif
+#endif
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index 632c5d6efe6f..8288857d2ade 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -40,12 +40,21 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
int timeout);
+#ifdef CONFIG_EPOLL
+
/* Used to initialize the epoll bits inside the "struct file" */
void eventpoll_init_file(struct file *file);
/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */
void eventpoll_release(struct file *file);
+#else
+
+static inline void eventpoll_init_file(struct file *file) {}
+static inline void eventpoll_release(struct file *file) {}
+
+#endif
+
#endif /* #ifdef __KERNEL__ */
#endif /* #ifndef _LINUX_EVENTPOLL_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7365aef817b5..de57729940ef 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -382,6 +382,8 @@ struct inode {
struct list_head i_devices;
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
+ struct cdev *i_cdev;
+ int i_cindex;
unsigned long i_dnotify_mask; /* Directory notify events */
struct dnotify_struct *i_dnotify; /* for directory notifications */
@@ -1056,13 +1058,12 @@ extern void bd_release(struct block_device *);
extern void blk_run_queues(void);
/* fs/char_dev.c */
-extern int register_chrdev_region(unsigned int, unsigned int, int,
- const char *, struct file_operations *);
+extern int alloc_chrdev_region(dev_t *, unsigned, char *);
+extern int register_chrdev_region(dev_t, unsigned, char *);
extern int register_chrdev(unsigned int, const char *,
struct file_operations *);
extern int unregister_chrdev(unsigned int, const char *);
-extern int unregister_chrdev_region(unsigned int, unsigned int, int,
- const char *);
+extern void unregister_chrdev_region(dev_t, unsigned);
extern int chrdev_open(struct inode *, struct file *);
/* fs/block_dev.c */
diff --git a/include/linux/futex.h b/include/linux/futex.h
index b91878c07352..ef87c1b0d637 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -2,10 +2,19 @@
#define _LINUX_FUTEX_H
/* Second argument to futex syscall */
+
+
#define FUTEX_WAIT (0)
#define FUTEX_WAKE (1)
#define FUTEX_FD (2)
+#define FUTEX_REQUEUE (3)
+
+
+asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
+ struct timespec __user *utime, u32 __user *uaddr2);
+
-extern asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, struct timespec __user *utime);
+long do_futex(unsigned long uaddr, int op, int val,
+ unsigned long timeout, unsigned long uaddr2, int val2);
#endif
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 7103121f4c9a..8020d5dfa91b 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -365,12 +365,12 @@ extern void add_partition(struct gendisk *, int, sector_t, sector_t);
extern void delete_partition(struct gendisk *, int);
extern struct gendisk *alloc_disk(int minors);
-extern struct gendisk *get_disk(struct gendisk *disk);
+extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
extern void blk_register_region(dev_t dev, unsigned long range,
struct module *module,
- struct gendisk *(*probe)(dev_t, int *, void *),
+ struct kobject *(*probe)(dev_t, int *, void *),
int (*lock)(dev_t, void *),
void *data);
extern void blk_unregister_region(dev_t dev, unsigned long range);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index ce564083904d..a252f5ab3198 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -37,8 +37,8 @@ mark_mm_hugetlb(struct mm_struct *mm, struct vm_area_struct *vma)
mm->used_hugetlb = 1;
}
-#ifndef ARCH_HAS_VALID_HUGEPAGE_RANGE
-#define check_valid_hugepage_range(addr, len) 0
+#ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE
+#define is_hugepage_only_range(addr, len) 0
#endif
#else /* !CONFIG_HUGETLB_PAGE */
@@ -62,7 +62,7 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
#define follow_huge_pmd(mm, addr, pmd, write) 0
#define is_aligned_hugepage_range(addr, len) 0
#define pmd_huge(x) 0
-#define check_valid_hugepage_range(addr, len) 0
+#define is_hugepage_only_range(addr, len) 0
#ifndef HPAGE_MASK
#define HPAGE_MASK 0 /* Keep the compiler happy */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 96a5f926300e..6372a411be8f 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -101,6 +101,7 @@
.blocked = {{0}}, \
.posix_timers = LIST_HEAD_INIT(tsk.posix_timers), \
.alloc_lock = SPIN_LOCK_UNLOCKED, \
+ .proc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
}
diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
new file mode 100644
index 000000000000..404a945c1533
--- /dev/null
+++ b/include/linux/kobj_map.h
@@ -0,0 +1,12 @@
+#ifdef __KERNEL__
+
+typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
+struct kobj_map;
+
+int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
+ kobj_probe_t *, int (*)(dev_t, void *), void *);
+void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
+struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
+struct kobj_map *kobj_map_init(kobj_probe_t *, struct subsystem *);
+
+#endif
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 0dd15d1cb2e2..4607df82fd93 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -87,6 +87,8 @@ extern void proc_root_init(void);
extern void proc_misc_init(void);
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry);
+struct dentry *proc_pid_unhash(struct task_struct *p);
+void proc_pid_flush(struct dentry *proc_dentry);
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index fa5b3bdb0de6..319730b9ff5a 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -872,11 +872,41 @@ struct stat_data_v1
#define set_sd_v1_first_direct_byte(sdp,v) \
((sdp)->sd_first_direct_byte = cpu_to_le32(v))
+#include <linux/ext2_fs.h>
+
+/* inode flags stored in sd_attrs (nee sd_reserved) */
+
+/* we want common flags to have the same values as in ext2,
+ so chattr(1) will work without problems */
+#define REISERFS_IMMUTABLE_FL EXT2_IMMUTABLE_FL
+#define REISERFS_SYNC_FL EXT2_SYNC_FL
+#define REISERFS_NOATIME_FL EXT2_NOATIME_FL
+#define REISERFS_NODUMP_FL EXT2_NODUMP_FL
+#define REISERFS_SECRM_FL EXT2_SECRM_FL
+#define REISERFS_UNRM_FL EXT2_UNRM_FL
+#define REISERFS_COMPR_FL EXT2_COMPR_FL
+/* persistent flag to disable tails on per-file basic.
+ Note, that is inheritable: mark directory with this and
+ all new files inside will not have tails.
+
+ Teodore Tso allocated EXT2_NODUMP_FL (0x00008000) for this. Change
+ numeric constant to ext2 macro when available. */
+#define REISERFS_NOTAIL_FL (0x00008000) /* EXT2_NOTAIL_FL */
+
+/* persistent flags that file inherits from the parent directory */
+#define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \
+ REISERFS_SYNC_FL | \
+ REISERFS_NOATIME_FL | \
+ REISERFS_NODUMP_FL | \
+ REISERFS_SECRM_FL | \
+ REISERFS_COMPR_FL | \
+ REISERFS_NOTAIL_FL )
+
/* Stat Data on disk (reiserfs version of UFS disk inode minus the
address blocks) */
struct stat_data {
__u16 sd_mode; /* file type, permissions */
- __u16 sd_reserved;
+ __u16 sd_attrs; /* persistent inode flags */
__u32 sd_nlink; /* number of hard links */
__u64 sd_size; /* file size */
__u32 sd_uid; /* owner */
@@ -929,6 +959,8 @@ struct stat_data {
#define set_sd_v2_rdev(sdp,v) ((sdp)->u.sd_rdev = cpu_to_le32(v))
#define sd_v2_generation(sdp) (le32_to_cpu((sdp)->u.sd_generation))
#define set_sd_v2_generation(sdp,v) ((sdp)->u.sd_generation = cpu_to_le32(v))
+#define sd_v2_attrs(sdp) (le16_to_cpu((sdp)->sd_attrs))
+#define set_sd_v2_attrs(sdp,v) ((sdp)->sd_attrs = cpu_to_le16(v))
/***************************************************************************/
@@ -1871,6 +1903,9 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode);
+void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
+void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
+
/* namei.c */
inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
int search_by_entry_key (struct super_block * sb, const struct cpu_key * key,
@@ -2145,6 +2180,12 @@ int reiserfs_unpack (struct inode * inode, struct file * filp);
/* ioctl's command */
#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long)
+/* define following flags to be the same as in ext2, so that chattr(1),
+ lsattr(1) will work with us. */
+#define REISERFS_IOC_GETFLAGS EXT2_IOC_GETFLAGS
+#define REISERFS_IOC_SETFLAGS EXT2_IOC_SETFLAGS
+#define REISERFS_IOC_GETVERSION EXT2_IOC_GETVERSION
+#define REISERFS_IOC_SETVERSION EXT2_IOC_SETVERSION
/* Locking primitives */
/* Right now we are still falling back to (un)lock_kernel, but eventually that
diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
index 5c6b26b1d9b5..87e1b74e1125 100644
--- a/include/linux/reiserfs_fs_i.h
+++ b/include/linux/reiserfs_fs_i.h
@@ -32,6 +32,9 @@ struct reiserfs_inode_info {
__u32 i_first_direct_byte; // offset of first byte stored in direct item.
+ /* copy of persistent inode flags read from sd_attrs. */
+ __u32 i_attrs;
+
int i_prealloc_block; /* first unused block of a sequence of unused blocks */
int i_prealloc_count; /* length of that sequence */
struct list_head i_prealloc_list; /* per-transaction list of inodes which
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 25eae6a8ece8..69342d6868fc 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -8,6 +8,9 @@
#include <linux/workqueue.h>
#endif
+typedef enum {
+ reiserfs_attrs_cleared = 0x00000001,
+} reiserfs_super_block_flags;
/* struct reiserfs_super_block accessors/mutators
* since this is a disk structure, it will always be in
@@ -436,7 +439,6 @@ struct reiserfs_sb_info
#define REISERFS_NO_BORDER 11
#define REISERFS_NO_UNHASHED_RELOCATION 12
#define REISERFS_HASHED_RELOCATION 13
-#define REISERFS_TEST4 14
#define REISERFS_ATTRS 15
@@ -458,6 +460,7 @@ struct reiserfs_sb_info
#define have_small_tails(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_SMALLTAIL))
#define replay_only(s) (REISERFS_SB(s)->s_mount_opt & (1 << REPLAYONLY))
#define reiserfs_dont_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_NOLOG))
+#define reiserfs_attrs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ATTRS))
#define old_format_only(s) (REISERFS_SB(s)->s_properties & (1 << REISERFS_3_5))
#define convert_reiserfs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_CONVERT))
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 46981bca766f..003195629026 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -245,7 +245,13 @@ struct signal_struct {
/* thread group exit support */
int group_exit;
int group_exit_code;
+ /* overloaded:
+ * - notify group_exit_task when ->count is equal to notify_count
+ * - everyone except group_exit_task is stopped during signal delivery
+ * of fatal signals, group_exit_task processes the signal.
+ */
struct task_struct *group_exit_task;
+ int notify_count;
/* thread group stop support, overloads group_exit_code too */
int group_stop_count;
@@ -429,6 +435,8 @@ struct task_struct {
u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty */
spinlock_t alloc_lock;
+/* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
+ spinlock_t proc_lock;
/* context-switch lock */
spinlock_t switch_lock;
diff --git a/include/linux/security.h b/include/linux/security.h
index 6741cc027ceb..c1d1480d2f49 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -376,6 +376,25 @@ struct swap_info_struct;
* Check permission before removing the extended attribute
* identified by @name for @dentry.
* Return 0 if permission is granted.
+ * @inode_getsecurity:
+ * Copy the extended attribute representation of the security label
+ * associated with @name for @dentry into @buffer. @buffer may be
+ * NULL to request the size of the buffer required. @size indicates
+ * the size of @buffer in bytes. Note that @name is the remainder
+ * of the attribute name after the security. prefix has been removed.
+ * Return number of bytes used/required on success.
+ * @inode_setsecurity:
+ * Set the security label associated with @name for @dentry from the
+ * extended attribute value @value. @size indicates the size of the
+ * @value in bytes. @flags may be XATTR_CREATE, XATTR_REPLACE, or 0.
+ * Note that @name is the remainder of the attribute name after the
+ * security. prefix has been removed.
+ * Return 0 on success.
+ * @inode_listsecurity:
+ * Copy the extended attribute names for the security labels
+ * associated with @dentry into @buffer. @buffer may be NULL to
+ * request the size of the buffer required.
+ * Returns number of bytes used/required on success.
*
* Security hooks for file operations
*
@@ -596,6 +615,11 @@ struct swap_info_struct;
* Set the security attributes in @p->security for a kernel thread that
* is being reparented to the init task.
* @p contains the task_struct for the kernel thread.
+ * @task_to_inode:
+ * Set the security attributes for an inode based on an associated task's
+ * security attributes, e.g. for /proc/pid inodes.
+ * @p contains the task_struct for the task.
+ * @inode contains the inode structure for the inode.
*
* Security hooks for Netlink messaging.
*
@@ -1044,6 +1068,9 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
+ int (*inode_getsecurity)(struct dentry *dentry, const char *name, void *buffer, size_t size);
+ int (*inode_setsecurity)(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
+ int (*inode_listsecurity)(struct dentry *dentry, char *buffer);
int (*file_permission) (struct file * file, int mask);
int (*file_alloc_security) (struct file * file);
@@ -1086,6 +1113,7 @@ struct security_operations {
unsigned long arg5);
void (*task_kmod_set_label) (void);
void (*task_reparent_to_init) (struct task_struct * p);
+ void (*task_to_inode)(struct task_struct *p, struct inode *inode);
int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
@@ -1128,6 +1156,9 @@ struct security_operations {
void (*d_instantiate) (struct dentry *dentry, struct inode *inode);
+ int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size);
+ int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size);
+
#ifdef CONFIG_SECURITY_NETWORK
int (*unix_stream_connect) (struct socket * sock,
struct socket * other, struct sock * newsk);
@@ -1490,6 +1521,21 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return security_ops->inode_removexattr (dentry, name);
}
+static inline int security_inode_getsecurity(struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ return security_ops->inode_getsecurity(dentry, name, buffer, size);
+}
+
+static inline int security_inode_setsecurity(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
+{
+ return security_ops->inode_setsecurity(dentry, name, value, size, flags);
+}
+
+static inline int security_inode_listsecurity(struct dentry *dentry, char *buffer)
+{
+ return security_ops->inode_listsecurity(dentry, buffer);
+}
+
static inline int security_file_permission (struct file *file, int mask)
{
return security_ops->file_permission (file, mask);
@@ -1656,6 +1702,11 @@ static inline void security_task_reparent_to_init (struct task_struct *p)
security_ops->task_reparent_to_init (p);
}
+static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
+{
+ security_ops->task_to_inode(p, inode);
+}
+
static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
short flag)
{
@@ -1766,6 +1817,16 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode *
security_ops->d_instantiate (dentry, inode);
}
+static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return security_ops->getprocattr(p, name, value, size);
+}
+
+static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return security_ops->setprocattr(p, name, value, size);
+}
+
static inline int security_netlink_send(struct sk_buff * skb)
{
return security_ops->netlink_send(skb);
@@ -2093,6 +2154,21 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
+static inline int security_inode_getsecurity(struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int security_inode_setsecurity(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int security_inode_listsecurity(struct dentry *dentry, char *buffer)
+{
+ return 0;
+}
+
static inline int security_file_permission (struct file *file, int mask)
{
return 0;
@@ -2255,6 +2331,9 @@ static inline void security_task_reparent_to_init (struct task_struct *p)
cap_task_reparent_to_init (p);
}
+static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
+{ }
+
static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
short flag)
{
@@ -2355,6 +2434,16 @@ static inline int security_sem_semop (struct sem_array * sma,
static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode)
{ }
+static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return -EINVAL;
+}
+
+static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return -EINVAL;
+}
+
/*
* The netlink capability defaults need to be used inline by default
* (rather than hooking into the capability module) to reduce overhead
diff --git a/include/linux/slab.h b/include/linux/slab.h
index b2b6f0498e2a..3e4e5491102c 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -41,6 +41,8 @@ typedef struct kmem_cache_s kmem_cache_t;
#define SLAB_CACHE_DMA 0x00004000UL /* use GFP_DMA memory */
#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* force alignment */
#define SLAB_STORE_USER 0x00010000UL /* store the last owner for bug hunting */
+#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* track pages allocated to indicate
+ what is reclaimable later*/
/* flags passed to a constructor func */
#define SLAB_CTOR_CONSTRUCTOR 0x001UL /* if not set, then deconstructor */
diff --git a/include/linux/string.h b/include/linux/string.h
index ddf6fea31b47..0f9e63df583d 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -28,6 +28,9 @@ extern char * strcpy(char *,const char *);
#ifndef __HAVE_ARCH_STRNCPY
extern char * strncpy(char *,const char *, __kernel_size_t);
#endif
+#ifndef __HAVE_ARCH_STRLCPY
+size_t strlcpy(char *, const char *, size_t);
+#endif
#ifndef __HAVE_ARCH_STRCAT
extern char * strcat(char *, const char *);
#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index fa5529ad5c6e..47fa75d9ace0 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -345,7 +345,6 @@ struct tty_struct {
extern void tty_write_flush(struct tty_struct *);
extern struct termios tty_std_termios;
-extern struct tty_struct * redirect;
extern struct tty_ldisc ldiscs[];
extern int fg_console, last_console, want_console;
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index d8d9fc435a3f..ef234da28a8c 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -117,9 +117,11 @@
#include <linux/fs.h>
#include <linux/list.h>
+#include <linux/cdev.h>
struct tty_driver {
int magic; /* magic number for this structure */
+ struct cdev cdev;
struct module *owner;
const char *driver_name;
const char *name;
diff --git a/include/net/sock.h b/include/net/sock.h
index 69162b947e44..3d4ba5ff3943 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -944,4 +944,6 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
extern __u32 sysctl_wmem_max;
extern __u32 sysctl_rmem_max;
+int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
#endif /* _SOCK_H */
diff --git a/init/Kconfig b/init/Kconfig
index 6b636f039048..d3a9874335aa 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -108,7 +108,31 @@ config LOG_BUF_SHIFT
13 => 8 KB
12 => 4 KB
-endmenu
+
+menuconfig EMBEDDED
+ bool "Remove kernel features (for embedded systems)"
+ help
+ This option allows certain base kernel features to be removed from
+ the build. This is for specialized environments which can tolerate
+ a "non-standard" kernel. Only use this if you really know what you
+ are doing.
+
+config FUTEX
+ bool "Enable futex support" if EMBEDDED
+ default y
+ help
+ Disabling this option will cause the kernel to be built without
+ support for "fast userspace mutexes". The resulting kernel may not
+ run glibc-based applications correctly.
+
+config EPOLL
+ bool "Enable eventpoll support" if EMBEDDED
+ default y
+ help
+ Disabling this option will cause the kernel to be built without
+ support for epoll family of system calls.
+
+endmenu # General setup
menu "Loadable module support"
@@ -181,4 +205,3 @@ config KMOD
in <file:Documentation/kmod.txt>.
endmenu
-
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index 33dbb38ae80b..9eb8eae5f60a 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -129,7 +129,7 @@ int __init rd_load_image(char *from)
int in_fd, out_fd;
unsigned long rd_blocks, devblocks;
int nblocks, i, disk;
- char *buf;
+ char *buf = NULL;
unsigned short rotate = 0;
#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
char rotator[4] = { '|' , '/' , '-' , '\\' };
@@ -226,7 +226,6 @@ int __init rd_load_image(char *from)
#endif
}
printk("done.\n");
- kfree(buf);
successful_load:
res = 1;
@@ -235,6 +234,7 @@ done:
noclose_input:
close(out_fd);
out:
+ kfree(buf);
sys_unlink("/dev/ram");
return res;
}
diff --git a/kernel/Makefile b/kernel/Makefile
index 2929aae0c2fe..1e652214037c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -5,9 +5,10 @@
obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
exit.o itimer.o time.o softirq.o resource.o \
sysctl.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o workqueue.o futex.o pid.o \
+ signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o intermodule.o extable.o params.o posix-timers.o
+obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
obj-$(CONFIG_SMP) += cpu.o
obj-$(CONFIG_UID16) += uid16.o
diff --git a/kernel/compat.c b/kernel/compat.c
index 0dcab5fc6acd..e0998f98b72b 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -18,6 +18,7 @@
#include <linux/signal.h>
#include <linux/sched.h> /* for MAX_SCHEDULE_TIMEOUT */
#include <linux/futex.h> /* for FUTEX_WAIT */
+#include <linux/unistd.h>
#include <asm/uaccess.h>
@@ -211,21 +212,25 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t *set,
return ret;
}
-extern long do_futex(unsigned long, int, int, unsigned long);
-
+#ifdef CONFIG_FUTEX
asmlinkage long compat_sys_futex(u32 *uaddr, int op, int val,
struct compat_timespec *utime)
{
struct timespec t;
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
+ int val2 = 0;
if ((op == FUTEX_WAIT) && utime) {
if (get_compat_timespec(&t, utime))
return -EFAULT;
timeout = timespec_to_jiffies(&t) + 1;
}
- return do_futex((unsigned long)uaddr, op, val, timeout);
+ if (op == FUTEX_REQUEUE)
+ val2 = (int) utime;
+
+ return do_futex((unsigned long)uaddr, op, val, timeout, uaddr2, val2);
}
+#endif
asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
diff --git a/kernel/exit.c b/kernel/exit.c
index c4130eb03ca1..c5b8ec241a83 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -21,6 +21,7 @@
#include <linux/ptrace.h>
#include <linux/profile.h>
#include <linux/mount.h>
+#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -31,10 +32,8 @@ extern struct task_struct *child_reaper;
int getrusage(struct task_struct *, int, struct rusage *);
-static struct dentry * __unhash_process(struct task_struct *p)
+static void __unhash_process(struct task_struct *p)
{
- struct dentry *proc_dentry;
-
nr_threads--;
detach_pid(p, PIDTYPE_PID);
detach_pid(p, PIDTYPE_TGID);
@@ -46,34 +45,25 @@ static struct dentry * __unhash_process(struct task_struct *p)
}
REMOVE_LINKS(p);
- proc_dentry = p->proc_dentry;
- if (unlikely(proc_dentry != NULL)) {
- spin_lock(&dcache_lock);
- if (!d_unhashed(proc_dentry)) {
- dget_locked(proc_dentry);
- __d_drop(proc_dentry);
- } else
- proc_dentry = NULL;
- spin_unlock(&dcache_lock);
- }
- return proc_dentry;
}
void release_task(struct task_struct * p)
{
- struct dentry *proc_dentry;
task_t *leader;
+ struct dentry *proc_dentry;
BUG_ON(p->state < TASK_ZOMBIE);
atomic_dec(&p->user->processes);
+ spin_lock(&p->proc_lock);
+ proc_dentry = proc_pid_unhash(p);
write_lock_irq(&tasklist_lock);
if (unlikely(p->ptrace))
__ptrace_unlink(p);
BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
__exit_signal(p);
__exit_sighand(p);
- proc_dentry = __unhash_process(p);
+ __unhash_process(p);
/*
* If we are the last non-leader member of the thread
@@ -92,11 +82,8 @@ void release_task(struct task_struct * p)
p->parent->cnswap += p->nswap + p->cnswap;
sched_exit(p);
write_unlock_irq(&tasklist_lock);
-
- if (unlikely(proc_dentry != NULL)) {
- shrink_dcache_parent(proc_dentry);
- dput(proc_dentry);
- }
+ spin_unlock(&p->proc_lock);
+ proc_pid_flush(proc_dentry);
release_thread(p);
put_task_struct(p);
}
@@ -107,14 +94,13 @@ void unhash_process(struct task_struct *p)
{
struct dentry *proc_dentry;
+ spin_lock(&p->proc_lock);
+ proc_dentry = proc_pid_unhash(p);
write_lock_irq(&tasklist_lock);
- proc_dentry = __unhash_process(p);
+ __unhash_process(p);
write_unlock_irq(&tasklist_lock);
-
- if (unlikely(proc_dentry != NULL)) {
- shrink_dcache_parent(proc_dentry);
- dput(proc_dentry);
- }
+ spin_unlock(&p->proc_lock);
+ proc_pid_flush(proc_dentry);
}
/*
diff --git a/kernel/fork.c b/kernel/fork.c
index a509e6da132f..23c6d34f800f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -457,7 +457,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
* not set up a proper pointer then tough luck.
*/
put_user(0, tidptr);
- sys_futex(tidptr, FUTEX_WAKE, 1, NULL);
+ sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL);
}
}
diff --git a/kernel/futex.c b/kernel/futex.c
index ce5c894e459e..df2dcbf557d0 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -2,6 +2,9 @@
* Fast Userspace Mutexes (which I call "Futexes!").
* (C) Rusty Russell, IBM 2002
*
+ * Generalized futexes, futex requeueing, misc fixes by Ingo Molnar
+ * (C) Copyright 2003 Red Hat Inc, All Rights Reserved
+ *
* Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
* enough at me, Linus for the original (flawed) idea, Matthew
* Kirkwood for proof-of-concept implementation.
@@ -9,9 +12,6 @@
* "The futexes are also cursed."
* "But they come in a choice of three flavours!"
*
- * Generalized futexes for every mapping type, Ingo Molnar, 2002
- *
- *
* 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
@@ -93,19 +93,18 @@ static inline struct list_head *hash_futex(struct page *page, int offset)
FUTEX_HASHBITS)];
}
-/* Waiter either waiting in FUTEX_WAIT or poll(), or expecting signal */
-static inline void tell_waiter(struct futex_q *q)
-{
- wake_up_all(&q->waiters);
- if (q->filp)
- send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
-}
-
/*
* Get kernel address of the user page and pin it.
*
* Must be called with (and returns with) all futex-MM locks held.
*/
+static inline struct page *__pin_page_atomic (struct page *page)
+{
+ if (!PageReserved(page))
+ get_page(page);
+ return page;
+}
+
static struct page *__pin_page(unsigned long addr)
{
struct mm_struct *mm = current->mm;
@@ -116,11 +115,8 @@ static struct page *__pin_page(unsigned long addr)
* Do a quick atomic lookup first - this is the fastpath.
*/
page = follow_page(mm, addr, 0);
- if (likely(page != NULL)) {
- if (!PageReserved(page))
- get_page(page);
- return page;
- }
+ if (likely(page != NULL))
+ return __pin_page_atomic(page);
/*
* No luck - need to fault in the page:
@@ -150,16 +146,11 @@ repeat_lookup:
return page;
}
-static inline void unpin_page(struct page *page)
-{
- put_page(page);
-}
-
/*
* Wake up all waiters hashed on the physical page that is mapped
* to this virtual address:
*/
-static int futex_wake(unsigned long uaddr, int offset, int num)
+static inline int futex_wake(unsigned long uaddr, int offset, int num)
{
struct list_head *i, *next, *head;
struct page *page;
@@ -181,7 +172,9 @@ static int futex_wake(unsigned long uaddr, int offset, int num)
if (this->page == page && this->offset == offset) {
list_del_init(i);
__detach_vcache(&this->vcache);
- tell_waiter(this);
+ wake_up_all(&this->waiters);
+ if (this->filp)
+ send_sigio(&this->filp->f_owner, this->fd, POLL_IN);
ret++;
if (ret >= num)
break;
@@ -189,7 +182,7 @@ static int futex_wake(unsigned long uaddr, int offset, int num)
}
unlock_futex_mm();
- unpin_page(page);
+ put_page(page);
return ret;
}
@@ -208,7 +201,9 @@ static void futex_vcache_callback(vcache_t *vcache, struct page *new_page)
spin_lock(&futex_lock);
if (!list_empty(&q->list)) {
+ put_page(q->page);
q->page = new_page;
+ __pin_page_atomic(new_page);
list_del(&q->list);
list_add_tail(&q->list, head);
}
@@ -216,6 +211,65 @@ static void futex_vcache_callback(vcache_t *vcache, struct page *new_page)
spin_unlock(&futex_lock);
}
+/*
+ * Requeue all waiters hashed on one physical page to another
+ * physical page.
+ */
+static inline int futex_requeue(unsigned long uaddr1, int offset1,
+ unsigned long uaddr2, int offset2, int nr_wake, int nr_requeue)
+{
+ struct list_head *i, *next, *head1, *head2;
+ struct page *page1 = NULL, *page2 = NULL;
+ int ret = 0;
+
+ lock_futex_mm();
+
+ page1 = __pin_page(uaddr1 - offset1);
+ if (!page1)
+ goto out;
+ page2 = __pin_page(uaddr2 - offset2);
+ if (!page2)
+ goto out;
+
+ head1 = hash_futex(page1, offset1);
+ head2 = hash_futex(page2, offset2);
+
+ list_for_each_safe(i, next, head1) {
+ struct futex_q *this = list_entry(i, struct futex_q, list);
+
+ if (this->page == page1 && this->offset == offset1) {
+ list_del_init(i);
+ __detach_vcache(&this->vcache);
+ if (++ret <= nr_wake) {
+ wake_up_all(&this->waiters);
+ if (this->filp)
+ send_sigio(&this->filp->f_owner,
+ this->fd, POLL_IN);
+ } else {
+ put_page(this->page);
+ __pin_page_atomic (page2);
+ list_add_tail(i, head2);
+ __attach_vcache(&this->vcache, uaddr2,
+ current->mm, futex_vcache_callback);
+ this->offset = offset2;
+ this->page = page2;
+ if (ret - nr_wake >= nr_requeue)
+ break;
+ }
+ }
+ }
+
+out:
+ unlock_futex_mm();
+
+ if (page1)
+ put_page(page1);
+ if (page2)
+ put_page(page2);
+
+ return ret;
+}
+
static inline void __queue_me(struct futex_q *q, struct page *page,
unsigned long uaddr, int offset,
int fd, struct file *filp)
@@ -252,7 +306,7 @@ static inline int unqueue_me(struct futex_q *q)
return ret;
}
-static int futex_wait(unsigned long uaddr,
+static inline int futex_wait(unsigned long uaddr,
int offset,
int val,
unsigned long time)
@@ -273,14 +327,17 @@ static int futex_wait(unsigned long uaddr,
}
__queue_me(&q, page, uaddr, offset, -1, NULL);
- unlock_futex_mm();
-
- /* Page is pinned, but may no longer be in this address space. */
+ /*
+ * Page is pinned, but may no longer be in this address space.
+ * It cannot schedule, so we access it with the spinlock held.
+ */
if (get_user(curval, (int *)uaddr) != 0) {
+ unlock_futex_mm();
ret = -EFAULT;
goto out;
}
if (curval != val) {
+ unlock_futex_mm();
ret = -EWOULDBLOCK;
goto out;
}
@@ -288,13 +345,15 @@ static int futex_wait(unsigned long uaddr,
* The get_user() above might fault and schedule so we
* cannot just set TASK_INTERRUPTIBLE state when queueing
* ourselves into the futex hash. This code thus has to
- * rely on the FUTEX_WAKE code doing a wakeup after removing
+ * rely on the futex_wake() code doing a wakeup after removing
* the waiter from the list.
*/
add_wait_queue(&q.waiters, &wait);
set_current_state(TASK_INTERRUPTIBLE);
- if (!list_empty(&q.list))
+ if (!list_empty(&q.list)) {
+ unlock_futex_mm();
time = schedule_timeout(time);
+ }
set_current_state(TASK_RUNNING);
/*
* NOTE: we don't remove ourselves from the waitqueue because
@@ -310,7 +369,7 @@ out:
/* Were we woken up anyway? */
if (!unqueue_me(&q))
ret = 0;
- unpin_page(page);
+ put_page(q.page);
return ret;
}
@@ -320,7 +379,7 @@ static int futex_close(struct inode *inode, struct file *filp)
struct futex_q *q = filp->private_data;
unqueue_me(q);
- unpin_page(q->page);
+ put_page(q->page);
kfree(filp->private_data);
return 0;
}
@@ -416,11 +475,12 @@ static int futex_fd(unsigned long uaddr, int offset, int signal)
page = NULL;
out:
if (page)
- unpin_page(page);
+ put_page(page);
return ret;
}
-long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout)
+long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout,
+ unsigned long uaddr2, int val2)
{
unsigned long pos_in_page;
int ret;
@@ -442,23 +502,45 @@ long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout)
/* non-zero val means F_SETOWN(getpid()) & F_SETSIG(val) */
ret = futex_fd(uaddr, pos_in_page, val);
break;
+ case FUTEX_REQUEUE:
+ {
+ unsigned long pos_in_page2 = uaddr2 % PAGE_SIZE;
+
+ /* Must be "naturally" aligned */
+ if (pos_in_page2 % sizeof(u32))
+ return -EINVAL;
+
+ ret = futex_requeue(uaddr, pos_in_page, uaddr2, pos_in_page2,
+ val, val2);
+ break;
+ }
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
}
return ret;
}
-asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, struct timespec __user *utime)
+
+asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
+ struct timespec __user *utime, u32 __user *uaddr2)
{
struct timespec t;
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
+ int val2 = 0;
if ((op == FUTEX_WAIT) && utime) {
if (copy_from_user(&t, utime, sizeof(t)) != 0)
return -EFAULT;
timeout = timespec_to_jiffies(&t) + 1;
}
- return do_futex((unsigned long)uaddr, op, val, timeout);
+ /*
+ * requeue parameter in 'utime' if op == FUTEX_REQUEUE.
+ */
+ if (op == FUTEX_REQUEUE)
+ val2 = (int) utime;
+
+ return do_futex((unsigned long)uaddr, op, val, timeout,
+ (unsigned long)uaddr2, val2);
}
static struct super_block *
diff --git a/kernel/signal.c b/kernel/signal.c
index d15a55ec9e5e..d1f02ea4b7b1 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -336,7 +336,7 @@ void __exit_signal(struct task_struct *tsk)
* If there is any task waiting for the group exit
* then notify it:
*/
- if (sig->group_exit_task && atomic_read(&sig->count) <= 2) {
+ if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) {
wake_up_process(sig->group_exit_task);
sig->group_exit_task = NULL;
}
@@ -1346,6 +1346,9 @@ do_notify_parent_cldstop(struct task_struct *tsk, struct task_struct *parent)
spin_unlock_irqrestore(&sighand->siglock, flags);
}
+
+#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
+
static void
finish_stop(int stop_count)
{
@@ -1460,9 +1463,6 @@ do_signal_stop(int signr)
finish_stop(stop_count);
}
-
-#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
-
/*
* Do appropriate magic when group_stop_count > 0.
* We return nonzero if we stopped, after releasing the siglock.
diff --git a/kernel/sys.c b/kernel/sys.c
index 8e7de84e1df5..5c2c439ae6bc 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -226,6 +226,11 @@ cond_syscall(sys_shutdown)
cond_syscall(sys_sendmsg)
cond_syscall(sys_recvmsg)
cond_syscall(sys_socketcall)
+cond_syscall(sys_futex)
+cond_syscall(compat_sys_futex)
+cond_syscall(sys_epoll_create)
+cond_syscall(sys_epoll_ctl)
+cond_syscall(sys_epoll_wait)
static int set_one_prio(struct task_struct *p, int niceval, int error)
{
diff --git a/lib/string.c b/lib/string.c
index c4b66913d228..b19212bc5d00 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#include <linux/module.h>
#ifndef __HAVE_ARCH_STRNICMP
/**
@@ -94,6 +95,32 @@ char * strncpy(char * dest,const char *src,size_t count)
}
#endif
+#ifndef __HAVE_ARCH_STRLCPY
+/**
+ * strlcpy - Copy a %NUL terminated string into a sized buffer
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @size: size of destination buffer
+ *
+ * Compatible with *BSD: the result is always a valid
+ * NUL-terminated string that fits in the buffer (unless,
+ * of course, the buffer size is zero). It does not pad
+ * out the result like strncpy() does.
+ */
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ size_t ret = strlen(src);
+
+ if (size) {
+ size_t len = (ret >= size) ? size-1 : ret;
+ memcpy(dest, src, len);
+ dest[len] = '\0';
+ }
+ return ret;
+}
+EXPORT_SYMBOL(strlcpy);
+#endif
+
#ifndef __HAVE_ARCH_STRCAT
/**
* strcat - Append one %NUL-terminated string to another
diff --git a/mm/fremap.c b/mm/fremap.c
index 663fa2ce7f20..0f0db6a2cdf8 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -84,7 +84,7 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
pte_unmap(pte);
if (flush)
flush_tlb_page(vma, addr);
-
+ update_mmu_cache(vma, addr, *pte);
spin_unlock(&mm->page_table_lock);
pte_chain_free(pte_chain);
return 0;
diff --git a/mm/mmap.c b/mm/mmap.c
index f773d3d429b1..1112349bf0f6 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -64,6 +64,7 @@ atomic_t vm_committed_space = ATOMIC_INIT(0);
* Strict overcommit modes added 2002 Feb 26 by Alan Cox.
* Additional code 2002 Jul 20 by Robert Love.
*/
+extern atomic_t slab_reclaim_pages;
int vm_enough_memory(long pages)
{
unsigned long free, allowed;
@@ -82,17 +83,19 @@ int vm_enough_memory(long pages)
free += nr_swap_pages;
/*
- * The code below doesn't account for free space in the
- * inode and dentry slab cache, slab cache fragmentation,
- * inodes and dentries which will become freeable under
- * VM load, etc. Lets just hope all these (complex)
- * factors balance out...
+ * Any slabs which are created with the
+ * SLAB_RECLAIM_ACCOUNT flag claim to have contents
+ * which are reclaimable, under pressure. The dentry
+ * cache and most inode caches should fall into this
*/
- free += (dentry_stat.nr_unused * sizeof(struct dentry)) >>
- PAGE_SHIFT;
- free += (inodes_stat.nr_unused * sizeof(struct inode)) >>
- PAGE_SHIFT;
+ free += atomic_read(&slab_reclaim_pages);
+ /*
+ * Leave the last 3% for root
+ */
+ if (!capable(CAP_SYS_ADMIN))
+ free -= free / 32;
+
if (free > pages)
return 1;
vm_unacct_memory(pages);
@@ -831,7 +834,7 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
* reserved hugepage range. For some archs like IA-64,
* there is a separate region for hugepages.
*/
- ret = check_valid_hugepage_range(addr, len);
+ ret = is_hugepage_only_range(addr, len);
}
if (ret)
return ret;
diff --git a/mm/shmem.c b/mm/shmem.c
index 799463b8d7da..6703b33d0458 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1744,7 +1744,7 @@ static int init_inodecache(void)
{
shmem_inode_cachep = kmem_cache_create("shmem_inode_cache",
sizeof(struct shmem_inode_info),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (shmem_inode_cachep == NULL)
return -ENOMEM;
diff --git a/mm/slab.c b/mm/slab.c
index 55ddd968cae2..4361695e9234 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -116,10 +116,12 @@
# define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
SLAB_POISON | SLAB_HWCACHE_ALIGN | \
SLAB_NO_REAP | SLAB_CACHE_DMA | \
- SLAB_MUST_HWCACHE_ALIGN | SLAB_STORE_USER)
+ SLAB_MUST_HWCACHE_ALIGN | SLAB_STORE_USER | \
+ SLAB_RECLAIM_ACCOUNT )
#else
# define CREATE_MASK (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \
- SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN)
+ SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN | \
+ SLAB_RECLAIM_ACCOUNT)
#endif
/*
@@ -420,6 +422,14 @@ static struct semaphore cache_chain_sem;
struct list_head cache_chain;
/*
+ * vm_enough_memory() looks at this to determine how many
+ * slab-allocated pages are possibly freeable under pressure
+ *
+ * SLAB_RECLAIM_ACCOUNT turns this on per-slab
+ */
+atomic_t slab_reclaim_pages;
+
+/*
* chicken and egg problem: delay the per-cpu array allocation
* until the general caches are up.
*/
@@ -720,6 +730,8 @@ static inline void * kmem_getpages (kmem_cache_t *cachep, unsigned long flags)
* would be relatively rare and ignorable.
*/
flags |= cachep->gfpflags;
+ if ( cachep->flags & SLAB_RECLAIM_ACCOUNT)
+ atomic_add(1<<cachep->gfporder, &slab_reclaim_pages);
addr = (void*) __get_free_pages(flags, cachep->gfporder);
/* Assume that now we have the pages no one else can legally
* messes with the 'struct page's.
@@ -750,6 +762,8 @@ static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
if (current->reclaim_state)
current->reclaim_state->reclaimed_slab += nr_freed;
free_pages((unsigned long)addr, cachep->gfporder);
+ if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
+ atomic_sub(1<<cachep->gfporder, &slab_reclaim_pages);
}
#if DEBUG
diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
index dfffde912404..efb6f22ae655 100644
--- a/net/rxrpc/krxtimod.c
+++ b/net/rxrpc/krxtimod.c
@@ -82,7 +82,7 @@ static int krxtimod(void *arg)
for (;;) {
unsigned long jif;
- signed long timeout;
+ unsigned long timeout;
/* deal with the server being asked to die */
if (krxtimod_die) {
diff --git a/net/socket.c b/net/socket.c
index ba8e4fb345ab..4d62ac970ca6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -311,7 +311,7 @@ static int init_inodecache(void)
{
sock_inode_cachep = kmem_cache_create("sock_inode_cache",
sizeof(struct socket_alloc),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (sock_inode_cachep == NULL)
return -ENOMEM;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index fbe59d39181d..768d5b373fd2 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -782,7 +782,7 @@ int register_rpc_pipefs(void)
{
rpc_inode_cachep = kmem_cache_create("rpc_inode_cache",
sizeof(struct rpc_inode),
- 0, SLAB_HWCACHE_ALIGN,
+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
init_once, NULL);
if (!rpc_inode_cachep)
return -ENOMEM;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index b7b05e2197f3..280eb1320bfc 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -169,7 +169,7 @@ cleanup_sunrpc(void)
#ifdef RPC_DEBUG
rpc_unregister_sysctl();
#endif
-#ifdef CONFIG_PROCFS
+#ifdef CONFIG_PROC_FS
rpc_proc_exit();
#endif
}
diff --git a/security/dummy.c b/security/dummy.c
index d12442182a94..4774b769a6de 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -354,6 +354,21 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
+static int dummy_inode_getsecurity(struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static int dummy_inode_setsecurity(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static int dummy_inode_listsecurity(struct dentry *dentry, char *buffer)
+{
+ return 0;
+}
+
static int dummy_file_permission (struct file *file, int mask)
{
return 0;
@@ -513,6 +528,9 @@ static void dummy_task_reparent_to_init (struct task_struct *p)
return;
}
+static void dummy_task_to_inode(struct task_struct *p, struct inode *inode)
+{ }
+
static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
{
return 0;
@@ -741,6 +759,16 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode)
return;
}
+static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return -EINVAL;
+}
+
+static int dummy_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return -EINVAL;
+}
+
struct security_operations dummy_security_ops;
@@ -812,6 +840,9 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inode_getxattr);
set_to_dummy_if_null(ops, inode_listxattr);
set_to_dummy_if_null(ops, inode_removexattr);
+ set_to_dummy_if_null(ops, inode_getsecurity);
+ set_to_dummy_if_null(ops, inode_setsecurity);
+ set_to_dummy_if_null(ops, inode_listsecurity);
set_to_dummy_if_null(ops, file_permission);
set_to_dummy_if_null(ops, file_alloc_security);
set_to_dummy_if_null(ops, file_free_security);
@@ -842,6 +873,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, task_prctl);
set_to_dummy_if_null(ops, task_kmod_set_label);
set_to_dummy_if_null(ops, task_reparent_to_init);
+ set_to_dummy_if_null(ops, task_to_inode);
set_to_dummy_if_null(ops, ipc_permission);
set_to_dummy_if_null(ops, msg_msg_alloc_security);
set_to_dummy_if_null(ops, msg_msg_free_security);
@@ -866,6 +898,8 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, register_security);
set_to_dummy_if_null(ops, unregister_security);
set_to_dummy_if_null(ops, d_instantiate);
+ set_to_dummy_if_null(ops, getprocattr);
+ set_to_dummy_if_null(ops, setprocattr);
#ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
set_to_dummy_if_null(ops, unix_may_send);
diff --git a/sound/Makefile b/sound/Makefile
index b834f731a02b..8bb1f0aaa785 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -3,6 +3,7 @@
obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_SOUND_PRIME) += oss/
+obj-$(CONFIG_DMASOUND) += oss/
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/
ifeq ($(CONFIG_SND),y)
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index 4578d2b335bf..a82aa78e3a96 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -23,6 +23,7 @@
#include <linux/version.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <sound/memalloc.h>
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 7d30ee2d0f82..4d00410c55c5 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -944,10 +944,10 @@ static void cs_play_setup(struct cs_state *state)
}
-struct InitStruct
+static struct InitStruct
{
- u32 long off;
- u32 long val;
+ u32 off;
+ u32 val;
} InitArray[] = { {0x00000040, 0x3fc0000f},
{0x0000004c, 0x04800000},
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index c367c72493e7..539072f1375d 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -1,4 +1,4 @@
-
+#ifndef _dmasound_h_
/*
* linux/drivers/sound/dmasound/dmasound.h
*
@@ -10,11 +10,11 @@
* device for true DSP processors but it will be called something else.
* In v3.0 it's /dev/sndproc but this could be a temporary solution.
*/
+#define _dmasound_h_
-
+#include <linux/types.h>
#include <linux/config.h>
-
#define SND_NDEVS 256 /* Number of supported devices */
#define SND_DEV_CTL 0 /* Control port /dev/mixer */
#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
@@ -29,23 +29,16 @@
#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
#define SND_DEV_PSS SND_DEV_SNDPROC
-#define DSP_DEFAULT_SPEED 8000
-
-#define ON 1
-#define OFF 0
+/* switch on various prinks */
+#define DEBUG_DMASOUND 1
#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 2
+#define MAX_MIXER_DEV 4
#define MAX_SYNTH_DEV 3
#define MAX_MIDI_DEV 6
#define MAX_TIMER_DEV 3
-
#define MAX_CATCH_RADIUS 10
-#define MIN_BUFFERS 4
-#define MIN_BUFSIZE 4 /* in KB */
-#define MAX_BUFSIZE 128 /* Limit for Amiga in KB */
-
#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
@@ -67,21 +60,34 @@ static inline int ioctl_return(int *addr, int value)
*/
#undef HAS_8BIT_TABLES
-#undef HAS_14BIT_TABLES
-#undef HAS_16BIT_TABLES
#undef HAS_RECORD
#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
defined(CONFIG_DMASOUND_Q40) || defined(CONFIG_DMASOUND_Q40_MODULE)
#define HAS_8BIT_TABLES
+#define MIN_BUFFERS 4
+#define MIN_BUFSIZE (1<<12) /* in bytes (- where does this come from ?) */
+#define MIN_FRAG_SIZE 8 /* not 100% sure about this */
+#define MAX_BUFSIZE (1<<17) /* Limit for Amiga is 128 kb */
+#define MAX_FRAG_SIZE 15 /* allow *4 for mono-8 => stereo-16 (for multi) */
+
+#else /* is pmac and multi is off */
+
+#define MIN_BUFFERS 2
+#define MIN_BUFSIZE (1<<8) /* in bytes */
+#define MIN_FRAG_SIZE 8
+#define MAX_BUFSIZE (1<<18) /* this is somewhat arbitrary for pmac */
+#define MAX_FRAG_SIZE 16 /* need to allow *4 for mono-8 => stereo-16 */
#endif
-#if defined(CONFIG_DMASOUND_AWACS) || defined(CONFIG_DMASOUND_AWACS_MODULE)
-#define HAS_16BIT_TABLES
+
+#define DEFAULT_N_BUFFERS 4
+#define DEFAULT_BUFF_SIZE (1<<15)
+
+#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
#define HAS_RECORD
#endif
-
/*
* Initialization
*/
@@ -93,6 +99,14 @@ extern void dmasound_deinit(void);
#define dmasound_deinit() do { } while (0)
#endif
+/* description of the set-up applies to either hard or soft settings */
+
+typedef struct {
+ int format; /* AFMT_* */
+ int stereo; /* 0 = mono, 1 = stereo */
+ int size; /* 8/16 bit*/
+ int speed; /* speed */
+} SETTINGS;
/*
* Machine definitions
@@ -117,30 +131,29 @@ typedef struct {
int (*setTreble)(int);
int (*setGain)(int);
void (*play)(void);
- void (*record)(void); /* optional */
- void (*mixer_init)(void); /* optional */
- int (*mixer_ioctl)(u_int, u_long); /* optional */
- void (*write_sq_setup)(void); /* optional */
- void (*read_sq_setup)(void); /* optional */
- void (*sq_open)(void); /* optional */
- int (*state_info)(char *); /* optional */
- void (*abort_read)(void); /* optional */
+ void (*record)(void); /* optional */
+ void (*mixer_init)(void); /* optional */
+ int (*mixer_ioctl)(u_int, u_long); /* optional */
+ int (*write_sq_setup)(void); /* optional */
+ int (*read_sq_setup)(void); /* optional */
+ int (*sq_open)(mode_t); /* optional */
+ int (*state_info)(char *, size_t); /* optional */
+ void (*abort_read)(void); /* optional */
int min_dsp_speed;
+ int max_dsp_speed;
+ int version ;
+ int hardware_afmts ; /* OSS says we only return h'ware info */
+ /* when queried via SNDCTL_DSP_GETFMTS */
+ int capabilities ; /* low-level reply to SNDCTL_DSP_GETCAPS */
+ SETTINGS default_hard ; /* open() or init() should set something valid */
+ SETTINGS default_soft ; /* you can make it look like old OSS, if you want to */
} MACHINE;
-
/*
* Low level stuff
*/
typedef struct {
- int format; /* AFMT_* */
- int stereo; /* 0 = mono, 1 = stereo */
- int size; /* 8/16 bit*/
- int speed; /* speed */
-} SETTINGS;
-
-typedef struct {
ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
@@ -171,11 +184,10 @@ struct sound_settings {
extern struct sound_settings dmasound;
+#ifdef HAS_8BIT_TABLES
extern char dmasound_ulaw2dma8[];
extern char dmasound_alaw2dma8[];
-extern short dmasound_ulaw2dma16[];
-extern short dmasound_alaw2dma16[];
-
+#endif
/*
* Mid level stuff
@@ -208,14 +220,17 @@ static inline int dmasound_set_gain(int gain)
struct sound_queue {
/* buffers allocated for this queue */
- int numBufs;
- int bufSize; /* in bytes */
+ int numBufs; /* real limits on what the user can have */
+ int bufSize; /* in bytes */
char **buffers;
/* current parameters */
- int max_count;
- int block_size; /* in bytes */
- int max_active;
+ int locked ; /* params cannot be modified when != 0 */
+ int user_frags ; /* user requests this many */
+ int user_frag_size ; /* of this size */
+ int max_count; /* actual # fragments <= numBufs */
+ int block_size; /* internal block size in bytes */
+ int max_active; /* in-use fragments <= max_count */
/* it shouldn't be necessary to declare any of these volatile */
int front, rear, count;
@@ -231,19 +246,32 @@ struct sound_queue {
int active;
wait_queue_head_t action_queue, open_queue, sync_queue;
int open_mode;
- int busy, syncing;
+ int busy, syncing, xruns, died;
};
#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ)
#define WAKE_UP(queue) (wake_up_interruptible(&queue))
extern struct sound_queue dmasound_write_sq;
-extern struct sound_queue dmasound_read_sq;
-
#define write_sq dmasound_write_sq
+
+#ifdef HAS_RECORD
+extern struct sound_queue dmasound_read_sq;
#define read_sq dmasound_read_sq
+#endif
extern int dmasound_catchRadius;
-
#define catchRadius dmasound_catchRadius
+/* define the value to be put in the byte-swap reg in mac-io
+ when we want it to swap for us.
+*/
+#define BS_VAL 1
+
+static inline void wait_ms(unsigned int ms)
+{
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(1 + ms * HZ / 1000);
+}
+
+#endif /* _dmasound_h_ */
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 4d0994a4451e..3e3e31c1e826 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -20,6 +20,8 @@
#include <linux/soundcard.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
#include <asm/atariints.h>
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index d2935119d2a7..98627ddea56f 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -904,7 +904,7 @@ static int sq_open(struct inode *inode, struct file *file)
O_RDONLY and dsp1 could be opened O_WRONLY
*/
- dmasound.minDev = MINOR(inode->i_rdev) & 0x0f;
+ dmasound.minDev = minor(inode->i_rdev) & 0x0f;
/* OK. - we should make some attempt at consistency. At least the H'ware
options should be set with a valid mode. We will make it that the LL
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 18ebbcee853c..4be7c98ac0f5 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/soundcard.h>
+#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/setup.h>
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 1bb949878f2d..17ce92628826 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/soundcard.h>
+#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/q40ints.h>
@@ -461,7 +462,7 @@ static void Q40Play(void)
}
spin_lock_irqsave(&dmasound.lock, flags);
Q40PlayNextFrame(1);
- spin_unlock_irqrestore_flags(&dmasound.lock, flags);
+ spin_unlock_irqrestore(&dmasound.lock, flags);
}
static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp)