summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-15 03:32:22 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-15 03:32:22 +0000
commitf1da2c3860e301527d56a1ef0b56c649ee7c4b1b (patch)
tree562b5d2e8b9cb62eb983d78ff6bcf9789e08fcf6
parent00f11569ac8ca73cbcdef8822de1583e79aee571 (diff)
Merge with Linux 2.4.0-test5-pre1. This works again on Origin UP.
The IP22 cache bugs which are plaguing some machines are still unfixed.
-rw-r--r--CREDITS1
-rw-r--r--Documentation/Changes12
-rw-r--r--Documentation/Configure.help14
-rw-r--r--Documentation/DocBook/parportbook.tmpl31
-rw-r--r--Documentation/filesystems/Locking16
-rw-r--r--Documentation/kernel-parameters.txt62
-rw-r--r--Documentation/networking/tulip.txt4
-rw-r--r--Documentation/usb/usb-help.txt8
-rw-r--r--MAINTAINERS41
-rw-r--r--Makefile4
-rw-r--r--README34
-rw-r--r--arch/alpha/boot/tools/objstrip.c2
-rw-r--r--arch/arm/config.in19
-rw-r--r--arch/i386/config.in18
-rw-r--r--arch/i386/defconfig14
-rw-r--r--arch/i386/kernel/apm.c3
-rw-r--r--arch/i386/kernel/microcode.c2
-rw-r--r--arch/i386/kernel/mtrr.c3
-rw-r--r--arch/i386/kernel/smp.c13
-rw-r--r--arch/i386/kernel/visws_apic.c2
-rw-r--r--arch/ia64/boot/bootloader.c2
-rw-r--r--arch/ia64/config.in28
-rw-r--r--arch/m68k/amiga/amisound.c2
-rw-r--r--arch/m68k/apollo/dn_ints.c3
-rw-r--r--arch/m68k/atari/atakeyb.c2
-rw-r--r--arch/m68k/atari/joystick.c3
-rw-r--r--arch/m68k/bvme6000/rtc.c3
-rw-r--r--arch/m68k/config.in18
-rw-r--r--arch/m68k/mac/macboing.c2
-rw-r--r--arch/m68k/mvme16x/rtc.c3
-rw-r--r--arch/mips/cobalt/reset.c1
-rw-r--r--arch/mips64/sgi-ip27/ip27-rtc.c3
-rw-r--r--arch/mips64/sgi-ip27/ip27-setup.c1
-rw-r--r--arch/ppc/8xx_io/Config.in12
-rw-r--r--arch/ppc/8xx_io/commproc.h79
-rw-r--r--arch/ppc/8xx_io/enet.c55
-rw-r--r--arch/ppc/8xx_io/uart.c656
-rw-r--r--arch/ppc/coffboot/Makefile4
-rw-r--r--arch/ppc/config.in38
-rw-r--r--arch/ppc/kernel/Makefile3
-rw-r--r--arch/ppc/kernel/bitops.c197
-rw-r--r--arch/ppc/kernel/chrp_pci.c2
-rw-r--r--arch/ppc/kernel/chrp_setup.c2
-rw-r--r--arch/ppc/kernel/chrp_time.c2
-rw-r--r--arch/ppc/kernel/entry.S14
-rw-r--r--arch/ppc/kernel/feature.c170
-rw-r--r--arch/ppc/kernel/gemini_setup.c2
-rw-r--r--arch/ppc/kernel/head.S47
-rw-r--r--arch/ppc/kernel/idle.c1
-rw-r--r--arch/ppc/kernel/irq.c22
-rw-r--r--arch/ppc/kernel/m8260_setup.c2
-rw-r--r--arch/ppc/kernel/m8xx_setup.c2
-rw-r--r--arch/ppc/kernel/misc.S13
-rw-r--r--arch/ppc/kernel/oak_setup.c2
-rw-r--r--arch/ppc/kernel/open_pic.c7
-rw-r--r--arch/ppc/kernel/pci.c147
-rw-r--r--arch/ppc/kernel/pmac_backlight.c148
-rw-r--r--arch/ppc/kernel/pmac_nvram.c39
-rw-r--r--arch/ppc/kernel/pmac_pci.c107
-rw-r--r--arch/ppc/kernel/pmac_pic.c34
-rw-r--r--arch/ppc/kernel/pmac_setup.c64
-rw-r--r--arch/ppc/kernel/pmac_time.c56
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c19
-rw-r--r--arch/ppc/kernel/prep_setup.c2
-rw-r--r--arch/ppc/kernel/prep_time.c2
-rw-r--r--arch/ppc/kernel/prom.c87
-rw-r--r--arch/ppc/kernel/setup.c26
-rw-r--r--arch/ppc/kernel/signal.c211
-rw-r--r--arch/ppc/kernel/smp.c2
-rw-r--r--arch/ppc/kernel/syscalls.c10
-rw-r--r--arch/ppc/kernel/time.c12
-rw-r--r--arch/ppc/kernel/walnut_setup.c2
-rw-r--r--arch/ppc/mbxboot/m8xx_tty.c45
-rw-r--r--arch/ppc/mbxboot/misc.c4
-rw-r--r--arch/ppc/mm/init.c8
-rw-r--r--arch/ppc/xmon/xmon.c8
-rw-r--r--arch/s390/config.in16
-rw-r--r--arch/sh/config.in18
-rw-r--r--arch/sparc/defconfig2
-rw-r--r--arch/sparc/kernel/process.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c8
-rw-r--r--arch/sparc64/defconfig22
-rw-r--r--arch/sparc64/kernel/binfmt_elf32.c2
-rw-r--r--arch/sparc64/solaris/socksys.c3
-rw-r--r--arch/sparc64/solaris/timod.c37
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/cpu.c307
-rw-r--r--drivers/acpi/driver.c388
-rw-r--r--drivers/acpi/driver.h115
-rw-r--r--drivers/acpi/ec.c191
-rw-r--r--drivers/acpi/os.c379
-rw-r--r--drivers/acpi/osd.c1319
-rw-r--r--drivers/acpi/sys.c182
-rw-r--r--drivers/acpi/tables.c303
-rw-r--r--drivers/block/acsi_slm.c5
-rw-r--r--drivers/block/ll_rw_blk.c84
-rw-r--r--drivers/block/lvm.c9
-rw-r--r--drivers/block/md.c4
-rw-r--r--drivers/block/paride/paride.c27
-rw-r--r--drivers/block/paride/pg.c3
-rw-r--r--drivers/block/paride/pt.c3
-rw-r--r--drivers/block/ps2esdi.c12
-rw-r--r--drivers/block/rd.c14
-rw-r--r--drivers/cdrom/aztcd.c2
-rw-r--r--drivers/cdrom/sjcd.c2
-rw-r--r--drivers/char/acquirewdt.c3
-rw-r--r--drivers/char/agp/agpgart_fe.c15
-rw-r--r--drivers/char/amikeyb.c2
-rw-r--r--drivers/char/applicom.c26
-rw-r--r--drivers/char/busmouse.c3
-rw-r--r--drivers/char/cyclades.c173
-rw-r--r--drivers/char/dn_keyb.c3
-rw-r--r--drivers/char/drm/ffb_drv.c48
-rw-r--r--drivers/char/drm/gamma_drv.c31
-rw-r--r--drivers/char/drm/tdfx_drv.c15
-rw-r--r--drivers/char/drm/vm.c2
-rw-r--r--drivers/char/dsp56k.c3
-rw-r--r--drivers/char/dtlk.c3
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c106
-rw-r--r--drivers/char/h8.c12
-rw-r--r--drivers/char/i2c-parport.c2
-rw-r--r--drivers/char/i810_rng.c7
-rw-r--r--drivers/char/ip2main.c3
-rw-r--r--drivers/char/joystick/Config.in4
-rw-r--r--drivers/char/lp.c3
-rw-r--r--drivers/char/mixcomwd.c4
-rw-r--r--drivers/char/msp3400.c2
-rw-r--r--drivers/char/nvram.c4
-rw-r--r--drivers/char/pc110pad.c8
-rw-r--r--drivers/char/pc_keyb.c7
-rw-r--r--drivers/char/pcmcia/Config.in6
-rw-r--r--drivers/char/pcwd.c3
-rw-r--r--drivers/char/ppdev.c86
-rw-r--r--drivers/char/qpmouse.c3
-rw-r--r--drivers/char/raw.c3
-rw-r--r--drivers/char/sbc60xxwdt.c3
-rw-r--r--drivers/char/softdog.c7
-rw-r--r--drivers/char/tpqic02.c3
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/tvmixer.c10
-rw-r--r--drivers/char/videodev.c19
-rw-r--r--drivers/char/wdt.c3
-rw-r--r--drivers/char/wdt285.c7
-rw-r--r--drivers/char/wdt977.c7
-rw-r--r--drivers/char/wdt_pci.c8
-rw-r--r--drivers/i2c/i2c-dev.c6
-rw-r--r--drivers/i2o/i2o_config.c3
-rw-r--r--drivers/ide/ide-tape.c34
-rw-r--r--drivers/ieee1394/raw1394.c3
-rw-r--r--drivers/ieee1394/video1394.c17
-rw-r--r--drivers/isdn/avmb1/capi.c18
-rw-r--r--drivers/isdn/divert/divert_procfs.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_procfs.c3
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c2
-rw-r--r--drivers/isdn/isdn_common.c43
-rw-r--r--drivers/macintosh/adb.c3
-rw-r--r--drivers/macintosh/via-pmu.c3
-rw-r--r--drivers/mtd/Config.in96
-rw-r--r--drivers/mtd/Makefile267
-rw-r--r--drivers/mtd/cfi_cmdset_0001.c8
-rw-r--r--drivers/mtd/cfi_cmdset_0002.c610
-rw-r--r--drivers/mtd/doc2000.c8
-rw-r--r--drivers/mtd/doc2001.c748
-rw-r--r--drivers/mtd/docprobe.c6
-rw-r--r--drivers/mtd/mtdblock.c2
-rw-r--r--drivers/mtd/mtdchar.c10
-rw-r--r--drivers/mtd/mtdcore.c126
-rw-r--r--drivers/mtd/mtdram.c6
-rw-r--r--drivers/mtd/nftl.c4
-rw-r--r--drivers/mtd/nora.c12
-rw-r--r--drivers/mtd/octagon-5066.c6
-rw-r--r--drivers/mtd/pmc551.c11
-rw-r--r--drivers/mtd/pnc2000.c210
-rw-r--r--drivers/net/atari_bionet.c2
-rw-r--r--drivers/net/atari_pamsnet.c2
-rw-r--r--drivers/net/de4x5.c1
-rw-r--r--drivers/net/pcmcia/xircom_tulip_cb.c3
-rw-r--r--drivers/net/ppp_generic.c3
-rw-r--r--drivers/net/sk_g16.c2
-rw-r--r--drivers/net/tulip/tulip_core.c8
-rw-r--r--drivers/net/wan/Makefile3
-rw-r--r--drivers/net/wan/cosa.c6
-rw-r--r--drivers/net/wan/cycx_main.c12
-rw-r--r--drivers/parport/ChangeLog38
-rw-r--r--drivers/parport/init.c4
-rw-r--r--drivers/parport/share.c255
-rw-r--r--drivers/pcmcia/ds.c24
-rw-r--r--drivers/pnp/isapnp_proc.c2
-rw-r--r--drivers/sbus/audio/audio.c4
-rw-r--r--drivers/sbus/char/bpp.c4
-rw-r--r--drivers/sbus/char/flash.c14
-rw-r--r--drivers/sbus/char/jsflash.c3
-rw-r--r--drivers/sbus/char/pcikbd.c6
-rw-r--r--drivers/sbus/char/rtc.c3
-rw-r--r--drivers/sbus/char/sunkbd.c20
-rw-r--r--drivers/sbus/char/sunmouse.c3
-rw-r--r--drivers/sbus/char/vfc_dev.c21
-rw-r--r--drivers/scsi/pluto.c5
-rw-r--r--drivers/scsi/scsi_scan.c4
-rw-r--r--drivers/scsi/sg.c26
-rw-r--r--drivers/scsi/st.c10
-rw-r--r--drivers/sgi/char/graphics.c3
-rw-r--r--drivers/sgi/char/shmiq.c6
-rw-r--r--drivers/sgi/char/streamable.c19
-rw-r--r--drivers/sgi/char/usema.c7
-rw-r--r--drivers/sound/cmpci.c29
-rw-r--r--drivers/sound/dmasound/dmasound_core.c7
-rw-r--r--drivers/sound/emu10k1/audio.c12
-rw-r--r--drivers/sound/emu10k1/midi.c7
-rw-r--r--drivers/sound/es1370.c49
-rw-r--r--drivers/sound/es1371.c49
-rw-r--r--drivers/sound/esssolo1.c29
-rw-r--r--drivers/sound/i810_audio.c26
-rw-r--r--drivers/sound/maestro.c26
-rw-r--r--drivers/sound/msnd.h11
-rw-r--r--drivers/sound/msnd_pinnacle.c72
-rw-r--r--drivers/sound/sonicvibes.c29
-rw-r--r--drivers/sound/soundcard.c13
-rw-r--r--drivers/sound/trident.c34
-rw-r--r--drivers/sound/via82cxxx_audio.c3
-rw-r--r--drivers/sound/vwsnd.c37
-rw-r--r--drivers/sound/wavfront.c3
-rw-r--r--drivers/telephony/ixj.c3
-rw-r--r--drivers/usb/Config.in4
-rw-r--r--drivers/usb/audio.c31
-rw-r--r--drivers/usb/bluetooth.c9
-rw-r--r--drivers/usb/dabusb.c3
-rw-r--r--drivers/usb/dc2xx.c3
-rw-r--r--drivers/usb/devices.c116
-rw-r--r--drivers/usb/evdev.c6
-rw-r--r--drivers/usb/joydev.c6
-rw-r--r--drivers/usb/mdc800.c3
-rw-r--r--drivers/usb/mousedev.c6
-rw-r--r--drivers/usb/printer.c18
-rw-r--r--drivers/usb/usb.c27
-rw-r--r--drivers/video/fbcon-mac.c120
-rw-r--r--drivers/video/fbcon.c10
-rw-r--r--drivers/video/fbmem.c17
-rw-r--r--drivers/video/vesafb.c6
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/coda/dir.c2
-rw-r--r--fs/coda/pioctl.c25
-rw-r--r--fs/coda/psdev.c10
-rw-r--r--fs/dcache.c3
-rw-r--r--fs/devfs/base.c8
-rw-r--r--fs/ext2/file.c6
-rw-r--r--fs/file_table.c5
-rw-r--r--fs/hpfs/dir.c4
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/inode.c1
-rw-r--r--fs/jffs/inode-v23.c10
-rw-r--r--fs/jffs/jffs_fm.c8
-rw-r--r--fs/ncpfs/sock.c31
-rw-r--r--fs/nfs/inode.c8
-rw-r--r--fs/nfsd/vfs.c8
-rw-r--r--fs/openpromfs/inode.c3
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/select.c41
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--fs/udf/file.c6
-rw-r--r--include/asm-mips64/sn/klconfig.h27
-rw-r--r--include/asm-ppc/backlight.h28
-rw-r--r--include/asm-ppc/feature.h17
-rw-r--r--include/asm-ppc/hardirq.h30
-rw-r--r--include/asm-ppc/heathrow.h57
-rw-r--r--include/asm-ppc/machdep.h5
-rw-r--r--include/asm-ppc/mpc8xx.h8
-rw-r--r--include/asm-ppc/pci-bridge.h13
-rw-r--r--include/asm-ppc/pci.h9
-rw-r--r--include/asm-ppc/processor.h3
-rw-r--r--include/asm-ppc/prom.h3
-rw-r--r--include/asm-ppc/softirq.h6
-rw-r--r--include/asm-ppc/time.h (renamed from arch/ppc/kernel/time.h)0
-rw-r--r--include/asm-ppc/tqm860.h65
-rw-r--r--include/asm-ppc/tqm8xxL.h66
-rw-r--r--include/asm-ppc/ucontext.h1
-rw-r--r--include/asm-ppc/unistd.h4
-rw-r--r--include/asm-ppc/vga.h4
-rw-r--r--include/asm-s390/elf.h2
-rw-r--r--include/asm-sparc/asm_offsets.h304
-rw-r--r--include/asm-sparc/bitops.h1
-rw-r--r--include/asm-sparc/elf.h2
-rw-r--r--include/asm-sparc64/asm_offsets.h468
-rw-r--r--include/asm-sparc64/elf.h2
-rw-r--r--include/asm-sparc64/semaphore.h1
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/cyclomx.h5
-rw-r--r--include/linux/mtd/doc2000.h109
-rw-r--r--include/linux/netfilter_ipv4/ip_nat_core.h8
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h2
-rw-r--r--include/linux/netfilter_ipv4/ipt_REJECT.h5
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h2
-rw-r--r--include/linux/parport.h17
-rw-r--r--include/linux/pci_ids.h4
-rw-r--r--include/linux/poll.h21
-rw-r--r--include/linux/usb.h1
-rw-r--r--include/video/fbcon.h1
-rw-r--r--kernel/ksyms.c1
-rw-r--r--kernel/sched.c9
-rw-r--r--mm/memory.c8
-rw-r--r--mm/slab.c2
-rw-r--r--mm/vmscan.c6
-rw-r--r--net/atm/mpoa_proc.c1
-rw-r--r--net/core/netfilter.c12
-rw-r--r--net/decnet/dn_route.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c19
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c11
-rw-r--r--net/ipv4/netfilter/ip_fw_compat.c3
-rw-r--r--net/ipv4/netfilter/ip_fw_compat_masq.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c20
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c5
-rw-r--r--net/ipv4/netfilter/ip_queue.c5
-rw-r--r--net/ipv4/netfilter/ip_tables.c2
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c131
-rw-r--r--net/ipv4/tcp_ipv4.c6
-rw-r--r--net/ipv6/netfilter/ip6_tables.c2
-rw-r--r--net/ipv6/reassembly.c2
-rw-r--r--net/irda/irmod.c6
-rw-r--r--net/netlink/netlink_dev.c6
-rw-r--r--net/sched/sch_cbq.c3
-rw-r--r--net/socket.c2
-rw-r--r--net/unix/garbage.c2
-rw-r--r--scripts/Menuconfig2
324 files changed, 7762 insertions, 4475 deletions
diff --git a/CREDITS b/CREDITS
index a7beebcd7..af6c3d6d4 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1387,6 +1387,7 @@ E: greg@kroah.com
W: http://www.kroah.com/linux-usb/
D: USB Serial Converter driver framework, USB Handspring Visor driver
D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver
+D: USB Bluetooth driver
D: bits and pieces of USB core code.
N: Russell Kroll
diff --git a/Documentation/Changes b/Documentation/Changes
index 525932df1..f8b055d21 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -317,12 +317,12 @@ o ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/testing/isdn4k-
Netfilter
---------
-o http://netfilter.filewatcher.org/iptables-1.1.0.tar.bz2
- <http://netfilter.filewatcher.org/iptables-1.1.0.tar.bz2>
-o http://www.samba.org/netfilter/iptables-1.1.0.tar.bz2
- <http://www.samba.org/netfilter/iptables-1.1.0.tar.bz2>
-o http://netfilter.kernelnotes.org/iptables-1.1.0.tar.bz2
- <http://netfilter.kernelnotes.org/iptables-1.1.0.tar.bz2>
+o http://netfilter.filewatcher.org/iptables-1.1.1.tar.bz2
+ <http://netfilter.filewatcher.org/iptables-1.1.1.tar.bz2>
+o http://www.samba.org/netfilter/iptables-1.1.1.tar.bz2
+ <http://www.samba.org/netfilter/iptables-1.1.1.tar.bz2>
+o http://netfilter.kernelnotes.org/iptables-1.1.1.tar.bz2
+ <http://netfilter.kernelnotes.org/iptables-1.1.1.tar.bz2>
Ip-route2
---------
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index 8e10720f9..8a1b4ad9b 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -15126,16 +15126,10 @@ CONFIG_6xx
There are four types of PowerPC chips supported. The more common
types (601, 603, 604, 740, 750), the Motorola embedded versions
(821, 823, 850, 855, 860), the IBM embedded versions (403 and
- 405) and the high end 64 bit Power processors (Power 3, Power 4).
- Unless you are building a kernel for one of the embedded
- processor systems, or a 64 bit IBM RS/6000, choose 6xx.
-
-CONFIG_PPC64BRIDGE
- Currently there is not a 64 bit PowerPC Linux kernel. As a result
- if you choose the CONFIG_POWER3 or CONFIG_POWER4 options you
- must choose this option as well. This enables gcc to emit
- both 32 and 64 bit instructions as well as cause your kernel
- to be built as a 32 bit kernel.
+ 405) and the high end 64 bit Power processors (Power 3, Power 4).
+ Unless you are building a kernel for one of the embedded
+ processor systems, or a 64 bit IBM RS/6000, choose 6xx. Note that
+ the kernel runs in 32-bit mode even on 64-bit chips.
Machine Type
CONFIG_PMAC
diff --git a/Documentation/DocBook/parportbook.tmpl b/Documentation/DocBook/parportbook.tmpl
index 754f1a96b..ef8c07d33 100644
--- a/Documentation/DocBook/parportbook.tmpl
+++ b/Documentation/DocBook/parportbook.tmpl
@@ -386,7 +386,7 @@
announces it. The <function>parport_announce_port</function>
function walks down the list of parallel port device drivers
(<structname>struct parport_driver</structname>s) calling the
- <function>attach</function> function of each.
+ <function>attach</function> function of each (which may block).
</para>
<para>
@@ -394,7 +394,7 @@
registering a port with the
<function>parport_unregister_port</function> function, and device
drivers are notified using the <function>detach</function>
- callback.
+ callback (which may not block).
</para>
<para>
@@ -656,9 +656,31 @@ struct parport_driver {
to the <function>attach</function> function when it is called, or
alternatively can be found from the list of detected parallel ports
directly with the (now deprecated)
- <function>parport_enumerate</function> function.
+ <function>parport_enumerate</function> function. A better way of
+ doing this is with <function>parport_find_number</function> or
+ <function>parport_find_base</function> functions, which find ports
+ by number and by base I/O address respectively.
</para>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>struct parport *<function>parport_find_number</function></funcdef>
+ <paramdef>int <parameter>number</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ <funcsynopsis>
+ <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+ </funcsynopsisinfo>
+ <funcprototype>
+ <funcdef>struct parport *<function>parport_find_base</function></funcdef>
+ <paramdef>unsigned long <parameter>base</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+
<para>
The next three parameters, <parameter>pf</parameter>,
<parameter>kf</parameter>, and <parameter>irq_func</parameter>, are
@@ -2202,6 +2224,9 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
!Fdrivers/parport/daisy.c parport_find_class
!Fdrivers/parport/share.c parport_register_driver
!Fdrivers/parport/share.c parport_unregister_driver
+!Fdrivers/parport/share.c parport_get_port
+!Fdrivers/parport/share.c parport_put_port
+!Fdrivers/parport/share.c parport_find_number parport_find_base
!Fdrivers/parport/share.c parport_register_device
!Fdrivers/parport/share.c parport_unregister_device
!Fdrivers/parport/daisy.c parport_open
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 0dd2cc8eb..421b17318 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -66,6 +66,7 @@ getattr: (see below)
revalidate: no (see below)
Additionally, ->rmdir() has i_zombie on victim and so does ->rename()
in case when target exists and is a directory.
+ ->rename() on directories has (per-superblock) ->s_vfs_rename_sem.
->revalidate(), it may be called both with and without the i_sem
on dentry->d_inode. VFS never calls it with i_zombie on dentry->d_inode,
but watch for other methods directly calling this one...
@@ -226,7 +227,7 @@ ioctl: yes (see below)
mmap: no
open: maybe (see below)
flush: yes
-release: yes
+release: no
fsync: yes (see below)
fasync: yes (see below)
lock: yes
@@ -238,12 +239,13 @@ The only exception is ->open() in the instances of file_operations that never
end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices
(chrdev_open() takes lock before replacing ->f_op and calling the secondary
method. As soon as we fix the handling of module reference counters all
-instances of ->open() will be called without the BKL. At the same point
-->release() will lose BKL. Currently ext2_release() is *the* source of
-contention on fs-intensive loads and dropping BKL on ->release() will get
-rid of that (we will still need some locking for cases when we close a file
-that had been opened r/w, but that can be done using the internal locking with
-smaller critical areas). sock_close() is also going to win from that change.
+instances of ->open() will be called without the BKL.
+
+Note: ext2_release() was *the* source of contention on fs-intensive
+loads and dropping BKL on ->release() helps to get rid of that (we still
+grab BKL for cases when we close a file that had been opened r/w, but that
+can and should be done using the internal locking with smaller critical areas).
+Current worst offender is ext2_get_block()...
->fasync() is a mess. This area needs a big cleanup and that will probably
affect locking.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 611d8be80..072508d51 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1,4 +1,4 @@
-June 2000 Kernel Parameters v2.4.0
+July 2000 Kernel Parameters v2.4.0
~~~~~~~~~~~~~~~~~
The following is a consolidated list of the kernel parameters as implemented
@@ -80,6 +80,8 @@ running once the system is up.
AM53C974= [HW,SCSI]
+ amijoy= [HW,JOY] Amiga joystick support
+
apm= [APM] Advanced Power Management.
applicom= [HW]
@@ -139,6 +141,12 @@ running once the system is up.
dasd= [HW,NET]
+ db9= [HW,JOY]
+
+ db9_2= [HW,JOY]
+
+ db9_3= [HW,JOY]
+
debug [KNL] Enable kernel debugging (events log level).
decnet= [HW,NET]
@@ -179,6 +187,12 @@ running once the system is up.
ftape= [HW] Floppy Tape subsystem debugging options.
+ gc= [HW,JOY]
+
+ gc_2= [HW,JOY]
+
+ gc_3= [HW,JOY]
+
gdth= [HW,SCSI]
gscd= [HW,CD]
@@ -194,10 +208,6 @@ running once the system is up.
hisax= [HW,ISDN]
- in2000= [HW,SCSI]
-
- init= [KNL]
-
ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter.
icn= [HW,ISDN]
@@ -208,40 +218,20 @@ running once the system is up.
idebus= [HW] (E)IDE subsystem : VLB/PCI bus speed.
+ idle= [HW]
+
+ in2000= [HW,SCSI]
+
+ init= [KNL]
+
ip= [PNP]
isp16= [HW,CD]
iucv= [HW,NET]
- js_am= [HW,JOY]
-
- js_an= [HW,JOY]
-
- js_as= [HW.JOY]
-
- js_console= [HW,JOY]
-
- js_console2= [HW,JOY]
-
- js_console3= [HW,JOY]
-
- js_db9= [HW,JOY]
-
- js_db9_2= [HW,JOY]
-
- js_db9_3= [HW,JOY]
-
- js_l4= [HW,JOY]
-
- js_pci= [HW,JOY,PCI]
+ js= [HW,JOY] Analog joystick
- js_tg= [HW,JOY]
-
- js_tg_2= [HW,JOY]
-
- js_tg_3= [HW,JOY]
-
kbd-reset [VT]
load_ramdisk= [RAM] List of ramdisks to load from floppy.
@@ -354,6 +344,8 @@ running once the system is up.
nosync [HW, M68K] Disables sync negotiation for all devices.
+ notsc [BUGS=ix86] Disable Time Stamp Counter
+
nowb [ARM]
opl3= [HW,SOUND]
@@ -484,6 +476,12 @@ running once the system is up.
tdfx= [HW,DRM]
+ tgfx= [HW,JOY]
+
+ tgfx_2= [HW,JOY]
+
+ tgfx_3= [HW,JOY]
+
tmc8xx= [HW,SCSI]
tmscsim= [HW,SCSI]
diff --git a/Documentation/networking/tulip.txt b/Documentation/networking/tulip.txt
index 11494e1dc..35d5dea65 100644
--- a/Documentation/networking/tulip.txt
+++ b/Documentation/networking/tulip.txt
@@ -142,6 +142,10 @@ tulip_core.c - Driver core (a.k.a. where "everything else" goes)
Version history
===============
+0.9.8 (July 13, 2000):
+* Correct signed/unsigned comparison for dummy frame index
+* Remove outdated references to struct enet_statistics
+
0.9.7 (June 17, 2000):
* Timer cleanups (Andrew Morton)
* Alpha compile fix (somebody?)
diff --git a/Documentation/usb/usb-help.txt b/Documentation/usb/usb-help.txt
index 9abd4a08b..5ad2aaa57 100644
--- a/Documentation/usb/usb-help.txt
+++ b/Documentation/usb/usb-help.txt
@@ -1,5 +1,5 @@
usb-help.txt
-2000-March-24
+2000-July-12
For USB help other than the readme files that are located in
linux/Documentation/usb/*, see the following:
@@ -7,10 +7,12 @@ linux/Documentation/usb/*, see the following:
Linux-USB project: http://www.linux-usb.org
mirrors at http://www.suse.cz/development/linux-usb/
and http://usb.in.tum.de/linux-usb/
-Linux USB Guide: http://linuxusbguide.sourceforge.net
+Linux USB Guide: http://linux-usb.sourceforge.net
Linux-USB device overview (working devices and drivers):
http://www.qbik.ch/usb/devices/
-The Linux-USB mailing list is linux-usb@suse.com .
+The Linux-USB mailing lists are:
+ linux-usb-users@lists.sourceforge.net for general user help
+ linux-usb-devel@lists.sourceforge.net for developer discussions
###
diff --git a/MAINTAINERS b/MAINTAINERS
index a2140268a..e0cf32593 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1156,72 +1156,91 @@ S: Supported
USB ACM DRIVER
P: Vojtech Pavlik
M: vojtech@suse.cz
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Supported
+USB BLUETOOTH DRIVER
+P: Greg Kroah-Hartman
+M: greg@kroah.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
+S: Maintained
+W: http://www.kroah.com/linux-usb/
+
USB HID/HIDBP/INPUT DRIVERS
P: Vojtech Pavlik
M: vojtech@suse.cz
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
W: http://www.suse.cz/development/input/
S: Supported
USB HUB
P: Johannes Erdfelt
M: jerdfelt@sventech.com
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB OHCI DRIVER
P: Roman Weissgaerber
M: weissg@vienna.at
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB OV511 DRIVER
P: Mark McClelland
M: mmcclelland@delphi.com
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
W: http://alpha.dyndns.org/ov511/
S: Maintained
USB PEGASUS DRIVER
P: Petko Manolov
M: petkan@spct.net
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB PRINTER DRIVER
P: Vojtech Pavlik
M: vojtech@suse.cz
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Supported
USB SERIAL DIGI ACCELEPORT DRIVER
P: Peter Berger and Al Borchers
M: pberger@brimson.com
M: alborchers@steinerpoint.com
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Supported
USB SERIAL DRIVER
P: Greg Kroah-Hartman
M: greg@kroah.com
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
W: http://www.kroah.com/linux-usb/
USB MASS STORAGE DRIVER
P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
USB UHCI DRIVER
P: Georg Acher
M: usb@in.tum.de
-L: linux-usb@suse.com
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
W: http://usb.in.tum.de
S: Maintained
diff --git a/Makefile b/Makefile
index c0c545267..8fcf0c108 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 0
-#EXTRAVERSION = -test4
-EXTRAVERSION = -test4-pre3
+#EXTRAVERSION = -test5
+EXTRAVERSION = -test5-pre1
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/README b/README
index e77f3a3e8..611354d42 100644
--- a/README
+++ b/README
@@ -169,14 +169,18 @@ COMPILING the kernel:
Please note that you can still run a.out user programs with this
kernel.
- - Do a "make zImage" to create a compressed kernel image. If you want
+ - Do a "make bzImage" to create a compressed kernel image. If you want
to make a boot disk (without root filesystem or LILO), insert a floppy
- in your A: drive, and do a "make zdisk". It is also possible to do
- "make zlilo" if you have lilo installed to suit the kernel makefiles,
+ in your A: drive, and do a "make bzdisk". It is also possible to do
+ "make bzlilo" if you have lilo installed to suit the kernel makefiles,
but you may want to check your particular lilo setup first.
- - If your kernel is too large for "make zImage", use "make bzImage"
- instead.
+ - In the unlikely event that your system cannot boot bzImage kernels you
+ can still compile your kernel as zImage. However, since zImage support
+ will be removed at some point in the future in favor of bzImage we
+ encourage people having problems with booting bzImage kernels to report
+ these, with detailed hardware configuration information, to the
+ linux-kernel mailing list and to H. Peter Anvin <hpa+linux@zytor.com>.
- If you configured any of the parts of the kernel as `modules', you
will have to do "make modules" followed by "make modules_install".
@@ -192,11 +196,11 @@ COMPILING the kernel:
do a "make modules_install".
- In order to boot your new kernel, you'll need to copy the kernel
- image (found in /usr/src/linux/arch/i386/boot/zImage after compilation)
+ image (found in /usr/src/linux/arch/i386/boot/bzImage after compilation)
to the place where your regular bootable kernel is found.
For some, this is on a floppy disk, in which case you can "cp
- /usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable
+ /usr/src/linux/arch/i386/boot/bzImage /dev/fd0" to make a bootable
floppy. Please note that you can not boot a kernel by
directly dumping it to a 720k double-density 3.5" floppy. In this
case, it is highly recommended that you install LILO on your
@@ -204,11 +208,11 @@ COMPILING the kernel:
If you boot Linux from the hard drive, chances are you use LILO which
uses the kernel image as specified in the file /etc/lilo.conf. The
- kernel image file is usually /vmlinuz, or /zImage, or /etc/zImage.
- To use the new kernel, save a copy of the old image and copy the new
- image over the old one. Then, you MUST RERUN LILO to update the
- loading map!! If you don't, you won't be able to boot the new kernel
- image.
+ kernel image file is usually /vmlinuz, /boot/vmlinuz, /bzImage or
+ /boot/bzImage. To use the new kernel, save a copy of the old image
+ and copy the new image over the old one. Then, you MUST RERUN LILO
+ to update the loading map!! If you don't, you won't be able to boot
+ the new kernel image.
Reinstalling LILO is usually a matter of running /sbin/lilo.
You may wish to edit /etc/lilo.conf to specify an entry for your
@@ -260,9 +264,9 @@ IF SOMETHING GOES WRONG:
the above example it's due to a bad kernel pointer). More information
on making sense of the dump is in Documentation/oops-tracing.txt
- - You can use the "ksymoops" program to make sense of the dump. Find
- the C++ sources under the scripts/ directory to avoid having to do
- the dump lookup by hand:
+ - You can use the "ksymoops" program to make sense of the dump. This
+ utility can be downloaded from ftp://ftp.ocs.com.au/pub/ksymoops .
+ Alternately you can do the dump lookup by hand:
- In debugging dumps like the above, it helps enormously if you can
look up what the EIP value means. The hex value as such doesn't help
diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
index 765e68f2e..569496061 100644
--- a/arch/alpha/boot/tools/objstrip.c
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -150,7 +150,7 @@ main (int argc, char *argv[])
prog_name, inname);
exit(1);
}
- if (!elf_check_arch(elf->e_machine)) {
+ if (!elf_check_arch(elf)) {
fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n",
prog_name, elf->e_machine);
exit(1);
diff --git a/arch/arm/config.in b/arch/arm/config.in
index e270007f9..7e7e337b6 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -15,6 +15,14 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE
endmenu
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
mainmenu_option next_comment
comment 'System Type'
@@ -157,17 +165,6 @@ else
fi
endmenu
-
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-
mainmenu_option next_comment
comment 'General setup'
source drivers/pci/Config.in
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 6557d822d..d9fcd91db 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -16,6 +16,15 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'Processor type and features'
choice 'Processor family' \
"386 CONFIG_M386 \
@@ -146,15 +155,6 @@ fi
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'General setup'
bool 'Networking support' CONFIG_NET
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 35444fef3..507ea5469 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -12,6 +12,13 @@ CONFIG_UID16=y
# CONFIG_EXPERIMENTAL is not set
#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
# Processor type and features
#
# CONFIG_M386 is not set
@@ -48,13 +55,6 @@ CONFIG_SMP=y
CONFIG_HAVE_DEC_LOCK=y
#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
# General setup
#
CONFIG_NET=y
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index a915181a9..bd7c62bdf 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -181,6 +181,7 @@
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -1268,6 +1269,7 @@ static int do_release(struct inode * inode, struct file * filp)
if (check_apm_user(as, "release"))
return 0;
filp->private_data = NULL;
+ lock_kernel();
if (as->standbys_pending > 0) {
standbys_pending -= as->standbys_pending;
if (standbys_pending <= 0)
@@ -1292,6 +1294,7 @@ static int do_release(struct inode * inode, struct file * filp)
else
as1->next = as->next;
}
+ unlock_kernel();
kfree_s(as, sizeof(*as));
return 0;
}
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index c693b2dc2..0519aee0c 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -147,7 +147,9 @@ static int microcode_open(struct inode *inode, struct file *file)
static int microcode_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
clear_bit(MICROCODE_IS_OPEN, &microcode_status);
+ unlock_kernel();
return 0;
}
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index c0a158694..05b57c93a 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -251,6 +251,7 @@
#include <asm/mtrr.h>
#include <linux/init.h>
#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -1532,6 +1533,7 @@ static int mtrr_close (struct inode *ino, struct file *file)
unsigned int *fcount = file->private_data;
if (fcount == NULL) return 0;
+ lock_kernel();
max = get_num_var_ranges ();
for (i = 0; i < max; ++i)
{
@@ -1541,6 +1543,7 @@ static int mtrr_close (struct inode *ino, struct file *file)
--fcount[i];
}
}
+ unlock_kernel();
kfree (fcount);
file->private_data = NULL;
return 0;
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index e08418fe0..b11b629fe 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -392,6 +392,8 @@ void smp_send_reschedule(int cpu)
* Structure and data for smp_call_function(). This is designed to minimise
* static memory requirements. It also looks cleaner.
*/
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
static volatile struct call_data_struct {
void (*func) (void *info);
void *info;
@@ -422,9 +424,8 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
{
struct call_data_struct data;
int ret, cpus = smp_num_cpus-1;
- static spinlock_t lock = SPIN_LOCK_UNLOCKED;
- if(cpus == 0)
+ if (!cpus)
return 0;
data.func = func;
@@ -434,21 +435,21 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
if (wait)
atomic_set(&data.finished, 0);
- spin_lock_bh(&lock);
+ spin_lock_bh(&call_lock);
call_data = &data;
/* Send a message to all other CPUs and wait for them to respond */
send_IPI_allbutself(CALL_FUNCTION_VECTOR);
/* Wait for response */
- /* FIXME: lock-up detection, backtrace on lock-up */
- while(atomic_read(&data.started) != cpus)
+ while (atomic_read(&data.started) != cpus)
barrier();
ret = 0;
if (wait)
while (atomic_read(&data.finished) != cpus)
barrier();
- spin_unlock_bh(&lock);
+ spin_unlock_bh(&call_lock);
+
return 0;
}
diff --git a/arch/i386/kernel/visws_apic.c b/arch/i386/kernel/visws_apic.c
index 288f83e8f..017b8eb58 100644
--- a/arch/i386/kernel/visws_apic.c
+++ b/arch/i386/kernel/visws_apic.c
@@ -91,6 +91,8 @@ static void disable_cobalt_irq(unsigned int irq);
static void startup_cobalt_irq(unsigned int irq);
#define shutdown_cobalt_irq disable_cobalt_irq
+static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+
static struct hw_interrupt_type cobalt_irq_type = {
"Cobalt-APIC",
startup_cobalt_irq,
diff --git a/arch/ia64/boot/bootloader.c b/arch/ia64/boot/bootloader.c
index cb6fc1f96..b73f396dc 100644
--- a/arch/ia64/boot/bootloader.c
+++ b/arch/ia64/boot/bootloader.c
@@ -157,7 +157,7 @@ _start (void)
cons_write("not an ELF executable\n");
return;
}
- if (!elf_check_arch(elf->e_machine)) {
+ if (!elf_check_arch(elf)) {
cons_write("kernel not for this processor\n");
return;
}
diff --git a/arch/ia64/config.in b/arch/ia64/config.in
index e17fbd6af..09131fac7 100644
--- a/arch/ia64/config.in
+++ b/arch/ia64/config.in
@@ -4,6 +4,20 @@
mainmenu_name "Kernel configuration of Linux for IA-64 machines"
mainmenu_option next_comment
+ comment 'Code maturity level options'
+ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_IA64 y
@@ -67,20 +81,6 @@ else
define_bool CONFIG_PCMCIA n
fi
-mainmenu_option next_comment
- comment 'Code maturity level options'
- bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
-endmenu
-
-mainmenu_option next_comment
- comment 'Loadable module support'
- bool 'Enable loadable module support' CONFIG_MODULES
- if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
- fi
-endmenu
-
source drivers/parport/Config.in
endmenu
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index faba5841b..2210d05d6 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -54,7 +54,7 @@ void __init amiga_init_sound(void)
}
static void nosound( unsigned long ignored );
-static struct timer_list sound_timer = { NULL, NULL, 0, 0, nosound };
+static struct timer_list sound_timer = { function: nosound };
void amiga_mksound( unsigned int hz, unsigned int ticks )
{
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index e3a628107..d46ba0852 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -128,8 +128,7 @@ static void dn_nosound (unsigned long ignored) {
void dn_mksound( unsigned int count, unsigned int ticks ) {
- static struct timer_list sound_timer = { NULL, NULL, 0, 0,
- dn_nosound };
+ static struct timer_list sound_timer = { function: dn_nosound };
del_timer( &sound_timer );
if(count) {
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index ebef991e9..d7a64faea 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -272,7 +272,7 @@ static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
static unsigned char rep_scancode;
-static struct timer_list atakeyb_rep_timer = { NULL, NULL, 0, 0, atakeyb_rep };
+static struct timer_list atakeyb_rep_timer = { function: atakeyb_rep };
static void atakeyb_rep( unsigned long ignore )
diff --git a/arch/m68k/atari/joystick.c b/arch/m68k/atari/joystick.c
index 2d20eb653..df41b38d8 100644
--- a/arch/m68k/atari/joystick.c
+++ b/arch/m68k/atari/joystick.c
@@ -13,6 +13,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/atarikb.h>
#include <asm/atari_joystick.h>
@@ -60,11 +61,13 @@ static int release_joystick(struct inode *inode, struct file *file)
{
int minor = DEVICE_NR(inode->i_rdev);
+ lock_kernel();
joystick[minor].active = 0;
joystick[minor].ready = 0;
if ((joystick[0].active == 0) && (joystick[1].active == 0))
ikbd_joystick_disable();
+ unlock_kernel();
return 0;
}
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index 4a244f851..263cdaff7 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
+#include <linux/smp_lock.h>
#include <asm/bvme6000hw.h>
#include <asm/io.h>
@@ -149,7 +150,9 @@ static int rtc_open(struct inode *inode, struct file *file)
static int rtc_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
rtc_status = 0;
+ unlock_kernel();
return 0;
}
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index bde3a370a..076d9107c 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -13,6 +13,15 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'Platform dependent setup'
define_bool CONFIG_ISA n
@@ -136,15 +145,6 @@ fi
endmenu
-mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
source drivers/mtd/Config.in
source drivers/block/Config.in
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index 557bcba27..2a05a013f 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -56,7 +56,7 @@ static void ( *mac_special_bell )( unsigned int, unsigned int, unsigned int ) =
/*
* our timer to start/continue/stop the bell
*/
-static struct timer_list mac_sound_timer = { NULL, NULL, 0, 0, mac_nosound };
+static struct timer_list mac_sound_timer = { function: mac_nosound };
/*
* Sort of initialize the sound chip (called from mac_mksound on the first
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index a47e4c634..677621629 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
+#include <linux/smp_lock.h>
#include <asm/mvme16xhw.h>
#include <asm/io.h>
@@ -138,7 +139,9 @@ static int rtc_open(struct inode *inode, struct file *file)
static int rtc_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
rtc_status = 0;
+ unlock_kernel();
return 0;
}
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index b91c51fe5..6f7cb0a88 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -1,6 +1,7 @@
/*
* Reset a Cobalt Qube.
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/io.h>
diff --git a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c
index 0e3987296..61fd5421b 100644
--- a/arch/mips64/sgi-ip27/ip27-rtc.c
+++ b/arch/mips64/sgi-ip27/ip27-rtc.c
@@ -34,6 +34,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
#include <asm/m48t35.h>
#include <asm/ioc3.h>
@@ -179,7 +180,9 @@ static int rtc_release(struct inode *inode, struct file *file)
* in use, and clear the data.
*/
+ lock_kernel();
rtc_status &= ~RTC_IS_OPEN;
+ unlock_kernel();
return 0;
}
diff --git a/arch/mips64/sgi-ip27/ip27-setup.c b/arch/mips64/sgi-ip27/ip27-setup.c
index fbd8d1fa7..1525855e8 100644
--- a/arch/mips64/sgi-ip27/ip27-setup.c
+++ b/arch/mips64/sgi-ip27/ip27-setup.c
@@ -26,7 +26,6 @@
#include <asm/pci/bridge.h>
#include <asm/paccess.h>
#include <asm/sn/sn0/ip27.h>
-#include <asm/sn/sn0/hubio.h>
/* Check against user dumbness. */
#ifdef CONFIG_VT
diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in
index 412b50338..090c09cb4 100644
--- a/arch/ppc/8xx_io/Config.in
+++ b/arch/ppc/8xx_io/Config.in
@@ -13,8 +13,16 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
fi
fi
bool '860T FEC Ethernet' CONFIG_FEC_ENET
- bool 'Use SMC2 for UART' CONFIG_8xxSMC2
- bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC
+ bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS
+fi
+bool 'Use SMC2 for UART' CONFIG_8xxSMC2
+if [ "$CONFIG_8xxSMC2" = "y" ]; then
+ bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2
+fi
+bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC
+
+if [ "$CONFIG_TQM860" = "y" -o "$CONFIG_TQM860L" = "y" -o "$CONFIG_TQM8xxL" = "y" ]; then
+ bool 'Use SMC2 for Console' TQM_SMC2_CONSOLE
fi
# This doesn't really belong here, but it is convenient to ask
diff --git a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h
index 7e7e9896d..7faae4ca3 100644
--- a/arch/ppc/8xx_io/commproc.h
+++ b/arch/ppc/8xx_io/commproc.h
@@ -191,7 +191,9 @@ typedef struct smc_centronics {
/* SMC Event and Mask register.
*/
-#define SMCM_TXE ((unsigned char)0x10)
+#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */
+#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */
+#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */
#define SMCM_BSY ((unsigned char)0x04)
#define SMCM_TX ((unsigned char)0x02)
#define SMCM_RX ((unsigned char)0x01)
@@ -457,6 +459,81 @@ typedef struct scc_enet {
#define SICR_ENET_CLKRT ((uint)0x0000003d)
#endif
+#if (defined(CONFIG_TQM860) || defined(CONFIG_TQM860L))
+/*
+ * TQM860 and TQM860L Configuration:
+ *
+ * Signal PAR DIR ODR DAT Function
+ * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet
+ * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet
+ * Port A, 14 1 0 - - TXD for Ethernet (SCC1)
+ * Port A, 15 1 0 - - RXD for Ethernet (SCC1)
+ * Port C, 7 0 0 0 - -> ETH-LOOP
+ * Port C, 10 0 0 1 - CD for Ethernet (SCC1)
+ * Port C, 11 0 0 1 - CTS for Ethernet (SCC1)
+ * Port C, 15 * * 0 - TENA/RTS for Ethernet
+ */
+
+#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */
+#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
+#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+
+#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */
+#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */
+#define PC_ENET_RENA ((ushort)0x0020) /* PC 10 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK ((uint)0x000000ff)
+#define SICR_ENET_CLKRT ((uint)0x00000026)
+
+#endif /* CONFIG_TQM860, TQM860L */
+
+#ifdef CONFIG_TQM8xxL
+/*
+ * TQM8xxL Configuration (except TQM860L):
+ *
+ * Signal PAR DIR ODR DAT Function
+ * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet
+ * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet
+ * Port A, 12 1 0 - - TXD for Ethernet (SCC2)
+ * Port A, 13 1 0 - - RXD for Ethernet (SCC2)
+ * Port B, 18 1 1 - - TENA/RTS for Ethernet on STK8xx
+ * Port C, 7 0 0 0 - -> ETH-LOOP
+ * Port C, 8 0 0 1 - CD for Ethernet (SCC2)
+ * Port C, 9 0 0 1 - CTS for Ethernet (SCC2)
+ * Port C, 14 * * 0 - TENA/RTS for Ethernet on FPS850
+ *
+ * Note: Using PC14 as RTS2 (TENA) does not work on the TQM850L when
+ * used with the starter-kit mainboard; we *must* use PB18 instead.
+ * For the FPS850 system, we *must* use PC14 :-(
+ */
+
+#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
+#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
+#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */
+#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */
+
+#ifndef CONFIG_FPS850 /* not valid on FPS board */
+#define PB_ENET_TENA ((uint)0x00002000)
+#endif /* !CONFIG_FPS850 */
+
+#ifdef CONFIG_FPS850 /* FPS uses default configuration */
+#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */
+#endif /* CONFIG_FPS850 */
+#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */
+#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */
+
+/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to
+ * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero.
+ */
+#define SICR_ENET_MASK ((uint)0x0000ff00)
+#define SICR_ENET_CLKRT ((uint)0x00002600)
+
+#endif /* CONFIG_TQM8xxL */
+
/* SCC Event register as used by Ethernet.
*/
#define SCCE_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 4d95bc9eb..730453bbb 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -73,40 +73,14 @@
* finished otherwise it sets the 'lp->tx_full' flag.
*
* The MBX has a control register external to the MPC8xx that has some
- * control of the Ethernet interface. Control Register 1 has the
- * following format:
- * bit 0 - Set to enable Ethernet transceiver
- * bit 1 - Set to enable Ethernet internal loopback
- * bit 2 - Set to auto select AUI or TP port
- * bit 3 - if bit 2 is 0, set to select TP port
- * bit 4 - Set to disable full duplex (loopback)
- * bit 5 - Set to disable XCVR collision test
- * bit 6, 7 - Used for RS-232 control.
+ * control of the Ethernet interface. Information is in the manual for
+ * your board.
*
- * EPPC-Bug sets this register to 0x98 for normal Ethernet operation,
- * so we should not have to touch it.
+ * The RPX boards have an external control/status register. Consult the
+ * programming documents for details unique to your board.
*
- * The following I/O is used by the MBX implementation of the MPC8xx to
- * the MC68160 transceiver. It DOES NOT exactly follow the cookbook
- * example from the MPC860 manual.
- * Port A, 15 - SCC1 Ethernet Rx
- * Port A, 14 - SCC1 Ethernet Tx
- * Port A, 6 (CLK2) - SCC1 Ethernet Tx Clk
- * Port A, 4 (CLK4) - SCC1 Ethernet Rx Clk
- * Port C, 15 - SCC1 Ethernet Tx Enable
- * Port C, 11 - SCC1 Ethernet Collision
- * Port C, 10 - SCC1 Ethernet Rx Enable
- *
- * The RPX-Lite (that I had :-), was the MPC850SAR. It has a control
- * register to enable Ethernet functions in the 68160, and the Ethernet
- * was controlled by SCC2. So, the pin I/O was like this:
- * Port A, 13 - SCC2 Ethernet Rx
- * Port A, 12 - SCC2 Ethernet Tx
- * Port A, 6 (CLK2) - Ethernet Tx Clk
- * Port A, 4 (CLK4) - Ethernet Rx Clk
- * Port B, 18 (RTS2) - Ethernet Tx Enable
- * Port C, 8 (CD2) - Ethernet Rx Enable
- * Port C, 9 (CTS2) - SCC Ethernet Collision
+ * For the TQM8xx(L) modules, there is no control register interface.
+ * All functions are directly controlled using I/O pins. See commproc.h.
*/
/* The transmitter timeout
@@ -119,12 +93,21 @@
* We don't need to allocate pages for the transmitter. We just use
* the skbuffer directly.
*/
+#ifdef CONFIG_ENET_BIG_BUFFERS
+#define CPM_ENET_RX_PAGES 32
+#define CPM_ENET_RX_FRSIZE 2048
+#define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE)
+#define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES)
+#define TX_RING_SIZE 64 /* Must be power of two */
+#define TX_RING_MOD_MASK 63 /* for this to work */
+#else
#define CPM_ENET_RX_PAGES 4
#define CPM_ENET_RX_FRSIZE 2048
#define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE)
#define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES)
#define TX_RING_SIZE 8 /* Must be power of two */
#define TX_RING_MOD_MASK 7 /* for this to work */
+#endif
/* The CPM stores dest/src/type, data, and checksum for receive packets.
*/
@@ -896,11 +879,16 @@ int __init scc_enet_init(void)
/* It is now OK to enable the Ethernet transmitter.
* Unfortunately, there are board implementation differences here.
*/
-#ifdef CONFIG_MBX
+#if (defined(CONFIG_MBX) || defined(CONFIG_TQM860) || defined(CONFIG_TQM860L) || defined(CONFIG_FPS850))
immap->im_ioport.iop_pcpar |= PC_ENET_TENA;
immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#endif
+#if (defined(CONFIG_TQM8xxL) && !defined(CONFIG_FPS850))
+ cp->cp_pbpar |= PB_ENET_TENA;
+ cp->cp_pbdir |= PB_ENET_TENA;
+#endif
+
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
cp->cp_pbpar |= PB_ENET_TENA;
cp->cp_pbdir |= PB_ENET_TENA;
@@ -928,6 +916,7 @@ int __init scc_enet_init(void)
immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif
+
dev->base_addr = (unsigned long)ep;
dev->priv = cep;
#if 0
diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c
index 00f4fa86c..b9f791832 100644
--- a/arch/ppc/8xx_io/uart.c
+++ b/arch/ppc/8xx_io/uart.c
@@ -41,8 +41,10 @@
#include <asm/8xx_immap.h>
#include <asm/mpc8xx.h>
#include "commproc.h"
-
+
#ifdef CONFIG_KGDB
+extern void breakpoint(void);
+extern void set_debug_traps(void);
extern int kgdb_output_string (const char* s, unsigned int count);
#endif
@@ -56,10 +58,17 @@ extern int kgdb_output_string (const char* s, unsigned int count);
#endif
#endif
+#if 0
+/* SCC2 for console
+*/
+#undef CONFIG_SERIAL_CONSOLE_PORT
+#define CONFIG_SERIAL_CONSOLE_PORT 2
+#endif
+
#define TX_WAKEUP ASYNC_SHARE_IRQ
static char *serial_name = "CPM UART driver";
-static char *serial_version = "0.02";
+static char *serial_version = "0.03";
static DECLARE_TASK_QUEUE(tq_serial);
@@ -89,54 +98,33 @@ static int serial_console_setup(struct console *co, char *options);
* needs. For example, the port address is the CPM parameter ram
* offset for the SCC or SMC. The maximum number of ports is 4 SCCs and
* 2 SMCs. The "hub6" field is used to indicate the channel number, with
- * 0 and 1 indicating the SMCs and 2, 3, 4, and 5 are the SCCs.
- * Since these ports are so versatile, I don't yet have a strategy for
- * their management. For example, SCC1 is used for Ethernet. Right
- * now, just don't put them in the table. Of course, right now I just
- * want the SMC to work as a uart :-)..
+ * a flag indicating SCC or SMC, and the number is used as an index into
+ * the CPM parameter area for this device.
* The "type" field is currently set to 0, for PORT_UNKNOWN. It is
* not currently used. I should probably use it to indicate the port
- * type of CMS or SCC.
+ * type of SMC or SCC.
* The SMCs do not support any modem control signals.
*/
#define smc_scc_num hub6
-
-#ifdef CONFIG_8xxSMC2
-/* SMC2 is sometimes used for low performance TDM interfaces. Define
- * this as 1 if you want SMC2 as a serial port UART managed by this driver.
- * Define this as 0 if you wish to use SMC2 for something else.
- */
-#define USE_SMC2 1
-#else
-#define USE_SMC2 0
-#endif
-
-/* Define SCC to ttySx mapping.
-*/
-#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */
-
-/* Define which SCC is the first one to use for a serial port. These
- * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used
- * for Ethernet, and the first available SCC for serial UART is SCC2.
- * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and
- * interrupt vectors in the table below to match.
- */
-#define SCC_IDX_BASE 1 /* table index */
+#define NUM_IS_SCC ((int)0x00010000)
+#define PORT_NUM(P) ((P) & 0x0000ffff)
/* Processors other than the 860 only get SMCs configured by default.
* Either they don't have SCCs or they are allocated somewhere else.
* Of course, there are now 860s without some SCCs, so we will need to
* address that someday.
+ * The Embedded Planet Multimedia I/O cards use TDM interfaces to the
+ * stereo codec parts, and we use SMC2 to help support that.
*/
static struct serial_state rs_table[] = {
/* UART CLK PORT IRQ FLAGS NUM */
{ 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */
-#if USE_SMC2
+#ifdef CONFIG_8xxSMC2
{ 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */
#endif
#ifdef CONFIG_8xxSCC
- { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, SCC_NUM_BASE}, /* SCC2 ttyS2 */
- { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, SCC_NUM_BASE + 1}, /* SCC3 ttyS3 */
+ { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */
+ { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */
#endif
};
@@ -245,13 +233,14 @@ static void rs_8xx_stop(struct tty_struct *tty)
return;
save_flags(flags); cli();
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
- smcp = &cpmp->cp_smc[idx];
- smcp->smc_smcm &= ~SMCM_TX;
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ sccp->scc_sccm &= ~UART_SCCM_TX;
}
else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- sccp->scc_sccm &= ~UART_SCCM_TX;
+ smcp = &cpmp->cp_smc[idx];
+ smcp->smc_smcm &= ~SMCM_TX;
}
restore_flags(flags);
}
@@ -267,14 +256,15 @@ static void rs_8xx_start(struct tty_struct *tty)
if (serial_paranoia_check(info, tty->device, "rs_stop"))
return;
+ idx = PORT_NUM(info->state->smc_scc_num);
save_flags(flags); cli();
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
- smcp = &cpmp->cp_smc[idx];
- smcp->smc_smcm |= SMCM_TX;
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ sccp->scc_sccm |= UART_SCCM_TX;
}
else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- sccp->scc_sccm |= UART_SCCM_TX;
+ smcp = &cpmp->cp_smc[idx];
+ smcp->smc_smcm |= SMCM_TX;
}
restore_flags(flags);
}
@@ -372,7 +362,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
icount->rx++;
#ifdef SERIAL_DEBUG_INTR
- printk("DR%02x:%02x...", ch, *status);
+ printk("DR%02x:%02x...", ch, status);
#endif
*tty->flip.flag_buf_ptr = 0;
if (status & (BD_SC_BR | BD_SC_FR |
@@ -452,10 +442,28 @@ static _INLINE_ void receive_chars(ser_info_t *info)
queue_task(&tty->flip.tqueue, &tq_timer);
}
+static _INLINE_ void receive_break(ser_info_t *info)
+{
+ struct tty_struct *tty = info->tty;
+
+ info->state->icount.brk++;
+ /* Check to see if there is room in the tty buffer for
+ * the break. If not, we exit now, losing the break. FIXME
+ */
+ if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE)
+ return;
+ *(tty->flip.flag_buf_ptr++) = TTY_BREAK;
+ *(tty->flip.char_buf_ptr++) = 0;
+ tty->flip.count++;
+
+ queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
static _INLINE_ void transmit_chars(ser_info_t *info)
{
- if (info->flags & TX_WAKEUP) {
+ if ((info->flags & TX_WAKEUP) ||
+ (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
}
@@ -549,24 +557,27 @@ static void rs_8xx_interrupt(void *dev_id)
info = (ser_info_t *)dev_id;
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ events = sccp->scc_scce;
+ if (events & SCCM_RX)
+ receive_chars(info);
+ if (events & SCCM_TX)
+ transmit_chars(info);
+ sccp->scc_scce = events;
+ }
+ else {
smcp = &cpmp->cp_smc[idx];
events = smcp->smc_smce;
+ if (events & SMCM_BRKE)
+ receive_break(info);
if (events & SMCM_RX)
receive_chars(info);
if (events & SMCM_TX)
transmit_chars(info);
smcp->smc_smce = events;
}
- else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- events = sccp->scc_scce;
- if (events & SCCM_RX)
- receive_chars(info);
- if (events & SCCM_TX)
- transmit_chars(info);
- sccp->scc_scce = events;
- }
#ifdef SERIAL_DEBUG_INTR
printk("rs_interrupt_single(%d, %x)...",
@@ -691,7 +702,16 @@ static int startup(ser_info_t *info)
*/
change_speed(info);
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ scup = (scc_uart_t *)&cpmp->cp_dparam[state->port];
+ scup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
+ scup->scc_maxidl = RX_BUF_SIZE;
+ sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX);
+ sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+ }
+ else {
smcp = &cpmp->cp_smc[idx];
/* Enable interrupts and I/O.
@@ -708,22 +728,10 @@ static int startup(ser_info_t *info)
* are coming.
*/
up = (smc_uart_t *)&cpmp->cp_dparam[state->port];
-
up->smc_mrblr = RX_BUF_SIZE;
up->smc_maxidl = RX_BUF_SIZE;
-
up->smc_brkcr = 1; /* number of break chars */
}
- else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- scup = (scc_uart_t *)&cpmp->cp_dparam[state->port];
-
- scup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
- scup->scc_maxidl = RX_BUF_SIZE;
-
- sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX);
- sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- }
info->flags |= ASYNC_INITIALIZED;
restore_flags(flags);
@@ -758,7 +766,19 @@ static void shutdown(ser_info_t * info)
save_flags(flags); cli(); /* Disable interrupts */
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(state->smc_scc_num);
+ if (state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#ifdef CONFIG_SERIAL_CONSOLE
+ /* We can't disable the transmitter if this is the
+ * system console.
+ */
+ if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT)
+#endif
+ sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+ }
+ else {
smcp = &cpmp->cp_smc[idx];
/* Disable interrupts and I/O.
@@ -768,15 +788,10 @@ static void shutdown(ser_info_t * info)
/* We can't disable the transmitter if this is the
* system console.
*/
- if (idx != CONFIG_SERIAL_CONSOLE_PORT)
+ if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT)
#endif
smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
}
- else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
- sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- }
if (info->tty)
set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -795,6 +810,7 @@ static void change_speed(ser_info_t *info)
unsigned cflag, cval, scval, prev_mode;
int i, bits, sbits, idx;
unsigned long flags;
+ struct serial_state *state;
volatile smc_t *smcp;
volatile scc_t *sccp;
@@ -802,6 +818,8 @@ static void change_speed(ser_info_t *info)
return;
cflag = info->tty->termios->c_cflag;
+ state = info->state;
+
/* Character length programmed into the mode register is the
* sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
* 1 or 2 stop bits, minus 1.
@@ -903,7 +921,12 @@ static void change_speed(ser_info_t *info)
* stops bits (there is always at least one).
*/
bits++;
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(state->smc_scc_num);
+ if (state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ sccp->scc_pmsr = (sbits << 12) | scval;
+ }
+ else {
smcp = &cpmp->cp_smc[idx];
/* Set the mode register. We want to keep a copy of the
@@ -914,12 +937,8 @@ static void change_speed(ser_info_t *info)
smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART;
smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
}
- else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- sccp->scc_pmsr = (sbits << 12) | scval;
- }
- m8xx_cpm_setbrg(info->state->smc_scc_num, baud_rate);
+ m8xx_cpm_setbrg((state - rs_table), baud_rate);
restore_flags(flags);
}
@@ -961,9 +980,9 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user,
volatile cbd_t *bdp;
#ifdef CONFIG_KGDB
- /* Try to let stub handle output. Returns true if it did. */
- if (kgdb_output_string(buf, count))
- return ret;
+ /* Try to let stub handle output. Returns true if it did. */
+ if (kgdb_output_string(buf, count))
+ return ret;
#endif
if (serial_paranoia_check(info, tty->device, "rs_write"))
@@ -986,8 +1005,7 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user,
}
if (from_user) {
- c -= copy_from_user(__va(bdp->cbd_bufaddr), buf, c);
- if (!c) {
+ if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
if (!ret)
ret = -EFAULT;
break;
@@ -1271,30 +1289,31 @@ static int set_modem_info(ser_info_t *info, unsigned int cmd,
* command. We take advantage of the begin/end functions to make this
* happen.
*/
+static ushort smc_chan_map[] = {
+ CPM_CR_CH_SMC1,
+ CPM_CR_CH_SMC2
+};
+
+static ushort scc_chan_map[] = {
+ CPM_CR_CH_SCC1,
+ CPM_CR_CH_SCC2,
+ CPM_CR_CH_SCC3,
+ CPM_CR_CH_SCC4
+};
+
static void begin_break(ser_info_t *info)
{
volatile cpm8xx_t *cp;
ushort chan;
- ushort num;
+ int idx;
cp = cpmp;
- if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) {
- if (num == 0)
- chan = CPM_CR_CH_SMC1;
- else
- chan = CPM_CR_CH_SMC2;
- }
- else {
- num -= SCC_NUM_BASE;
- switch (num) {
- case 0: chan = CPM_CR_CH_SCC1; break;
- case 1: chan = CPM_CR_CH_SCC2; break;
- case 2: chan = CPM_CR_CH_SCC3; break;
- case 3: chan = CPM_CR_CH_SCC4; break;
- default: return;
- }
- }
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC)
+ chan = scc_chan_map[idx];
+ else
+ chan = smc_chan_map[idx];
cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
}
@@ -1303,26 +1322,15 @@ static void end_break(ser_info_t *info)
{
volatile cpm8xx_t *cp;
ushort chan;
- ushort num;
+ int idx;
cp = cpmp;
- if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) {
- if (num == 0)
- chan = CPM_CR_CH_SMC1;
- else
- chan = CPM_CR_CH_SMC2;
- }
- else {
- num -= SCC_NUM_BASE;
- switch (num) {
- case 0: chan = CPM_CR_CH_SCC1; break;
- case 1: chan = CPM_CR_CH_SCC2; break;
- case 2: chan = CPM_CR_CH_SCC3; break;
- case 3: chan = CPM_CR_CH_SCC4; break;
- default: return;
- }
- }
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC)
+ chan = scc_chan_map[idx];
+ else
+ chan = smc_chan_map[idx];
cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
}
@@ -1623,16 +1631,17 @@ static void rs_8xx_close(struct tty_struct *tty, struct file * filp)
*/
info->read_status_mask &= ~BD_SC_EMPTY;
if (info->flags & ASYNC_INITIALIZED) {
- if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sccp = &cpmp->cp_scc[idx];
+ sccp->scc_sccm &= ~UART_SCCM_RX;
+ sccp->scc_gsmrl &= ~SCC_GSMRL_ENR;
+ }
+ else {
smcp = &cpmp->cp_smc[idx];
smcp->smc_smcm &= ~SMCM_RX;
smcp->smc_smcmr &= ~SMCMR_REN;
}
- else {
- sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE];
- sccp->scc_sccm &= ~UART_SCCM_RX;
- sccp->scc_gsmrl &= ~SCC_GSMRL_ENR;
- }
/*
* Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially
@@ -1713,7 +1722,18 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout)
break;
if (timeout && ((orig_jiffies + timeout) < jiffies))
break;
+
+ /* The 'tx_cur' is really the next buffer to send. We
+ * have to back up to the previous BD and wait for it
+ * to go. This isn't perfect, because all this indicates
+ * is the buffer is available. There are still characters
+ * in the CPM FIFO.
+ */
bdp = info->tx_cur;
+ if (bdp == info->tx_bd_base)
+ bdp += (TX_NUM_FIFO-1);
+ else
+ bdp--;
} while (bdp->cbd_sc & BD_SC_READY);
current->state = TASK_RUNNING;
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
@@ -1803,7 +1823,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR)) ||
- (info->state->smc_scc_num < SCC_NUM_BASE)) {
+ !(info->state->smc_scc_num & NUM_IS_SCC)) {
if (info->flags & ASYNC_CALLOUT_ACTIVE)
return -EBUSY;
info->flags |= ASYNC_NORMAL_ACTIVE;
@@ -1981,8 +2001,8 @@ static int inline line_info(char *buf, struct serial_state *state)
ret = sprintf(buf, "%d: uart:%s port:%X irq:%d",
state->line,
- (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC",
- state->port, state->irq);
+ (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC",
+ (unsigned int)(state->port), state->irq);
if (!state->port || (state->type == PORT_UNKNOWN)) {
ret += sprintf(buf+ret, "\n");
@@ -2070,7 +2090,7 @@ int rs_8xx_read_proc(char *page, char **start, off_t off, int count,
done:
if (off >= len+begin)
return 0;
- *start = page + (off-begin);
+ *start = page + (begin-off);
return ((count < begin+len-off) ? count : begin+len-off);
}
@@ -2229,7 +2249,7 @@ putDebugChar(char ch)
/*
* Receive character from the serial port. This only works well
- * before the port is initialize for real use.
+ * before the port is initialized for real use.
*/
static int my_console_wait_key(int idx, int xmon, char *obuf)
{
@@ -2350,7 +2370,7 @@ void kgdb_map_scc(void)
/* To avoid data cache CPM DMA coherency problems, allocate a
* buffer in the CPM DPRAM. This will work until the CPM and
* serial ports are initialized. At that time a memory buffer
- * will be allcoated.
+ * will be allocated.
* The port is already initialized from the boot procedure, all
* we do here is give it a different buffer and make it a FIFO.
*/
@@ -2382,7 +2402,7 @@ void kgdb_map_scc(void)
static kdev_t serial_console_device(struct console *c)
{
- return MKDEV(TTYAUX_MAJOR, 64 + c->index);
+ return MKDEV(TTY_MAJOR, 64 + c->index);
}
@@ -2411,12 +2431,9 @@ long __init console_8xx_init(long kmem_start, long kmem_end)
#endif
-/* This will be used for all boards when the MBX board information
- * is modified to include a default baud rate.
- */
-#ifndef CONFIG_MBX
+/* Index in baud rate table of the default console baud rate.
+*/
static int baud_idx;
-#endif
/*
* The serial driver boot-time initialization code!
@@ -2425,7 +2442,7 @@ int __init rs_8xx_init(void)
{
struct serial_state * state;
ser_info_t *info;
- uint mem_addr, dp_addr;
+ uint mem_addr, dp_addr, iobits;
int i, j, idx;
ushort chan;
volatile cbd_t *bdp;
@@ -2442,7 +2459,6 @@ int __init rs_8xx_init(void)
/* Initialize the tty_driver structure */
- /*memset(&serial_driver, 0, sizeof(struct tty_driver));*/
__clear_user(&serial_driver,sizeof(struct tty_driver));
serial_driver.magic = TTY_DRIVER_MAGIC;
serial_driver.driver_name = "serial";
@@ -2454,11 +2470,7 @@ int __init rs_8xx_init(void)
serial_driver.subtype = SERIAL_TYPE_NORMAL;
serial_driver.init_termios = tty_std_termios;
serial_driver.init_termios.c_cflag =
-#ifndef CONFIG_MBX
baud_idx | CS8 | CREAD | HUPCL | CLOCAL;
-#else
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-#endif
serial_driver.flags = TTY_DRIVER_REAL_RAW;
serial_driver.refcount = &serial_refcount;
serial_driver.table = serial_table;
@@ -2502,29 +2514,16 @@ int __init rs_8xx_init(void)
cp = cpmp; /* Get pointer to Communication Processor */
immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
- /* Configure SMCs Tx/Rx instead of port B parallel I/O.
- */
-#if USE_SMC2
- cp->cp_pbpar |= 0x00000cc0;
- cp->cp_pbdir &= ~0x00000cc0;
- cp->cp_pbodr &= ~0x00000cc0;
-#else
- /* This will only enable SMC1 if you want SMC2 for something else.
- */
- cp->cp_pbpar |= 0x000000c0;
- cp->cp_pbdir &= ~0x000000c0;
- cp->cp_pbodr &= ~0x000000c0;
-#endif
- /* Configure SCC2 and SCC3 instead of port A parallel I/O.
+ /* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O.
*/
-#if defined(CONFIG_MPC860) || defined(CONFIG_MPC860T)
+#ifdef CONFIG_8xxSCC
#ifndef CONFIG_MBX
/* The "standard" configuration through the 860.
*/
- immap->im_ioport.iop_papar |= 0x003c;
- immap->im_ioport.iop_padir &= ~0x003c;
- immap->im_ioport.iop_paodr &= ~0x003c;
+ immap->im_ioport.iop_papar |= 0x00fc;
+ immap->im_ioport.iop_padir &= ~0x00fc;
+ immap->im_ioport.iop_paodr &= ~0x00fc;
#else
/* On the MBX, SCC3 is through Port D.
*/
@@ -2547,11 +2546,21 @@ int __init rs_8xx_init(void)
*/
cp->cp_sicr &= ~0x00ffff00;
cp->cp_sicr |= 0x001b1200;
-#endif
- /* Wire BRG1 to SMC1 and BRG2 to SMC2.
+#ifdef CONFIG_PP04
+ /* Frequentis PP04 forced to RS-232 until we know better.
+ * Port C 12 and 13 low enables RS-232 on SCC3 and SCC4.
+ */
+ immap->im_ioport.iop_pcdir |= 0x000c;
+ immap->im_ioport.iop_pcpar &= ~0x000c;
+ immap->im_ioport.iop_pcdat &= ~0x000c;
+
+ /* This enables the TX driver.
*/
- cp->cp_simode = 0x10000000;
+ cp->cp_pbpar &= ~0x6000;
+ cp->cp_pbdat &= ~0x6000;
+#endif
+#endif
for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
state->magic = SSTATE_MAGIC;
@@ -2568,8 +2577,8 @@ int __init rs_8xx_init(void)
state->icount.frame = state->icount.parity = 0;
state->icount.overrun = state->icount.brk = 0;
printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n",
- i, state->port,
- (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC");
+ i, (unsigned int)(state->port),
+ (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC");
#ifdef CONFIG_SERIAL_CONSOLE
/* If we just printed the message on the console port, and
* we are about to initialize it for general use, we have
@@ -2581,7 +2590,6 @@ int __init rs_8xx_init(void)
#endif
info = kmalloc(sizeof(ser_info_t), GFP_KERNEL);
if (info) {
- /*memset(info, 0, sizeof(ser_info_t));*/
__clear_user(info,sizeof(ser_info_t));
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
@@ -2621,16 +2629,17 @@ int __init rs_8xx_init(void)
bdp->cbd_bufaddr = __pa(mem_addr);
bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
- if ((idx = state->smc_scc_num) < SCC_NUM_BASE) {
+ idx = PORT_NUM(info->state->smc_scc_num);
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ scp = &cp->cp_scc[idx];
+ sup = (scc_uart_t *)&cp->cp_dparam[state->port];
+ sup->scc_genscc.scc_rbase = dp_addr;
+ }
+ else {
sp = &cp->cp_smc[idx];
up = (smc_uart_t *)&cp->cp_dparam[state->port];
up->smc_rbase = dp_addr;
}
- else {
- scp = &cp->cp_scc[idx - SCC_IDX_BASE];
- sup = (scc_uart_t *)&cp->cp_dparam[state->port];
- sup->scc_genscc.scc_rbase = dp_addr;
- }
dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO);
@@ -2654,56 +2663,21 @@ int __init rs_8xx_init(void)
bdp->cbd_bufaddr = __pa(mem_addr);
bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
- if (idx < SCC_NUM_BASE) {
- up->smc_tbase = dp_addr;
+ if (info->state->smc_scc_num & NUM_IS_SCC) {
+ sup->scc_genscc.scc_tbase = dp_addr;
/* Set up the uart parameters in the
* parameter ram.
*/
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
+ sup->scc_genscc.scc_rfcr = SMC_EB;
+ sup->scc_genscc.scc_tfcr = SMC_EB;
/* Set this to 1 for now, so we get single
* character interrupts. Using idle charater
* time requires some additional tuning.
*/
- up->smc_mrblr = RX_BUF_SIZE;
- up->smc_maxidl = RX_BUF_SIZE;
- up->smc_brkcr = 1;
-
- /* Send the CPM an initialize command.
- */
- if (state->smc_scc_num == 0)
- chan = CPM_CR_CH_SMC1;
- else
- chan = CPM_CR_CH_SMC2;
-
- cp->cp_cpcr = mk_cr_cmd(chan,
- CPM_CR_INIT_TRX) | CPM_CR_FLG;
- while (cp->cp_cpcr & CPM_CR_FLG);
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
-
- /* Disable all interrupts and clear all pending
- * events.
- */
- sp->smc_smcm = 0;
- sp->smc_smce = 0xff;
- }
- else {
- sup->scc_genscc.scc_tbase = dp_addr;
-
- /* Set up the uart parameters in the
- * parameter ram.
- */
- sup->scc_genscc.scc_rfcr = SMC_EB;
- sup->scc_genscc.scc_tfcr = SMC_EB;
-
- sup->scc_genscc.scc_mrblr = RX_BUF_SIZE;
- sup->scc_maxidl = RX_BUF_SIZE;
+ sup->scc_genscc.scc_mrblr = 1;
+ sup->scc_maxidl = 0;
sup->scc_brkcr = 1;
sup->scc_parec = 0;
sup->scc_frmec = 0;
@@ -2724,10 +2698,7 @@ int __init rs_8xx_init(void)
/* Send the CPM an initialize command.
*/
- if (state->smc_scc_num == 2)
- chan = CPM_CR_CH_SCC2;
- else
- chan = CPM_CR_CH_SCC3;
+ chan = scc_chan_map[idx];
cp->cp_cpcr = mk_cr_cmd(chan,
CPM_CR_INIT_TRX) | CPM_CR_FLG;
@@ -2747,6 +2718,91 @@ int __init rs_8xx_init(void)
scp->scc_scce = 0xffff;
scp->scc_dsr = 0x7e7e;
scp->scc_pmsr = 0x3000;
+
+ /* If the port is the console, enable Rx and Tx.
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (i == CONFIG_SERIAL_CONSOLE_PORT)
+ scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+ }
+ else {
+ /* Configure SMCs Tx/Rx instead of port B
+ * parallel I/O. On 823/850 these are on
+ * port A for SMC2.
+ */
+#ifndef CONFIG_8xx_ALTSMC2
+ iobits = 0xc0 << (idx * 4);
+ cp->cp_pbpar |= iobits;
+ cp->cp_pbdir &= ~iobits;
+ cp->cp_pbodr &= ~iobits;
+#else
+ if (idx == 0) {
+ /* SMC1 on Port B, like all 8xx.
+ */
+ iobits = 0xc0;
+ cp->cp_pbpar |= iobits;
+ cp->cp_pbdir &= ~iobits;
+ cp->cp_pbodr &= ~iobits;
+ }
+ else {
+ /* SMC2 is on Port A.
+ */
+ iobits = 0x300;
+ immap->im_ioport.iop_papar |= iobits;
+ immap->im_ioport.iop_padir &= ~iobits;
+ immap->im_ioport.iop_paodr &= ~iobits;
+ }
+#endif
+
+ /* Connect the baud rate generator to the
+ * SMC based upon index in rs_table. Also
+ * make sure it is connected to NMSI.
+ */
+ cp->cp_simode &= ~(0xffff << (idx * 16));
+ cp->cp_simode |= (i << ((idx * 16) + 12));
+
+ up->smc_tbase = dp_addr;
+
+ /* Set up the uart parameters in the
+ * parameter ram.
+ */
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+ /* Set this to 1 for now, so we get single
+ * character interrupts. Using idle charater
+ * time requires some additional tuning.
+ */
+ up->smc_mrblr = 1;
+ up->smc_maxidl = 0;
+ up->smc_brkcr = 1;
+
+ /* Send the CPM an initialize command.
+ */
+ chan = smc_chan_map[idx];
+
+ cp->cp_cpcr = mk_cr_cmd(chan,
+ CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+ /* Disable all interrupts and clear all pending
+ * events.
+ */
+ sp->smc_smcm = 0;
+ sp->smc_smce = 0xff;
+
+ /* If the port is the console, enable Rx and Tx.
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (i == CONFIG_SERIAL_CONSOLE_PORT)
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
}
/* Install interrupt handler.
@@ -2755,19 +2811,8 @@ int __init rs_8xx_init(void)
/* Set up the baud rate generator.
*/
-#ifndef CONFIG_MBX
- m8xx_cpm_setbrg(state->smc_scc_num,
- baud_table[baud_idx]);
-#else
- m8xx_cpm_setbrg(state->smc_scc_num, 9600);
-#endif
+ m8xx_cpm_setbrg(i, baud_table[baud_idx]);
- /* If the port is the console, enable Rx and Tx.
- */
-#ifdef CONFIG_SERIAL_CONSOLE
- if (i == CONFIG_SERIAL_CONSOLE_PORT)
- sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
-#endif
}
}
@@ -2780,13 +2825,14 @@ int __init rs_8xx_init(void)
static int __init serial_console_setup(struct console *co, char *options)
{
struct serial_state *ser;
- uint mem_addr, dp_addr, bidx;
+ uint mem_addr, dp_addr, bidx, idx;
+ ushort chan;
volatile cbd_t *bdp;
volatile cpm8xx_t *cp;
volatile smc_t *sp;
+ volatile scc_t *scp;
volatile smc_uart_t *up;
-
-#ifndef CONFIG_MBX
+ volatile scc_uart_t *sup;
bd_t *bd;
bd = (bd_t *)__res;
@@ -2797,40 +2843,41 @@ static int __init serial_console_setup(struct console *co, char *options)
co->cflag = CREAD|CLOCAL|bidx|CS8;
baud_idx = bidx;
-#else
- co->cflag = CREAD|CLOCAL|B9600|CS8;
-#endif
ser = rs_table + co->index;
cp = cpmp; /* Get pointer to Communication Processor */
- /* Right now, assume we are using SMCs.
- */
- sp = &cp->cp_smc[ser->smc_scc_num];
+ idx = PORT_NUM(ser->smc_scc_num);
+ if (ser->smc_scc_num & NUM_IS_SCC) {
+ scp = &cp->cp_scc[idx];
+ sup = (scc_uart_t *)&cp->cp_dparam[ser->port];
+ }
+ else {
+ sp = &cp->cp_smc[idx];
+ up = (smc_uart_t *)&cpmp->cp_dparam[ser->port];
+ }
+
/* When we get here, the CPM has been reset, so we need
* to configure the port.
* We need to allocate a transmit and receive buffer descriptor
* from dual port ram, and a character buffer area from host mem.
*/
- up = (smc_uart_t *)&cp->cp_dparam[ser->port];
- cp->cp_pbpar = 0x00c0; /* Enable SMC1 instead of Port B I/O */
/* Allocate space for two buffer descriptors in the DP ram.
*/
dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2);
- /* Allocate space for an input FIFO, plus a few bytes for output.
- * Allocate bytes to maintain word alignment.
- */
- mem_addr = m8xx_cpm_hostalloc(RX_BUF_SIZE + 4);
+ /* Allocate space for two 2 byte FIFOs in the host memory.
+ */
+ mem_addr = m8xx_cpm_hostalloc(8);
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
bdp->cbd_bufaddr = __pa(mem_addr);
- (bdp+1)->cbd_bufaddr = __pa(mem_addr+RX_BUF_SIZE);
+ (bdp+1)->cbd_bufaddr = __pa(mem_addr+4);
/* For the receive, set empty and wrap.
* For transmit, set wrap.
@@ -2840,39 +2887,98 @@ static int __init serial_console_setup(struct console *co, char *options)
/* Set up the uart parameters in the parameter ram.
*/
- up->smc_rbase = dp_addr; /* Base of receive buffer desc. */
- up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */
- up->smc_rfcr = SMC_EB;
- up->smc_tfcr = SMC_EB;
+ if (ser->smc_scc_num & NUM_IS_SCC) {
- up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */
- up->smc_maxidl = RX_BUF_SIZE;
+ sup->scc_genscc.scc_rbase = dp_addr;
+ sup->scc_genscc.scc_tbase = dp_addr + sizeof(cbd_t);
- /* Send the CPM an initialize command.
- */
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG;
- /*
- * delay for a bit - this is necessary on my board!
- * -- Cort
- */
- printk("");
- while (cp->cp_cpcr & CPM_CR_FLG);
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
- */
- sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+ /* Set up the uart parameters in the
+ * parameter ram.
+ */
+ sup->scc_genscc.scc_rfcr = SMC_EB;
+ sup->scc_genscc.scc_tfcr = SMC_EB;
- /* Set up the baud rate generator.
- */
-#ifndef CONFIG_MBX
- m8xx_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate);
-#else
- m8xx_cpm_setbrg(ser->smc_scc_num, 9600);
-#endif
+ /* Set this to 1 for now, so we get single
+ * character interrupts. Using idle charater
+ * time requires some additional tuning.
+ */
+ sup->scc_genscc.scc_mrblr = 1;
+ sup->scc_maxidl = 0;
+ sup->scc_brkcr = 1;
+ sup->scc_parec = 0;
+ sup->scc_frmec = 0;
+ sup->scc_nosec = 0;
+ sup->scc_brkec = 0;
+ sup->scc_uaddr1 = 0;
+ sup->scc_uaddr2 = 0;
+ sup->scc_toseq = 0;
+ sup->scc_char1 = 0x8000;
+ sup->scc_char2 = 0x8000;
+ sup->scc_char3 = 0x8000;
+ sup->scc_char4 = 0x8000;
+ sup->scc_char5 = 0x8000;
+ sup->scc_char6 = 0x8000;
+ sup->scc_char7 = 0x8000;
+ sup->scc_char8 = 0x8000;
+ sup->scc_rccm = 0xc0ff;
+
+ /* Send the CPM an initialize command.
+ */
+ chan = scc_chan_map[idx];
+
+ cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ scp->scc_gsmrh = 0;
+ scp->scc_gsmrl =
+ (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+ /* Disable all interrupts and clear all pending
+ * events.
+ */
+ scp->scc_sccm = 0;
+ scp->scc_scce = 0xffff;
+ scp->scc_dsr = 0x7e7e;
+ scp->scc_pmsr = 0x3000;
+
+ scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+ }
+ else {
+ up->smc_rbase = dp_addr; /* Base of receive buffer desc. */
+ up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */
+ up->smc_rfcr = SMC_EB;
+ up->smc_tfcr = SMC_EB;
+
+ /* Set this to 1 for now, so we get single character interrupts.
+ */
+ up->smc_mrblr = 1; /* receive buffer length */
+ up->smc_maxidl = 0; /* wait forever for next char */
- /* And finally, enable Rx and Tx.
+ /* Send the CPM an initialize command.
+ */
+ chan = smc_chan_map[idx];
+ cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ printk("");
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* Set UART mode, 8 bit, no parity, one stop.
+ * Enable receive and transmit.
+ */
+ sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART;
+
+ /* And finally, enable Rx and Tx.
+ */
+ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+ }
+
+ /* Set up the baud rate generator.
*/
- sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+ m8xx_cpm_setbrg((ser - rs_table), bd->bi_baudrate);
return 0;
}
+
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index c8541965d..23afda4a8 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -42,7 +42,7 @@ znetboot: vmlinux.coff vmlinux.elf zImage
cp vmlinux.coff $(TFTPIMAGE)
cp vmlinux.elf $(TFTPIMAGE).elf
-znetboot.initrd: vmlinux.coff.initrd
+znetboot.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
cp vmlinux.coff.initrd $(TFTPIMAGE)
cp vmlinux.elf.initrd $(TFTPIMAGE).elf
@@ -81,7 +81,7 @@ vmlinux.coff: coffboot hack-coff
ln -sf vmlinux.coff zImage
vmlinux.coff.initrd: coffboot.initrd hack-coff
- $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
+ $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd $@
./hack-coff $@
vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 33f6eaa95..3e0721cb4 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -12,17 +12,28 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'Platform support'
define_bool CONFIG_PPC y
choice 'Processor Type' \
"6xx/7xx/7400 CONFIG_6xx \
4xx CONFIG_4xx \
- POWER3/POWER4(64-Bit) CONFIG_PPC64BRIDGE \
+ POWER3 CONFIG_POWER3 \
+ POWER4 CONFIG_POWER4 \
8260 CONFIG_8260 \
8xx CONFIG_8xx" 6xx
-if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then
- bool 'Power 4 support' CONFIG_POWER4
+if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then
+ define_bool CONFIG_PPC64BRIDGE y
+ define_bool CONFIG_ALL_PPC y
fi
if [ "$CONFIG_8260" = "y" ]; then
@@ -43,6 +54,9 @@ if [ "$CONFIG_8xx" = "y" ]; then
"RPX-Lite CONFIG_RPXLITE \
RPX-Classic CONFIG_RPXCLASSIC \
BSE-IP CONFIG_BSEIP \
+ TQM8xxL CONFIG_TQM8xxL \
+ TQM860L CONFIG_TQM860L \
+ TQM860 CONFIG_TQM860 \
MBX CONFIG_MBX \
WinCept CONFIG_WINCEPT" RPX-Lite
fi
@@ -54,14 +68,14 @@ if [ "$CONFIG_6xx" = "y" ]; then
APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP
fi
-if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then
- define_bool CONFIG_ALL_PPC y
-fi
-
if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
define_bool CONFIG_ALL_PPC n
fi
+if [ "$CONFIG_TQM8xxL" = "y" ]; then
+ bool 'FPS850 Mainboard' CONFIG_FPS850
+fi
+
bool 'Symmetric multi-processing support' CONFIG_SMP
if [ "$CONFIG_6xx" = "y" ];then
bool 'AltiVec Support' CONFIG_ALTIVEC
@@ -77,15 +91,6 @@ fi
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
- bool ' Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_ISA n
@@ -149,6 +154,7 @@ if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
bool 'Support for ADB keyboard' CONFIG_ADB_KEYBOARD
bool 'Support for ADB mouse' CONFIG_ADBMOUSE
fi
+ tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT
bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 501ed931a..0369ad800 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -99,7 +99,8 @@ endif
ifeq ($(CONFIG_ALL_PPC),y)
O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o \
chrp_setup.o chrp_time.o chrp_pci.o open_pic.o indirect_pci.o \
- prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o
+ prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o \
+ pmac_backlight.o
OX_OBJS += prep_setup.o
endif
ifeq ($(CONFIG_GEMINI),y)
diff --git a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c
index fb5a19e3a..69e07057a 100644
--- a/arch/ppc/kernel/bitops.c
+++ b/arch/ppc/kernel/bitops.c
@@ -6,60 +6,58 @@
#include <asm/bitops.h>
/*
- * I left these here since the problems with "cc" make it difficult to keep
- * them in bitops.h -- Cort
+ * If the bitops are not inlined in bitops.h, they are defined here.
+ * -- paulus
*/
-void set_bit(int nr, volatile void *addr)
+#if !__INLINE_BITOPS
+void set_bit(int nr, volatile void * addr)
{
- unsigned int t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
-
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "set_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%2
- or %0,%0,%1
- stwcx. %0,0,%2
+ unsigned long old;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%3
+ or %0,%0,%2
+ stwcx. %0,0,%3
bne 1b"
- : "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
- : "cc");
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
+ : "cc" );
}
void clear_bit(int nr, volatile void *addr)
{
- unsigned int t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
+ unsigned long old;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "clear_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%2
- andc %0,%0,%1
- stwcx. %0,0,%2
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%3
+ andc %0,%0,%2
+ stwcx. %0,0,%3
bne 1b"
- : "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
: "cc");
}
void change_bit(int nr, volatile void *addr)
{
- unsigned int t;
- unsigned int mask = 1 << (nr & 0x1f);
- volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
+ unsigned long old;
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "change_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%2
- xor %0,%0,%1
- stwcx. %0,0,%2
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%3
+ xor %0,%0,%2
+ stwcx. %0,0,%3
bne 1b"
- : "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
+ SMP_MB
+ : "=&r" (old), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
: "cc");
}
@@ -69,15 +67,14 @@ int test_and_set_bit(int nr, volatile void *addr)
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "test_and_set_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3
- or %1,%0,%2
- stwcx. %1,0,%3
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ or %1,%0,%3
+ stwcx. %1,0,%4
bne 1b"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
: "cc");
return (old & mask) != 0;
@@ -89,15 +86,14 @@ int test_and_clear_bit(int nr, volatile void *addr)
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "test_and_clear_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3
- andc %1,%0,%2
- stwcx. %1,0,%3
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ andc %1,%0,%3
+ stwcx. %1,0,%4
bne 1b"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
: "cc");
return (old & mask) != 0;
@@ -109,93 +105,16 @@ int test_and_change_bit(int nr, volatile void *addr)
unsigned int mask = 1 << (nr & 0x1f);
volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
- if ((unsigned long)addr & 3)
- printk(KERN_ERR "test_and_change_bit(%x, %p)\n", nr, addr);
- __asm__ __volatile__("\n\
-1: lwarx %0,0,%3
- xor %1,%0,%2
- stwcx. %1,0,%3
+ __asm__ __volatile__(SMP_WMB "\
+1: lwarx %0,0,%4
+ xor %1,%0,%3
+ stwcx. %1,0,%4
bne 1b"
- : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/
- : "r" (mask), "r" (p)
+ SMP_MB
+ : "=&r" (old), "=&r" (t), "=m" (*p)
+ : "r" (mask), "r" (p), "m" (*p)
: "cc");
return (old & mask) != 0;
}
-
-/* I put it in bitops.h -- Cort */
-#if 0
-int ffz(unsigned int x)
-{
- int n;
-
- x = ~x & (x+1); /* set LS zero to 1, other bits to 0 */
- __asm__ ("cntlzw %0,%1" : "=r" (n) : "r" (x));
- return 31 - n;
-}
-
-/*
- * This implementation of find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h.
- */
-
-int find_first_zero_bit(void * addr, int size)
-{
- unsigned int * p = ((unsigned int *) addr);
- unsigned int result = 0;
- unsigned int tmp;
-
- if (size == 0)
- return 0;
- while (size & ~31UL) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = *p;
- tmp |= ~0UL << size;
-found_middle:
- return result + ffz(tmp);
-}
-
-/*
- * Find next zero bit in a bitmap reasonably efficiently..
- */
-int find_next_zero_bit(void * addr, int size, int offset)
-{
- unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
- unsigned int result = offset & ~31UL;
- unsigned int tmp;
-
- if (offset >= size)
- return size;
- size -= result;
- offset &= 31UL;
- if (offset) {
- tmp = *(p++);
- tmp |= ~0UL >> (32-offset);
- if (size < 32)
- goto found_first;
- if (~tmp)
- goto found_middle;
- size -= 32;
- result += 32;
- }
- while (size & ~31UL) {
- if (~(tmp = *(p++)))
- goto found_middle;
- result += 32;
- size -= 32;
- }
- if (!size)
- return result;
- tmp = *p;
-found_first:
- tmp |= ~0UL << size;
-found_middle:
- return result + ffz(tmp);
-}
-#endif
+#endif /* !__INLINE_BITOPS */
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index 0d614fba1..c43296c42 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -288,7 +288,9 @@ void __init
chrp_pcibios_fixup(void)
{
struct pci_dev *dev;
+#ifdef CONFIG_POWER4
int i;
+#endif
int *brp;
struct device_node *np;
extern struct pci_ops generic_pci_ops;
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index d75ccaf5c..8d6649231 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -51,7 +51,7 @@
#include <asm/keyboard.h>
#include <asm/init.h>
-#include "time.h"
+#include <asm/time.h>
#include "local_irq.h"
#include "i8259.h"
#include "open_pic.h"
diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c
index 6d275e517..54b4a76bb 100644
--- a/arch/ppc/kernel/chrp_time.c
+++ b/arch/ppc/kernel/chrp_time.c
@@ -26,7 +26,7 @@
#include <asm/nvram.h>
#include <asm/prom.h>
#include <asm/init.h>
-#include "time.h"
+#include <asm/time.h>
static int nvram_as1 = NVRAM_AS1;
static int nvram_as0 = NVRAM_AS0;
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 354686c2d..8ccb0f571 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -5,8 +5,8 @@
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
+ * Copyright (C) 1996 Cort Dougan <cort@fsmlabs.com>
* Adapted for Power Macintosh by Paul Mackerras.
* Low-level exception handlers and MMU support
* rewritten by Paul Mackerras.
@@ -83,7 +83,9 @@ _GLOBAL(DoSyscall)
#endif /* SHOW_SYSCALLS */
cmpi 0,r0,0x7777 /* Special case for 'sys_sigreturn' */
beq- 10f
- lwz r10,TASK_PTRACE(r2)
+ cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */
+ beq- 16f
+ lwz r10,TASK_FLAGS(r2)
andi. r10,r10,PT_TRACESYS
bne- 50f
cmpli 0,r0,NR_syscalls
@@ -129,6 +131,12 @@ ret_from_syscall_1:
/* sys_sigreturn */
10: addi r3,r1,STACK_FRAME_OVERHEAD
bl sys_sigreturn
+ cmpi 0,r3,0 /* Check for restarted system call */
+ bge ret_from_except
+ b 20b
+/* sys_rt_sigreturn */
+16: addi r3,r1,STACK_FRAME_OVERHEAD
+ bl sys_rt_sigreturn
cmpi 0,r3,0 /* Check for restarted system call */
bge ret_from_except
b 20b
diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c
index e47befdd3..4b63d5dc0 100644
--- a/arch/ppc/kernel/feature.c
+++ b/arch/ppc/kernel/feature.c
@@ -2,6 +2,7 @@
* arch/ppc/kernel/feature.c
*
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
+ * Ben. Herrenschmidt (bh40@calva.net)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,7 +31,7 @@
#undef DEBUG_FEATURE
#define MAX_FEATURE_CONTROLLERS 2
-#define MAX_FEATURE_OFFSET 0x50
+#define MAX_FEATURE_OFFSET 0x100
#define FREG(c,r) (&(((c)->reg)[(r)>>2]))
typedef struct feature_bit {
@@ -70,6 +71,7 @@ static fbit feature_bits_ohare_pbook[] = {
{0x38,0,0}, /* FEATURE_IDE2_reset */
{0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */
{0x38,0,0}, /* FEATURE_Mediabay_content */
+ {0x38,0,0}, /* FEATURE_Airport_reset */
};
/* Those bits are from a PowerBook. It's possible that desktop machines
@@ -102,6 +104,7 @@ static fbit feature_bits_heathrow[] = {
{0x38,0,0}, /* FEATURE_IDE2_reset */
{0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */
{0x38,0,0}, /* FEATURE_Mediabay_content */
+ {0x38,0,0}, /* FEATURE_Airport_reset */
};
/*
@@ -135,6 +138,7 @@ static fbit feature_bits_paddington[] = {
{0x38,0,0}, /* FEATURE_IDE2_reset */
{0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */
{0x38,0,0}, /* FEATURE_Mediabay_content */
+ {0x38,0,0}, /* FEATURE_Airport_reset */
};
/* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...).
@@ -166,6 +170,7 @@ static fbit feature_bits_keylargo[] = {
{0x3c,1,0x40000000}, /* FEATURE_IDE2_reset */
{0x34,0,0x00001000}, /* FEATURE_Mediabay_IDE_switch */
{0x34,0,0x00000100}, /* FEATURE_Mediabay_content */
+ {0x40,1,0x08000000}, /* FEATURE_Airport_reset */
};
/* definition of a feature controller object */
@@ -177,22 +182,33 @@ struct feature_controller {
};
/* static functions */
-static void
+static struct feature_controller*
feature_add_controller(struct device_node *controller_device, fbit* bits);
static struct feature_controller*
feature_lookup_controller(struct device_node *device);
-/* static varialbles */
+static void heathrow_prepare_for_sleep(struct feature_controller* ctrler);
+static void heathrow_wakeup(struct feature_controller* ctrler);
+static void core99_prepare_for_sleep(struct feature_controller* ctrler);
+static void core99_wake_up(struct feature_controller* ctrler);
+
+/* static variables */
static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS];
static int controller_count = 0;
+/* Core99 stuffs */
+static volatile u32* uninorth_base = NULL;
+static volatile u32* keylargo_base = NULL;
+static int uninorth_rev;
+static int keylargo_rev;
void
feature_init(void)
{
struct device_node *np;
-
+ u32 *rev;
+
if (_machine != _MACH_Pmac)
return;
@@ -202,7 +218,14 @@ feature_init(void)
* plus some gpio's which could eventually be handled here.
*/
if (device_is_compatible(np, "Keylargo")) {
- feature_add_controller(np, feature_bits_keylargo);
+ struct feature_controller* ctrler =
+ feature_add_controller(np, feature_bits_keylargo);
+ if (ctrler) {
+ keylargo_base = ctrler->reg;
+ rev = (u32 *)get_property(ctrler->device, "revision-id", NULL);
+ if (rev)
+ keylargo_rev = *rev;
+ }
} else if (device_is_compatible(np, "paddington")) {
feature_add_controller(np, feature_bits_paddington);
} else {
@@ -222,6 +245,18 @@ feature_init(void)
}
}
+ /* Handle core99 Uni-N */
+ np = find_devices("uni-n");
+ if (np && np->n_addrs > 0) {
+ uninorth_base = ioremap(np->addrs[0].address, 0x1000);
+ rev = (u32 *)get_property(np, "device-rev", NULL);
+ if (rev)
+ uninorth_rev = *rev;
+ }
+ if (uninorth_base && keylargo_base)
+ printk("Uni-N revision: %d, KeyLargo revision: %d\n",
+ uninorth_rev, keylargo_rev);
+
if (controller_count)
printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count);
@@ -236,7 +271,7 @@ feature_init(void)
#endif
}
-static void
+static struct feature_controller*
feature_add_controller(struct device_node *controller_device, fbit* bits)
{
struct feature_controller* controller;
@@ -244,7 +279,7 @@ feature_add_controller(struct device_node *controller_device, fbit* bits)
if (controller_count >= MAX_FEATURE_CONTROLLERS) {
printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n",
controller_device->full_name, MAX_FEATURE_CONTROLLERS);
- return;
+ return NULL;
}
controller = &controllers[controller_count];
@@ -253,7 +288,7 @@ feature_add_controller(struct device_node *controller_device, fbit* bits)
if (controller_device->n_addrs == 0) {
printk(KERN_ERR "No addresses for %s\n",
controller_device->full_name);
- return;
+ return NULL;
}
controller->reg = (volatile u32 *)ioremap(
@@ -262,12 +297,14 @@ feature_add_controller(struct device_node *controller_device, fbit* bits)
if (bits == NULL) {
printk(KERN_INFO "Twiddling the magic ohare bits\n");
out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES);
- return;
+ return NULL;
}
spin_lock_init(&controller->lock);
controller_count++;
+
+ return controller;
}
static struct feature_controller*
@@ -389,3 +426,118 @@ feature_test(struct device_node* device, enum system_feature f)
return bit->polarity ? (value == 0) : (value == bit->mask);
}
+/*
+ * Core99 functions
+ *
+ * Note: We currently assume there is _one_ UniN chip and _one_ KeyLargo
+ * chip, which is the case on all Core99 machines so far
+ */
+
+/* Only one GMAC is assumed */
+void
+feature_set_gmac_power(struct device_node* device, int power)
+{
+ if (!uninorth_base)
+ return;
+ if (power)
+ out_le32(uninorth_base + 0x20/4,
+ in_le32(uninorth_base + 0x20/4) | 0x02000000);
+ else
+ out_le32(uninorth_base + 0x20/4,
+ in_le32(uninorth_base + 0x20/4) & ~0x02000000);
+ udelay(20);
+}
+
+/* Pass the node of the correct controller, please */
+void
+feature_set_usb_power(struct device_node* device, int power)
+{
+}
+
+/* Not yet implemented */
+void
+feature_set_firewire_power(struct device_node* device, int power)
+{
+}
+
+void
+feature_prepare_for_sleep(void)
+{
+ /* We assume gatwick is second */
+ struct feature_controller* ctrler = &controllers[0];
+
+ if (!ctrler)
+ return;
+ if (controller_count > 1 &&
+ device_is_compatible(ctrler->device, "gatwick"))
+ ctrler = &controllers[1];
+
+ if (ctrler->bits == feature_bits_heathrow ||
+ ctrler->bits == feature_bits_paddington) {
+ heathrow_prepare_for_sleep(ctrler);
+ return;
+ }
+ if (ctrler->bits == feature_bits_keylargo) {
+ core99_prepare_for_sleep(ctrler);
+ return;
+ }
+}
+
+
+void
+feature_wake_up(void)
+{
+ struct feature_controller* ctrler = &controllers[0];
+
+ if (!ctrler)
+ return;
+ if (controller_count > 1 &&
+ device_is_compatible(ctrler->device, "gatwick"))
+ ctrler = &controllers[1];
+
+ if (ctrler->bits == feature_bits_heathrow ||
+ ctrler->bits == feature_bits_paddington) {
+ heathrow_wakeup(ctrler);
+ return;
+ }
+ if (ctrler->bits == feature_bits_keylargo) {
+ core99_wake_up(ctrler);
+ return;
+ }
+}
+
+static u32 save_fcr0;
+//static u32 save_fcr1;
+//static u32 save_fcr2;
+static u32 save_mbcr;
+
+static void
+heathrow_prepare_for_sleep(struct feature_controller* ctrler)
+{
+ save_mbcr = in_le32(FREG(ctrler, 0x34));
+ save_fcr0 = in_le32(FREG(ctrler, 0x38));
+
+ out_le32(FREG(ctrler, 0x38), save_fcr0 & ~HRW_IOBUS_ENABLE);
+}
+
+static void
+heathrow_wakeup(struct feature_controller* ctrler)
+{
+ out_le32(FREG(ctrler, 0x38), save_fcr0);
+ out_le32(FREG(ctrler, 0x34), save_mbcr);
+
+ out_le32(FREG(ctrler, 0x38), save_fcr0 | HRW_IOBUS_ENABLE);
+}
+
+static void
+core99_prepare_for_sleep(struct feature_controller* ctrler)
+{
+ /* Not yet implemented */
+}
+
+static void
+core99_wake_up(struct feature_controller* ctrler)
+{
+ /* Not yet implemented */
+}
+
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index e069baf5b..7be4675c2 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -30,7 +30,7 @@
#include <asm/m48t35.h>
#include <asm/gemini.h>
-#include "time.h"
+#include <asm/time.h>
#include "local_irq.h"
#include "open_pic.h"
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 8c5911d30..067581f5d 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -171,6 +171,9 @@ __after_prom_start:
#ifndef CONFIG_POWER4
/* POWER4 doesn't have BATs */
bl initial_bats
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+ bl setup_disp_bat
+#endif
#else /* CONFIG_POWER4 */
/*
* Load up the SDR1 and segment register values now
@@ -1603,23 +1606,37 @@ initial_bats:
mtspr DBAT0U,r11 /* bit in upper BAT register */
mtspr IBAT0L,r8
mtspr IBAT0U,r11
-#if 0 /* Useful debug code, please leave in for now so I don't have to
- * look at docs when I need to setup a BAT ...
- */
-setup_screen_bat:
- li r3,0
- mtspr DBAT1U,r3
- lis r3,0xfa00
- CLR_TOP32(r3)
- lis r4,0xfa00
- CLR_TOP32(r4)
- ori r4,r4,0x2a
- mtspr DBAT1L,r4
- ori r3,r3,(BL_16M<<2)|0x2 /* set up BAT registers for 604 */
- mtspr DBAT1U,r3
-#endif
isync
blr
+
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+setup_disp_bat:
+ /*
+ * setup the display bat prepared for us in prom.c
+ */
+ mflr r8
+ bl reloc_offset
+ mtlr r8
+ lis r8, disp_BATL@h
+ ori r8, r8, disp_BATL@l
+ add r8, r3, r8
+ lwz r8, 0(r8)
+ lis r11, disp_BATU@h
+ ori r11, r11, disp_BATU@l
+ add r11, r3, r11
+ lwz r11, 0(r11)
+ mtspr IBAT3L,r8
+ mtspr IBAT3U,r11
+ mfspr r9,PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpi 0,r9,1
+ beq 1f
+ mtspr DBAT3L,r8
+ mtspr DBAT3U,r11
+1:
+ blr
+
+#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8260
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index a81156102..d29f7bd20 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -304,3 +304,4 @@ void power_save(void)
return;
}
}
+
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index b055f23ec..ee63ca902 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -74,8 +74,7 @@ volatile unsigned char *chrp_int_ack_special;
irq_desc_t irq_desc[NR_IRQS];
int ppc_spurious_interrupts = 0;
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
+irq_cpustat_t irq_stat [NR_CPUS];
struct irqaction *ppc_irq_action[NR_IRQS];
unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
@@ -248,6 +247,7 @@ int get_irq_list(char *buf)
len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
else
len += sprintf(buf+len, " None ");
+ len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge ");
len += sprintf(buf+len, " %s",action->name);
for (action=action->next; action; action = action->next) {
len += sprintf(buf+len, ", %s", action->name);
@@ -368,12 +368,12 @@ static void show(char * str)
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: %d [%d %d]\n",
atomic_read(&global_irq_count),
- local_irq_count[0],
- local_irq_count[1]);
+ local_irq_count(0),
+ local_irq_count(1));
printk("bh: %d [%d %d]\n",
atomic_read(&global_bh_count),
- local_bh_count[0],
- local_bh_count[1]);
+ local_bh_count(0),
+ local_bh_count(1));
stack = (unsigned long *) &str;
for (i = 40; i ; i--) {
unsigned long x = *++stack;
@@ -408,7 +408,7 @@ static inline void wait_on_irq(int cpu)
* already executing in one..
*/
if (!atomic_read(&global_irq_count)) {
- if (local_bh_count[cpu]
+ if (local_bh_count(cpu)
|| !atomic_read(&global_bh_count))
break;
}
@@ -430,7 +430,7 @@ static inline void wait_on_irq(int cpu)
continue;
if (global_irq_lock)
continue;
- if (!local_bh_count[cpu]
+ if (!local_bh_count(cpu)
&& atomic_read(&global_bh_count))
continue;
if (!test_and_set_bit(0,&global_irq_lock))
@@ -521,7 +521,7 @@ void __global_cli(void)
if (flags & (1 << 15)) {
int cpu = smp_processor_id();
__cli();
- if (!local_irq_count[cpu])
+ if (!local_irq_count(cpu))
get_irqlock(cpu);
}
}
@@ -530,7 +530,7 @@ void __global_sti(void)
{
int cpu = smp_processor_id();
- if (!local_irq_count[cpu])
+ if (!local_irq_count(cpu))
release_irqlock(cpu);
__sti();
}
@@ -554,7 +554,7 @@ unsigned long __global_save_flags(void)
retval = 2 + local_enabled;
/* check for global flags if we're not in an interrupt */
- if (!local_irq_count[smp_processor_id()]) {
+ if (!local_irq_count(smp_processor_id())) {
if (local_enabled)
retval = 1;
if (global_irq_holder == (unsigned char) smp_processor_id())
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
index 2ce3790c3..891b0ca44 100644
--- a/arch/ppc/kernel/m8260_setup.c
+++ b/arch/ppc/kernel/m8260_setup.c
@@ -44,7 +44,7 @@
#include <asm/immap_8260.h>
#include <asm/machdep.h>
-#include "time.h"
+#include <asm/time.h>
#include "ppc8260_pic.h"
static int m8260_set_rtc_time(unsigned long time);
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index 9f0a517e3..a00a8c452 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -45,7 +45,7 @@
#include <asm/8xx_immap.h>
#include <asm/machdep.h>
-#include "time.h"
+#include <asm/time.h>
#include "ppc8xx_pic.h"
static int m8xx_set_rtc_time(unsigned long time);
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index f8d230c7e..19a218bd4 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1205,6 +1205,17 @@ _GLOBAL(sys_call_table)
.long sys_ni_syscall /* streams2 */
.long sys_vfork
.long sys_getrlimit /* 190 */
- .rept NR_syscalls-190
+ .long sys_ni_syscall /* 191 */ /* Unused */
+ .long sys_ni_syscall /* 192 - reserved - mmap2 */
+ .long sys_ni_syscall /* 193 - reserved - truncate64 */
+ .long sys_ni_syscall /* 194 - reserved - ftruncate64 */
+ .long sys_ni_syscall /* 195 - reserved - stat64 */
+ .long sys_ni_syscall /* 196 - reserved - lstat64 */
+ .long sys_ni_syscall /* 197 - reserved - fstat64 */
+ .long sys_pciconfig_read /* 198 */
+ .long sys_pciconfig_write /* 199 */
+ .long sys_pciconfig_iobase /* 200 */
+ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */
+ .rept NR_syscalls-201
.long sys_ni_syscall
.endr
diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c
index f3c142e2b..09e6e6e6f 100644
--- a/arch/ppc/kernel/oak_setup.c
+++ b/arch/ppc/kernel/oak_setup.c
@@ -28,7 +28,7 @@
#include "local_irq.h"
#include "ppc4xx_pic.h"
-#include "time.h"
+#include <asm/time.h>
#include "oak_setup.h"
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 21001a7ce..416137934 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -261,12 +261,15 @@ void __init openpic_init(int main_pic)
while(np) {
int j, pri;
pri = strcmp(np->name, "programmer-switch") ? 2 : 7;
- for (j=0;j<np->n_intrs;j++)
+ for (j=0;j<np->n_intrs;j++) {
openpic_initirq( np->intrs[j].line,
pri,
np->intrs[j].line,
- np->intrs[j].sense,
+ 0,
np->intrs[j].sense);
+ if (np->intrs[j].sense)
+ irq_desc[np->intrs[j].line].status = IRQ_LEVEL;
+ }
np = np->next;
}
}
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 773c99b5c..cfa26b67d 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -4,11 +4,14 @@
*/
#include <linux/kernel.h>
+#include <linux/config.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/openpic.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/processor.h>
@@ -19,6 +22,7 @@
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/gg2.h>
+#include <asm/uaccess.h>
#include "pci.h"
@@ -184,3 +188,146 @@ int pcibios_enable_device(struct pci_dev *dev)
}
return 0;
}
+
+/*
+ * Those syscalls are derived from the Alpha versions, they
+ * allow userland apps to retreive the per-device iobase and
+ * mem-base. They also provide wrapper for userland to do
+ * config space accesses.
+ * The "host_number" returns the number of the Uni-N sub bridge
+ */
+
+asmlinkage int
+sys_pciconfig_read(unsigned long bus, unsigned long dfn,
+ unsigned long off, unsigned long len,
+ unsigned char *buf)
+{
+ unsigned char ubyte;
+ unsigned short ushort;
+ unsigned int uint;
+ long err = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!pcibios_present())
+ return -ENOSYS;
+
+ switch (len) {
+ case 1:
+ err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
+ put_user(ubyte, buf);
+ break;
+ case 2:
+ err = pcibios_read_config_word(bus, dfn, off, &ushort);
+ put_user(ushort, (unsigned short *)buf);
+ break;
+ case 4:
+ err = pcibios_read_config_dword(bus, dfn, off, &uint);
+ put_user(uint, (unsigned int *)buf);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+asmlinkage int
+sys_pciconfig_write(unsigned long bus, unsigned long dfn,
+ unsigned long off, unsigned long len,
+ unsigned char *buf)
+{
+ unsigned char ubyte;
+ unsigned short ushort;
+ unsigned int uint;
+ long err = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!pcibios_present())
+ return -ENOSYS;
+
+ switch (len) {
+ case 1:
+ err = get_user(ubyte, buf);
+ if (err)
+ break;
+ err = pcibios_write_config_byte(bus, dfn, off, ubyte);
+ if (err != PCIBIOS_SUCCESSFUL) {
+ err = -EFAULT;
+ }
+ break;
+ case 2:
+ err = get_user(ushort, (unsigned short *)buf);
+ if (err)
+ break;
+ err = pcibios_write_config_word(bus, dfn, off, ushort);
+ if (err != PCIBIOS_SUCCESSFUL) {
+ err = -EFAULT;
+ }
+ break;
+ case 4:
+ err = get_user(uint, (unsigned int *)buf);
+ if (err)
+ break;
+ err = pcibios_write_config_dword(bus, dfn, off, uint);
+ if (err != PCIBIOS_SUCCESSFUL) {
+ err = -EFAULT;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+void *
+pci_dev_io_base(unsigned char bus, unsigned char devfn)
+{
+ /* Defaults to old way */
+ if (!ppc_md.pci_dev_io_base)
+ return pci_io_base(bus);
+ return ppc_md.pci_dev_io_base(bus, devfn);
+}
+
+void *
+pci_dev_mem_base(unsigned char bus, unsigned char devfn)
+{
+ /* Default memory base is 0 (1:1 mapping) */
+ if (!ppc_md.pci_dev_mem_base)
+ return 0;
+ return ppc_md.pci_dev_mem_base(bus, devfn);
+}
+
+/* Returns the root-bridge number (Uni-N number) of a device */
+int
+pci_dev_root_bridge(unsigned char bus, unsigned char devfn)
+{
+ /* Defaults to 0 */
+ if (!ppc_md.pci_dev_root_bridge)
+ return 0;
+ return ppc_md.pci_dev_root_bridge(bus, devfn);
+}
+
+/* Provide information on locations of various I/O regions in physical
+ * memory. Do this on a per-card basis so that we choose the right
+ * root bridge.
+ * Note that the returned IO or memory base is a physical address
+ */
+
+asmlinkage long
+sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
+{
+ switch (which) {
+ case IOBASE_BRIDGE_NUMBER:
+ return (long)pci_dev_root_bridge(bus, devfn);
+ case IOBASE_MEMORY:
+ return (long)pci_dev_mem_base(bus, devfn);
+ case IOBASE_IO:
+ return (long)pci_dev_io_base(bus, devfn);
+ }
+
+ return -EOPNOTSUPP;
+}
+
diff --git a/arch/ppc/kernel/pmac_backlight.c b/arch/ppc/kernel/pmac_backlight.c
new file mode 100644
index 000000000..c4426a0b0
--- /dev/null
+++ b/arch/ppc/kernel/pmac_backlight.c
@@ -0,0 +1,148 @@
+/*
+ * Miscellaneous procedures for dealing with the PowerMac hardware.
+ * Contains support for the backlight.
+ *
+ * Copyright (C) 2000 Benjamin Herrenschmidt
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/reboot.h>
+#include <linux/nvram.h>
+#include <asm/init.h>
+#include <asm/ptrace.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/nvram.h>
+#include <asm/backlight.h>
+
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+static struct backlight_controller *backlighter = NULL;
+static void* backlighter_data = NULL;
+static int backlight_autosave = 0;
+static int backlight_level = BACKLIGHT_MAX;
+static int backlight_enabled = 1;
+
+void __pmac
+register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type)
+{
+ struct device_node* bk_node;
+ char *prop;
+ int valid = 0;
+
+ bk_node = find_devices("backlight");
+
+#ifdef CONFIG_ADB_PMU
+ /* Special case for the old PowerBook since I can't test on it */
+ if ((machine_is_compatible("AAPL,3400/2400") || machine_is_compatible("AAPL,3500")
+ || machine_is_compatible("AAPL,PowerBook1998")
+ || machine_is_compatible("AAPL,PowerBook1999"))
+ && !strcmp(type, "pmu"))
+ valid = 1;
+ else
+#endif
+ {
+ if (bk_node)
+ prop = get_property(bk_node, "backlight-control", NULL);
+ if (prop && !strncmp(prop, type, strlen(type)))
+ valid = 1;
+ }
+ if (!valid)
+ return;
+ backlighter = ctrler;
+ backlighter_data = data;
+
+ if (bk_node && !backlight_autosave)
+ prop = get_property(bk_node, "bklt", NULL);
+ else
+ prop = NULL;
+ if (prop) {
+ backlight_level = ((*prop)+1) >> 1;
+ if (backlight_level > BACKLIGHT_MAX)
+ backlight_level = BACKLIGHT_MAX;
+ }
+
+#ifdef CONFIG_ADB_PMU
+ backlight_autosave = machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500");
+ if (backlight_autosave) {
+ struct adb_request req;
+ pmu_request(&req, NULL, 2, 0xd9, 0);
+ while (!req.complete)
+ pmu_poll();
+ backlight_level = req.reply[1] >> 4;
+ }
+#endif
+ if (!backlighter->set_enable(1, backlight_level, data))
+ backlight_enabled = 1;
+
+ printk(KERN_INFO "Registered \"%s\" backlight controller, level: %d/15\n",
+ type, backlight_level);
+}
+
+void __pmac
+unregister_backlight_controller(struct backlight_controller *ctrler, void *data)
+{
+ /* We keep the current backlight level (for now) */
+ if (ctrler == backlighter && data == backlighter_data)
+ backlighter = NULL;
+}
+
+int __pmac
+set_backlight_enable(int enable)
+{
+ int rc;
+
+ if (!backlighter)
+ return -ENODEV;
+ rc = backlighter->set_enable(enable, backlight_level, backlighter_data);
+ if (!rc)
+ backlight_enabled = enable;
+ return rc;
+}
+
+int __pmac
+get_backlight_enable(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_enabled;
+}
+
+int __pmac
+set_backlight_level(int level)
+{
+ int rc = 0;
+
+ if (!backlighter)
+ return -ENODEV;
+ if (level < BACKLIGHT_MIN)
+ level = BACKLIGHT_OFF;
+ if (level > BACKLIGHT_MAX)
+ level = BACKLIGHT_MAX;
+ if (backlight_enabled)
+ rc = backlighter->set_level(level, backlighter_data);
+ if (!rc)
+ backlight_level = level;
+ if (!rc && !backlight_autosave) {
+ level <<=1;
+ if (level & 0x10)
+ level |= 0x01;
+ // -- todo: save to property "bklt"
+ }
+ return rc;
+}
+
+int __pmac
+get_backlight_level(void)
+{
+ if (!backlighter)
+ return -ENODEV;
+ return backlight_level;
+}
diff --git a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c
index db0632238..d8de113ec 100644
--- a/arch/ppc/kernel/pmac_nvram.c
+++ b/arch/ppc/kernel/pmac_nvram.c
@@ -19,20 +19,8 @@
#undef DEBUG
-/*
- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
- */
-static int nvram_naddrs;
-static volatile unsigned char *nvram_addr;
-static volatile unsigned char *nvram_data;
-static int nvram_mult, is_core_99;
-static char* nvram_image;
-static int core99_bank = 0;
-
-extern int pmac_newworld;
-
#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
-
+
#define CORE99_SIGNATURE 0x5a
#define CORE99_ADLER_START 0x14
@@ -60,8 +48,29 @@ struct core99_header {
u32 reserved[2];
};
+/*
+ * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
+ */
+static int nvram_naddrs;
+static volatile unsigned char *nvram_addr;
+static volatile unsigned char *nvram_data;
+static int nvram_mult, is_core_99;
+static int core99_bank = 0;
static int nvram_partitions[3];
+/* FIXME: kmalloc fails to allocate the image now that I had to move it
+ * before time_init(). For now, I allocate a static buffer here
+ * but it's a waste of space on all but core99 machines
+ */
+#if 0
+static char* nvram_image;
+#else
+__pmac static char nvram_image[NVRAM_SIZE];
+#endif
+
+extern int pmac_newworld;
+
+
static u8
chrp_checksum(struct chrp_header* hdr)
{
@@ -189,6 +198,7 @@ lookup_partitions(void)
hdr = (struct chrp_header *)buffer;
offset = 0;
+ buffer[16] = 0;
do {
for (i=0;i<16;i++)
buffer[i] = nvram_read_byte(offset+i);
@@ -234,11 +244,13 @@ void pmac_nvram_init(void)
printk(KERN_ERR "nvram: no address\n");
return;
}
+#if 0
nvram_image = kmalloc(NVRAM_SIZE, GFP_KERNEL);
if (!nvram_image) {
printk(KERN_ERR "nvram: can't allocate image\n");
return;
}
+#endif
nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
#ifdef DEBUG
printk("nvram: Checking bank 0...\n");
@@ -267,6 +279,7 @@ void pmac_nvram_init(void)
printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
nvram_naddrs);
}
+ lookup_partitions();
}
void
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index ee54ba37d..ced029722 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -34,6 +34,7 @@ struct uninorth_data {
struct device_node* node;
volatile unsigned int* cfg_addr;
volatile unsigned int* cfg_data;
+ void* iobase;
};
static struct uninorth_data uninorth_bridges[3];
@@ -54,6 +55,7 @@ static void add_bridges(struct device_node *dev);
#define BANDIT_MAGIC 0x50
#define BANDIT_COHERENT 0x40
+/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */
__pmac
void *pci_io_base(unsigned int bus)
{
@@ -83,6 +85,72 @@ int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
return 0;
}
+/* This routines figures out on which root bridge a given PCI device
+ * is attached.
+ */
+__pmac
+int
+pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn)
+{
+ struct device_node *node, *bridge_node;
+ int bridge = uninorth_default;
+
+ if (uninorth_count == 0)
+ return 0;
+ if (bus == 0 && PCI_SLOT(dev_fn) < 11)
+ return 0;
+
+ /* We look for the OF device corresponding to this bus/devfn pair. If we
+ * don't find it, we default to the external PCI */
+ bridge_node = NULL;
+ node = find_pci_device_OFnode(bus, dev_fn & 0xf8);
+ if (node) {
+ /* note: we don't stop on the first occurence since we need to go
+ * up to the root bridge */
+ do {
+ if (node->type && !strcmp(node->type, "pci")
+ && device_is_compatible(node, "uni-north"))
+ bridge_node = node;
+ node=node->parent;
+ } while (node);
+ }
+ if (bridge_node) {
+ int i;
+ for (i=0;i<uninorth_count;i++)
+ if (uninorth_bridges[i].node == bridge_node) {
+ bridge = i;
+ break;
+ }
+ }
+
+ if (bridge == -1) {
+ printk(KERN_WARNING "pmac_pci: no default bridge !\n");
+ return 0;
+ }
+
+ return bridge;
+}
+
+__pmac
+void *
+pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn)
+{
+ int bridge;
+ if (uninorth_count == 0)
+ return pci_io_base(bus);
+ bridge = pmac_pci_dev_root_bridge(bus, devfn);
+ if (bridge == -1)
+ return pci_io_base(bus);
+ return uninorth_bridges[bridge].iobase;
+}
+
+__pmac
+void *
+pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn)
+{
+ return 0;
+}
+
/* This function only works for bus 0, uni-N uses a different mecanism for
* other busses (see below)
*/
@@ -98,48 +166,20 @@ int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
|(((unsigned long)(off)) & 0xFCUL) \
|1UL)
-/* We should really use RTAS here, unfortunately, it's not available with BootX.
- * (one more reason for writing a beautiful OF booter). I'll do the RTAS stuff
- * later, once I have something that works enough with BootX.
- */
__pmac static
unsigned int
uni_north_access_data(unsigned char bus, unsigned char dev_fn,
unsigned char offset)
{
- struct device_node *node, *bridge_node;
- int bridge = uninorth_default;
+ int bridge;
unsigned int caddr;
- if (bus == 0) {
- if (PCI_SLOT(dev_fn) < 11) {
- return 0;
- }
- /* We look for the OF device corresponding to this bus/devfn pair. If we
- * don't find it, we default to the external PCI */
- bridge_node = NULL;
- node = find_pci_device_OFnode(bus, dev_fn & 0xf8);
- if (node) {
- /* note: we don't stop on the first occurence since we need to go
- * up to the root bridge */
- do {
- if (!strcmp(node->type, "pci"))
- bridge_node = node;
- node=node->parent;
- } while (node);
- }
- if (bridge_node) {
- int i;
- for (i=0;i<uninorth_count;i++)
- if (uninorth_bridges[i].node == bridge_node) {
- bridge = i;
- break;
- }
- }
+ bridge = pmac_pci_dev_root_bridge(bus, dev_fn);
+ if (bus == 0)
caddr = UNI_N_CFA0(dev_fn, offset);
- } else
+ else
caddr = UNI_N_CFA1(bus, dev_fn, offset);
-
+
if (bridge == -1) {
printk(KERN_WARNING "pmac_pci: no default bridge !\n");
return 0;
@@ -609,6 +649,7 @@ static void __init add_bridges(struct device_node *dev)
uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
uninorth_bridges[i].node = dev;
+ uninorth_bridges[i].iobase = (void *)addr->address;
/* XXX This is the bridge with the PCI expansion bus. This is also the
* address of the bus that will receive type 1 config accesses and io
* accesses. Appears to be correct for iMac DV and G4 Sawtooth too.
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index ab2fdbc15..e0e654305 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -61,14 +61,32 @@ static void pmac_openpic_unmask_irq(unsigned int irq_nr)
openpic_enable_irq(irq_nr);
}
+static void pmac_openpic_ack_irq(unsigned int irq_nr)
+{
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
+ openpic_eoi(smp_processor_id());
+ openpic_disable_irq(irq_nr);
+}
+
+static void pmac_openpic_end_irq(unsigned int irq_nr)
+{
+ if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
+ openpic_eoi(smp_processor_id());
+ openpic_enable_irq(irq_nr);
+}
+
struct hw_interrupt_type pmac_open_pic = {
" OpenPIC ",
NULL,
NULL,
pmac_openpic_unmask_irq,
pmac_openpic_mask_irq,
- pmac_openpic_mask_irq,
- 0
+ /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing
+ * so shows tons of bogus interrupts coming in.
+ */
+ pmac_openpic_ack_irq,
+ pmac_openpic_end_irq,
+ NULL
};
static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
@@ -141,7 +159,8 @@ struct hw_interrupt_type pmac_pic = {
pmac_unmask_irq,
pmac_mask_irq,
pmac_mask_and_ack_irq,
- 0
+ pmac_unmask_irq,
+ NULL
};
struct hw_interrupt_type gatwick_pic = {
@@ -151,7 +170,8 @@ struct hw_interrupt_type gatwick_pic = {
pmac_unmask_irq,
pmac_mask_irq,
pmac_mask_and_ack_irq,
- 0
+ pmac_unmask_irq,
+ NULL
};
static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
@@ -199,17 +219,13 @@ pmac_get_irq(struct pt_regs *regs)
}
#endif /* CONFIG_SMP */
- /* Yeah, I know, this could be a separate get_irq function */
- if (has_openpic)
- {
+ if (has_openpic) {
irq = openpic_irq(smp_processor_id());
if (irq == OPENPIC_VEC_SPURIOUS)
/* We get those when doing polled ADB requests,
* using -2 is a temp hack to disable the printk
*/
irq = -2; /*-1; */
- else
- openpic_eoi(smp_processor_id());
}
else
{
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 35aa7a76d..ec8c6eca4 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -62,17 +62,18 @@
#include <asm/dma.h>
#include <asm/bootx.h>
-#include "time.h"
+#include <asm/time.h>
#include "local_irq.h"
#include "pmac_pic.h"
#undef SHOW_GATWICK_IRQS
-unsigned long pmac_get_rtc_time(void);
-int pmac_set_rtc_time(unsigned long nowtime);
-void pmac_read_rtc_time(void);
-void pmac_calibrate_decr(void);
-void pmac_setup_pci_ptrs(void);
+extern void pmac_time_init(void);
+extern unsigned long pmac_get_rtc_time(void);
+extern int pmac_set_rtc_time(unsigned long nowtime);
+extern void pmac_read_rtc_time(void);
+extern void pmac_calibrate_decr(void);
+extern void pmac_setup_pci_ptrs(void);
extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int mackbd_getkeycode(unsigned int scancode);
@@ -91,6 +92,11 @@ extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
+extern void pmac_nvram_update(void);
+
+extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn);
+extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn);
+extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn);
unsigned char drive_info;
@@ -98,6 +104,8 @@ int ppc_override_l2cr = 0;
int ppc_override_l2cr_value;
int has_l2cache = 0;
+static int current_root_goodness = -1;
+
extern char saved_command_line[];
extern int pmac_newworld;
@@ -300,7 +308,9 @@ pmac_setup_arch(void)
#ifdef CONFIG_ADB_PMU
find_via_pmu();
#endif
-
+#ifdef CONFIG_NVRAM
+ pmac_nvram_init();
+#endif
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
@@ -364,27 +374,25 @@ static void __init
init_uninorth(void)
{
/*
- * Turns on the gmac clock so that it responds to PCI cycles
- * later, the driver may want to turn it off again to save
- * power when interface is down
+ * Turns OFF the gmac clock. The gmac driver will turn
+ * it back ON when the interface is enabled. This save
+ * power on portables.
+ *
+ * Note: We could also try to turn OFF the PHY. Since this
+ * has to be done by both the gmac driver and this code,
+ * I'll probably end-up moving some of this out of the
+ * modular gmac driver into a non-modular stub containing
+ * some basic PHY management and power management stuffs
*/
- struct device_node* uni_n = find_devices("uni-n");
struct device_node* gmac = find_devices("ethernet");
- unsigned long* addr;
-
- if (!uni_n || uni_n->n_addrs < 1)
- return;
- addr = ioremap(uni_n->addrs[0].address, 0x300);
while(gmac) {
if (device_is_compatible(gmac, "gmac"))
break;
gmac = gmac->next;
}
- if (gmac) {
- *(addr + 8) |= 2;
- eieio();
- }
+ if (gmac)
+ feature_set_gmac_power(gmac, 0);
}
extern char *bootpath;
@@ -402,9 +410,6 @@ pmac_init2(void)
#ifdef CONFIG_ADB_PMU
via_pmu_start();
#endif
-#ifdef CONFIG_NVRAM
- pmac_nvram_init();
-#endif
#ifdef CONFIG_PMAC_PBOOK
media_bay_init();
#endif
@@ -476,13 +481,14 @@ void __init find_boot_device(void)
/* can't be __init - can be called whenever a disk is first accessed */
__pmac
-void note_bootable_part(kdev_t dev, int part)
+void note_bootable_part(kdev_t dev, int part, int goodness)
{
static int found_boot = 0;
char *p;
/* Do nothing if the root has been set already. */
- if (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))
+ if ((goodness < current_root_goodness) &&
+ (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
return;
p = strstr(saved_command_line, "root=");
if (p != NULL && (p == saved_command_line || p[-1] == ' '))
@@ -495,7 +501,7 @@ void note_bootable_part(kdev_t dev, int part)
if (boot_dev == 0 || dev == boot_dev) {
ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
boot_dev = NODEV;
- printk(" (root on %d)", part);
+ current_root_goodness = goodness;
}
}
@@ -666,11 +672,15 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.power_off = pmac_power_off;
ppc_md.halt = pmac_halt;
- ppc_md.time_init = NULL;
+ ppc_md.time_init = pmac_time_init;
ppc_md.set_rtc_time = pmac_set_rtc_time;
ppc_md.get_rtc_time = pmac_get_rtc_time;
ppc_md.calibrate_decr = pmac_calibrate_decr;
+ ppc_md.pci_dev_io_base = pmac_pci_dev_io_base;
+ ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base;
+ ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge;
+
#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
ppc_md.kbd_setkeycode = mackbd_setkeycode;
ppc_md.kbd_getkeycode = mackbd_getkeycode;
diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c
index ebd0037de..9eb326bf9 100644
--- a/arch/ppc/kernel/pmac_time.c
+++ b/arch/ppc/kernel/pmac_time.c
@@ -26,7 +26,8 @@
#include <asm/pgtable.h>
#include <asm/machdep.h>
-#include "time.h"
+#include <asm/time.h>
+#include <asm/nvram.h>
extern rwlock_t xtime_lock;
@@ -54,8 +55,30 @@ extern rwlock_t xtime_lock;
/* Bits in IFR and IER */
#define T1_INT 0x40 /* Timer 1 interrupt */
-__pmac
+extern struct timezone sys_tz;
+
+__init
+void pmac_time_init(void)
+{
+#ifdef CONFIG_NVRAM
+ s32 delta = 0;
+ int dst;
+
+ delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
+ delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
+ delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
+ if (delta & 0x00800000UL)
+ delta |= 0xFF000000UL;
+ dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
+ printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
+ dst ? "on" : "off");
+ sys_tz.tz_minuteswest = -delta/60;
+ /* I _suppose_ this is 0:off, 1:on */
+ sys_tz.tz_dsttime = dst;
+#endif
+}
+__pmac
unsigned long pmac_get_rtc_time(void)
{
#ifdef CONFIG_ADB
@@ -95,7 +118,34 @@ unsigned long pmac_get_rtc_time(void)
int pmac_set_rtc_time(unsigned long nowtime)
{
- return 0;
+ struct adb_request req;
+
+ nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60;
+
+ switch (sys_ctrler) {
+ case SYS_CTRLER_CUDA:
+ if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
+ nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
+ return 0;
+ while (!req.complete)
+ cuda_poll();
+// if (req.reply_len != 7)
+ printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
+ req.reply_len);
+ return 1;
+ case SYS_CTRLER_PMU:
+ if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
+ nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
+ return 0;
+ while (!req.complete)
+ pmu_poll();
+ if (req.reply_len != 5)
+ printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
+ req.reply_len);
+ return 1;
+ default:
+ return 0;
+ }
}
/*
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 76809881b..b140dd25c 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -35,10 +35,11 @@
#include <asm/dma.h>
#include <asm/machdep.h>
#include <asm/hw_irq.h>
+#include <asm/nvram.h>
#ifdef CONFIG_SMP
#include <asm/smplock.h>
#endif /* CONFIG_SMP */
-#include "time.h"
+#include <asm/time.h>
/* Tell string.h we don't want memcpy etc. as cpp defines */
#define EXPORT_SYMTAB_STROPS
@@ -76,8 +77,7 @@ EXPORT_SYMBOL(do_lost_interrupts);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
-EXPORT_SYMBOL(local_irq_count);
-EXPORT_SYMBOL(local_bh_count);
+EXPORT_SYMBOL(irq_stat);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(kernel_flag);
#endif /* CONFIG_SMP */
@@ -96,6 +96,10 @@ EXPORT_SYMBOL(_prep_type);
EXPORT_SYMBOL(ucSystemType);
#endif
#endif
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL(pci_dev_io_base);
+EXPORT_SYMBOL(pci_dev_mem_base);
+#endif
#if !__INLINE_BITOPS
EXPORT_SYMBOL(set_bit);
@@ -234,6 +238,9 @@ EXPORT_SYMBOL(pci_device_loc);
EXPORT_SYMBOL(feature_set);
EXPORT_SYMBOL(feature_clear);
EXPORT_SYMBOL(feature_test);
+EXPORT_SYMBOL(feature_set_gmac_power);
+EXPORT_SYMBOL(feature_set_usb_power);
+EXPORT_SYMBOL(feature_set_firewire_power);
#endif /* defined(CONFIG_ALL_PPC) */
#if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL(note_scsi_host);
@@ -242,7 +249,13 @@ EXPORT_SYMBOL(kd_mksound);
#ifdef CONFIG_NVRAM
EXPORT_SYMBOL(nvram_read_byte);
EXPORT_SYMBOL(nvram_write_byte);
+EXPORT_SYMBOL(pmac_xpram_read);
+EXPORT_SYMBOL(pmac_xpram_write);
#endif /* CONFIG_NVRAM */
+#ifdef CONFIG_PPC_RTC
+EXPORT_SYMBOL(mktime);
+EXPORT_SYMBOL(to_tm);
+#endif
EXPORT_SYMBOL_NOVERS(__ashrdi3);
EXPORT_SYMBOL_NOVERS(__ashldi3);
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index cb1110eca..a09b4cf81 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -49,7 +49,7 @@
#include <asm/raven.h>
#include <asm/keyboard.h>
-#include "time.h"
+#include <asm/time.h>
#include "local_irq.h"
#include "i8259.h"
#include "open_pic.h"
diff --git a/arch/ppc/kernel/prep_time.c b/arch/ppc/kernel/prep_time.c
index f720841be..7274dfd0b 100644
--- a/arch/ppc/kernel/prep_time.c
+++ b/arch/ppc/kernel/prep_time.c
@@ -27,7 +27,7 @@
#include <asm/prep_nvram.h>
#include <asm/mk48t59.h>
-#include "time.h"
+#include <asm/time.h>
/*
* The motorola uses the m48t18 rtc (includes DS1643) whose registers
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 7f51ca13f..1d661fa71 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -118,10 +118,16 @@ static struct device_node *allnodes = 0;
#ifdef CONFIG_BOOTX_TEXT
+#define NO_SCROLL
+
static void clearscreen(void);
static void flushscreen(void);
+#ifndef NO_SCROLL
static void scrollscreen(void);
+#endif
+
+static void prepare_disp_BAT(void);
static void draw_byte(unsigned char c, long locX, long locY);
static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
@@ -134,6 +140,9 @@ static long g_loc_Y = 0;
static long g_max_loc_X = 0;
static long g_max_loc_Y = 0;
+unsigned long disp_BATL = 0;
+unsigned long disp_BATU = 0;
+
#define cmapsz (16*256)
static unsigned char vga_font[cmapsz];
@@ -473,9 +482,10 @@ bootx_init(unsigned long r4, unsigned long phys)
}
#ifdef CONFIG_BOOTX_TEXT
+ prepare_disp_BAT();
prom_drawstring(RELOC("booting...\n"));
flushscreen();
- RELOC(bootx_text_mapped) = 0;
+ RELOC(bootx_text_mapped) = 1;
#endif
}
@@ -748,11 +758,15 @@ prom_init(int r3, int r4, prom_entry pp)
#ifdef CONFIG_BOOTX_TEXT
if (!chrp && RELOC(disp_bi)) {
+ RELOC(prom_stdout) = 0; /* stop OF output */
clearscreen();
+ prepare_disp_BAT();
prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
prom_drawstring(RELOC("booting...\n"));
+ RELOC(bootx_text_mapped) = 1;
+ } else {
+ RELOC(bootx_text_mapped) = 0;
}
- RELOC(bootx_text_mapped) = 0;
#endif
prom_print(RELOC("returning from prom_init\n"));
@@ -820,6 +834,45 @@ prom_welcome(boot_infos_t* bi, unsigned long phys)
}
prom_drawstring(RELOC("\n\n"));
}
+
+/* Calc BAT values for mapping the display and store them
+ * in disp_BATH and disp_BATL. Those values are then used
+ * from head.S to map the display during identify_machine()
+ * and MMU_Init()
+ *
+ * For now, the display is mapped in place (1:1). This should
+ * be changed if the display physical address overlaps
+ * KERNELBASE, which is fortunately not the case on any machine
+ * I know of. This mapping is temporary and will disappear as
+ * soon as the setup done by MMU_Init() is applied
+ *
+ * For now, we align the BAT and then map 8Mb on 601 and 16Mb
+ * on other PPCs. This may cause trouble if the framebuffer
+ * is really badly aligned, but I didn't encounter this case
+ * yet.
+ */
+__init
+static void
+prepare_disp_BAT(void)
+{
+ unsigned long offset = reloc_offset();
+ boot_infos_t* bi = PTRRELOC(RELOC(disp_bi));
+ unsigned long addr = (unsigned long)bi->dispDeviceBase;
+
+ if ((_get_PVR() >> 16) != 1) {
+ /* 603, 604, G3, G4, ... */
+ addr &= 0xFF000000UL;
+ RELOC(disp_BATU) = addr | (BL_16M<<2) | 2;
+ RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
+ } else {
+ /* 601 */
+ addr &= 0xFF800000UL;
+ RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+ RELOC(disp_BATL) = addr | BL_8M | 0x40;
+ }
+ bi->logicalDisplayBase = bi->dispDeviceBase;
+}
+
#endif
static int prom_set_color(ihandle ih, int i, int r, int g, int b)
@@ -1133,14 +1186,14 @@ finish_device_tree(void)
/* All newworld machines now use the interrupt tree */
struct device_node *np = allnodes;
- while(np) {
+ while(np && (_machine == _MACH_Pmac)) {
if (get_property(np, "interrupt-parent", 0)) {
pmac_newworld = 1;
break;
}
np = np->allnext;
}
- if (boot_infos == 0 && pmac_newworld)
+ if ((_machine == _MACH_chrp) || (boot_infos == 0 && pmac_newworld))
use_of_interrupt_tree = 1;
mem = finish_node(allnodes, mem, NULL, 0, 0);
@@ -1746,8 +1799,17 @@ find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn)
int l;
for (np = allnodes; np != 0; np = np->allnext) {
- if (np->parent == NULL || np->parent->type == NULL
- || strcmp(np->parent->type, "pci") != 0)
+ int in_macio = 0;
+ struct device_node* parent = np->parent;
+ while(parent) {
+ char *pname = (char *)get_property(parent, "name", &l);
+ if (pname && strcmp(pname, "mac-io") == 0) {
+ in_macio = 1;
+ break;
+ }
+ parent = parent->parent;
+ }
+ if (in_macio)
continue;
reg = (unsigned int *) get_property(np, "reg", &l);
if (reg == 0 || l < sizeof(struct reg_property))
@@ -2014,11 +2076,14 @@ __init
void
map_bootx_text(void)
{
+ unsigned long base, offset, size;
if (disp_bi == 0)
return;
- disp_bi->logicalDisplayBase =
- ioremap((unsigned long) disp_bi->dispDeviceBase,
- disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3]);
+ base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL;
+ offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
+ size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
+ + disp_bi->dispDeviceRect[0];
+ disp_bi->logicalDisplayBase = ioremap(base, size) + offset;
bootx_text_mapped = 1;
}
@@ -2084,6 +2149,7 @@ flushscreen(void)
}
}
+#ifndef NO_SCROLL
__pmac
static void
scrollscreen(void)
@@ -2113,6 +2179,7 @@ scrollscreen(void)
dst += (bi->dispDeviceRowBytes >> 2);
}
}
+#endif /* ndef NO_SCROLL */
__pmac
void
@@ -2148,7 +2215,7 @@ prom_drawchar(char c)
RELOC(g_loc_Y)++;
cline = 1;
}
-#if 0
+#ifndef NO_SCROLL
while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) {
scrollscreen();
RELOC(g_loc_Y)--;
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 6c0c38273..67387cca0 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -75,9 +75,6 @@ extern void gemini_init(unsigned long r3,
unsigned long r6,
unsigned long r7);
-#ifdef CONFIG_BOOTX_TEXT
-extern void map_bootx_text(void);
-#endif
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
@@ -110,6 +107,14 @@ unsigned long SYSRQ_KEY;
struct machdep_calls ppc_md;
/*
+ * These are used in binfmt_elf.c to put aux entries on the stack
+ * for each elf executable being started.
+ */
+int dcache_bsize;
+int icache_bsize;
+int ucache_bsize;
+
+/*
* Perhaps we can put the pmac screen_info[] here
* on pmac as well so we don't need the ifdef's.
* Until we get multiple-console support in here
@@ -131,14 +136,6 @@ struct screen_info screen_info = {
};
/*
- * These are used in binfmt_elf.c to put aux entries on the stack
- * for each elf executable being started.
- */
-int dcache_bsize;
-int icache_bsize;
-int ucache_bsize;
-
-/*
* I really need to add multiple-console support... -- Cort
*/
int __init pmac_display_supported(char *name)
@@ -286,7 +283,7 @@ int get_cpuinfo(char *buffer)
case 0x000C:
len += sprintf(len+buffer, "7400 (G4");
#ifdef CONFIG_ALTIVEC
- len += sprintf(len+buffer, ", altivec enabled");
+ len += sprintf(len+buffer, ", altivec supported");
#endif /* CONFIG_ALTIVEC */
len += sprintf(len+buffer, ")\n");
break;
@@ -686,14 +683,9 @@ void __init setup_arch(char **cmdline_p)
extern char *klimit;
extern void do_init_bootmem(void);
-#ifdef CONFIG_BOOTX_TEXT
- map_bootx_text();
-#endif
-
#ifdef CONFIG_ALL_PPC
feature_init();
#endif
-
#ifdef CONFIG_XMON
xmon_map_scc();
if (strstr(cmd_line, "xmon"))
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index ee7ba852c..79847fa0d 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -1,8 +1,6 @@
/*
* linux/arch/ppc/kernel/signal.c
*
- * $Id: signal.c,v 1.27 1999/08/03 19:16:38 cort Exp $
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
@@ -156,13 +154,6 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
}
-asmlinkage int sys_rt_sigreturn(unsigned long __unused)
-{
- printk("sys_rt_sigreturn(): %s/%d not yet implemented.\n",
- current->comm,current->pid);
- do_exit(SIGSEGV);
-}
-
asmlinkage int
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
{
@@ -206,13 +197,11 @@ sys_sigaction(int sig, const struct old_sigaction *act,
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
* a sigregs struct
- * one or more sigcontext structs
+ * one or more sigcontext structs with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
- * XXX ultimately we will have to stack up a siginfo and ucontext
- * for each rt signal.
*/
struct sigregs {
elf_gregset_t gp_regs;
@@ -223,6 +212,149 @@ struct sigregs {
int abigap[56];
};
+struct rt_sigframe
+{
+ unsigned long _unused[2];
+ struct siginfo *pinfo;
+ void *puc;
+ struct siginfo info;
+ struct ucontext uc;
+};
+
+
+/*
+ * When we have rt signals to deliver, we set up on the
+ * user stack, going down from the original stack pointer:
+ * a sigregs struct
+ * one rt_sigframe struct (siginfo + ucontext)
+ * a gap of __SIGNAL_FRAMESIZE bytes
+ *
+ * Each of these things must be a multiple of 16 bytes in size.
+ *
+ */
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe *rt_sf;
+ struct sigcontext_struct sigctx;
+ struct sigregs *sr;
+ int ret;
+ elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
+ sigset_t set;
+ stack_t st;
+ unsigned long prevsp;
+
+ rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
+ if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
+ || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
+ || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
+ goto badframe;
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ rt_sf++; /* Look at next rt_sigframe */
+ if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) {
+ /* Last stacked signal - restore registers -
+ * sigctx is initialized to point to the
+ * preamble frame (where registers are stored)
+ * see handle_signal()
+ */
+ sr = (struct sigregs *) sigctx.regs;
+ if (regs->msr & MSR_FP )
+ giveup_fpu(current);
+ if (copy_from_user(saved_regs, &sr->gp_regs,
+ sizeof(sr->gp_regs)))
+ goto badframe;
+ saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
+ | (saved_regs[PT_MSR] & MSR_USERCHANGE);
+ memcpy(regs, saved_regs, GP_REGS_SIZE);
+ if (copy_from_user(current->thread.fpr, &sr->fp_regs,
+ sizeof(sr->fp_regs)))
+ goto badframe;
+ /* This function sets back the stack flags into
+ the current task structure. */
+ sys_sigaltstack(&st, NULL);
+
+ ret = regs->result;
+ } else {
+ /* More signals to go */
+ /* Set up registers for next signal handler */
+ regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE;
+ if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)))
+ goto badframe;
+ sr = (struct sigregs *) sigctx.regs;
+ regs->gpr[3] = ret = sigctx.signal;
+ /* Get the siginfo */
+ get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo);
+ /* Get the ucontext */
+ get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc);
+ regs->gpr[6] = (unsigned long) rt_sf;
+
+ regs->link = (unsigned long) &sr->tramp;
+ regs->nip = sigctx.handler;
+ if (get_user(prevsp, &sr->gp_regs[PT_R1])
+ || put_user(prevsp, (unsigned long *) regs->gpr[1]))
+ goto badframe;
+ }
+ return ret;
+
+badframe:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+static void
+setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
+ signed long newsp)
+{
+ struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp;
+
+ /* Set up preamble frame */
+ if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto badframe;
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
+ if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
+ || __copy_to_user(&frame->fp_regs, current->thread.fpr,
+ ELF_NFPREG * sizeof(double))
+ /* Set up to return from user space.
+ It calls the sc exception at offset 0x9999
+ for sys_rt_sigreturn().
+ */
+ || __put_user(0x38006666UL, &frame->tramp[0]) /* li r0,0x6666 */
+ || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
+ goto badframe;
+ flush_icache_range((unsigned long) &frame->tramp[0],
+ (unsigned long) &frame->tramp[2]);
+
+ /* Retrieve rt_sigframe from stack and
+ set up registers for signal handler
+ */
+ newsp -= __SIGNAL_FRAMESIZE;
+ if (put_user(regs->gpr[1], (unsigned long *)newsp)
+ || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
+ || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
+ || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo)
+ || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc))
+ goto badframe;
+
+ regs->gpr[1] = newsp;
+ regs->gpr[6] = (unsigned long) rt_sf;
+ regs->link = (unsigned long) frame->tramp;
+
+ return;
+
+badframe:
+#if DEBUG_SIG
+ printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
+ regs, frame, newsp);
+#endif
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
/*
* Do a signal return; undo the signal stack.
*/
@@ -341,6 +473,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
unsigned long *newspp, unsigned long frame)
{
struct sigcontext_struct *sc;
+ struct rt_sigframe *rt_sf;
if (regs->trap == 0x0C00 /* System Call! */
&& ((int)regs->result == -ERESTARTNOHAND ||
@@ -348,20 +481,47 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
!(ka->sa.sa_flags & SA_RESTART))))
regs->result = -EINTR;
- /* Put another sigcontext on the stack */
- *newspp -= sizeof(*sc);
- sc = (struct sigcontext_struct *) *newspp;
- if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
- goto badframe;
+ /* Set up Signal Frame */
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ /* Put a Real Time Context onto stack */
+ *newspp -= sizeof(*rt_sf);
+ rt_sf = (struct rt_sigframe *) *newspp;
+ if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
+ goto badframe;
- if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
+ if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
+ || __put_user(&rt_sf->info, &rt_sf->pinfo)
+ || __put_user(&rt_sf->uc, &rt_sf->puc)
+ /* Put the siginfo */
+ || __copy_to_user(&rt_sf->info, info, sizeof(*info))
+ /* Create the ucontext */
+ || __put_user(0, &rt_sf->uc.uc_flags)
+ || __put_user(0, &rt_sf->uc.uc_link)
+ || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
+ || __put_user(sas_ss_flags(regs->gpr[1]),
+ &rt_sf->uc.uc_stack.ss_flags)
+ || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+ || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
+ /* mcontext.regs points to preamble register frame */
+ || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
+ || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
+ goto badframe;
+ } else {
+ /* Put another sigcontext on the stack */
+ *newspp -= sizeof(*sc);
+ sc = (struct sigcontext_struct *) *newspp;
+ if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
+ goto badframe;
+
+ if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
+ || __put_user(oldset->sig[0], &sc->oldmask)
#if _NSIG_WORDS > 1
- || __put_user(oldset->sig[1], &sc->_unused[3])
+ || __put_user(oldset->sig[1], &sc->_unused[3])
#endif
- || __put_user((struct pt_regs *)frame, &sc->regs)
- || __put_user(sig, &sc->signal))
- goto badframe;
+ || __put_user((struct pt_regs *)frame, &sc->regs)
+ || __put_user(sig, &sc->signal))
+ goto badframe;
+ }
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
@@ -517,7 +677,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if (newsp == frame)
return 0; /* no signals delivered */
- setup_frame(regs, (struct sigregs *) frame, newsp);
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(regs, (struct sigregs *) frame, newsp);
+ else
+ setup_frame(regs, (struct sigregs *) frame, newsp);
return 1;
}
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 176a47ca5..8cb68c6b2 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -39,7 +39,7 @@
#include <asm/smp.h>
#include <asm/gemini.h>
-#include "time.h"
+#include <asm/time.h>
#include "open_pic.h"
int smp_threads_ready = 0;
volatile int smp_commenced = 0;
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 11aa42cad..4c1802135 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -274,3 +274,13 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
error = error ? -EFAULT : 0;
return error;
}
+
+#ifndef CONFIG_PCI
+/*
+ * Those are normally defined in arch/ppc/kernel/pci.c. But when CONFIG_PCI is
+ * not defined, this file is not linked at all, so here are the "empty" versions
+ */
+asmlinkage int sys_pciconfig_read() { return -ENOSYS; }
+asmlinkage int sys_pciconfig_write() { return -ENOSYS; }
+asmlinkage long sys_pciconfig_iobase() { return -ENOSYS; }
+#endif
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 3303bf785..aff4838b3 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -44,7 +44,7 @@
#include <asm/8xx_immap.h>
#include <asm/machdep.h>
-#include "time.h"
+#include <asm/time.h>
void smp_local_timer_interrupt(struct pt_regs *);
@@ -70,7 +70,9 @@ unsigned long last_tb;
int timer_interrupt(struct pt_regs * regs)
{
int dval, d;
+#if 0
unsigned long flags;
+#endif
unsigned long cpu = smp_processor_id();
hardirq_enter(cpu);
@@ -120,6 +122,13 @@ int timer_interrupt(struct pt_regs * regs)
if ( !smp_processor_id() )
{
do_timer(regs);
+#if 0
+ /* -- BenH -- I'm removing this for now since it can cause various
+ * troubles with local-time RTCs. Now that we have a
+ * /dev/rtc that uses ppc_md.set_rtc_time() on mac, it
+ * should be possible to program the RTC from userland
+ * in all cases.
+ */
/*
* update the rtc when needed
*/
@@ -135,6 +144,7 @@ int timer_interrupt(struct pt_regs * regs)
last_rtc_update = xtime.tv_sec;
}
read_unlock_irqrestore(&xtime_lock, flags);
+#endif
}
#ifdef CONFIG_SMP
smp_local_timer_interrupt(regs);
diff --git a/arch/ppc/kernel/walnut_setup.c b/arch/ppc/kernel/walnut_setup.c
index 284c732c1..768c36a94 100644
--- a/arch/ppc/kernel/walnut_setup.c
+++ b/arch/ppc/kernel/walnut_setup.c
@@ -28,7 +28,7 @@
#include "local_irq.h"
#include "ppc4xx_pic.h"
-#include "time.h"
+#include <asm/time.h>
#include "walnut_setup.h"
diff --git a/arch/ppc/mbxboot/m8xx_tty.c b/arch/ppc/mbxboot/m8xx_tty.c
index a591d824d..811a13796 100644
--- a/arch/ppc/mbxboot/m8xx_tty.c
+++ b/arch/ppc/mbxboot/m8xx_tty.c
@@ -21,6 +21,17 @@
#define CSR1_COMEN (u_char)0x02
#endif
+#ifdef TQM_SMC2_CONSOLE
+#define PROFF_CONS PROFF_SMC2
+#define CPM_CR_CH_CONS CPM_CR_CH_SMC2
+#define SMC_INDEX 1
+static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
+#else
+#define PROFF_CONS PROFF_SMC1
+#define CPM_CR_CH_CONS CPM_CR_CH_SMC1
+#define SMC_INDEX 0
+#endif
+
static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
void
@@ -33,8 +44,8 @@ serial_init(bd_t *bd)
uint dpaddr, memaddr;
cp = cpmp;
- sp = (smc_t*)&(cp->cp_smc[0]);
- up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
+ sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
+ up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
/* Disable transmitter/receiver.
*/
@@ -42,18 +53,26 @@ serial_init(bd_t *bd)
#ifndef CONFIG_MBX
{
- /* Initialize SMC1 and use it for the console port.
+ /* Initialize SMCx and use it for the console port.
*/
/* Enable SDMA.
*/
((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+#ifdef TQM_SMC2_CONSOLE
+ /* Use Port A for SMC2 instead of other functions.
+ */
+ iopp->iop_papar |= 0x00c0;
+ iopp->iop_padir &= ~0x00c0;
+ iopp->iop_paodr &= ~0x00c0;
+#else
/* Use Port B for SMCs instead of other functions.
*/
cp->cp_pbpar |= 0x00000cc0;
cp->cp_pbdir &= ~0x00000cc0;
cp->cp_pbodr &= ~0x00000cc0;
+#endif
/* Allocate space for two buffer descriptors in the DP ram.
* For now, this address seems OK, but it may have to
@@ -61,8 +80,7 @@ serial_init(bd_t *bd)
*/
dpaddr = 0x0800;
- /* Grab a few bytes from the top of memory. EPPC-Bug isn't
- * running any more, so we can do this.
+ /* Grab a few bytes from the top of memory for SMC FIFOs.
*/
memaddr = (bd->bi_memsize - 32) & ~15;
@@ -95,9 +113,14 @@ serial_init(bd_t *bd)
/* Set up the baud rate generator.
* See 8xx_io/commproc.c for details.
+ * This wires BRG1 to SMC1 and BRG2 to SMC2;
*/
cp->cp_simode = 0x10000000;
+#ifdef TQM_SMC2_CONSOLE
+ cp->cp_brgc2 =
+#else
cp->cp_brgc1 =
+#endif
((((bd->bi_intfreq * 1000000)/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN;
#else /* CONFIG_MBX */
@@ -167,14 +190,14 @@ serial_init(bd_t *bd)
}
else {
#endif /* ndef CONFIG_MBX */
- /* SMC1 is used as console port.
+ /* SMCx is used as console port.
*/
tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
/* Issue a stop transmit, and wait for it.
*/
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1,
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
CPM_CR_STOP_TX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
}
@@ -191,7 +214,7 @@ serial_init(bd_t *bd)
/* Initialize Tx/Rx parameters.
*/
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
/* Enable transmitter/receiver.
@@ -206,7 +229,7 @@ serial_putchar(const char c)
volatile char *buf;
volatile smc_uart_t *up;
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
/* Wait for last character to go.
@@ -227,7 +250,7 @@ serial_getc()
volatile smc_uart_t *up;
char c;
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
/* Wait for character to show up.
@@ -246,7 +269,7 @@ serial_tstc()
volatile cbd_t *rbdf;
volatile smc_uart_t *up;
- up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1];
+ up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
return(!(rbdf->cbd_sc & BD_SC_EMPTY));
diff --git a/arch/ppc/mbxboot/misc.c b/arch/ppc/mbxboot/misc.c
index d5a44df1e..60563122d 100644
--- a/arch/ppc/mbxboot/misc.c
+++ b/arch/ppc/mbxboot/misc.c
@@ -225,7 +225,9 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
s.avail_out = dstlen;
r = inflate(&s, Z_FINISH);
if (r != Z_OK && r != Z_STREAM_END) {
- puts("inflate returned %d\n");
+ puts("inflate returned ");
+ puthex(r);
+ puts("\n");
exit();
}
*lenp = s.next_out - (unsigned char *) dst;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 0cfb5916c..16c3bc694 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -931,6 +931,9 @@ MMU_init(void)
/* How about ppc_md.md_find_end_of_memory instead of these
* ifdefs? -- Dan.
*/
+#ifdef CONFIG_BOOTX_TEXT
+extern boot_infos_t *disp_bi;
+#endif
void __init MMU_init(void)
{
if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
@@ -1050,6 +1053,11 @@ void __init MMU_init(void)
#endif
#endif /* CONFIG_8xx */
if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
+#ifdef CONFIG_BOOTX_TEXT
+ /* Must be done last, or ppc_md.progress will die */
+ if (_machine == _MACH_Pmac)
+ map_bootx_text();
+#endif
}
#endif /* CONFIG_4xx */
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 4abc138cf..75160d9b8 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -84,8 +84,10 @@ static void insert_bpts(void);
static struct bpt *at_breakpoint(unsigned pc);
static void bpt_cmds(void);
static void cacheflush(void);
+#if 0 /* Makes compile with -Wall */
static char *pretty_print_addr(unsigned long addr);
static char *lookup_name(unsigned long addr);
+#endif
static void csum(void);
extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
@@ -1493,6 +1495,7 @@ char *str;
lineptr = str;
}
+#if 0 /* Makes compile with -Wall */
static char *pretty_print_addr(unsigned long addr)
{
printf("%08x", addr);
@@ -1500,14 +1503,15 @@ static char *pretty_print_addr(unsigned long addr)
printf(" %s", lookup_name(addr) );
return NULL;
}
+#endif
+#if 0 /* Makes compile with -Wall */
static char *lookup_name(unsigned long addr)
{
extern char *sysmap;
extern unsigned long sysmap_size;
char *c = sysmap;
unsigned long cmp;
-
if ( !sysmap || !sysmap_size )
return NULL;
return NULL;
@@ -1525,4 +1529,4 @@ return NULL;
return last;
#endif
}
-
+#endif
diff --git a/arch/s390/config.in b/arch/s390/config.in
index 9e946365f..7835a0162 100644
--- a/arch/s390/config.in
+++ b/arch/s390/config.in
@@ -14,21 +14,21 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
-comment 'Processor type and features'
-bool 'Symmetric multi-processing support' CONFIG_SMP
-bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION
-endmenu
-
-mainmenu_option next_comment
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
fi
endmenu
mainmenu_option next_comment
+comment 'Processor type and features'
+bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION
+endmenu
+
+mainmenu_option next_comment
comment 'General setup'
bool 'Fast IRQ handling' CONFIG_FAST_IRQ
bool 'Builtin IPL record support' CONFIG_IPL
diff --git a/arch/sh/config.in b/arch/sh/config.in
index 025e8a8ea..0a83038dc 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -14,6 +14,15 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'Processor type and features'
choice 'SuperH system type' \
"Generic CONFIG_SH_GENERIC \
@@ -48,15 +57,6 @@ fi
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_ISA n
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index 0813c9501..b4b50975d 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -300,7 +300,7 @@ CONFIG_NFSD=m
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_SMB_FS=m
-CONFIG_NCP_FS=m
+# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 857658391..f119c59ac 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.150 2000/07/11 18:49:22 anton Exp $
+/* $Id: process.c,v 1.151 2000/07/11 23:22:17 davem Exp $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 4d1a8db1c..a51995713 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.100 2000/07/07 07:49:08 anton Exp $
+/* $Id: sparc_ksyms.c,v 1.101 2000/07/12 00:25:32 anton Exp $
* arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -19,6 +19,9 @@
#include <linux/in6.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#endif
#include <asm/oplib.h>
#include <asm/delay.h>
@@ -42,9 +45,6 @@
#include <asm/sbus.h>
#include <asm/dma.h>
#endif
-#ifdef CONFIG_PCI
-#include <asm/pci.h>
-#endif
#include <asm/a.out.h>
#include <asm/io-unit.h>
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 3cf68e2b5..55e8516c6 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -437,17 +437,17 @@ CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_SMB_FS=m
-CONFIG_NCP_FS=m
-CONFIG_NCPFS_PACKET_SIGNING=y
-CONFIG_NCPFS_IOCTL_LOCKING=y
-CONFIG_NCPFS_STRONG=y
-CONFIG_NCPFS_NFS_NS=y
-CONFIG_NCPFS_OS2_NS=y
-CONFIG_NCPFS_SMALLDOS=y
-CONFIG_NCPFS_MOUNT_SUBDIR=y
-CONFIG_NCPFS_NDS_DOMAINS=y
-CONFIG_NCPFS_NLS=y
-CONFIG_NCPFS_EXTRAS=y
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
index 59b48600d..6d9e291d4 100644
--- a/arch/sparc64/kernel/binfmt_elf32.c
+++ b/arch/sparc64/kernel/binfmt_elf32.c
@@ -79,7 +79,7 @@ typedef struct {
} pr_un;
} elf_xregset_t;
-#define elf_check_arch(x) (((x) == EM_SPARC) || ((x) == EM_SPARC32PLUS))
+#define elf_check_arch(x) (((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS))
#define ELF_ET_DYN_BASE 0x08000000
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index 9a2556bbc..01595faee 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -19,6 +19,7 @@
#include <linux/malloc.h>
#include <linux/in.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/termios.h>
@@ -118,6 +119,7 @@ static int socksys_release(struct inode * inode, struct file * filp)
struct T_primsg *it;
/* XXX: check this */
+ lock_kernel();
sock = (struct sol_socket_struct *)filp->private_data;
SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
it = sock->pfirst;
@@ -131,6 +133,7 @@ static int socksys_release(struct inode * inode, struct file * filp)
filp->private_data = NULL;
SOLDD(("socksys_release %016lx\n", sock));
mykfree((char*)sock);
+ unlock_kernel();
return 0;
}
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
index 37f38c75b..946b20fae 100644
--- a/arch/sparc64/solaris/timod.c
+++ b/arch/sparc64/solaris/timod.c
@@ -1,4 +1,4 @@
-/* $Id: timod.c,v 1.7 2000/06/09 07:35:30 davem Exp $
+/* $Id: timod.c,v 1.9 2000/07/12 23:21:02 davem Exp $
* timod.c: timod emulation.
*
* Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
@@ -15,6 +15,7 @@
#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
+#include <linux/file.h>
#include <linux/netdevice.h>
#include <linux/poll.h>
@@ -619,22 +620,6 @@ int timod_putmsg(unsigned int fd, char *ctl_buf, int ctl_len,
return -EINVAL;
}
-/* copied directly from fs/select.c */
-
-static void free_wait(poll_table * p)
-{
- struct poll_table_entry * entry = p->entry + p->nr;
-
- SOLD("entry");
- while (p->nr > 0) {
- p->nr--;
- entry--;
- remove_wait_queue(entry->wait_address,&entry->wait);
- }
- SOLD("done");
-}
-
-
int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len,
char *data_buf, int data_maxlen, s32 *data_len, int *flags_p)
{
@@ -670,14 +655,8 @@ int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len,
}
if (!(filp->f_flags & O_NONBLOCK)) {
poll_table wait_table, *wait;
- struct poll_table_entry *entry;
- SOLD("getting poll_table");
- entry = (struct poll_table_entry *)__get_free_page(GFP_KERNEL);
- if (!entry)
- return -ENOMEM;
- SOLD("got one");
- wait_table.nr = 0;
- wait_table.entry = entry;
+
+ poll_initwait(&wait_table);
wait = &wait_table;
for(;;) {
SOLD("loop");
@@ -705,13 +684,17 @@ int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len,
SOLD("avoiding lockup");
break ;
}
+ if(wait_table.error) {
+ SOLD("wait-table error");
+ poll_freewait(&wait_table);
+ return wait_table.error;
+ }
SOLD("scheduling");
schedule();
}
SOLD("loop done");
current->state = TASK_RUNNING;
- free_wait(&wait_table);
- free_page((unsigned long)entry);
+ poll_freewait(&wait_table);
if (signal_pending(current)) {
SOLD("signal pending");
return -EINTR;
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index c8b888ff1..2c9606663 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -11,7 +11,7 @@ O_TARGET := acpi.o
O_OBJS :=
M_OBJS :=
-ACPI_OBJS := osd.o
+ACPI_OBJS := driver.o ec.o cpu.o os.o sys.o tables.o
ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard */*.c))
EXTRA_CFLAGS += -I./include -D_LINUX
diff --git a/drivers/acpi/cpu.c b/drivers/acpi/cpu.c
new file mode 100644
index 000000000..f1feeb12b
--- /dev/null
+++ b/drivers/acpi/cpu.c
@@ -0,0 +1,307 @@
+/*
+ * cpu.c - Processor handling
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
+unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
+unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
+unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
+
+static unsigned long acpi_pblk = ACPI_INVALID;
+static int acpi_c2_tested = 0;
+static int acpi_c3_tested = 0;
+
+/*
+ * Clear busmaster activity flag
+ */
+static inline void
+acpi_clear_bm_activity(struct acpi_facp *facp)
+{
+ acpi_write_pm1_status(facp, ACPI_BM);
+}
+
+/*
+ * Returns 1 if there has been busmaster activity
+ */
+static inline int
+acpi_bm_activity(struct acpi_facp *facp)
+{
+ return acpi_read_pm1_status(facp) & ACPI_BM;
+}
+
+/*
+ * Set system to sleep through busmaster requests
+ */
+static void
+acpi_sleep_on_busmaster(struct acpi_facp *facp)
+{
+ u32 pm1_cntr = acpi_read_pm1_control(facp);
+ if (pm1_cntr & ACPI_BM_RLD) {
+ pm1_cntr &= ~ACPI_BM_RLD;
+ acpi_write_pm1_control(facp, pm1_cntr);
+ }
+}
+
+/*
+ * Set system to wake on busmaster requests
+ */
+static void
+acpi_wake_on_busmaster(struct acpi_facp *facp)
+{
+ u32 pm1_cntr = acpi_read_pm1_control(facp);
+ if (!(pm1_cntr & ACPI_BM_RLD)) {
+ pm1_cntr |= ACPI_BM_RLD;
+ acpi_write_pm1_control(facp, pm1_cntr);
+ }
+ acpi_clear_bm_activity(facp);
+}
+
+/* The ACPI timer is just the low 24 bits */
+#define TIME_BEGIN(tmr) inl(tmr)
+#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
+
+/*
+ * Idle loop (uniprocessor only)
+ */
+static void
+acpi_idle(void)
+{
+ static int sleep_level = 1;
+ struct acpi_facp *facp = &acpi_facp;
+
+ if (!facp
+ || facp->hdr.signature != ACPI_FACP_SIG
+ || !facp->pm_tmr
+ || !acpi_pblk)
+ goto not_initialized;
+
+ /*
+ * start from the previous sleep level..
+ */
+ if (sleep_level == 1)
+ goto sleep1;
+ if (sleep_level == 2)
+ goto sleep2;
+ sleep3:
+ sleep_level = 3;
+ if (!acpi_c3_tested) {
+ printk(KERN_DEBUG "ACPI C3 works\n");
+ acpi_c3_tested = 1;
+ }
+ acpi_wake_on_busmaster(facp);
+ if (facp->pm2_cnt)
+ goto sleep3_with_arbiter;
+
+ for (;;) {
+ unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
+ __cli();
+ if (current->need_resched)
+ goto out;
+ if (acpi_bm_activity(facp))
+ goto sleep2;
+
+ time = TIME_BEGIN(pm_tmr);
+ inb(acpi_pblk + ACPI_P_LVL3);
+ /* Dummy read, force synchronization with the PMU */
+ inl(pm_tmr);
+ time = TIME_END(pm_tmr, time);
+
+ __sti();
+ if (time < acpi_c3_exit_latency)
+ goto sleep2;
+ }
+
+ sleep3_with_arbiter:
+ for (;;) {
+ unsigned long time;
+ u8 arbiter;
+ unsigned int pm2_cntr = facp->pm2_cnt;
+ unsigned int pm_tmr = facp->pm_tmr;
+
+ __cli();
+ if (current->need_resched)
+ goto out;
+ if (acpi_bm_activity(facp))
+ goto sleep2;
+
+ time = TIME_BEGIN(pm_tmr);
+ arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
+ /* Disable arbiter, park on CPU */
+ outb(arbiter | ACPI_ARB_DIS, pm2_cntr);
+ inb(acpi_pblk + ACPI_P_LVL3);
+ /* Dummy read, force synchronization with the PMU */
+ inl(pm_tmr);
+ time = TIME_END(pm_tmr, time);
+ /* Enable arbiter again.. */
+ outb(arbiter, pm2_cntr);
+
+ __sti();
+ if (time < acpi_c3_exit_latency)
+ goto sleep2;
+ }
+
+ sleep2:
+ sleep_level = 2;
+ if (!acpi_c2_tested) {
+ printk(KERN_DEBUG "ACPI C2 works\n");
+ acpi_c2_tested = 1;
+ }
+ acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */
+ for (;;) {
+ unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
+ __cli();
+ if (current->need_resched)
+ goto out;
+
+ time = TIME_BEGIN(pm_tmr);
+ inb(acpi_pblk + ACPI_P_LVL2);
+ /* Dummy read, force synchronization with the PMU */
+ inl(pm_tmr);
+ time = TIME_END(pm_tmr, time);
+
+ __sti();
+ if (time < acpi_c2_exit_latency)
+ goto sleep1;
+ if (acpi_bm_activity(facp)) {
+ acpi_clear_bm_activity(facp);
+ continue;
+ }
+ if (time > acpi_c3_enter_latency)
+ goto sleep3;
+ }
+
+ sleep1:
+ sleep_level = 1;
+ acpi_sleep_on_busmaster(facp);
+ for (;;) {
+ unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
+ __cli();
+ if (current->need_resched)
+ goto out;
+ time = TIME_BEGIN(pm_tmr);
+ safe_halt();
+ time = TIME_END(pm_tmr, time);
+ if (time > acpi_c2_enter_latency)
+ goto sleep2;
+ }
+
+ not_initialized:
+ for (;;) {
+ __cli();
+ if (current->need_resched)
+ goto out;
+ safe_halt();
+ }
+
+ out:
+ __sti();
+}
+
+/*
+ * Get processor information
+ */
+static ACPI_STATUS
+acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
+{
+ ACPI_OBJECT obj;
+ ACPI_CX_STATE lat[4];
+ ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
+ ACPI_BUFFER buf;
+ int i, count;
+
+ buf.length = sizeof(obj);
+ buf.pointer = &obj;
+ if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
+ return AE_OK;
+
+ printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n",
+ obj.processor.proc_id,
+ obj.processor.pblk_address,
+ obj.processor.pblk_length);
+ if (acpi_pblk != ACPI_INVALID
+ || !obj.processor.pblk_address
+ || obj.processor.pblk_length != 6)
+ return AE_OK;
+
+ acpi_pblk = obj.processor.pblk_address;
+
+ buf.length = sizeof(lat);
+ buf.pointer = lat;
+ if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
+ return AE_OK;
+
+ if (lat[2].latency < MAX_CX_STATE_LATENCY) {
+ printk(KERN_INFO "ACPI: C2 supported\n");
+ acpi_c2_exit_latency = lat[2].latency;
+ }
+ if (lat[3].latency < MAX_CX_STATE_LATENCY) {
+ printk(KERN_INFO "ACPI: C3 supported\n");
+ acpi_c3_exit_latency = lat[3].latency;
+ }
+
+ memset(throttle, 0, sizeof(throttle));
+ buf.length = sizeof(throttle);
+ buf.pointer = throttle;
+
+ if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
+ return AE_OK;
+
+ for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
+ if (throttle[i].percent_of_clock)
+ count++;
+ }
+ count--;
+ if (count > 0)
+ printk(KERN_INFO "ACPI: %d throttling states\n", count);
+
+ return AE_OK;
+}
+
+int
+acpi_cpu_init(void)
+{
+ acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
+ ACPI_ROOT_OBJECT,
+ ACPI_INT32_MAX,
+ acpi_find_cpu,
+ NULL,
+ NULL);
+
+#ifdef CONFIG_SMP
+ if (smp_num_cpus == 1)
+ pm_idle = acpi_idle;
+#else
+ pm_idle = acpi_idle;
+#endif
+
+ return 0;
+}
diff --git a/drivers/acpi/driver.c b/drivers/acpi/driver.c
new file mode 100644
index 000000000..0c668f59b
--- /dev/null
+++ b/drivers/acpi/driver.c
@@ -0,0 +1,388 @@
+/*
+ * driver.c - ACPI driver
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <asm/uaccess.h>
+#include "acpi.h"
+#include "driver.h"
+
+struct acpi_run_entry
+{
+ void (*callback)(void*);
+ void *context;
+ struct tq_struct task;
+};
+
+static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
+static volatile u32 acpi_event_status = 0;
+static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
+static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
+
+static volatile int acpi_thread_pid = -1;
+static DECLARE_TASK_QUEUE(acpi_thread_run);
+static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait);
+
+static struct ctl_table_header *acpi_sysctl = NULL;
+
+/*
+ * Examine/modify value
+ */
+static int
+acpi_do_ulong(ctl_table * ctl,
+ int write,
+ struct file *file,
+ void *buffer,
+ size_t * len)
+{
+ char str[2 * sizeof(unsigned long) + 4], *strend;
+ unsigned long val;
+ int size;
+
+ if (!write) {
+ if (file->f_pos) {
+ *len = 0;
+ return 0;
+ }
+
+ val = *(unsigned long *) ctl->data;
+ size = sprintf(str, "0x%08lx\n", val);
+ if (*len >= size) {
+ copy_to_user(buffer, str, size);
+ *len = size;
+ }
+ else
+ *len = 0;
+ }
+ else {
+ size = sizeof(str) - 1;
+ if (size > *len)
+ size = *len;
+ copy_from_user(str, buffer, size);
+ str[size] = '\0';
+ val = simple_strtoul(str, &strend, 0);
+ if (strend == str)
+ return -EINVAL;
+ *(unsigned long *) ctl->data = val;
+ }
+
+ file->f_pos += *len;
+ return 0;
+}
+
+/*
+ * Handle ACPI event
+ */
+static u32
+acpi_event(void *context)
+{
+ unsigned long flags;
+ int event = (int) context;
+ int mask = 0;
+
+ switch (event) {
+ case ACPI_EVENT_POWER_BUTTON: mask = ACPI_PWRBTN; break;
+ case ACPI_EVENT_SLEEP_BUTTON: mask = ACPI_SLPBTN; break;
+ default: return AE_ERROR;
+ }
+
+ if (mask) {
+ // notify process waiting on /dev/acpi
+ spin_lock_irqsave(&acpi_event_lock, flags);
+ acpi_event_status |= mask;
+ spin_unlock_irqrestore(&acpi_event_lock, flags);
+ acpi_event_state = acpi_sleep_state;
+ wake_up_interruptible(&acpi_event_wait);
+ }
+
+ return AE_OK;
+}
+
+/*
+ * Wait for next event
+ */
+static int
+acpi_do_event(ctl_table * ctl,
+ int write,
+ struct file *file,
+ void *buffer,
+ size_t * len)
+{
+ u32 event_status = 0;
+ acpi_sstate_t event_state = 0;
+ char str[27];
+ int size;
+
+ if (write)
+ return -EPERM;
+ if (*len < sizeof(str)) {
+ *len = 0;
+ return 0;
+ }
+
+ for (;;) {
+ unsigned long flags;
+
+ // we need an atomic exchange here
+ spin_lock_irqsave(&acpi_event_lock, flags);
+ event_status = acpi_event_status;
+ acpi_event_status = 0;
+ spin_unlock_irqrestore(&acpi_event_lock, flags);
+ event_state = acpi_event_state;
+
+ if (event_status)
+ break;
+
+ // wait for an event to arrive
+ interruptible_sleep_on(&acpi_event_wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ }
+
+ size = sprintf(str,
+ "0x%08x 0x%08x 0x%01x\n",
+ event_status,
+ 0,
+ event_state);
+ copy_to_user(buffer, str, size);
+ *len = size;
+ file->f_pos += size;
+
+ return 0;
+}
+
+/*
+ * Enter system sleep state
+ */
+static int
+acpi_do_sleep(ctl_table * ctl,
+ int write,
+ struct file *file,
+ void *buffer,
+ size_t * len)
+{
+ if (!write) {
+ if (file->f_pos) {
+ *len = 0;
+ return 0;
+ }
+ }
+ else {
+#ifdef CONFIG_ACPI_S1_SLEEP
+ int status = acpi_enter_sx(ACPI_S1);
+ if (status)
+ return status;
+#endif
+ }
+ file->f_pos += *len;
+ return 0;
+}
+
+/*
+ * Run queued callback
+ */
+static void
+acpi_run_exec(void *context)
+{
+ struct acpi_run_entry *entry
+ = (struct acpi_run_entry*) context;
+ (*entry->callback)(entry->context);
+ kfree(entry);
+}
+
+/*
+ * Queue for execution by the ACPI thread
+ */
+int
+acpi_run(void (*callback)(void*), void *context)
+{
+ struct acpi_run_entry *entry;
+
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ if (!entry)
+ return -1;
+
+ memset(entry, 0, sizeof(entry));
+ entry->callback = callback;
+ entry->context = context;
+ entry->task.routine = acpi_run_exec;
+ entry->task.data = entry;
+
+ queue_task(&entry->task, &acpi_thread_run);
+
+ if (waitqueue_active(&acpi_thread_wait))
+ wake_up(&acpi_thread_wait);
+
+ return 0;
+}
+
+static struct ctl_table acpi_table[] =
+{
+ {ACPI_P_LVL2_LAT, "c2_exit_latency",
+ &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
+ 0644, NULL, &acpi_do_ulong},
+
+ {ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
+ &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
+ 0644, NULL, &acpi_do_ulong},
+
+ {ACPI_P_LVL3_LAT, "c3_exit_latency",
+ &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
+ 0644, NULL, &acpi_do_ulong},
+
+ {ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
+ &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
+ 0644, NULL, &acpi_do_ulong},
+
+ {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
+
+ {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
+
+ {0}
+};
+
+static struct ctl_table acpi_dir_table[] =
+{
+ {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
+ {0}
+};
+
+/*
+ * Initialize and run interpreter within a kernel thread
+ */
+static int
+acpi_thread(void *context)
+{
+ /*
+ * initialize
+ */
+ exit_files(current);
+ daemonize();
+ strcpy(current->comm, "acpi");
+
+ if (!ACPI_SUCCESS(acpi_initialize(NULL))) {
+ printk(KERN_ERR "ACPI: initialize failed\n");
+ return -ENODEV;
+ }
+
+ if (acpi_load_tables())
+ return -ENODEV;
+
+ if (PM_IS_ACTIVE()) {
+ printk(KERN_NOTICE "ACPI: APM is already active.\n");
+ acpi_terminate();
+ return -ENODEV;
+ }
+
+ pm_active = 1;
+
+ if (!ACPI_SUCCESS(acpi_enable())) {
+ printk(KERN_ERR "ACPI: enable failed\n");
+ acpi_terminate();
+ return -ENODEV;
+ }
+
+ acpi_cpu_init();
+ acpi_sys_init();
+ acpi_ec_init();
+
+ if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
+ ACPI_EVENT_POWER_BUTTON,
+ acpi_event,
+ (void *) ACPI_EVENT_POWER_BUTTON))) {
+ printk(KERN_ERR "ACPI: power button enable failed\n");
+ }
+ if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
+ ACPI_EVENT_SLEEP_BUTTON,
+ acpi_event,
+ (void *) ACPI_EVENT_SLEEP_BUTTON))) {
+ printk(KERN_ERR "ACPI: sleep button enable failed\n");
+ }
+
+ acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
+
+ /*
+ * run
+ */
+ for (;;) {
+ interruptible_sleep_on(&acpi_thread_wait);
+ if (signal_pending(current))
+ break;
+ do {
+ run_task_queue(&acpi_thread_run);
+ } while (acpi_thread_run);
+ }
+
+ /*
+ * terminate
+ */
+ unregister_sysctl_table(acpi_sysctl);
+ acpi_terminate();
+
+ acpi_thread_pid = -1;
+
+ return 0;
+}
+
+/*
+ * Start the interpreter
+ */
+int __init
+acpi_init(void)
+{
+ acpi_thread_pid = kernel_thread(acpi_thread,
+ NULL,
+ (CLONE_FS | CLONE_FILES
+ | CLONE_SIGHAND | SIGCHLD));
+ return ((acpi_thread_pid >= 0) ? 0:-ENODEV);
+}
+
+/*
+ * Terminate the interpreter
+ */
+void __exit
+acpi_exit(void)
+{
+ int count;
+
+ if (!kill_proc(acpi_thread_pid, SIGTERM, 1)) {
+ // wait until thread terminates (at most 5 seconds)
+ count = 5 * HZ;
+ while (acpi_thread_pid >= 0 && --count) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ }
+
+ pm_idle = NULL;
+ pm_power_off = NULL;
+ pm_active = 0;
+}
+
+module_init(acpi_init);
+module_exit(acpi_exit);
diff --git a/drivers/acpi/driver.h b/drivers/acpi/driver.h
new file mode 100644
index 000000000..a26402b40
--- /dev/null
+++ b/drivers/acpi/driver.h
@@ -0,0 +1,115 @@
+/*
+ * driver.h - ACPI driver
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __DRIVER_H
+#define __DRIVER_H
+
+#include <linux/tqueue.h>
+#include <linux/wait.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <asm/io.h>
+
+#define ACPI_MAX_THROTTLE 10
+#define ACPI_INVALID ~0UL
+#define ACPI_INFINITE ~0UL
+
+/*
+ * cpu.c
+ */
+int acpi_cpu_init(void);
+
+extern unsigned long acpi_c2_exit_latency;
+extern unsigned long acpi_c3_exit_latency;
+extern unsigned long acpi_c2_enter_latency;
+extern unsigned long acpi_c3_enter_latency;
+
+/*
+ * driver.c
+ */
+int acpi_run(void (*callback)(void*), void *context);
+
+/*
+ * ec.c
+ */
+int acpi_ec_init(void);
+int acpi_ec_read(int addr, int *value);
+int acpi_ec_write(int addr, int value);
+
+/*
+ * sys.c
+ */
+int acpi_sys_init(void);
+int acpi_enter_sx(acpi_sstate_t state);
+
+extern volatile acpi_sstate_t acpi_sleep_state;
+
+/*
+ * tables.c
+ */
+extern struct acpi_facp acpi_facp;
+
+int acpi_load_tables(void);
+
+/*
+ * access ACPI registers
+ */
+
+extern inline u32
+acpi_read_pm1_control(struct acpi_facp *facp)
+{
+ u32 value = 0;
+ if (facp->pm1a_cnt)
+ value = inw(facp->pm1a_cnt);
+ if (facp->pm1b_cnt)
+ value |= inw(facp->pm1b_cnt);
+ return value;
+}
+
+extern inline void
+acpi_write_pm1_control(struct acpi_facp *facp, u32 value)
+{
+ if (facp->pm1a_cnt)
+ outw(value, facp->pm1a_cnt);
+ if (facp->pm1b_cnt)
+ outw(value, facp->pm1b_cnt);
+}
+
+extern inline u32
+acpi_read_pm1_status(struct acpi_facp *facp)
+{
+ u32 value = 0;
+ if (facp->pm1a_evt)
+ value = inw(facp->pm1a_evt);
+ if (facp->pm1b_evt)
+ value |= inw(facp->pm1b_evt);
+ return value;
+}
+
+extern inline void
+acpi_write_pm1_status(struct acpi_facp *facp, u32 value)
+{
+ if (facp->pm1a_evt)
+ outw(value, facp->pm1a_evt);
+ if (facp->pm1b_evt)
+ outw(value, facp->pm1b_evt);
+}
+
+#endif /* __DRIVER_H */
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
new file mode 100644
index 000000000..3e5fe753f
--- /dev/null
+++ b/drivers/acpi/ec.c
@@ -0,0 +1,191 @@
+/*
+ * ec.c - Embedded controller support
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "acpi.h"
+#include "driver.h"
+
+enum
+{
+ ACPI_EC_HID = 0x090cd041,
+};
+
+enum
+{
+ ACPI_EC_SMI = 0x40,
+ ACPI_EC_SCI = 0x20,
+ ACPI_EC_BURST = 0x10,
+ ACPI_EC_CMD = 0x08,
+ ACPI_EC_IBF = 0x02,
+ ACPI_EC_OBF = 0x01
+};
+
+enum
+{
+ ACPI_EC_READ = 0x80,
+ ACPI_EC_WRITE = 0x81,
+ ACPI_EC_BURST_ENABLE = 0x82,
+ ACPI_EC_BURST_DISABLE = 0x83,
+ ACPI_EC_QUERY = 0x84,
+};
+
+
+static int acpi_ec_data = 0;
+static int acpi_ec_status = 0;
+static DECLARE_WAIT_QUEUE_HEAD(acpi_ec_wait);
+
+/*
+ * handle GPE
+ */
+static void
+acpi_ec_gpe(void *context)
+{
+ printk(KERN_INFO "ACPI: EC GPE\n");
+ if (waitqueue_active(&acpi_ec_wait))
+ wake_up_interruptible(&acpi_ec_wait);
+}
+
+/*
+ * wait for read/write status to clear
+ */
+static void
+acpi_ec_wait_control(void)
+{
+ udelay(1);
+ while(inb(acpi_ec_status) & ACPI_EC_IBF)
+ udelay(10);
+}
+
+/*
+ * read a byte from the EC
+ */
+int
+acpi_ec_read(int addr, int *value)
+{
+ if (!acpi_ec_data || !acpi_ec_status)
+ return -1;
+
+ outb(ACPI_EC_READ, acpi_ec_status);
+ acpi_ec_wait_control();
+ outb(addr, acpi_ec_data);
+ acpi_ec_wait_control();
+ interruptible_sleep_on(&acpi_ec_wait);
+ *value = inb(acpi_ec_data);
+
+ return 0;
+}
+
+/*
+ * write a byte to the EC
+ */
+int
+acpi_ec_write(int addr, int value)
+{
+ if (!acpi_ec_data || !acpi_ec_status)
+ return -1;
+
+ outb(ACPI_EC_WRITE, acpi_ec_status);
+ acpi_ec_wait_control();
+ outb(addr, acpi_ec_data);
+ acpi_ec_wait_control();
+ outb(value, acpi_ec_data);
+ acpi_ec_wait_control();
+ interruptible_sleep_on(&acpi_ec_wait);
+
+ return 0;
+}
+
+/*
+ * Get processor information
+ */
+static ACPI_STATUS
+acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
+{
+ ACPI_BUFFER buf;
+ ACPI_OBJECT obj;
+ RESOURCE *res;
+ int gpe;
+
+ buf.length = sizeof(obj);
+ buf.pointer = &obj;
+ if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_HID", NULL, &buf))
+ || obj.type != ACPI_TYPE_NUMBER
+ || obj.number.value != ACPI_EC_HID)
+ return AE_OK;
+
+ buf.length = 0;
+ buf.pointer = NULL;
+ if (acpi_get_current_resources(handle, &buf) != AE_BUFFER_OVERFLOW)
+ return AE_OK;
+
+ buf.pointer = kmalloc(buf.length, GFP_KERNEL);
+ if (!buf.pointer)
+ return AE_OK;
+
+ if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) {
+ kfree(buf.pointer);
+ return AE_OK;
+ }
+
+ res = (RESOURCE*) buf.pointer;
+ acpi_ec_data = (int) res->data.io.min_base_address;
+ res = (RESOURCE*)((u8*) buf.pointer + res->length);
+ acpi_ec_status = (int) res->data.io.min_base_address;
+
+ kfree(buf.pointer);
+
+ buf.length = sizeof(obj);
+ buf.pointer = &obj;
+ if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf))
+ || obj.type != ACPI_TYPE_NUMBER)
+ return AE_OK;
+ gpe = (int) obj.number.value;
+
+ printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n",
+ acpi_ec_data, acpi_ec_status, gpe);
+
+ if (!ACPI_SUCCESS(acpi_install_gpe_handler(
+ gpe,
+ (ACPI_EVENT_LEVEL_TRIGGERED
+ | ACPI_EVENT_EDGE_TRIGGERED),
+ acpi_ec_gpe,
+ NULL)))
+ return AE_OK;
+
+ return AE_OK;
+}
+
+int
+acpi_ec_init(void)
+{
+ acpi_walk_namespace(ACPI_TYPE_DEVICE,
+ ACPI_ROOT_OBJECT,
+ ACPI_INT32_MAX,
+ acpi_find_ec,
+ NULL,
+ NULL);
+ return 0;
+}
diff --git a/drivers/acpi/os.c b/drivers/acpi/os.c
new file mode 100644
index 000000000..7398534ad
--- /dev/null
+++ b/drivers/acpi/os.c
@@ -0,0 +1,379 @@
+/*
+ * os.c - OS-dependent functions
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include "acpi.h"
+#include "driver.h"
+
+static int acpi_irq_irq = 0;
+static OSD_HANDLER acpi_irq_handler = NULL;
+static void *acpi_irq_context = NULL;
+
+char *
+strupr(char *str)
+{
+ char *s = str;
+ while (*s) {
+ *s = TOUPPER(*s);
+ s++;
+ }
+ return str;
+}
+
+ACPI_STATUS
+acpi_os_initialize(void)
+{
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_terminate(void)
+{
+ if (acpi_irq_handler) {
+ acpi_os_remove_interrupt_handler(acpi_irq_irq,
+ acpi_irq_handler);
+ }
+ return AE_OK;
+}
+
+s32
+acpi_os_printf(const char *fmt,...)
+{
+ s32 size;
+ va_list args;
+ va_start(args, fmt);
+ size = acpi_os_vprintf(fmt, args);
+ va_end(args);
+ return size;
+}
+
+s32
+acpi_os_vprintf(const char *fmt, va_list args)
+{
+ static char buffer[512];
+ int size = vsprintf(buffer, fmt, args);
+ printk(KERN_DEBUG "ACPI: %s", buffer);
+ return size;
+}
+
+void *
+acpi_os_allocate(u32 size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+void *
+acpi_os_callocate(u32 size)
+{
+ void *ptr = acpi_os_allocate(size);
+ if (ptr)
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+void
+acpi_os_free(void *ptr)
+{
+ kfree(ptr);
+}
+
+ACPI_STATUS
+acpi_os_map_memory(void *phys, u32 size, void **virt)
+{
+ if ((unsigned long) phys < virt_to_phys(high_memory)) {
+ *virt = phys_to_virt((unsigned long) phys);
+ return AE_OK;
+ }
+
+ *virt = ioremap((unsigned long) phys, size);
+ if (!*virt)
+ return AE_ERROR;
+
+ return AE_OK;
+}
+
+void
+acpi_os_unmap_memory(void *virt, u32 size)
+{
+ if (virt >= high_memory)
+ iounmap(virt);
+}
+
+static void
+acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ (*acpi_irq_handler)(acpi_irq_context);
+}
+
+ACPI_STATUS
+acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
+{
+ acpi_irq_irq = irq;
+ acpi_irq_handler = handler;
+ acpi_irq_context = context;
+ if (request_irq(irq,
+ acpi_irq,
+ SA_INTERRUPT | SA_SHIRQ,
+ "acpi",
+ acpi_irq)) {
+ printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);
+ return AE_ERROR;
+ }
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
+{
+ if (acpi_irq_handler) {
+ free_irq(irq, acpi_irq);
+ acpi_irq_handler = NULL;
+ }
+ return AE_OK;
+}
+
+/*
+ * Running in interpreter thread context, safe to sleep
+ */
+
+void
+acpi_os_sleep(u32 sec, u32 ms)
+{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ * sec + (ms * HZ) / 1000);
+}
+
+void
+acpi_os_sleep_usec(u32 us)
+{
+ udelay(us);
+}
+
+u8
+acpi_os_in8(ACPI_IO_ADDRESS port)
+{
+ return inb(port);
+}
+
+u16
+acpi_os_in16(ACPI_IO_ADDRESS port)
+{
+ return inw(port);
+}
+
+u32
+acpi_os_in32(ACPI_IO_ADDRESS port)
+{
+ return inl(port);
+}
+
+void
+acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
+{
+ outb(val, port);
+}
+
+void
+acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
+{
+ outw(val, port);
+}
+
+void
+acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
+{
+ outl(val, port);
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_byte(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u8 * val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!val || !dev || pci_read_config_byte(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_word(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u16 * val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!val || !dev || pci_read_config_word(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_read_pci_cfg_dword(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u32 * val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!val || !dev || pci_read_config_dword(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_byte(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u8 val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!dev || pci_write_config_byte(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_word(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u16 val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!dev || pci_write_config_word(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_write_pci_cfg_dword(
+ u32 bus,
+ u32 func,
+ u32 addr,
+ u32 val)
+{
+ int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
+ struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
+ if (!dev || pci_write_config_dword(dev, addr, val))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+/*
+ * Queue for interpreter thread
+ */
+
+ACPI_STATUS
+acpi_os_queue_for_execution(
+ u32 priority,
+ OSD_EXECUTION_CALLBACK callback,
+ void *context)
+{
+ if (acpi_run(callback, context))
+ return AE_ERROR;
+ return AE_OK;
+}
+
+/*
+ * Semaphores are unused, interpreter access is single threaded
+ */
+
+ACPI_STATUS
+acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle)
+{
+ *handle = (ACPI_HANDLE) 0;
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_delete_semaphore(ACPI_HANDLE handle)
+{
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout)
+{
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units)
+{
+ return AE_OK;
+}
+
+ACPI_STATUS
+acpi_os_breakpoint(char *msg)
+{
+ acpi_os_printf("breakpoint: %s", msg);
+ return AE_OK;
+}
+
+void
+acpi_os_dbg_trap(char *msg)
+{
+ acpi_os_printf("trap: %s", msg);
+}
+
+void
+acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg)
+{
+ acpi_os_printf("assert: %s", msg);
+}
+
+u32
+acpi_os_get_line(char *buffer)
+{
+ return 0;
+}
+
+/*
+ * We just have to assume we're dealing with valid memory
+ */
+
+BOOLEAN
+acpi_os_readable(void *ptr, u32 len)
+{
+ return 1;
+}
+
+BOOLEAN
+acpi_os_writable(void *ptr, u32 len)
+{
+ return 1;
+}
diff --git a/drivers/acpi/osd.c b/drivers/acpi/osd.c
deleted file mode 100644
index 402df75d7..000000000
--- a/drivers/acpi/osd.c
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- * osd.c - Linux specific code
- *
- * Copyright (C) 2000 Andrew Henroid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/pm.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include "acpi.h"
-
-#define ACPI_MAX_THROTTLE 10
-#define ACPI_INVALID ~0UL
-#define ACPI_INFINITE ~0UL
-
-static struct acpi_facp *acpi_facp = NULL;
-
-static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
-static volatile u32 acpi_event_status = 0;
-static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
-static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
-static int acpi_irq_irq = 0;
-static OSD_HANDLER acpi_irq_handler = NULL;
-static void *acpi_irq_context = NULL;
-
-static unsigned long acpi_pblk = ACPI_INVALID;
-static unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
-static unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
-static unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
-static unsigned long acpi_c3_enter_latency = ACPI_INFINITE;
-static int acpi_c2_tested = 0;
-static int acpi_c3_tested = 0;
-
-struct acpi_intrp_entry
-{
- int priority;
- OSD_EXECUTION_CALLBACK callback;
- void *context;
- struct list_head list;
-};
-
-struct acpi_enter_sx_ctx
-{
- wait_queue_head_t wait;
- int state;
-};
-
-static volatile int acpi_intrp_pid = -1;
-static DECLARE_WAIT_QUEUE_HEAD(acpi_intrp_wait);
-static LIST_HEAD(acpi_intrp_exec);
-static spinlock_t acpi_intrp_exec_lock = SPIN_LOCK_UNLOCKED;
-
-#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
-#define ACPI_SLP_TYPA(value) \
- ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
-#define ACPI_SLP_TYPB(value) \
- ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
-
-static volatile acpi_sstate_t acpi_sleep_state = ACPI_S0;
-static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,};
-
-static struct ctl_table_header *acpi_sysctl = NULL;
-
-static int acpi_do_ulong(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len);
-static int acpi_do_sleep(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len);
-static int acpi_do_event(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len);
-
-static struct ctl_table acpi_table[] =
-{
- {ACPI_P_LVL2_LAT, "c2_exit_latency",
- &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency),
- 0644, NULL, &acpi_do_ulong},
-
- {ACPI_ENTER_LVL2_LAT, "c2_enter_latency",
- &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency),
- 0644, NULL, &acpi_do_ulong},
-
- {ACPI_P_LVL3_LAT, "c3_exit_latency",
- &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency),
- 0644, NULL, &acpi_do_ulong},
-
- {ACPI_ENTER_LVL3_LAT, "c3_enter_latency",
- &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency),
- 0644, NULL, &acpi_do_ulong},
-
- {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
-
- {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event},
-
- {0}
-};
-
-static struct ctl_table acpi_dir_table[] =
-{
- {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table},
- {0}
-};
-
-static u32 FASTCALL(acpi_read_pm1_control(struct acpi_facp *));
-static u32 FASTCALL(acpi_read_pm1_status(struct acpi_facp *));
-static void FASTCALL(acpi_write_pm1_control(struct acpi_facp *, u32));
-static void FASTCALL(acpi_write_pm1_status(struct acpi_facp *, u32));
-
-/*
- * Get the value of the PM1 control register (ACPI_SCI_EN, ...)
- */
-static u32
-acpi_read_pm1_control(struct acpi_facp *facp)
-{
- u32 value = 0;
- if (facp->pm1a_cnt)
- value = inw(facp->pm1a_cnt);
- if (facp->pm1b_cnt)
- value |= inw(facp->pm1b_cnt);
- return value;
-}
-
-/*
- * Set the value of the PM1 control register (ACPI_BM_RLD, ...)
- */
-static void
-acpi_write_pm1_control(struct acpi_facp *facp, u32 value)
-{
- if (facp->pm1a_cnt)
- outw(value, facp->pm1a_cnt);
- if (facp->pm1b_cnt)
- outw(value, facp->pm1b_cnt);
-}
-
-/*
- * Get the value of the fixed event status register
- */
-static u32
-acpi_read_pm1_status(struct acpi_facp *facp)
-{
- u32 value = 0;
- if (facp->pm1a_evt)
- value = inw(facp->pm1a_evt);
- if (facp->pm1b_evt)
- value |= inw(facp->pm1b_evt);
- return value;
-}
-
-/*
- * Set the value of the fixed event status register (clear events)
- */
-static void
-acpi_write_pm1_status(struct acpi_facp *facp, u32 value)
-{
- if (facp->pm1a_evt)
- outw(value, facp->pm1a_evt);
- if (facp->pm1b_evt)
- outw(value, facp->pm1b_evt);
-}
-
-/*
- * Examine/modify value
- */
-static int
-acpi_do_ulong(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len)
-{
- char str[2 * sizeof(unsigned long) + 4], *strend;
- unsigned long val;
- int size;
-
- if (!write) {
- if (file->f_pos) {
- *len = 0;
- return 0;
- }
-
- val = *(unsigned long *) ctl->data;
- size = sprintf(str, "0x%08lx\n", val);
- if (*len >= size) {
- copy_to_user(buffer, str, size);
- *len = size;
- }
- else
- *len = 0;
- }
- else {
- size = sizeof(str) - 1;
- if (size > *len)
- size = *len;
- copy_from_user(str, buffer, size);
- str[size] = '\0';
- val = simple_strtoul(str, &strend, 0);
- if (strend == str)
- return -EINVAL;
- *(unsigned long *) ctl->data = val;
- }
-
- file->f_pos += *len;
- return 0;
-}
-
-/*
- * Handle ACPI event
- */
-u32
-acpi_event(void *context)
-{
- unsigned long flags;
- int event = (int) context;
- int mask = 0;
-
- switch (event) {
- case ACPI_EVENT_POWER_BUTTON:
- mask = ACPI_PWRBTN;
- break;
- case ACPI_EVENT_SLEEP_BUTTON:
- mask = ACPI_SLPBTN;
- break;
- }
-
- if (mask) {
- // notify process waiting on /dev/acpi
- spin_lock_irqsave(&acpi_event_lock, flags);
- acpi_event_status |= mask;
- spin_unlock_irqrestore(&acpi_event_lock, flags);
- acpi_event_state = acpi_sleep_state;
- wake_up_interruptible(&acpi_event_wait);
- }
-
- return AE_OK;
-}
-
-/*
- * Wait for next event
- */
-int
-acpi_do_event(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len)
-{
- u32 event_status = 0;
- acpi_sstate_t event_state = 0;
- char str[27];
- int size;
-
- if (write)
- return -EPERM;
- if (*len < sizeof(str)) {
- *len = 0;
- return 0;
- }
-
- for (;;) {
- unsigned long flags;
-
- // we need an atomic exchange here
- spin_lock_irqsave(&acpi_event_lock, flags);
- event_status = acpi_event_status;
- acpi_event_status = 0;
- spin_unlock_irqrestore(&acpi_event_lock, flags);
- event_state = acpi_event_state;
-
- if (event_status)
- break;
-
- // wait for an event to arrive
- interruptible_sleep_on(&acpi_event_wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
-
- size = sprintf(str,
- "0x%08x 0x%08x 0x%01x\n",
- event_status,
- 0,
- event_state);
- copy_to_user(buffer, str, size);
- *len = size;
- file->f_pos += size;
-
- return 0;
-}
-
-/*
- * Enter system sleep state
- */
-static void
-acpi_enter_sx(void *context)
-{
- struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context;
- struct acpi_facp *facp = acpi_facp;
- ACPI_OBJECT_LIST arg_list;
- ACPI_OBJECT arg;
- u16 value;
-
- /*
- * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
- */
-
- // run the _PTS method
- memset(&arg_list, 0, sizeof(arg_list));
- arg_list.count = 1;
- arg_list.pointer = &arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = ACPI_TYPE_NUMBER;
- arg.number.value = ctx->state;
-
- acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
-
- // clear wake status
- acpi_write_pm1_status(facp, ACPI_WAK);
-
- acpi_sleep_state = ctx->state;
-
- // set ACPI_SLP_TYPA/b and ACPI_SLP_EN
- __cli();
- if (facp->pm1a_cnt) {
- value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
- value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state])
- | ACPI_SLP_EN);
- outw(value, facp->pm1a_cnt);
- }
- if (facp->pm1b_cnt) {
- value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK;
- value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state])
- | ACPI_SLP_EN);
- outw(value, facp->pm1b_cnt);
- }
- __sti();
-
- if (ctx->state != ACPI_S1) {
- printk(KERN_ERR "ACPI: S%d failed\n", ctx->state);
- goto out;
- }
-
- // wait until S1 is entered
- while (!(acpi_read_pm1_status(facp) & ACPI_WAK))
- safe_halt();
-
- // run the _WAK method
- memset(&arg_list, 0, sizeof(arg_list));
- arg_list.count = 1;
- arg_list.pointer = &arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = ACPI_TYPE_NUMBER;
- arg.number.value = ctx->state;
-
- acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
-
- out:
- acpi_sleep_state = ACPI_S0;
-
- if (waitqueue_active(&ctx->wait))
- wake_up_interruptible(&ctx->wait);
-}
-
-/*
- * Enter system sleep state and wait for completion
- */
-static int
-acpi_enter_sx_and_wait(acpi_sstate_t state)
-{
- struct acpi_enter_sx_ctx ctx;
-
- if (!acpi_facp
- || acpi_facp->hdr.signature != ACPI_FACP_SIG
- || acpi_slptyp[state] == ACPI_INVALID)
- return -EINVAL;
-
- init_waitqueue_head(&ctx.wait);
- ctx.state = state;
-
- if (acpi_os_queue_for_execution(0, acpi_enter_sx, &ctx))
- return -1;
-
- interruptible_sleep_on(&ctx.wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
-
- return 0;
-}
-
-/*
- * Enter system sleep state
- */
-static int
-acpi_do_sleep(ctl_table * ctl,
- int write,
- struct file *file,
- void *buffer,
- size_t * len)
-{
- if (!write) {
- if (file->f_pos) {
- *len = 0;
- return 0;
- }
- }
- else {
-#ifdef CONFIG_ACPI_S1_SLEEP
- int status = acpi_enter_sx_and_wait(ACPI_S1);
- if (status)
- return status;
-#endif
- }
- file->f_pos += *len;
- return 0;
-}
-
-/*
- * Clear busmaster activity flag
- */
-static inline void
-acpi_clear_bm_activity(struct acpi_facp *facp)
-{
- acpi_write_pm1_status(facp, ACPI_BM);
-}
-
-/*
- * Returns 1 if there has been busmaster activity
- */
-static inline int
-acpi_bm_activity(struct acpi_facp *facp)
-{
- return acpi_read_pm1_status(facp) & ACPI_BM;
-}
-
-/*
- * Set system to sleep through busmaster requests
- */
-static void
-acpi_sleep_on_busmaster(struct acpi_facp *facp)
-{
- u32 pm1_cntr = acpi_read_pm1_control(facp);
- if (pm1_cntr & ACPI_BM_RLD) {
- pm1_cntr &= ~ACPI_BM_RLD;
- acpi_write_pm1_control(facp, pm1_cntr);
- }
-}
-
-/*
- * Set system to wake on busmaster requests
- */
-static void
-acpi_wake_on_busmaster(struct acpi_facp *facp)
-{
- u32 pm1_cntr = acpi_read_pm1_control(facp);
- if (!(pm1_cntr & ACPI_BM_RLD)) {
- pm1_cntr |= ACPI_BM_RLD;
- acpi_write_pm1_control(facp, pm1_cntr);
- }
- acpi_clear_bm_activity(facp);
-}
-
-/* The ACPI timer is just the low 24 bits */
-#define TIME_BEGIN(tmr) inl(tmr)
-#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
-
-/*
- * Idle loop (uniprocessor only)
- */
-void
-acpi_idle(void)
-{
- static int sleep_level = 1;
- struct acpi_facp *facp = acpi_facp;
-
- if (!facp
- || facp->hdr.signature != ACPI_FACP_SIG
- || !facp->pm_tmr
- || !acpi_pblk)
- goto not_initialized;
-
- /*
- * start from the previous sleep level..
- */
- if (sleep_level == 1)
- goto sleep1;
- if (sleep_level == 2)
- goto sleep2;
- sleep3:
- sleep_level = 3;
- if (!acpi_c3_tested) {
- printk(KERN_DEBUG "ACPI C3 works\n");
- acpi_c3_tested = 1;
- }
- acpi_wake_on_busmaster(facp);
- if (facp->pm2_cnt)
- goto sleep3_with_arbiter;
-
- for (;;) {
- unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
-
- __cli();
- if (current->need_resched)
- goto out;
- if (acpi_bm_activity(facp))
- goto sleep2;
-
- time = TIME_BEGIN(pm_tmr);
- inb(acpi_pblk + ACPI_P_LVL3);
- /* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
-
- __sti();
- if (time < acpi_c3_exit_latency)
- goto sleep2;
- }
-
- sleep3_with_arbiter:
- for (;;) {
- unsigned long time;
- u8 arbiter;
- unsigned int pm2_cntr = facp->pm2_cnt;
- unsigned int pm_tmr = facp->pm_tmr;
-
- __cli();
- if (current->need_resched)
- goto out;
- if (acpi_bm_activity(facp))
- goto sleep2;
-
- time = TIME_BEGIN(pm_tmr);
- arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
- /* Disable arbiter, park on CPU */
- outb(arbiter | ACPI_ARB_DIS, pm2_cntr);
- inb(acpi_pblk + ACPI_P_LVL3);
- /* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
- /* Enable arbiter again.. */
- outb(arbiter, pm2_cntr);
-
- __sti();
- if (time < acpi_c3_exit_latency)
- goto sleep2;
- }
-
- sleep2:
- sleep_level = 2;
- if (!acpi_c2_tested) {
- printk(KERN_DEBUG "ACPI C2 works\n");
- acpi_c2_tested = 1;
- }
- acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */
- for (;;) {
- unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
-
- __cli();
- if (current->need_resched)
- goto out;
-
- time = TIME_BEGIN(pm_tmr);
- inb(acpi_pblk + ACPI_P_LVL2);
- /* Dummy read, force synchronization with the PMU */
- inl(pm_tmr);
- time = TIME_END(pm_tmr, time);
-
- __sti();
- if (time < acpi_c2_exit_latency)
- goto sleep1;
- if (acpi_bm_activity(facp)) {
- acpi_clear_bm_activity(facp);
- continue;
- }
- if (time > acpi_c3_enter_latency)
- goto sleep3;
- }
-
- sleep1:
- sleep_level = 1;
- acpi_sleep_on_busmaster(facp);
- for (;;) {
- unsigned long time;
- unsigned int pm_tmr = facp->pm_tmr;
-
- __cli();
- if (current->need_resched)
- goto out;
- time = TIME_BEGIN(pm_tmr);
- safe_halt();
- time = TIME_END(pm_tmr, time);
- if (time > acpi_c2_enter_latency)
- goto sleep2;
- }
-
- not_initialized:
- for (;;) {
- __cli();
- if (current->need_resched)
- goto out;
- safe_halt();
- }
-
- out:
- __sti();
-}
-
-/*
- * Enter soft-off (S5)
- */
-static void
-acpi_power_off(void)
-{
- struct acpi_enter_sx_ctx ctx;
-
- if (!acpi_facp
- || acpi_facp->hdr.signature != ACPI_FACP_SIG
- || acpi_slptyp[ACPI_S5] == ACPI_INVALID)
- return;
-
- init_waitqueue_head(&ctx.wait);
- ctx.state = ACPI_S5;
- acpi_enter_sx(&ctx);
-}
-
-/*
- * Get processor information
- */
-static ACPI_STATUS
-acpi_get_cpu_info(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
-{
- ACPI_OBJECT obj;
- ACPI_CX_STATE lat[4];
- ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE];
- ACPI_BUFFER buf;
- int i, count;
-
- buf.length = sizeof(obj);
- buf.pointer = &obj;
- if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf)))
- return AE_OK;
-
- printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n",
- obj.processor.proc_id,
- obj.processor.pblk_address,
- obj.processor.pblk_length);
- if (acpi_pblk != ACPI_INVALID
- || !obj.processor.pblk_address
- || obj.processor.pblk_length != 6)
- return AE_OK;
-
- acpi_pblk = obj.processor.pblk_address;
-
- buf.length = sizeof(lat);
- buf.pointer = lat;
- if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf)))
- return AE_OK;
-
- if (lat[2].latency < MAX_CX_STATE_LATENCY) {
- printk(KERN_INFO "ACPI: C2 supported\n");
- acpi_c2_exit_latency = lat[2].latency;
- }
- if (lat[3].latency < MAX_CX_STATE_LATENCY) {
- printk(KERN_INFO "ACPI: C3 supported\n");
- acpi_c3_exit_latency = lat[3].latency;
- }
-
- memset(throttle, 0, sizeof(throttle));
- buf.length = sizeof(throttle);
- buf.pointer = throttle;
-
- if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf)))
- return AE_OK;
-
- for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) {
- if (throttle[i].percent_of_clock)
- count++;
- }
- count--;
- if (count > 0)
- printk(KERN_INFO "ACPI: %d throttling states\n", count);
-
- return AE_OK;
-}
-
-/*
- * Fetch the FACP information
- */
-static int
-acpi_fetch_facp(void)
-{
- ACPI_BUFFER buffer;
-
- buffer.pointer = acpi_facp;
- buffer.length = sizeof(*acpi_facp);
- if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
- printk(KERN_ERR "ACPI: no FACP\n");
- kfree(acpi_facp);
- return -ENODEV;
- }
-
- if (acpi_facp->p_lvl2_lat
- && acpi_facp->p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
- acpi_c2_exit_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl2_lat);
- acpi_c2_enter_latency
- = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
- }
- if (acpi_facp->p_lvl3_lat
- && acpi_facp->p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
- acpi_c3_exit_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat);
- acpi_c3_enter_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat * 5);
- }
-
- return 0;
-}
-
-/*
- * Execute callbacks (interpret methods)
- */
-static void
-acpi_intrp_run(void)
-{
- for (;;) {
- struct acpi_intrp_entry *entry;
- unsigned long flags;
-
- interruptible_sleep_on(&acpi_intrp_wait);
- if (signal_pending(current))
- return;
-
- for (;;) {
- entry = NULL;
-
- spin_lock_irqsave(&acpi_intrp_exec_lock, flags);
- if (!list_empty(&acpi_intrp_exec)) {
- entry = list_entry(acpi_intrp_exec.next,
- struct acpi_intrp_entry,
- list);
- list_del(&entry->list);
- }
- spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags);
-
- if (!entry)
- break;
-
- (*entry->callback)(entry->context);
-
- kfree(entry);
- }
- }
-}
-
-/*
- * Initialize and run interpreter within a kernel thread
- */
-static int
-acpi_intrp_thread(void *context)
-{
- ACPI_STATUS status;
- u8 sx, typa, typb;
-
- /*
- * initialize interpreter
- */
- exit_files(current);
- daemonize();
- strcpy(current->comm, "acpi");
-
- if (!ACPI_SUCCESS(acpi_initialize(NULL))) {
- printk(KERN_ERR "ACPI: initialize failed\n");
- return -ENODEV;
- }
-
- if (!ACPI_SUCCESS(acpi_load_firmware_tables())) {
- printk(KERN_ERR "ACPI: table load failed\n");
- acpi_terminate();
- return -ENODEV;
- }
-
- if (acpi_fetch_facp()) {
- acpi_terminate();
- return -ENODEV;
- }
-
- status = acpi_load_namespace();
- if (!ACPI_SUCCESS(status) && status != AE_CTRL_PENDING) {
- printk(KERN_ERR "ACPI: namespace load failed\n");
- acpi_terminate();
- return -ENODEV;
- }
-
- printk(KERN_INFO "ACPI: ACPI support found\n");
-
- acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
- ACPI_ROOT_OBJECT,
- ACPI_INT32_MAX,
- acpi_get_cpu_info,
- NULL,
- NULL);
-
- for (sx = ACPI_S0; sx <= ACPI_S5; sx++) {
- int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1);
- if (ACPI_SUCCESS(
- acpi_hw_obtain_sleep_type_register_data(ca_sx,
- &typa,
- &typb)))
- acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb);
- else
- acpi_slptyp[sx] = ACPI_INVALID;
- }
- if (acpi_slptyp[ACPI_S1] != ACPI_INVALID)
- printk(KERN_INFO "ACPI: S1 supported\n");
- if (acpi_slptyp[ACPI_S5] != ACPI_INVALID)
- printk(KERN_INFO "ACPI: S5 supported\n");
-
- if (!ACPI_SUCCESS(acpi_enable())) {
- printk(KERN_ERR "ACPI: enable failed\n");
- acpi_terminate();
- return -ENODEV;
- }
-
- if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
- ACPI_EVENT_POWER_BUTTON,
- acpi_event,
- (void *) ACPI_EVENT_POWER_BUTTON))) {
- printk(KERN_ERR "ACPI: power button enable failed\n");
- }
- if (!ACPI_SUCCESS(acpi_install_fixed_event_handler(
- ACPI_EVENT_SLEEP_BUTTON,
- acpi_event,
- (void *) ACPI_EVENT_SLEEP_BUTTON))) {
- printk(KERN_ERR "ACPI: sleep button enable failed\n");
- }
-
-#ifdef CONFIG_SMP
- if (smp_num_cpus == 1)
- pm_idle = acpi_idle;
-#else
- pm_idle = acpi_idle;
-#endif
- pm_power_off = acpi_power_off;
-
- acpi_sysctl = register_sysctl_table(acpi_dir_table, 1);
-
- /*
- * run interpreter
- */
- acpi_intrp_run();
-
- /*
- * terminate interpreter
- */
- unregister_sysctl_table(acpi_sysctl);
- acpi_terminate();
-
- acpi_intrp_pid = -1;
-
- return 0;
-}
-
-/*
- * Start the interpreter
- */
-int __init
-acpi_init(void)
-{
- acpi_facp = kmalloc(sizeof(*acpi_facp), GFP_KERNEL);
- if (!acpi_facp)
- return -ENOMEM;
- memset(acpi_facp, 0, sizeof(*acpi_facp));
-
- acpi_intrp_pid = kernel_thread(acpi_intrp_thread,
- NULL,
- (CLONE_FS | CLONE_FILES
- | CLONE_SIGHAND | SIGCHLD));
- return ((acpi_intrp_pid >= 0) ? 0:-ENODEV);
-}
-
-/*
- * Terminate the interpreter
- */
-void __exit
-acpi_exit(void)
-{
- int count;
-
- if (!kill_proc(acpi_intrp_pid, SIGTERM, 1)) {
- // wait until interpreter thread terminates (at most 5 seconds)
- count = 5 * HZ;
- while (acpi_intrp_pid >= 0 && --count) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
- }
-
- // clean up after the interpreter
-
- if (acpi_irq_handler) {
- acpi_os_remove_interrupt_handler(acpi_irq_irq,
- acpi_irq_handler);
- }
-
- if (pm_power_off == acpi_power_off)
- pm_power_off = NULL;
- if (pm_idle == acpi_idle)
- pm_idle = NULL;
-
- kfree(acpi_facp);
-}
-
-module_init(acpi_init);
-module_exit(acpi_exit);
-
-/*
- * OS-dependent functions
- *
- */
-
-char *
-strupr(char *str)
-{
- char *s = str;
- while (*s) {
- *s = TOUPPER(*s);
- s++;
- }
- return str;
-}
-
-ACPI_STATUS
-acpi_os_initialize(void)
-{
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_terminate(void)
-{
- return AE_OK;
-}
-
-s32
-acpi_os_printf(const char *fmt,...)
-{
- s32 size;
- va_list args;
- va_start(args, fmt);
- size = acpi_os_vprintf(fmt, args);
- va_end(args);
- return size;
-}
-
-s32
-acpi_os_vprintf(const char *fmt, va_list args)
-{
- static char buffer[512];
- int size = vsprintf(buffer, fmt, args);
- printk(KERN_DEBUG "%s", buffer);
- return size;
-}
-
-void *
-acpi_os_allocate(u32 size)
-{
- return kmalloc(size, GFP_KERNEL);
-}
-
-void *
-acpi_os_callocate(u32 size)
-{
- void *ptr = acpi_os_allocate(size);
- if (ptr)
- memset(ptr, 0, size);
- return ptr;
-}
-
-void
-acpi_os_free(void *ptr)
-{
- kfree(ptr);
-}
-
-ACPI_STATUS
-acpi_os_map_memory(void *phys, u32 size, void **virt)
-{
- if ((unsigned long) phys < virt_to_phys(high_memory)) {
- *virt = phys_to_virt((unsigned long) phys);
- return AE_OK;
- }
-
- *virt = ioremap((unsigned long) phys, size);
- if (!*virt)
- return AE_ERROR;
-
- return AE_OK;
-}
-
-void
-acpi_os_unmap_memory(void *virt, u32 size)
-{
- if (virt >= high_memory)
- iounmap(virt);
-}
-
-static void
-acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
- (*acpi_irq_handler)(acpi_irq_context);
-}
-
-ACPI_STATUS
-acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
-{
- acpi_irq_irq = irq;
- acpi_irq_handler = handler;
- acpi_irq_context = context;
- if (request_irq(irq,
- acpi_irq,
- SA_INTERRUPT | SA_SHIRQ,
- "acpi",
- acpi_irq)) {
- printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);
- return AE_ERROR;
- }
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
-{
- if (acpi_irq_handler) {
- free_irq(irq, acpi_irq);
- acpi_irq_handler = NULL;
- }
- return AE_OK;
-}
-
-/*
- * Running in interpreter thread context, safe to sleep
- */
-
-void
-acpi_os_sleep(u32 sec, u32 ms)
-{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ * sec + (ms * HZ) / 1000);
-}
-
-void
-acpi_os_sleep_usec(u32 us)
-{
- udelay(us);
-}
-
-u8
-acpi_os_in8(ACPI_IO_ADDRESS port)
-{
- return inb(port);
-}
-
-u16
-acpi_os_in16(ACPI_IO_ADDRESS port)
-{
- return inw(port);
-}
-
-u32
-acpi_os_in32(ACPI_IO_ADDRESS port)
-{
- return inl(port);
-}
-
-void
-acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
-{
- outb(val, port);
-}
-
-void
-acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
-{
- outw(val, port);
-}
-
-void
-acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
-{
- outl(val, port);
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_byte(
- u32 bus,
- u32 func,
- u32 addr,
- u8 * val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!val || !dev || pci_read_config_byte(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_word(
- u32 bus,
- u32 func,
- u32 addr,
- u16 * val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!val || !dev || pci_read_config_word(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_read_pci_cfg_dword(
- u32 bus,
- u32 func,
- u32 addr,
- u32 * val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!val || !dev || pci_read_config_dword(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_byte(
- u32 bus,
- u32 func,
- u32 addr,
- u8 val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!dev || pci_write_config_byte(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_word(
- u32 bus,
- u32 func,
- u32 addr,
- u16 val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!dev || pci_write_config_word(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_write_pci_cfg_dword(
- u32 bus,
- u32 func,
- u32 addr,
- u32 val)
-{
- int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff);
- struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn);
- if (!dev || pci_write_config_dword(dev, addr, val))
- return AE_ERROR;
- return AE_OK;
-}
-
-/*
- * Queue for interpreter thread
- */
-
-ACPI_STATUS
-acpi_os_queue_for_execution(
- u32 priority,
- OSD_EXECUTION_CALLBACK callback,
- void *context)
-{
- struct acpi_intrp_entry *entry;
- unsigned long flags;
-
- entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry)
- return AE_ERROR;
-
- memset(entry, 0, sizeof(entry));
- entry->priority = priority;
- entry->callback = callback;
- entry->context = context;
- INIT_LIST_HEAD(&entry->list);
-
- if (!waitqueue_active(&acpi_intrp_wait)) {
- kfree(entry);
- return AE_ERROR;
- }
-
- spin_lock_irqsave(&acpi_intrp_exec_lock, flags);
- list_add(&entry->list, &acpi_intrp_exec);
- wake_up(&acpi_intrp_wait);
- spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags);
-
- return AE_OK;
-}
-
-/*
- * Semaphores are unused, interpreter access is single threaded
- */
-
-ACPI_STATUS
-acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle)
-{
- *handle = (ACPI_HANDLE) 0;
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_delete_semaphore(ACPI_HANDLE handle)
-{
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout)
-{
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units)
-{
- return AE_OK;
-}
-
-ACPI_STATUS
-acpi_os_breakpoint(char *msg)
-{
- acpi_os_printf("breakpoint: %s", msg);
- return AE_OK;
-}
-
-void
-acpi_os_dbg_trap(char *msg)
-{
- acpi_os_printf("trap: %s", msg);
-}
-
-void
-acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg)
-{
- acpi_os_printf("assert: %s", msg);
-}
-
-u32
-acpi_os_get_line(char *buffer)
-{
- return 0;
-}
-
-/*
- * We just have to assume we're dealing with valid memory
- */
-
-BOOLEAN
-acpi_os_readable(void *ptr, u32 len)
-{
- return 1;
-}
-
-BOOLEAN
-acpi_os_writable(void *ptr, u32 len)
-{
- return 1;
-}
diff --git a/drivers/acpi/sys.c b/drivers/acpi/sys.c
new file mode 100644
index 000000000..1a403f86f
--- /dev/null
+++ b/drivers/acpi/sys.c
@@ -0,0 +1,182 @@
+/*
+ * sys.c - System management (suspend, ...)
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
+#define ACPI_SLP_TYPA(value) \
+ ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
+#define ACPI_SLP_TYPB(value) \
+ ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
+
+struct acpi_enter_sx_ctx
+{
+ wait_queue_head_t wait;
+ int state;
+};
+
+volatile acpi_sstate_t acpi_sleep_state = ACPI_S0;
+static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,};
+
+/*
+ * Enter system sleep state
+ */
+static void
+acpi_enter_sx_async(void *context)
+{
+ struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context;
+ struct acpi_facp *facp = &acpi_facp;
+ ACPI_OBJECT_LIST arg_list;
+ ACPI_OBJECT arg;
+ u16 value;
+
+ /*
+ * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
+ */
+
+ // run the _PTS method
+ memset(&arg_list, 0, sizeof(arg_list));
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = ACPI_TYPE_NUMBER;
+ arg.number.value = ctx->state;
+
+ acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL);
+
+ // clear wake status
+ acpi_write_pm1_status(facp, ACPI_WAK);
+
+ acpi_sleep_state = ctx->state;
+
+ // set ACPI_SLP_TYPA/b and ACPI_SLP_EN
+ __cli();
+ if (facp->pm1a_cnt) {
+ value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
+ value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state])
+ | ACPI_SLP_EN);
+ outw(value, facp->pm1a_cnt);
+ }
+ if (facp->pm1b_cnt) {
+ value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK;
+ value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state])
+ | ACPI_SLP_EN);
+ outw(value, facp->pm1b_cnt);
+ }
+ __sti();
+
+ if (ctx->state != ACPI_S1) {
+ printk(KERN_ERR "ACPI: S%d failed\n", ctx->state);
+ goto out;
+ }
+
+ // wait until S1 is entered
+ while (!(acpi_read_pm1_status(facp) & ACPI_WAK))
+ safe_halt();
+
+ // run the _WAK method
+ memset(&arg_list, 0, sizeof(arg_list));
+ arg_list.count = 1;
+ arg_list.pointer = &arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = ACPI_TYPE_NUMBER;
+ arg.number.value = ctx->state;
+
+ acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL);
+
+ out:
+ acpi_sleep_state = ACPI_S0;
+
+ if (waitqueue_active(&ctx->wait))
+ wake_up_interruptible(&ctx->wait);
+}
+
+/*
+ * Enter soft-off (S5)
+ */
+static void
+acpi_power_off(void)
+{
+ struct acpi_enter_sx_ctx ctx;
+
+ if (acpi_facp.hdr.signature != ACPI_FACP_SIG
+ || acpi_slptyp[ACPI_S5] == ACPI_INVALID)
+ return;
+
+ init_waitqueue_head(&ctx.wait);
+ ctx.state = ACPI_S5;
+ acpi_enter_sx_async(&ctx);
+}
+
+/*
+ * Enter system sleep state and wait for completion
+ */
+int
+acpi_enter_sx(acpi_sstate_t state)
+{
+ struct acpi_enter_sx_ctx ctx;
+
+ if (acpi_facp.hdr.signature != ACPI_FACP_SIG
+ || acpi_slptyp[state] == ACPI_INVALID)
+ return -EINVAL;
+
+ init_waitqueue_head(&ctx.wait);
+ ctx.state = state;
+
+ if (acpi_os_queue_for_execution(0, acpi_enter_sx_async, &ctx))
+ return -1;
+
+ interruptible_sleep_on(&ctx.wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ return 0;
+}
+
+int
+acpi_sys_init(void)
+{
+ u8 sx, typa, typb;
+
+ for (sx = ACPI_S0; sx <= ACPI_S5; sx++) {
+ int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1);
+ if (ACPI_SUCCESS(
+ acpi_hw_obtain_sleep_type_register_data(ca_sx,
+ &typa,
+ &typb)))
+ acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb);
+ else
+ acpi_slptyp[sx] = ACPI_INVALID;
+ }
+ if (acpi_slptyp[ACPI_S1] != ACPI_INVALID)
+ printk(KERN_INFO "ACPI: S1 supported\n");
+ if (acpi_slptyp[ACPI_S5] != ACPI_INVALID)
+ printk(KERN_INFO "ACPI: S5 supported\n");
+
+ pm_power_off = acpi_power_off;
+
+ return 0;
+}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
new file mode 100644
index 000000000..9ec6c58f4
--- /dev/null
+++ b/drivers/acpi/tables.c
@@ -0,0 +1,303 @@
+/*
+ * tables.c - ACPI tables, chipset, and errata handling
+ *
+ * Copyright (C) 2000 Andrew Henroid
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+struct acpi_facp acpi_facp;
+
+#define ACPI_DUMMY_CHECKSUM 9
+#define ACPI_DUMMY_PBLK 51
+
+static u8 acpi_dummy_dsdt[] =
+{
+ 0x44, 0x53, 0x44, 0x54, // "DSDT"
+ 0x38, 0x00, 0x00, 0x00, // length
+ 0x01, // revision
+ 0x00, // checksum
+ 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX"
+ 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY"
+ 0x01, 0x00, 0x00, 0x00, // OEM rev
+ 0x4c, 0x4e, 0x55, 0x58, // "LNUX"
+ 0x01, 0x00, 0x00, 0x00, // creator rev
+ 0x10, // Scope
+ 0x13, // PkgLength
+ 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_
+ 0x5b, 0x83, // Processor
+ 0x0b, // PkgLength
+ 0x43, 0x50, 0x55, 0x30, // CPU0
+ 0x00, // ID
+ 0x00, 0x00, 0x00, 0x00, // PBLK
+ 0x06 // PBLK size
+};
+
+/*
+ * Calculate and set ACPI table checksum
+ */
+static void
+acpi_set_checksum(u8 *table, int size)
+{
+ int i, sum = 0;
+ for (i = 0; i < size; i++)
+ sum += (int) table[i];
+ sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff));
+ table[ACPI_DUMMY_CHECKSUM] = sum;
+}
+
+/*
+ * Init PIIX4 device, create a fake FACP
+ */
+static int
+acpi_init_piix4(struct pci_dev *dev)
+{
+ u32 base, pblk;
+ u16 cmd;
+ u8 pmregmisc;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (!(cmd & PCI_COMMAND_IO))
+ return -ENODEV;
+
+ pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc);
+ if (!(pmregmisc & ACPI_PIIX4_PMIOSE))
+ return -ENODEV;
+
+ base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES);
+ if (!base)
+ return -ENODEV;
+
+ printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ acpi_facp.hdr.signature = ACPI_FACP_SIG;
+ acpi_facp.hdr.length = sizeof(acpi_facp);
+ acpi_facp.int_model = ACPI_PIIX4_INT_MODEL;
+ acpi_facp.sci_int = ACPI_PIIX4_SCI_INT;
+ acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD;
+ acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE;
+ acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE;
+ acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ;
+ acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
+ acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
+ acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT;
+ acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR;
+ acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0;
+ acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN;
+ acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN;
+ acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN;
+ acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN;
+ acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN;
+ acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+ acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+ acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+ acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+ pblk = base + ACPI_PIIX4_P_BLK;
+ memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+ acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+ acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+ return 0;
+}
+
+/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int
+acpi_init_via(struct pci_dev *dev)
+{
+ u32 base, pblk;
+ u8 tmp, irq;
+
+ pci_read_config_byte(dev, 0x41, &tmp);
+ if (!(tmp & 0x80))
+ return -ENODEV;
+
+ base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES);
+ if (!base) {
+ base = pci_resource_start(dev, PCI_BASE_ADDRESS_4);
+ if (!base)
+ return -ENODEV;
+ }
+
+ pci_read_config_byte(dev, 0x42, &irq);
+
+ printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ acpi_facp.hdr.signature = ACPI_FACP_SIG;
+ acpi_facp.hdr.length = sizeof(acpi_facp);
+ acpi_facp.int_model = ACPI_VIA_INT_MODEL;
+ acpi_facp.sci_int = irq;
+ acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD;
+ acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE;
+ acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE;
+ acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT;
+ acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT;
+ acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR;
+ acpi_facp.gpe0 = base + ACPI_VIA_GPE0;
+
+ acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+ acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+ acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN;
+ acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN;
+ acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+ acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+ acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET;
+ acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH;
+
+ acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM;
+ acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM;
+ acpi_facp.century = ACPI_VIA_CENTURY;
+
+ acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+ acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+ pblk = base + ACPI_VIA_P_BLK;
+ memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+ acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+ acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+ return 0;
+}
+
+typedef enum
+{
+ CH_UNKNOWN = 0,
+ CH_INTEL_PIIX4,
+ CH_VIA_586,
+ CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct
+{
+ int (*chip_init)(struct pci_dev *dev);
+} acpi_chip_info[] =
+{
+ {NULL,},
+ {acpi_init_piix4},
+ {acpi_init_via},
+ {acpi_init_via},
+};
+
+static struct pci_device_id acpi_pci_tbl[] =
+{
+ {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4},
+ {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586},
+ {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A},
+ {0,} /* terminate list */
+};
+
+static int
+acpi_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ return acpi_chip_info[id->driver_data].chip_init(dev);
+}
+
+static struct pci_driver acpi_driver =
+{
+ name: "acpi",
+ id_table: acpi_pci_tbl,
+ probe: acpi_probe,
+};
+static int acpi_driver_registered = 0;
+
+/*
+ * Locate a known ACPI chipset
+ */
+static int
+acpi_find_chipset(void)
+{
+ if (pci_register_driver(&acpi_driver) < 1)
+ return -ENODEV;
+ acpi_driver_registered = 1;
+ return 0;
+}
+
+/*
+ * Fetch the FACP information
+ */
+static int
+acpi_fetch_facp(void)
+{
+ ACPI_BUFFER buffer;
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ buffer.pointer = &acpi_facp;
+ buffer.length = sizeof(acpi_facp);
+ if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
+ printk(KERN_ERR "ACPI: missing FACP\n");
+ return -ENODEV;
+ }
+
+ if (acpi_facp.p_lvl2_lat
+ && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
+ acpi_c2_exit_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat);
+ acpi_c2_enter_latency
+ = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
+ }
+ if (acpi_facp.p_lvl3_lat
+ && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
+ acpi_c3_exit_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat);
+ acpi_c3_enter_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5);
+ }
+
+ return 0;
+}
+
+/*
+ * Find and load ACPI tables
+ */
+int
+acpi_load_tables(void)
+{
+ if (ACPI_SUCCESS(acpi_load_firmware_tables()))
+ {
+ printk(KERN_INFO "ACPI: support found\n");
+ }
+ else if (acpi_find_chipset()) {
+ acpi_terminate();
+ return -1;
+ }
+
+ if (acpi_fetch_facp()) {
+ acpi_terminate();
+ return -1;
+ }
+
+ if (!ACPI_SUCCESS(acpi_load_namespace())) {
+ printk(KERN_ERR "ACPI: namespace load failed\n");
+ acpi_terminate();
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 785a0e551..b8f1c693e 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -66,6 +66,7 @@ not be guaranteed. There are several ways to assure this:
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -269,7 +270,7 @@ static int slm_get_pagesize( int device, int *w, int *h );
/************************* End of Prototypes **************************/
-static struct timer_list slm_timer = { NULL, NULL, 0, 0, slm_test_ready };
+static struct timer_list slm_timer = { function: slm_test_ready };
static struct file_operations slm_fops = {
owner: THIS_MODULE,
@@ -799,10 +800,12 @@ static int slm_release( struct inode *inode, struct file *file )
device = MINOR(inode->i_rdev);
sip = &slm_info[device];
+ lock_kernel();
if (file->f_mode & 2)
sip->wbusy = 0;
if (file->f_mode & 1)
sip->rbusy = 0;
+ unlock_kernel();
return( 0 );
}
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 37e50dbcd..6e094e4d8 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -578,7 +578,6 @@ static inline void attempt_front_merge(request_queue_t * q,
static inline void __make_request(request_queue_t * q, int rw,
struct buffer_head * bh)
{
- int major = MAJOR(bh->b_rdev);
unsigned int sector, count;
int max_segments = MAX_SEGMENTS;
struct request * req = NULL;
@@ -590,26 +589,6 @@ static inline void __make_request(request_queue_t * q, int rw,
count = bh->b_size >> 9;
sector = bh->b_rsector;
- if (blk_size[major]) {
- unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1;
-
- if (maxsector < count || maxsector - count < sector) {
- bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped);
- if (!blk_size[major][MINOR(bh->b_rdev)])
- goto end_io;
- /* This may well happen - the kernel calls bread()
- without checking the size of the device, e.g.,
- when mounting a device. */
- printk(KERN_INFO
- "attempt to access beyond end of device\n");
- printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n",
- kdevname(bh->b_rdev), rw,
- (sector + count)>>1,
- blk_size[major][MINOR(bh->b_rdev)]);
- goto end_io;
- }
- }
-
rw_ahead = 0; /* normal case; gets changed below for READA */
switch (rw) {
case READA:
@@ -758,9 +737,35 @@ end_io:
bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
}
-int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+void generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
{
- int ret;
+ int major = MAJOR(bh->b_rdev);
+
+ if (blk_size[major]) {
+ unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1;
+ unsigned int sector, count;
+
+ count = bh->b_size >> 9;
+ sector = bh->b_rsector;
+
+ if (maxsector < count || maxsector - count < sector) {
+ bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped);
+ if (blk_size[major][MINOR(bh->b_rdev)]) {
+
+ /* This may well happen - the kernel calls bread()
+ without checking the size of the device, e.g.,
+ when mounting a device. */
+ printk(KERN_INFO
+ "attempt to access beyond end of device\n");
+ printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n",
+ kdevname(bh->b_rdev), rw,
+ (sector + count)>>1,
+ blk_size[major][MINOR(bh->b_rdev)]);
+ }
+ bh->b_end_io(bh, 0);
+ return;
+ }
+ }
/*
* Resolve the mapping until finished. (drivers are
@@ -768,12 +773,9 @@ int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
* by explicitly returning 0)
*/
while (q->make_request_fn) {
- ret = q->make_request_fn(q, rw, bh);
- if (ret > 0) {
- q = blk_get_queue(bh->b_rdev);
- continue;
- }
- return ret;
+ if (q->make_request_fn(q, rw, bh) == 0)
+ return;
+ q = blk_get_queue(bh->b_rdev);
}
/*
* Does the block device want us to queue
@@ -784,16 +786,13 @@ int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
if (q && !q->plugged)
(q->request_fn)(q);
spin_unlock_irq(&io_request_lock);
-
- return 0;
}
/* This function can be used to request a number of buffers from a block
device. Currently the only restriction is that all buffers must belong to
the same device */
-static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[],
- int haslock)
+void ll_rw_block(int rw, int nr, struct buffer_head * bhs[])
{
struct buffer_head *bh;
request_queue_t *q;
@@ -840,13 +839,9 @@ static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[],
bh = bhs[i];
/* Only one thread can actually submit the I/O. */
- if (haslock) {
- if (!buffer_locked(bh))
- BUG();
- } else {
- if (test_and_set_bit(BH_Lock, &bh->b_state))
- continue;
- }
+ if (test_and_set_bit(BH_Lock, &bh->b_state))
+ continue;
+
set_bit(BH_Req, &bh->b_state);
/*
@@ -865,15 +860,6 @@ sorry:
buffer_IO_error(bhs[i]);
}
-void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
-{
- __ll_rw_block(rw, nr, bh, 0);
-}
-
-void ll_rw_block_locked(int rw, int nr, struct buffer_head * bh[])
-{
- __ll_rw_block(rw, nr, bh, 1);
-}
#ifdef CONFIG_STRAM_SWAP
extern int stram_device_init (void);
diff --git a/drivers/block/lvm.c b/drivers/block/lvm.c
index 1e2a21cf1..d8cf20d79 100644
--- a/drivers/block/lvm.c
+++ b/drivers/block/lvm.c
@@ -301,6 +301,7 @@ static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
static struct file_operations lvm_chr_fops =
{
+ owner: THIS_MODULE,
open: lvm_chr_open,
release: lvm_chr_close,
ioctl: lvm_chr_ioctl,
@@ -517,8 +518,6 @@ static int lvm_chr_open(struct inode *inode,
/* Group special file open */
if (VG_CHR(minor) > MAX_VG) return -ENXIO;
- MOD_INC_USE_COUNT;
-
lvm_chr_open_count++;
return 0;
} /* lvm_chr_open() */
@@ -743,6 +742,7 @@ static int lvm_chr_close(struct inode *inode, struct file *file)
"%s -- lvm_chr_close VG#: %d\n", lvm_name, VG_CHR(minor));
#endif
+ lock_kernel();
#ifdef LVM_TOTAL_RESET
if (lvm_reset_spindown > 0) {
lvm_reset_spindown = 0;
@@ -755,10 +755,7 @@ static int lvm_chr_close(struct inode *inode, struct file *file)
lock = 0; /* release lock */
wake_up_interruptible(&lvm_wait);
}
-
-#ifdef MODULE
- if (GET_USE_COUNT(&__this_module) > 0) MOD_DEC_USE_COUNT;
-#endif
+ unlock_kernel();
return 0;
} /* lvm_chr_close() */
diff --git a/drivers/block/md.c b/drivers/block/md.c
index 651c3dd6d..087b5aee1 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -3412,7 +3412,7 @@ repeat:
currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1;
if (currspeed > sysctl_speed_limit_min) {
- current->priority = 19;
+ current->nice = 19;
if ((currspeed > sysctl_speed_limit_max) ||
!is_mddev_idle(mddev)) {
@@ -3422,7 +3422,7 @@ repeat:
goto repeat;
}
} else
- current->priority = -20;
+ current->nice = -20;
}
fsync_dev(read_disk);
printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 2315e1d30..b36fdab11 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -13,10 +13,11 @@
1.02 GRG 1998.05.05 init_proto, release_proto, ktti
1.03 GRG 1998.08.15 eliminate compiler warning
1.04 GRG 1998.11.28 added support for FRIQ
-
+ 1.05 TMW 2000.06.06 use parport_find_number instead of
+ parport_enumerate
*/
-#define PI_VERSION "1.04"
+#define PI_VERSION "1.05"
#include <linux/module.h>
#include <linux/config.h>
@@ -238,22 +239,25 @@ static void pi_register_parport( PIA *pi, int verbose)
{
#ifdef CONFIG_PARPORT
- struct parport *pp;
-
- pp = parport_enumerate();
+ struct parport *port;
- while((pp)&&(pp->base != pi->port)) pp = pp->next;
+ port = parport_find_base (pi->port);
+ if (!port) return;
- if (!pp) return;
+ pi->pardev = parport_register_device(port,
+ pi->device,NULL,
+ pi_wake_up,NULL,
+ 0,(void *)pi);
+ parport_put_port (port);
+ if (!pi->pardev) return;
- pi->pardev = (void *) parport_register_device(
- pp,pi->device,NULL,pi_wake_up,NULL,0,(void *)pi);
init_waitqueue_head(&pi->parq);
- if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name);
+ if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,
+ port->name);
- pi->parname = (char *)pp->name;
+ pi->parname = (char *)port->name;
#endif
}
@@ -406,6 +410,7 @@ int init_module(void)
{ int k;
for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
+
printk("paride: version %s installed\n",PI_VERSION);
return 0;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index c282d82a1..e2709ce97 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -171,6 +171,7 @@ static int pg_drive_count;
#include <linux/mtio.h>
#include <linux/pg.h>
#include <linux/wait.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -604,10 +605,12 @@ static int pg_release (struct inode *inode, struct file *file)
if ((unit >= PG_UNITS) || (PG.access <= 0))
return -EINVAL;
+ lock_kernel();
PG.access--;
kfree(PG.bufptr);
PG.bufptr = NULL;
+ unlock_kernel();
return 0;
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 0d3e81838..5cb91ae0a 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -149,6 +149,7 @@ static int pt_drive_count;
#include <linux/malloc.h>
#include <linux/mtio.h>
#include <linux/wait.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -773,6 +774,7 @@ static int pt_release (struct inode *inode, struct file *file)
if ((unit >= PT_UNITS) || (PT.access <= 0))
return -EINVAL;
+ lock_kernel();
if (PT.flags & PT_WRITING) pt_write_fm(unit);
if (PT.flags & PT_REWIND) pt_rewind(unit);
@@ -781,6 +783,7 @@ static int pt_release (struct inode *inode, struct file *file)
kfree(PT.bufptr);
PT.bufptr = NULL;
+ unlock_kernel();
return 0;
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 61cb27ec7..8ff56a70a 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -114,14 +114,14 @@ static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open);
int no_int_yet;
-static int access_count[MAX_HD] = {0,};
-static char ps2esdi_valid[MAX_HD] = {0,};
-static int ps2esdi_sizes[MAX_HD << 6] = {0,};
-static int ps2esdi_blocksizes[MAX_HD << 6] = {0,};
-static int ps2esdi_drives = 0;
+static int access_count[MAX_HD];
+static char ps2esdi_valid[MAX_HD];
+static int ps2esdi_sizes[MAX_HD << 6];
+static int ps2esdi_blocksizes[MAX_HD << 6];
+static int ps2esdi_drives;
static struct hd_struct ps2esdi[MAX_HD << 6];
static u_short io_base;
-static struct timer_list esdi_timer = {{NULL, NULL}, 0, 0L, ps2esdi_reset_timer};
+static struct timer_list esdi_timer = { function: ps2esdi_reset_timer };
static int reset_status;
static int ps2esdi_slot = -1;
int tp720esdi = 0; /* Is it Integrated ESDI of ThinkPad-720? */
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 727c1c543..2db08531a 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -59,6 +59,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -298,11 +299,14 @@ static int initrd_release(struct inode *inode,struct file *file)
{
extern void free_initrd_mem(unsigned long, unsigned long);
- if (--initrd_users) return 0;
- blkdev_put(inode->i_bdev, BDEV_FILE);
- iput(inode);
- free_initrd_mem(initrd_start, initrd_end);
- initrd_start = 0;
+ lock_kernel();
+ if (!--initrd_users) {
+ blkdev_put(inode->i_bdev, BDEV_FILE);
+ iput(inode);
+ free_initrd_mem(initrd_start, initrd_end);
+ initrd_start = 0;
+ }
+ unlock_kernel();
return 0;
}
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
index 8b551a99d..b71f023aa 100644
--- a/drivers/cdrom/aztcd.c
+++ b/drivers/cdrom/aztcd.c
@@ -310,7 +310,7 @@ static char azt_auto_eject = AZT_AUTO_EJECT;
static int AztTimeout, AztTries;
static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
-static struct timer_list delay_timer = { {NULL, NULL}, 0, 0, NULL };
+static struct timer_list delay_timer;
static struct azt_DiskInfo DiskInfo;
static struct azt_Toc Toc[MAX_TRACKS];
diff --git a/drivers/cdrom/sjcd.c b/drivers/cdrom/sjcd.c
index b793bac4b..eb102a4a7 100644
--- a/drivers/cdrom/sjcd.c
+++ b/drivers/cdrom/sjcd.c
@@ -150,7 +150,7 @@ static struct sjcd_stat statistic;
/*
* Timer.
*/
-static struct timer_list sjcd_delay_timer = { function: NULL };
+static struct timer_list sjcd_delay_timer;
#define SJCD_SET_TIMER( func, tmout ) \
( sjcd_delay_timer.expires = jiffies+tmout, \
diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c
index eaa9e6bae..b28df7e34 100644
--- a/drivers/char/acquirewdt.c
+++ b/drivers/char/acquirewdt.c
@@ -38,6 +38,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
static int acq_is_open=0;
static spinlock_t acq_lock;
@@ -140,6 +141,7 @@ static int acq_open(struct inode *inode, struct file *file)
static int acq_close(struct inode *inode, struct file *file)
{
+ lock_kernel();
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
spin_lock(&acq_lock);
@@ -149,6 +151,7 @@ static int acq_close(struct inode *inode, struct file *file)
acq_is_open=0;
spin_unlock(&acq_lock);
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
index e67beef38..d16c62a22 100644
--- a/drivers/char/agp/agpgart_fe.c
+++ b/drivers/char/agp/agpgart_fe.c
@@ -41,6 +41,7 @@
#include <linux/miscdevice.h>
#include <linux/agp_backend.h>
#include <linux/agpgart.h>
+#include <linux/smp_lock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -605,14 +606,17 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
agp_file_private *priv = (agp_file_private *) file->private_data;
agp_kern_info kerninfo;
+ lock_kernel();
AGP_LOCK();
if (agp_fe.backend_acquired != TRUE) {
AGP_UNLOCK();
+ unlock_kernel();
return -EPERM;
}
if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) {
AGP_UNLOCK();
+ unlock_kernel();
return -EPERM;
}
agp_copy_info(&kerninfo);
@@ -624,42 +628,51 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
if ((size + offset) > current_size) {
AGP_UNLOCK();
+ unlock_kernel();
return -EINVAL;
}
client = agp_find_client_by_pid(current->pid);
if (client == NULL) {
AGP_UNLOCK();
+ unlock_kernel();
return -EPERM;
}
if (!agp_find_seg_in_client(client, offset,
size, vma->vm_page_prot)) {
AGP_UNLOCK();
+ unlock_kernel();
return -EINVAL;
}
if (remap_page_range(vma->vm_start,
(kerninfo.aper_base + offset),
size, vma->vm_page_prot)) {
AGP_UNLOCK();
+ unlock_kernel();
return -EAGAIN;
}
AGP_UNLOCK();
+ unlock_kernel();
return 0;
}
if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
if (size != current_size) {
AGP_UNLOCK();
+ unlock_kernel();
return -EINVAL;
}
if (remap_page_range(vma->vm_start, kerninfo.aper_base,
size, vma->vm_page_prot)) {
AGP_UNLOCK();
+ unlock_kernel();
return -EAGAIN;
}
AGP_UNLOCK();
+ unlock_kernel();
return 0;
}
AGP_UNLOCK();
+ unlock_kernel();
return -EPERM;
}
@@ -667,6 +680,7 @@ static int agp_release(struct inode *inode, struct file *file)
{
agp_file_private *priv = (agp_file_private *) file->private_data;
+ lock_kernel();
AGP_LOCK();
if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
@@ -688,6 +702,7 @@ static int agp_release(struct inode *inode, struct file *file)
agp_remove_file_private(priv);
kfree(priv);
AGP_UNLOCK();
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/amikeyb.c b/drivers/char/amikeyb.c
index 15e21be68..73b8fecd2 100644
--- a/drivers/char/amikeyb.c
+++ b/drivers/char/amikeyb.c
@@ -176,7 +176,7 @@ static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
static unsigned char rep_scancode;
static void amikeyb_rep(unsigned long ignore);
-static struct timer_list amikeyb_rep_timer = {NULL, NULL, 0, 0, amikeyb_rep};
+static struct timer_list amikeyb_rep_timer = {function: amikeyb_rep};
static void amikeyb_rep(unsigned long ignore)
{
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index d5091ff4d..c109c5965 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -101,21 +101,18 @@ static unsigned int ReadErrorCount; /* number of read error */
static unsigned int DeviceErrorCount; /* number of device error */
static loff_t ac_llseek(struct file *, loff_t, int);
-static int ac_open(struct inode *, struct file *);
static ssize_t ac_read (struct file *, char *, size_t, loff_t *);
static ssize_t ac_write (struct file *, const char *, size_t, loff_t *);
static int ac_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
-static int ac_release(struct inode *, struct file *);
static void ac_interrupt(int, void *, struct pt_regs *);
struct file_operations ac_fops = {
+ owner:THIS_MODULE,
llseek:ac_llseek,
read:ac_read,
write:ac_write,
ioctl:ac_ioctl,
- open:ac_open,
- release:ac_release,
};
struct miscdevice ac_miscdev = {
@@ -124,6 +121,8 @@ struct miscdevice ac_miscdev = {
&ac_fops
};
+static int dummy; /* dev_id for request_irq() */
+
int ac_register_board(unsigned long physloc, unsigned long loc,
unsigned char boardno)
{
@@ -180,7 +179,7 @@ void cleanup_module(void)
iounmap((void *) apbs[i].RamIO);
if (apbs[i].irq)
- free_irq(apbs[i].irq, &ac_open);
+ free_irq(apbs[i].irq, &dummy);
}
}
@@ -226,7 +225,7 @@ int __init applicom_init(void)
continue;
}
- if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &ac_open)) {
+ if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &dummy)) {
printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq);
iounmap(RamIO);
apbs[boardno - 1].RamIO = 0;
@@ -277,7 +276,7 @@ int __init applicom_init(void)
printk(KERN_NOTICE "Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO*i), irq);
if (!numisa) {
- if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &ac_open)) {
+ if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &dummy)) {
printk(KERN_WARNING "Could not allocate IRQ %d for ISA Applicom device.\n", irq);
iounmap((void *) RamIO);
apbs[boardno - 1].RamIO = 0;
@@ -346,19 +345,6 @@ static loff_t ac_llseek(struct file *file, loff_t offset, int origin)
return -ESPIPE;
}
-static int ac_open(struct inode *inode, struct file *filp)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int ac_release(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-
static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
{
unsigned int NumCard; /* Board number 1 -> 8 */
diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c
index bc8345cff..9bfe4b2b3 100644
--- a/drivers/char/busmouse.c
+++ b/drivers/char/busmouse.c
@@ -19,6 +19,7 @@
#include <linux/miscdevice.h>
#include <linux/random.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -167,6 +168,7 @@ static int busmouse_release(struct inode *inode, struct file *file)
struct busmouse_data *mse = (struct busmouse_data *)file->private_data;
int ret = 0;
+ lock_kernel();
busmouse_fasync(-1, file, 0);
if (--mse->active == 0) {
@@ -178,6 +180,7 @@ static int busmouse_release(struct inode *inode, struct file *file)
}
mse->ready = 0;
}
+ unlock_kernel();
return ret;
}
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index cf4bb1f83..d0e801180 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -2,7 +2,7 @@
#define Z_WAKE
#undef Z_EXT_CHARS_IN_BUFFER
static char rcsid[] =
-"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $";
+"$Revision: 2.3.2.8 $$Date: 2000/07/06 18:14:16 $";
/*
* linux/drivers/char/cyclades.c
@@ -25,6 +25,11 @@ static char rcsid[] =
* This version supports shared IRQ's (only for PCI boards).
*
* $Log: cyclades.c,v $
+ * Revision 2.3.2.8 2000/07/06 18:14:16 ivan
+ * Fixed the PCI detection function to work properly on Alpha systems.
+ * Implemented support for TIOCSERGETLSR ioctl.
+ * Implemented full support for non-standard baud rates.
+ *
* Revision 2.3.2.7 2000/06/01 18:26:34 ivan
* Request PLX I/O region, although driver doesn't use it, to avoid
* problems with other drivers accessing it.
@@ -1363,9 +1368,16 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while (char_count-- > 0){
if (!info->xmit_cnt){
- cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) &
- ~CyTxRdy);
+ if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ cy_readb(base_addr+(CySRER<<index)) &
+ ~CyTxMpty);
+ } else {
+ cy_writeb((u_long)base_addr+(CySRER<<index),
+ ((cy_readb(base_addr+(CySRER<<index))
+ & ~CyTxRdy)
+ | CyTxMpty));
+ }
goto txdone;
}
if (info->xmit_buf == 0){
@@ -3176,6 +3188,30 @@ cy_chars_in_buffer(struct tty_struct *tty)
* ------------------------------------------------------------
*/
+static void
+cyy_baud_calc(struct cyclades_port *info, uclong baud)
+{
+ int co, co_val, bpr;
+ uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000);
+
+ if (baud == 0) {
+ info->tbpr = info->tco = info->rbpr = info->rco = 0;
+ return;
+ }
+
+ /* determine which prescaler to use */
+ for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
+ if (cy_clock / co_val / baud > 63)
+ break;
+ }
+
+ bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
+ if (bpr > 255)
+ bpr = 255;
+
+ info->tbpr = info->rbpr = bpr;
+ info->tco = info->rco = co;
+}
/*
* This routine finds or computes the various line characteristics.
@@ -3189,7 +3225,7 @@ set_line_char(struct cyclades_port * info)
int card,chip,channel,index;
unsigned cflag, iflag;
unsigned short chip_number;
- int baud;
+ int baud, baud_rate = 0;
int i;
@@ -3225,12 +3261,14 @@ set_line_char(struct cyclades_port * info)
index = cy_card[card].bus_index;
/* baud rate */
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
- baud = info->baud;
- } else {
- baud = tty_get_baud_rate(info->tty);
- }
- if (baud > CD1400_MAX_SPEED) {
+ baud = tty_get_baud_rate(info->tty);
+ if ((baud == 38400) &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+ if (info->custom_divisor)
+ baud_rate = info->baud / info->custom_divisor;
+ else
+ baud_rate = info->baud;
+ } else if (baud > CD1400_MAX_SPEED) {
baud = CD1400_MAX_SPEED;
}
/* find the baud index */
@@ -3243,22 +3281,29 @@ set_line_char(struct cyclades_port * info)
i = 19; /* CD1400_MAX_SPEED */
}
-
- if(info->chip_rev >= CD1400_REV_J) {
- /* It is a CD1400 rev. J or later */
- info->tbpr = baud_bpr_60[i]; /* Tx BPR */
- info->tco = baud_co_60[i]; /* Tx CO */
- info->rbpr = baud_bpr_60[i]; /* Rx BPR */
- info->rco = baud_co_60[i]; /* Rx CO */
+ if ((baud == 38400) &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+ cyy_baud_calc(info, baud_rate);
} else {
- info->tbpr = baud_bpr_25[i]; /* Tx BPR */
- info->tco = baud_co_25[i]; /* Tx CO */
- info->rbpr = baud_bpr_25[i]; /* Rx BPR */
- info->rco = baud_co_25[i]; /* Rx CO */
+ if(info->chip_rev >= CD1400_REV_J) {
+ /* It is a CD1400 rev. J or later */
+ info->tbpr = baud_bpr_60[i]; /* Tx BPR */
+ info->tco = baud_co_60[i]; /* Tx CO */
+ info->rbpr = baud_bpr_60[i]; /* Rx BPR */
+ info->rco = baud_co_60[i]; /* Rx CO */
+ } else {
+ info->tbpr = baud_bpr_25[i]; /* Tx BPR */
+ info->tco = baud_co_25[i]; /* Tx CO */
+ info->rbpr = baud_bpr_25[i]; /* Rx BPR */
+ info->rco = baud_co_25[i]; /* Rx CO */
+ }
}
if (baud_table[i] == 134) {
- info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
/* get it right for 134.5 baud */
+ info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+ } else if ((baud == 38400) &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+ info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
} else if (baud_table[i]) {
info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
/* this needs to be propagated into the card info */
@@ -3447,19 +3492,24 @@ set_line_char(struct cyclades_port * info)
buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
/* baud rate */
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
- baud = info->baud;
- } else {
- baud = tty_get_baud_rate(info->tty);
- }
- if (baud > CYZ_MAX_SPEED) {
+ baud = tty_get_baud_rate(info->tty);
+ if ((baud == 38400) &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+ if (info->custom_divisor)
+ baud_rate = info->baud / info->custom_divisor;
+ else
+ baud_rate = info->baud;
+ } else if (baud > CYZ_MAX_SPEED) {
baud = CYZ_MAX_SPEED;
}
cy_writel(&ch_ctrl->comm_baud , baud);
if (baud == 134) {
- info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
/* get it right for 134.5 baud */
+ info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+ } else if ((baud == 38400) &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+ info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
} else if (baud) {
info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
/* this needs to be propagated into the card info */
@@ -3549,8 +3599,6 @@ set_line_char(struct cyclades_port * info)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
}
-
-
} /* set_line_char */
@@ -3571,7 +3619,7 @@ get_serial_info(struct cyclades_port * info,
tmp.flags = info->flags;
tmp.close_delay = info->close_delay;
tmp.baud_base = info->baud;
- tmp.custom_divisor = 0; /*!!!*/
+ tmp.custom_divisor = info->custom_divisor;
tmp.hub6 = 0; /*!!!*/
return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
} /* get_serial_info */
@@ -3597,6 +3645,7 @@ set_serial_info(struct cyclades_port * info,
info->flags = ((info->flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
info->baud = new_serial.baud_base;
+ info->custom_divisor = new_serial.custom_divisor;
goto check_and_exit;
}
@@ -3607,6 +3656,7 @@ set_serial_info(struct cyclades_port * info,
*/
info->baud = new_serial.baud_base;
+ info->custom_divisor = new_serial.custom_divisor;
info->flags = ((info->flags & ~ASYNC_FLAGS) |
(new_serial.flags & ASYNC_FLAGS));
info->close_delay = new_serial.close_delay * HZ/100;
@@ -3621,6 +3671,43 @@ check_and_exit:
}
} /* set_serial_info */
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * is emptied. On bus types like RS485, the transmitter must
+ * release the bus after transmitting. This must be done when
+ * the transmit shift register is empty, not be done when the
+ * transmit holding register is empty. This functionality
+ * allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
+{
+ int card, chip, channel, index;
+ unsigned char status;
+ unsigned int result;
+ unsigned long flags;
+ unsigned char *base_addr;
+
+ card = info->card;
+ channel = (info->line) - (cy_card[card].first_line);
+ if (!IS_CYC_Z(cy_card[card])) {
+ chip = channel>>2;
+ channel &= 0x03;
+ index = cy_card[card].bus_index;
+ base_addr = (unsigned char *)
+ (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
+
+ CY_LOCK(info, flags);
+ status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty);
+ CY_UNLOCK(info, flags);
+ result = (status ? 0 : TIOCSER_TEMT);
+ } else {
+ /* Not supported yet */
+ return -EINVAL;
+ }
+ return cy_put_user(result, (unsigned long *) value);
+}
static int
get_modem_info(struct cyclades_port * info, unsigned int *value)
@@ -4247,6 +4334,9 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
case TIOCSSERIAL:
ret_val = set_serial_info(info, (struct serial_struct *) arg);
break;
+ case TIOCSERGETLSR: /* Get line status register */
+ ret_val = get_lsr_info(info, (unsigned int *) arg);
+ break;
/*
* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
* - mask passed in arg for lines of interest
@@ -4937,10 +5027,9 @@ cy_detect_pci(void)
i--;
continue;
}
-#else
+#endif
cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Yctl);
cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ywin);
-#endif
#ifdef CY_PCI_DEBUG
printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
@@ -5048,9 +5137,7 @@ cy_detect_pci(void)
printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
(ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
#endif
-#if !defined(__alpha__)
- cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
-#endif
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
/* Disable interrupts on the PLX before resetting it */
cy_writew(cy_pci_addr0+0x68,
@@ -5078,9 +5165,7 @@ cy_detect_pci(void)
request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z");
if (mailbox == ZE_V1) {
-#if !defined(__alpha__)
- cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
-#endif
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
if (ZeIndex == NR_CARDS) {
printk("Cyclades-Ze/PCI found at 0x%lx ",
(ulong)cy_pci_phys2);
@@ -5097,9 +5182,7 @@ cy_detect_pci(void)
i--;
continue;
} else {
-#if !defined(__alpha__)
- cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
-#endif
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
}
#ifdef CY_PCI_DEBUG
@@ -5538,6 +5621,7 @@ cy_init(void)
info->tco = 0;
info->rbpr = 0;
info->rco = 0;
+ info->custom_divisor = 0;
info->close_delay = 5*HZ/10;
info->closing_wait = CLOSING_WAIT_DELAY;
info->icount.cts = info->icount.dsr =
@@ -5596,6 +5680,7 @@ cy_init(void)
info->cor3 = 0x08; /* _very_ small rcv threshold */
info->cor4 = 0;
info->cor5 = 0;
+ info->custom_divisor = 0;
info->close_delay = 5*HZ/10;
info->closing_wait = CLOSING_WAIT_DELAY;
info->icount.cts = info->icount.dsr =
diff --git a/drivers/char/dn_keyb.c b/drivers/char/dn_keyb.c
index 8d8766b85..980ee13ba 100644
--- a/drivers/char/dn_keyb.c
+++ b/drivers/char/dn_keyb.c
@@ -51,8 +51,7 @@ static u_char *shadow_buf=&debug_buf2[0];
static short debug_buf_count=0;
static int debug_buf_overrun=0,debug_timer_running=0;
static unsigned long debug_buffer_updated=0;
-static struct timer_list debug_keyb_timer = { NULL, NULL, 0, 0,
- debug_keyb_timer_handler };
+static struct timer_list debug_keyb_timer = { function: debug_keyb_timer_handler };
#endif
static u_short dnplain_map[NR_KEYS] __initdata = {
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index a1ab1f279..5ad4885bf 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -6,6 +6,8 @@
#include "drmP.h"
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <asm/oplib.h>
#include <asm/upa.h>
@@ -44,6 +46,7 @@ extern int ffb_rmctx(struct inode *, struct file *, unsigned int, unsigned long)
extern int ffb_context_switch(drm_device_t *, int, int);
static struct file_operations ffb_fops = {
+ owner: THIS_MODULE,
open: ffb_open,
flush: drm_flush,
release: ffb_release,
@@ -501,7 +504,6 @@ static int ffb_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
ret = drm_open_helper(inode, filp, dev);
if (!ret) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -517,9 +519,11 @@ static int ffb_open(struct inode *inode, struct file *filp)
static int ffb_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ drm_device_t *dev;
int ret = 0;
+ lock_kernel();
+ dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (dev->lock.hw_lock != NULL
&& _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
@@ -541,7 +545,6 @@ static int ffb_release(struct inode *inode, struct file *filp)
ret = drm_release(inode, filp);
if (!ret) {
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
@@ -550,14 +553,18 @@ static int ffb_release(struct inode *inode, struct file *filp)
atomic_read(&dev->ioctl_count),
dev->blocked);
spin_unlock(&dev->count_lock);
+ unlock_kernel();
return -EBUSY;
}
spin_unlock(&dev->count_lock);
- return ffb_takedown(dev);
+ ret = ffb_takedown(dev);
+ unlock_kernel();
+ return ret;
}
spin_unlock(&dev->count_lock);
}
+ unlock_kernel();
return ret;
}
@@ -756,6 +763,7 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+ lock_kernel();
minor = MINOR(filp->f_dentry->d_inode->i_rdev);
ffb_priv = NULL;
for (i = 0; i < ffb_dev_table_size; i++) {
@@ -763,13 +771,15 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
if (ffb_priv->miscdev.minor == minor)
break;
}
- if (i >= ffb_dev_table_size)
+ if (i >= ffb_dev_table_size) {
+ unlock_kernel();
return -EINVAL;
-
+ }
/* We don't support/need dma mappings, so... */
- if (!VM_OFFSET(vma))
+ if (!VM_OFFSET(vma)) {
+ unlock_kernel();
return -EINVAL;
-
+ }
for (i = 0; i < dev->map_count; i++) {
unsigned long off;
@@ -781,16 +791,19 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
break;
}
- if (i >= dev->map_count)
+ if (i >= dev->map_count) {
+ unlock_kernel();
return -EINVAL;
-
+ }
if (!map ||
- ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+ ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) {
+ unlock_kernel();
return -EPERM;
-
- if (map->size != (vma->vm_end - vma->vm_start))
+ }
+ if (map->size != (vma->vm_end - vma->vm_start)) {
+ unlock_kernel();
return -EINVAL;
-
+ }
/* Set read-only attribute before mappings are created
* so it works for fb/reg maps too.
*/
@@ -813,9 +826,10 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
if (io_remap_page_range(vma->vm_start,
ffb_priv->card_phys_base + VM_OFFSET(vma),
vma->vm_end - vma->vm_start,
- vma->vm_page_prot, 0))
+ vma->vm_page_prot, 0)) {
+ unlock_kernel();
return -EAGAIN;
-
+ }
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_SHM:
@@ -828,8 +842,10 @@ static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_LOCKED;
break;
default:
+ unlock_kernel();
return -EINVAL; /* This should never happen. */
};
+ unlock_kernel();
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c
index 7e0d6e53e..8809d1810 100644
--- a/drivers/char/drm/gamma_drv.c
+++ b/drivers/char/drm/gamma_drv.c
@@ -29,6 +29,8 @@
*/
#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "drmP.h"
#include "gamma_drv.h"
EXPORT_SYMBOL(gamma_init);
@@ -44,14 +46,15 @@ EXPORT_SYMBOL(gamma_cleanup);
static drm_device_t gamma_device;
static struct file_operations gamma_fops = {
- open: gamma_open,
- flush: drm_flush,
- release: gamma_release,
- ioctl: gamma_ioctl,
- mmap: drm_mmap,
- read: drm_read,
- fasync: drm_fasync,
- poll: drm_poll,
+ owner: THIS_MODULE,
+ open: gamma_open,
+ flush: drm_flush,
+ release: gamma_release,
+ ioctl: gamma_ioctl,
+ mmap: drm_mmap,
+ read: drm_read,
+ fasync: drm_fasync,
+ poll: drm_poll,
};
static struct miscdevice gamma_misc = {
@@ -407,7 +410,6 @@ int gamma_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -422,12 +424,13 @@ int gamma_open(struct inode *inode, struct file *filp)
int gamma_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ drm_device_t *dev;
int retcode = 0;
+ lock_kernel();
+ dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_release(inode, filp))) {
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
@@ -436,13 +439,17 @@ int gamma_release(struct inode *inode, struct file *filp)
atomic_read(&dev->ioctl_count),
dev->blocked);
spin_unlock(&dev->count_lock);
+ unlock_kernel();
return -EBUSY;
}
spin_unlock(&dev->count_lock);
- return gamma_takedown(dev);
+ retcode = gamma_takedown(dev);
+ unlock_kernel();
+ return retcode;
}
spin_unlock(&dev->count_lock);
}
+ unlock_kernel();
return retcode;
}
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index 23c9c55bf..b0c41c93c 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -30,6 +30,8 @@
*/
#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "drmP.h"
#include "tdfx_drv.h"
@@ -44,6 +46,7 @@ static drm_device_t tdfx_device;
drm_ctx_t tdfx_res_ctx;
static struct file_operations tdfx_fops = {
+ owner: THIS_MODULE,
open: tdfx_open,
flush: drm_flush,
release: tdfx_release,
@@ -343,7 +346,6 @@ int tdfx_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -358,12 +360,13 @@ int tdfx_open(struct inode *inode, struct file *filp)
int tdfx_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ drm_device_t *dev;
int retcode = 0;
+ lock_kernel();
+ dev = priv->dev;
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_release(inode, filp))) {
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
@@ -372,13 +375,17 @@ int tdfx_release(struct inode *inode, struct file *filp)
atomic_read(&dev->ioctl_count),
dev->blocked);
spin_unlock(&dev->count_lock);
+ unlock_kernel();
return -EBUSY;
}
spin_unlock(&dev->count_lock);
- return tdfx_takedown(dev);
+ retcode = tdfx_takedown(dev);
+ unlock_kernel();
+ return retcode;
}
spin_unlock(&dev->count_lock);
}
+ unlock_kernel();
return retcode;
}
diff --git a/drivers/char/drm/vm.c b/drivers/char/drm/vm.c
index b4c4c5bbf..b6595c88c 100644
--- a/drivers/char/drm/vm.c
+++ b/drivers/char/drm/vm.c
@@ -144,7 +144,6 @@ void drm_vm_open(struct vm_area_struct *vma)
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_inc(&dev->vma_count);
- MOD_INC_USE_COUNT;
#if DRM_DEBUG_CODE
vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
@@ -169,7 +168,6 @@ void drm_vm_close(struct vm_area_struct *vma)
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
- MOD_DEC_USE_COUNT;
atomic_dec(&dev->vma_count);
#if DRM_DEBUG_CODE
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 6fe41e118..0ada290ac 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -35,6 +35,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/atarihw.h>
@@ -483,7 +484,9 @@ static int dsp56k_release(struct inode *inode, struct file *file)
{
case DSP56K_DEV_56001:
+ lock_kernel();
dsp56k.in_use = 0;
+ unlock_kernel();
break;
default:
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 475e1d052..867a7fcec 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -69,6 +69,7 @@
#include <linux/poll.h> /* for POLLIN, etc. */
#include <linux/dtlk.h> /* local header file for DoubleTalk values */
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#ifdef TRACING
#define TRACE_TEXT(str) printk(str);
@@ -333,7 +334,9 @@ static int dtlk_release(struct inode *inode, struct file *file)
}
TRACE_RET;
+ lock_kernel();
del_timer(&dtlk_timer);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index fd81f24ca..a57e3abc1 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -35,15 +35,11 @@
#endif
#include <linux/fcntl.h>
#include <linux/wrapper.h>
+#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/zftape.h>
-#if LINUX_VERSION_CODE >=KERNEL_VER(2,1,16)
#include <linux/init.h>
-#else
-#define __initdata
-#define __initfunc(__arg) __arg
-#endif
#include "../zftape/zftape-init.h"
#include "../zftape/zftape-read.h"
@@ -56,7 +52,6 @@ char zft_src[] __initdata = "$Source: /homes/cvs/ftape-stacked/ftape/zftape/zfta
char zft_rev[] __initdata = "$Revision: 1.8 $";
char zft_dat[] __initdata = "$Date: 1997/11/06 00:48:56 $";
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18)
MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine "
"(claus@momo.math.rwth-aachen.de)");
MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
@@ -64,7 +59,6 @@ MODULE_DESCRIPTION(ZFTAPE_VERSION " - "
"Support for QIC-113 compatible volume table "
"and builtin compression (lzrw3 algorithm)");
MODULE_SUPPORTED_DEVICE("char-major-27");
-#endif
/* Global vars.
*/
@@ -90,38 +84,18 @@ static sigset_t orig_sigmask;
*/
static int zft_open (struct inode *ino, struct file *filep);
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31)
static int zft_close(struct inode *ino, struct file *filep);
-#else
-static void zft_close(struct inode *ino, struct file *filep);
-#endif
static int zft_ioctl(struct inode *ino, struct file *filep,
unsigned int command, unsigned long arg);
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56)
static int zft_mmap(struct file *filep, struct vm_area_struct *vma);
-#else
-static int zft_mmap(struct inode *ino, struct file *filep,
- struct vm_area_struct *vma);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
static ssize_t zft_read (struct file *fp, char *buff,
size_t req_len, loff_t *ppos);
static ssize_t zft_write(struct file *fp, const char *buff,
size_t req_len, loff_t *ppos);
-#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
-static long zft_read (struct inode *ino, struct file *fp, char *buff,
- unsigned long req_len);
-static long zft_write(struct inode *ino, struct file *fp, const char *buff,
- unsigned long req_len);
-#else
-static int zft_read (struct inode *ino, struct file *fp, char *buff,
- int req_len);
-static int zft_write(struct inode *ino, struct file *fp, const char *buff,
- int req_len);
-#endif
static struct file_operations zft_cdev =
{
+ owner: THIS_MODULE,
read: zft_read,
write: zft_write,
ioctl: zft_ioctl,
@@ -137,15 +111,6 @@ static int zft_open(struct inode *ino, struct file *filep)
int result;
TRACE_FUN(ft_t_flow);
-#if LINUX_VERSION_CODE < KERNEL_VER(2,1,18)
- if (!MOD_IN_USE) {
- MOD_INC_USE_COUNT; /* lock module in memory */
- }
-#else
- MOD_INC_USE_COUNT; /* sets MOD_VISITED and MOD_USED_ONCE,
- * locking is done with can_unload()
- */
-#endif
TRACE(ft_t_flow, "called for minor %d", MINOR(ino->i_rdev));
if (busy_flag) {
TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy");
@@ -155,11 +120,6 @@ static int zft_open(struct inode *ino, struct file *filep)
>
FTAPE_SEL_D) {
busy_flag = 0;
-#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18)
- if (!zft_dirty()) {
- MOD_DEC_USE_COUNT; /* unlock module in memory */
- }
-#endif
TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr");
}
orig_sigmask = current->blocked;
@@ -168,11 +128,6 @@ static int zft_open(struct inode *ino, struct file *filep)
if (result < 0) {
current->blocked = orig_sigmask; /* restore mask */
busy_flag = 0;
-#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18)
- if (!zft_dirty()) {
- MOD_DEC_USE_COUNT; /* unlock module in memory */
- }
-#endif
TRACE_ABORT(result, ft_t_err, "_ftape_open failed");
} else {
/* Mask signals that will disturb proper operation of the
@@ -191,13 +146,11 @@ static int zft_close(struct inode *ino, struct file *filep)
int result;
TRACE_FUN(ft_t_flow);
+ lock_kernel();
if (!busy_flag || MINOR(ino->i_rdev) != zft_unit) {
TRACE(ft_t_err, "failed: not busy or wrong unit");
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31)
+ unlock_kernel();
TRACE_EXIT 0;
-#else
- TRACE_EXIT; /* keep busy_flag !(?) */
-#endif
}
sigfillset(&current->blocked);
result = _zft_close();
@@ -206,16 +159,8 @@ static int zft_close(struct inode *ino, struct file *filep)
}
current->blocked = orig_sigmask; /* restore before open state */
busy_flag = 0;
-#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18)
- if (!zft_dirty()) {
- MOD_DEC_USE_COUNT; /* unlock module in memory */
- }
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31)
+ unlock_kernel();
TRACE_EXIT 0;
-#else
- TRACE_EXIT;
-#endif
}
/* Ioctl for floppy tape device
@@ -241,24 +186,14 @@ static int zft_ioctl(struct inode *ino, struct file *filep,
/* Ioctl for floppy tape device
*/
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56)
static int zft_mmap(struct file *filep, struct vm_area_struct *vma)
-#else
-static int zft_mmap(struct inode *ino,
- struct file *filep,
- struct vm_area_struct *vma)
-#endif
{
int result = -EIO;
sigset_t old_sigmask;
TRACE_FUN(ft_t_flow);
if (!busy_flag ||
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56)
MINOR(filep->f_dentry->d_inode->i_rdev) != zft_unit ||
-#else
- MINOR(ino->i_rdev) != zft_unit ||
-#endif
ft_failure)
{
TRACE_ABORT(-EIO, ft_t_err,
@@ -266,34 +201,26 @@ static int zft_mmap(struct inode *ino,
}
old_sigmask = current->blocked; /* save mask */
sigfillset(&current->blocked);
+ lock_kernel();
if ((result = ftape_mmap(vma)) >= 0) {
#ifndef MSYNC_BUG_WAS_FIXED
static struct vm_operations_struct dummy = { NULL, };
vma->vm_ops = &dummy;
#endif
}
+ unlock_kernel();
current->blocked = old_sigmask; /* restore mask */
TRACE_EXIT result;
}
/* Read from floppy tape device
*/
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
static ssize_t zft_read(struct file *fp, char *buff,
size_t req_len, loff_t *ppos)
-#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
-static long zft_read(struct inode *ino, struct file *fp, char *buff,
- unsigned long req_len)
-#else
-static int zft_read(struct inode *ino, struct file *fp, char *buff,
- int req_len)
-#endif
{
int result = -EIO;
sigset_t old_sigmask;
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
struct inode *ino = fp->f_dentry->d_inode;
-#endif
TRACE_FUN(ft_t_flow);
TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len);
@@ -311,22 +238,12 @@ static int zft_read(struct inode *ino, struct file *fp, char *buff,
/* Write to tape device
*/
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
static ssize_t zft_write(struct file *fp, const char *buff,
size_t req_len, loff_t *ppos)
-#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
-static long zft_write(struct inode *ino, struct file *fp, const char *buff,
- unsigned long req_len)
-#else
-static int zft_write(struct inode *ino, struct file *fp, const char *buff,
- int req_len)
-#endif
{
int result = -EIO;
sigset_t old_sigmask;
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60)
struct inode *ino = fp->f_dentry->d_inode;
-#endif
TRACE_FUN(ft_t_flow);
TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len);
@@ -470,9 +387,6 @@ KERN_INFO
&zft_cdev, NULL);
}
-#if LINUX_VERSION_CODE < KERNEL_VER(2,1,18)
- register_symtab(&zft_symbol_table); /* add global zftape symbols */
-#endif
#ifdef CONFIG_ZFT_COMPRESSOR
(void)zft_compressor_init();
#endif
@@ -484,24 +398,20 @@ KERN_INFO
#ifdef MODULE
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18)
/* Called by modules package before trying to unload the module
*/
static int can_unload(void)
{
- return (zft_dirty() || busy_flag) ? -EBUSY : 0;
+ return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0;
}
-#endif
/* Called by modules package when installing the driver
*/
int init_module(void)
{
-#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18)
if (!mod_member_present(&__this_module, can_unload)) {
return -EBUSY;
}
__this_module.can_unload = can_unload;
-#endif
return zft_init();
}
diff --git a/drivers/char/h8.c b/drivers/char/h8.c
index acc898cb8..8a4b4de51 100644
--- a/drivers/char/h8.c
+++ b/drivers/char/h8.c
@@ -106,16 +106,6 @@ static int h8_monitor_timer_active = 0;
static char driver_version[] = "X0.0";/* no spaces */
-static struct file_operations h8_fops = {
- /* twelve lines of crap^WNULLs were here */
-};
-
-static struct miscdevice h8_device = {
- H8_MINOR_DEV,
- "h8",
- &h8_fops
-};
-
union intr_buf intrbuf;
int intr_buf_ptr;
union intr_buf xx;
@@ -297,7 +287,6 @@ static void h8_intr(int irq, void *dev_id, struct pt_regs *regs)
static void __exit h8_cleanup (void)
{
remove_proc_entry("driver/h8", NULL);
- misc_deregister(&h8_device);
release_region(h8_base, 8);
free_irq(h8_irq, NULL);
}
@@ -313,7 +302,6 @@ static int __init h8_init(void)
create_proc_info_entry("driver/h8", 0, NULL, h8_get_info);
- misc_register(&h8_device);
request_region(h8_base, 8, "h8");
h8_alloc_queues();
diff --git a/drivers/char/i2c-parport.c b/drivers/char/i2c-parport.c
index 8304a6ab5..00b574f60 100644
--- a/drivers/char/i2c-parport.c
+++ b/drivers/char/i2c-parport.c
@@ -75,7 +75,7 @@ static void i2c_parport_attach(struct parport *port)
struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus),
GFP_KERNEL);
b->i2c = parport_i2c_bus_template;
- b->i2c.data = port;
+ b->i2c.data = parport_get_port (port);
strncpy(b->i2c.name, port->name, 32);
spin_lock(&bus_list_lock);
b->next = bus_list;
diff --git a/drivers/char/i810_rng.c b/drivers/char/i810_rng.c
index 905d8e8cd..7a6718c02 100644
--- a/drivers/char/i810_rng.c
+++ b/drivers/char/i810_rng.c
@@ -165,6 +165,7 @@
#include <linux/random.h>
#include <linux/sysctl.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -626,12 +627,16 @@ err_out:
static int rng_dev_release (struct inode *inode, struct file *filp)
{
- if (rng_enable(0) != 0)
+ lock_kernel();
+ if (rng_enable(0) != 0) {
+ unlock_kernel();
return -EIO;
+ }
spin_lock_bh (&rng_lock);
rng_open = 0;
spin_unlock_bh (&rng_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 449bd2f76..6fbfe22df 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -329,8 +329,7 @@ static long bh_counter = 0;
* selected, the board is serviced periodically to see if anything needs doing.
*/
#define POLL_TIMEOUT (jiffies + 1)
-static struct timer_list PollTimer = { {NULL, NULL}, 0, 0, ip2_poll };
-// next, prev, expires,data, func()
+static struct timer_list PollTimer = { function: ip2_poll };
static char TimerOn = 0;
#ifdef IP2DEBUG_TRACE
diff --git a/drivers/char/joystick/Config.in b/drivers/char/joystick/Config.in
index 1547e5f38..b020f1728 100644
--- a/drivers/char/joystick/Config.in
+++ b/drivers/char/joystick/Config.in
@@ -7,9 +7,7 @@ comment 'Joysticks'
tristate 'Joystick support' CONFIG_JOYSTICK
if [ "$CONFIG_JOYSTICK" != "n" ]; then
-
- define_tristate CONFIG_USB $CONFIG_JOYSTICK
- define_tristate CONFIG_INPUT_JOYDEV $CONFIG_JOYSTICK
+ define_tristate CONFIG_INPUT_JOYDEV $CONFIG_JOYSTICK
comment 'Game port support'
dep_tristate ' ns558 gameports' CONFIG_INPUT_NS558 $CONFIG_JOYSTICK
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 5e212af34..a602e3b3b 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -119,6 +119,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/malloc.h>
#include <linux/fcntl.h>
@@ -407,9 +408,11 @@ static int lp_release(struct inode * inode, struct file * file)
{
unsigned int minor = MINOR(inode->i_rdev);
+ lock_kernel();
kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE);
lp_table[minor].lp_buffer = NULL;
LP_F(minor) &= ~LP_BUSY;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/mixcomwd.c b/drivers/char/mixcomwd.c
index 6352d6f73..1daff0de7 100644
--- a/drivers/char/mixcomwd.c
+++ b/drivers/char/mixcomwd.c
@@ -43,6 +43,7 @@
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -100,9 +101,11 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
static int mixcomwd_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
if(mixcomwd_timer_alive) {
printk(KERN_ERR "mixcomwd: release called while internal timer alive");
+ unlock_kernel();
return -EBUSY;
}
init_timer(&mixcomwd_timer);
@@ -114,6 +117,7 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
#endif
clear_bit(0,&mixcomwd_opened);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c
index dce40c671..5c30ca2f0 100644
--- a/drivers/char/msp3400.c
+++ b/drivers/char/msp3400.c
@@ -1265,8 +1265,10 @@ msp3400c_mixer_release(struct inode *inode, struct file *file)
{
struct i2c_client *client = file->private_data;
+ lock_kernel();
if (client->adapter->dec_use)
client->adapter->dec_use(client->adapter);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index a32cd18df..6fa72fc8e 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -34,6 +34,8 @@
#include <linux/module.h>
#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#define PC 1
#define ATARI 2
@@ -341,11 +343,13 @@ static int nvram_open( struct inode *inode, struct file *file )
static int nvram_release( struct inode *inode, struct file *file )
{
+ lock_kernel();
nvram_open_cnt--;
if (file->f_flags & O_EXCL)
nvram_open_mode &= ~NVRAM_EXCL;
if (file->f_mode & 2)
nvram_open_mode &= ~NVRAM_WRITE;
+ unlock_kernel();
return( 0 );
}
diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c
index dfef66e39..556d8630e 100644
--- a/drivers/char/pc110pad.c
+++ b/drivers/char/pc110pad.c
@@ -41,6 +41,7 @@
#include <linux/poll.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
#include <asm/signal.h>
#include <asm/io.h>
@@ -583,10 +584,11 @@ static int fasync_pad(int fd, struct file *filp, int on)
static int close_pad(struct inode * inode, struct file * file)
{
+ lock_kernel();
fasync_pad(-1, file, 0);
- if (--active)
- return 0;
- outb(0x30, current_params.io+2); /* switch off digitiser */
+ if (!--active)
+ outb(0x30, current_params.io+2); /* switch off digitiser */
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index c265b927f..34e13c97f 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -31,6 +31,7 @@
#include <linux/miscdevice.h>
#include <linux/malloc.h>
#include <linux/kbd_kern.h>
+#include <linux/smp_lock.h>
#include <asm/keyboard.h>
#include <asm/bitops.h>
@@ -872,12 +873,16 @@ static int fasync_aux(int fd, struct file *filp, int on)
static int release_aux(struct inode * inode, struct file * file)
{
+ lock_kernel();
fasync_aux(-1, file, 0);
- if (--aux_count)
+ if (--aux_count) {
+ unlock_kernel();
return 0;
+ }
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
aux_free_irq(AUX_DEV);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/pcmcia/Config.in b/drivers/char/pcmcia/Config.in
index 766fdd1d0..8baf1932e 100644
--- a/drivers/char/pcmcia/Config.in
+++ b/drivers/char/pcmcia/Config.in
@@ -3,12 +3,12 @@
#
if [ "$CONFIG_SERIAL" = "n" ]; then
- define_bool CONFIG_PCMCIA_SERIAL n
+ define_tristate CONFIG_PCMCIA_SERIAL n
else
if [ "$CONFIG_SERIAL" = "m" -o "$CONFIG_PCMCIA" = "m" ]; then
- define_bool CONFIG_PCMCIA_SERIAL m
+ define_tristate CONFIG_PCMCIA_SERIAL m
else
- define_bool CONFIG_PCMCIA_SERIAL y
+ define_tristate CONFIG_PCMCIA_SERIAL y
fi
fi
diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c
index b85a168de..cb197afc5 100644
--- a/drivers/char/pcwd.c
+++ b/drivers/char/pcwd.c
@@ -63,6 +63,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -451,6 +452,7 @@ static int pcwd_close(struct inode *ino, struct file *filep)
{
if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)
{
+ lock_kernel();
is_open = 0;
#ifndef CONFIG_WATCHDOG_NOWAYOUT
/* Disable the board */
@@ -460,6 +462,7 @@ static int pcwd_close(struct inode *ino, struct file *filep)
outb_p(0xA5, current_readport + 3);
spin_unlock(&io_lock);
}
+ unlock_kernel();
#endif
}
return 0;
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 4e2be3c8b..07877c1a7 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -52,6 +52,7 @@
#include <linux/poll.h>
#include <asm/uaccess.h>
#include <linux/ppdev.h>
+#include <linux/smp_lock.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
#define CHRDEV "ppdev"
@@ -83,64 +84,6 @@ struct pp_struct {
/* ROUND_UP macro from fs/select.c */
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-struct pp_port_list_struct {
- struct parport *port;
- struct pp_port_list_struct *next;
-};
-static struct pp_port_list_struct *pp_port_list;
-static DECLARE_MUTEX(pp_port_list_lock);
-
-/* pp_attach and pp_detach are for keeping a list of currently
- * available ports, held under a mutex. We do this rather than
- * using parport_enumerate because it stops a load of races.
- */
-
-static void pp_attach (struct parport *port)
-{
- struct pp_port_list_struct *add;
-
- add = kmalloc (sizeof (struct pp_port_list_struct), GFP_KERNEL);
- if (!add) {
- printk (KERN_WARNING CHRDEV ": memory squeeze\n");
- return;
- }
-
- add->port = port;
- down (&pp_port_list_lock);
- add->next = pp_port_list;
- pp_port_list = add;
- up (&pp_port_list_lock);
-}
-
-static void pp_detach (struct parport *port)
-{
- struct pp_port_list_struct *del;
-
- down (&pp_port_list_lock);
- del = pp_port_list;
- if (del->port == port)
- pp_port_list = del->next;
- else {
- struct pp_port_list_struct *prev;
- do {
- prev = del;
- del = del->next;
- } while (del && del->port != port);
- if (del)
- prev->next = del->next;
- }
- up (&pp_port_list_lock);
-
- if (del)
- kfree (del);
-}
-
-static struct parport_driver ppdev_driver = {
- name: CHRDEV,
- attach: pp_attach,
- detach: pp_detach
-};
-
static inline void pp_enable_irq (struct pp_struct *pp)
{
struct parport *port = pp->pdev->port;
@@ -274,7 +217,7 @@ static void pp_irq (int irq, void * private, struct pt_regs * unused)
static int register_device (int minor, struct pp_struct *pp)
{
- struct pp_port_list_struct *ports;
+ struct parport *port;
struct pardevice * pdev = NULL;
char *name;
int fl;
@@ -285,23 +228,17 @@ static int register_device (int minor, struct pp_struct *pp)
sprintf (name, CHRDEV "%x", minor);
- down (&pp_port_list_lock);
- ports = pp_port_list;
- while (ports && ports->port->number != minor)
- ports = ports->next;
- if (ports->port) {
- fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
- pdev = parport_register_device (ports->port, name, NULL,
- NULL, pp_irq, fl, pp);
- }
- up (&pp_port_list_lock);
-
- if (!ports->port) {
+ port = parport_find_number (minor);
+ if (!port) {
printk (KERN_WARNING "%s: no associated port!\n", name);
kfree (name);
return -ENXIO;
}
+ fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+ pdev = parport_register_device (port, name, NULL,
+ NULL, pp_irq, fl, pp);
+ parport_put_port (port);
if (!pdev) {
printk (KERN_WARNING "%s: failed to register device!\n", name);
@@ -595,6 +532,7 @@ static int pp_release (struct inode * inode, struct file * file)
unsigned int minor = MINOR (inode->i_rdev);
struct pp_struct *pp = file->private_data;
+ lock_kernel();
if (pp->pdev && pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT) {
if (!(pp->flags & PP_CLAIMED)) {
parport_claim_or_block (pp->pdev);
@@ -620,6 +558,7 @@ static int pp_release (struct inode * inode, struct file * file)
printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n",
minor);
}
+ unlock_kernel();
kfree (pp);
@@ -654,10 +593,6 @@ static devfs_handle_t devfs_handle = NULL;
static int __init ppdev_init (void)
{
- if (parport_register_driver (&ppdev_driver)) {
- printk (KERN_WARNING CHRDEV ": unable to register driver\n");
- return -EIO;
- }
if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
PP_MAJOR);
@@ -678,7 +613,6 @@ static void __exit ppdev_cleanup (void)
/* Clean up all parport stuff */
devfs_unregister (devfs_handle);
devfs_unregister_chrdev (PP_MAJOR, CHRDEV);
- parport_unregister_driver (&ppdev_driver);
}
module_init(ppdev_init);
diff --git a/drivers/char/qpmouse.c b/drivers/char/qpmouse.c
index 6fd5a3d65..4db93b1fb 100644
--- a/drivers/char/qpmouse.c
+++ b/drivers/char/qpmouse.c
@@ -36,6 +36,7 @@
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -141,6 +142,7 @@ static int release_qp(struct inode * inode, struct file * file)
{
unsigned char status;
+ lock_kernel();
fasync_qp(-1, file, 0);
if (!--qp_count) {
if (!poll_qp_status())
@@ -151,6 +153,7 @@ static int release_qp(struct inode * inode, struct file * file)
printk("Warning: Mouse device busy in release_qp()\n");
free_irq(QP_IRQ, NULL);
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index a3159c836..4b1281b50 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -14,6 +14,7 @@
#include <linux/blkdev.h>
#include <linux/raw.h>
#include <linux/capability.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#define dprintk(x...)
@@ -126,9 +127,11 @@ int raw_release(struct inode *inode, struct file *filp)
struct block_device *bdev;
minor = MINOR(inode->i_rdev);
+ lock_kernel();
bdev = raw_device_bindings[minor];
blkdev_put(bdev, BDEV_RAW);
raw_device_inuse[minor]--;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/sbc60xxwdt.c b/drivers/char/sbc60xxwdt.c
index a0bea62c0..813594244 100644
--- a/drivers/char/sbc60xxwdt.c
+++ b/drivers/char/sbc60xxwdt.c
@@ -66,6 +66,7 @@
#include <linux/malloc.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -207,6 +208,7 @@ static int fop_open(struct inode * inode, struct file * file)
static int fop_close(struct inode * inode, struct file * file)
{
+ lock_kernel();
if(MINOR(inode->i_rdev) == WATCHDOG_MINOR)
{
if(wdt_expect_close)
@@ -217,6 +219,7 @@ static int fop_close(struct inode * inode, struct file * file)
}
}
wdt_is_open = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c
index a7620dda0..3d1c57907 100644
--- a/drivers/char/softdog.c
+++ b/drivers/char/softdog.c
@@ -37,6 +37,7 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -79,7 +80,9 @@ static int softdog_open(struct inode *inode, struct file *file)
{
if(timer_alive)
return -EBUSY;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
+#endif
/*
* Activate timer
*/
@@ -94,11 +97,12 @@ static int softdog_release(struct inode *inode, struct file *file)
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
+ lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
del_timer(&watchdog_ticktock);
- MOD_DEC_USE_COUNT;
#endif
timer_alive=0;
+ unlock_kernel();
return 0;
}
@@ -146,6 +150,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
static struct file_operations softdog_fops=
{
+ owner: THIS_MODULE,
write: softdog_write,
ioctl: softdog_ioctl,
open: softdog_open,
diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c
index 3ca976b6e..14a42682d 100644
--- a/drivers/char/tpqic02.c
+++ b/drivers/char/tpqic02.c
@@ -89,6 +89,7 @@
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/dma.h>
@@ -2411,6 +2412,7 @@ static int qic02_tape_release(struct inode * inode, struct file * filp)
{
kdev_t dev = inode->i_rdev;
+ lock_kernel();
if (TP_DIAGS(dev))
{
printk("qic02_tape_release: dev=%s\n", kdevname(dev));
@@ -2437,6 +2439,7 @@ static int qic02_tape_release(struct inode * inode, struct file * filp)
(void) do_qic_cmd(QCMD_REWIND, TIM_R);
}
}
+ unlock_kernel();
return 0;
} /* qic02_tape_release */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 60a5c41f5..816f385e1 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1430,7 +1430,9 @@ init_dev_done:
static int tty_release(struct inode * inode, struct file * filp)
{
+ lock_kernel();
release_dev(filp);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/tvmixer.c b/drivers/char/tvmixer.c
index 0ef5bbd03..c3db65bae 100644
--- a/drivers/char/tvmixer.c
+++ b/drivers/char/tvmixer.c
@@ -7,6 +7,7 @@
#include <linux/errno.h>
#include <linux/malloc.h>
#include <linux/i2c.h>
+#include <linux/smp_lock.h>
#include <linux/videodev.h>
#include <asm/semaphore.h>
#include <linux/init.h>
@@ -220,13 +221,18 @@ static int tvmixer_open(struct inode *inode, struct file *file)
static int tvmixer_release(struct inode *inode, struct file *file)
{
struct TVMIXER *mix = file->private_data;
- struct i2c_client *client = mix->dev;
+ struct i2c_client *client;
- if (NULL == client)
+ lock_kernel();
+ client = mix->dev;
+ if (NULL == client) {
+ unlock_kernel();
return -ENODEV;
+ }
if (client->adapter->dec_use)
client->adapter->dec_use(client->adapter);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/videodev.c b/drivers/char/videodev.c
index 5103433e1..3657cb518 100644
--- a/drivers/char/videodev.c
+++ b/drivers/char/videodev.c
@@ -21,6 +21,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -158,11 +159,9 @@ static int video_open(struct inode *inode, struct file *file)
if(vfl==NULL) {
char modname[20];
- MOD_INC_USE_COUNT;
sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
request_module(modname);
vfl=video_device[minor];
- MOD_DEC_USE_COUNT;
if (vfl==NULL)
return -ENODEV;
}
@@ -188,10 +187,13 @@ static int video_open(struct inode *inode, struct file *file)
static int video_release(struct inode *inode, struct file *file)
{
- struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
+ struct video_device *vfl;
+ lock_kernel();
+ vfl=video_device[MINOR(inode->i_rdev)];
if(vfl->close)
vfl->close(vfl);
vfl->busy=0;
+ unlock_kernel();
return 0;
}
@@ -229,11 +231,15 @@ static int video_ioctl(struct inode *inode, struct file *file,
int video_mmap(struct file *file, struct vm_area_struct *vma)
{
+ int ret = -EINVAL;
struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
- if(vfl->mmap)
- return vfl->mmap(vfl, (char *)vma->vm_start,
+ if(vfl->mmap) {
+ lock_kernel();
+ ret = vfl->mmap(vfl, (char *)vma->vm_start,
(unsigned long)(vma->vm_end-vma->vm_start));
- return -EINVAL;
+ unlock_kernel();
+ }
+ return ret;
}
/*
@@ -515,6 +521,7 @@ void video_unregister_device(struct video_device *vfd)
static struct file_operations video_fops=
{
+ owner: THIS_MODULE,
llseek: video_lseek,
read: video_read,
write: video_write,
diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c
index 3ac86bf3a..bde40c589 100644
--- a/drivers/char/wdt.c
+++ b/drivers/char/wdt.c
@@ -35,6 +35,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include "wd501p.h"
@@ -372,6 +373,7 @@ static int wdt_open(struct inode *inode, struct file *file)
static int wdt_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
#ifndef CONFIG_WATCHDOG_NOWAYOUT
@@ -380,6 +382,7 @@ static int wdt_release(struct inode *inode, struct file *file)
#endif
wdt_is_open=0;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/wdt285.c b/drivers/char/wdt285.c
index 6efdd7f76..66633fd20 100644
--- a/drivers/char/wdt285.c
+++ b/drivers/char/wdt285.c
@@ -26,6 +26,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -74,7 +75,6 @@ static int watchdog_open(struct inode *inode, struct file *file)
{
if(timer_alive)
return -EBUSY;
- MOD_INC_USE_COUNT;
/*
* Ahead watchdog factor ten, Mr Sulu
*/
@@ -86,6 +86,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL);
#else
*CSR_SA110_CNTL |= 1 << 13;
+ MOD_INC_USE_COUNT;
#endif
timer_alive = 1;
return 0;
@@ -94,9 +95,10 @@ static int watchdog_open(struct inode *inode, struct file *file)
static int watchdog_release(struct inode *inode, struct file *file)
{
#ifdef ONLY_TESTING
+ lock_kernel();
free_irq(IRQ_TIMER4, NULL);
timer_alive = 0;
- MOD_DEC_USE_COUNT;
+ unlock_kernel();
#else
/*
* It's irreversible!
@@ -153,6 +155,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *file,
static struct file_operations watchdog_fops=
{
+ owner: THIS_MODULE,
write: watchdog_write,
ioctl: watchdog_ioctl,
open: watchdog_open,
diff --git a/drivers/char/wdt977.c b/drivers/char/wdt977.c
index 9bfbf0cc6..fef6bc7fc 100644
--- a/drivers/char/wdt977.c
+++ b/drivers/char/wdt977.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -38,7 +39,9 @@ static int wdt977_open(struct inode *inode, struct file *file)
{
if(timer_alive)
return -EBUSY;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
+#endif
timer_alive++;
//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
@@ -88,6 +91,7 @@ static int wdt977_release(struct inode *inode, struct file *file)
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ lock_kernel();
// unlock the SuperIO chip
outb(0x87,0x370);
@@ -118,8 +122,8 @@ static int wdt977_release(struct inode *inode, struct file *file)
// lock the SuperIO chip
outb(0xAA,0x370);
- MOD_DEC_USE_COUNT;
timer_alive=0;
+ unlock_kernel();
printk(KERN_INFO "Watchdog: shutdown.\n");
#endif
@@ -162,6 +166,7 @@ static ssize_t wdt977_write(struct file *file, const char *data, size_t len, lof
static struct file_operations wdt977_fops=
{
+ owner: THIS_MODULE,
write: wdt977_write,
open: wdt977_open,
release: wdt977_release,
diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c
index 2bd09930a..8e960841b 100644
--- a/drivers/char/wdt_pci.c
+++ b/drivers/char/wdt_pci.c
@@ -51,6 +51,7 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/pci.h>
@@ -358,7 +359,9 @@ static int wdtpci_open(struct inode *inode, struct file *file)
case WATCHDOG_MINOR:
if(wdt_is_open)
return -EBUSY;
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
+#endif
/*
* Activate
*/
@@ -391,7 +394,6 @@ static int wdtpci_open(struct inode *inode, struct file *file)
outb_p(0, WDT_DC); /* Enable */
return 0;
case TEMP_MINOR:
- MOD_INC_USE_COUNT;
return 0;
default:
return -ENODEV;
@@ -414,13 +416,14 @@ static int wdtpci_release(struct inode *inode, struct file *file)
{
if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
{
+ lock_kernel();
#ifndef CONFIG_WATCHDOG_NOWAYOUT
inb_p(WDT_DC); /* Disable counters */
wdtpci_ctr_load(2,0); /* 0 length reset pulses now */
#endif
wdt_is_open=0;
+ unlock_kernel();
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -454,6 +457,7 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
static struct file_operations wdtpci_fops = {
+ owner: THIS_MODULE,
llseek: wdtpci_llseek,
read: wdtpci_read,
write: wdtpci_write,
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index e373ce2f3..47a6292d1 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -32,6 +32,7 @@
#include <linux/fs.h>
#include <linux/malloc.h>
#include <linux/version.h>
+#include <linux/smp_lock.h>
/* If you want debugging uncomment: */
/* #define DEBUG */
@@ -76,6 +77,7 @@ extern
static int i2cdev_cleanup(void);
static struct file_operations i2cdev_fops = {
+ owner: THIS_MODULE,
llseek: i2cdev_lseek,
read: i2cdev_read,
write: i2cdev_write,
@@ -374,7 +376,6 @@ int i2cdev_open (struct inode *inode, struct file *file)
if (i2cdev_adaps[minor]->inc_use)
i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]);
- MOD_INC_USE_COUNT;
#ifdef DEBUG
printk("i2c-dev.o: opened i2c-%d\n",minor);
@@ -390,9 +391,10 @@ static int i2cdev_release (struct inode *inode, struct file *file)
#ifdef DEBUG
printk("i2c-dev.o: Closed: i2c-%d\n", minor);
#endif
- MOD_DEC_USE_COUNT;
+ lock_kernel();
if (i2cdev_adaps[minor]->dec_use)
i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/i2o/i2o_config.c b/drivers/i2o/i2o_config.c
index 7a50f64e9..9a9cfec6e 100644
--- a/drivers/i2o/i2o_config.c
+++ b/drivers/i2o/i2o_config.c
@@ -35,6 +35,7 @@
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -848,6 +849,7 @@ static int cfg_release(struct inode *inode, struct file *file)
struct i2o_cfg_info *p1, *p2;
unsigned int flags;
+ lock_kernel();
p1 = p2 = NULL;
spin_lock_irqsave(&i2o_config_lock, flags);
@@ -870,6 +872,7 @@ static int cfg_release(struct inode *inode, struct file *file)
p1 = p1->next;
}
spin_unlock_irqrestore(&i2o_config_lock, flags);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 911234014..bd89fcc61 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -402,6 +402,7 @@
#include <linux/malloc.h>
#include <linux/pci.h>
#include <linux/ide.h>
+#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -5235,11 +5236,6 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
if (test_and_set_bit (IDETAPE_BUSY, &tape->flags))
return -EBUSY;
- MOD_INC_USE_COUNT;
-#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_chrdev_open-1\n");
-#endif
if (!tape->onstream) {
idetape_read_position(drive);
if (!test_bit (IDETAPE_ADDRESS_VALID, &tape->flags))
@@ -5255,28 +5251,13 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
}
if (idetape_wait_ready(drive, 60 * HZ)) {
clear_bit(IDETAPE_BUSY, &tape->flags);
- MOD_DEC_USE_COUNT;
-#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_open-1\n");
-#endif
printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
return -EBUSY;
}
idetape_read_position(drive);
- MOD_DEC_USE_COUNT;
-#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_open-2\n");
-#endif
clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags);
if (tape->chrdev_direction == idetape_direction_none) {
- MOD_INC_USE_COUNT;
-#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_chrdev_open-2\n");
-#endif
idetape_create_prevent_cmd(drive, &pc, 1);
if (!idetape_queue_pc_tail (drive,&pc)) {
if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
@@ -5296,10 +5277,12 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp)
static int idetape_chrdev_release (struct inode *inode, struct file *filp)
{
ide_drive_t *drive = get_drive_ptr (inode->i_rdev);
- idetape_tape_t *tape = drive->driver_data;
+ idetape_tape_t *tape;
idetape_pc_t pc;
unsigned int minor=MINOR (inode->i_rdev);
-
+
+ lock_kernel();
+ tape = drive->driver_data;
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 3)
printk (KERN_INFO "ide-tape: Reached idetape_chrdev_release\n");
@@ -5337,13 +5320,9 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp)
if (!idetape_queue_pc_tail (drive,&pc))
tape->door_locked = DOOR_UNLOCKED;
}
- MOD_DEC_USE_COUNT;
-#if ONSTREAM_DEBUG
- if (tape->debug_level >= 6)
- printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_release\n");
-#endif
}
clear_bit (IDETAPE_BUSY, &tape->flags);
+ unlock_kernel();
return 0;
}
@@ -5919,6 +5898,7 @@ static ide_module_t idetape_module = {
* Our character device supporting functions, passed to register_chrdev.
*/
static struct file_operations idetape_fops = {
+ owner: THIS_MODULE,
read: idetape_chrdev_read,
write: idetape_chrdev_write,
ioctl: idetape_chrdev_ioctl,
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 83c1169fe..3c23c45a5 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -17,6 +17,7 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/version.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)
@@ -869,6 +870,7 @@ static int dev_release(struct inode *inode, struct file *file)
struct pending_request *req;
int done = 0, i;
+ lock_kernel();
for (i = 0; i < 64; i++) {
if (fi->listen_channels & (1ULL << i)) {
hpsb_unlisten_channel(hl_handle, fi->host, i);
@@ -913,6 +915,7 @@ static int dev_release(struct inode *inode, struct file *file)
kfree(fi);
V22_COMPAT_MOD_DEC_USE_COUNT;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 9f00fd3f0..9afbb58ec 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -27,6 +27,7 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
+#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -1043,18 +1044,20 @@ int video1394_mmap(struct file *file, struct vm_area_struct *vma)
{
struct video_card *video =
&video_cards[MINOR(file->f_dentry->d_inode->i_rdev)];
- struct ti_ohci *ohci= video->ohci;
+ struct ti_ohci *ohci;
+ int res = -EINVAL;
+ lock_kernel();
+ ohci = video->ohci;
PRINT(KERN_INFO, ohci->id, "mmap");
if (video->current_ctx == NULL) {
PRINT(KERN_ERR, ohci->id, "current iso context not set");
- return -EINVAL;
- }
-
- return do_iso_mmap(ohci, video->current_ctx,
+ } else
+ res = do_iso_mmap(ohci, video->current_ctx,
(char *)vma->vm_start,
(unsigned long)(vma->vm_end-vma->vm_start));
- return 0;
+ unlock_kernel();
+ return res;
}
static int video1394_open(struct inode *inode, struct file *file)
@@ -1079,6 +1082,7 @@ static int video1394_release(struct inode *inode, struct file *file)
struct ti_ohci *ohci= video->ohci;
int i;
+ lock_kernel();
for (i=0;i<ohci->nb_iso_rcv_ctx-1;i++)
if (video->ir_context[i]) {
if (!test_and_clear_bit(
@@ -1115,6 +1119,7 @@ static int video1394_release(struct inode *inode, struct file *file)
V22_COMPAT_MOD_DEC_USE_COUNT;
PRINT(KERN_INFO, ohci->id, "release");
+ unlock_kernel();
return 0;
}
diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c
index 06ddc8199..4c7e68266 100644
--- a/drivers/isdn/avmb1/capi.c
+++ b/drivers/isdn/avmb1/capi.c
@@ -182,6 +182,7 @@
#include <linux/fs.h>
#include <linux/signal.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/wait.h>
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -379,10 +380,8 @@ struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci)
struct capiminor *mp, **pp;
unsigned int minor = 0;
- MOD_INC_USE_COUNT;
mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC);
if (!mp) {
- MOD_DEC_USE_COUNT;
printk(KERN_ERR "capi: can't alloc capiminor\n");
return 0;
}
@@ -434,7 +433,6 @@ void capiminor_free(struct capiminor *mp)
kfree_skb(skb);
capiminor_del_all_ack(mp);
kmem_cache_free(capiminor_cachep, mp);
- MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
@@ -1212,7 +1210,6 @@ capi_open(struct inode *inode, struct file *file)
if ((file->private_data = capidev_alloc(file)) == 0)
return -ENOMEM;
- MOD_INC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capi_open %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
@@ -1224,14 +1221,15 @@ capi_release(struct inode *inode, struct file *file)
{
struct capidev *cdev = (struct capidev *)file->private_data;
+ lock_kernel();
capincci_free(cdev, 0xffffffff);
capidev_free(cdev);
file->private_data = NULL;
- MOD_DEC_USE_COUNT;
#ifdef _DEBUG_REFCOUNT
printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE));
#endif
+ unlock_kernel();
return 0;
}
@@ -1414,11 +1412,13 @@ capinc_raw_release(struct inode *inode, struct file *file)
struct capiminor *mp = (struct capiminor *)file->private_data;
if (mp) {
+ lock_kernel();
mp->file = 0;
if (mp->nccip == 0) {
capiminor_free(mp);
file->private_data = NULL;
}
+ unlock_kernel();
}
#ifdef _DEBUG_REFCOUNT
@@ -2050,8 +2050,6 @@ int capi_init(void)
{
char *p;
- MOD_INC_USE_COUNT;
-
if ((p = strchr(revision, ':'))) {
strcpy(rev, p + 2);
p = strchr(rev, '$');
@@ -2061,7 +2059,6 @@ int capi_init(void)
if (devfs_register_chrdev(capi_major, "capi20", &capi_fops)) {
printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
- MOD_DEC_USE_COUNT;
return -EIO;
}
@@ -2069,7 +2066,6 @@ int capi_init(void)
if (devfs_register_chrdev(capi_rawmajor, "capi/r%d", &capinc_raw_fops)) {
devfs_unregister_chrdev(capi_major, "capi20");
printk(KERN_ERR "capi20: unable to get major %d\n", capi_rawmajor);
- MOD_DEC_USE_COUNT;
return -EIO;
}
devfs_register_series (NULL, "capi/r%u", CAPINC_NR_PORTS,
@@ -2085,7 +2081,6 @@ int capi_init(void)
if ((capifuncs = attach_capi_interface(&cuser)) == 0) {
- MOD_DEC_USE_COUNT;
devfs_unregister_chrdev(capi_major, "capi20");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
@@ -2101,7 +2096,6 @@ int capi_init(void)
(void) detach_capi_interface(&cuser);
devfs_unregister_chrdev(capi_major, "capi20");
devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
@@ -2122,7 +2116,6 @@ int capi_init(void)
devfs_unregister(devfs_find_handle(NULL, "capi20",
capi_major, 0,
DEVFS_SPECIAL_CHR, 0));
- MOD_DEC_USE_COUNT;
return -ENOMEM;
}
@@ -2131,7 +2124,6 @@ int capi_init(void)
printk(KERN_NOTICE "capi20: Rev%s: started up with major %d\n",
rev, capi_major);
- MOD_DEC_USE_COUNT;
return 0;
}
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index f7d7ee8d5..bd065a48d 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -199,6 +199,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
struct divert_info *inf;
int flags;
+ lock_kernel();
save_flags(flags);
cli();
if_used--;
@@ -214,6 +215,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
divert_info_head = divert_info_head->next;
kfree(inf);
}
+ unlock_kernel();
return (0);
} /* isdn_divert_close */
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index c27c926a1..c28aedc1f 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -372,6 +372,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
int retval = 0;
struct proc_dir_entry *pd;
+ lock_kernel();
/* search the addressed card */
card = card_root;
while (card) {
@@ -381,6 +382,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
card = card->next; /* search next entry */
}
if (!card) {
+ unlock_kernel();
return (-ENODEV); /* device is unknown/invalid */
}
if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
@@ -403,6 +405,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
if (filep->private_data)
kfree(filep->private_data); /* release memory */
}
+ unlock_kernel();
return (retval);
} /* hysdn_conf_close */
diff --git a/drivers/isdn/hysdn/hysdn_procfs.c b/drivers/isdn/hysdn/hysdn_procfs.c
index ae07f6597..864935625 100644
--- a/drivers/isdn/hysdn/hysdn_procfs.c
+++ b/drivers/isdn/hysdn/hysdn_procfs.c
@@ -254,7 +254,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
hysdn_card *card;
int flags, retval = 0;
-
+ lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
/* write only access -> write debug completely written */
retval = 0; /* success */
@@ -297,6 +297,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
}
} /* read access */
+ unlock_kernel();
return (retval);
} /* hysdn_log_close */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 1a2980f02..ba454b9dc 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -345,6 +345,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
int flags, retval = 0;
+ lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
/* write only access -> write debug level written */
retval = 0; /* success */
@@ -386,6 +387,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
kfree(inf);
}
} /* read access */
+ unlock_kernel();
return (retval);
} /* hysdn_log_close */
diff --git a/drivers/isdn/isdn_common.c b/drivers/isdn/isdn_common.c
index f6c326301..b543d8690 100644
--- a/drivers/isdn/isdn_common.c
+++ b/drivers/isdn/isdn_common.c
@@ -439,6 +439,7 @@
#include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/isdn.h>
+#include <linux/smp_lock.h>
#include "isdn_common.h"
#include "isdn_tty.h"
#include "isdn_net.h"
@@ -485,11 +486,10 @@ static void isdn_register_devfs(int);
static void isdn_unregister_devfs(int);
void
-isdn_MOD_INC_USE_COUNT(void)
+isdn_lock_drivers(void)
{
int i;
- MOD_INC_USE_COUNT;
for (i = 0; i < dev->drivers; i++) {
isdn_ctrl cmd;
@@ -502,11 +502,17 @@ isdn_MOD_INC_USE_COUNT(void)
}
void
-isdn_MOD_DEC_USE_COUNT(void)
+isdn_MOD_INC_USE_COUNT(void)
+{
+ MOD_INC_USE_COUNT;
+ isdn_lock_drivers();
+}
+
+void
+isdn_unlock_drivers(void)
{
int i;
- MOD_DEC_USE_COUNT;
for (i = 0; i < dev->drivers; i++)
if (dev->drv[i]->locks > 0) {
isdn_ctrl cmd;
@@ -519,6 +525,13 @@ isdn_MOD_DEC_USE_COUNT(void)
}
}
+void
+isdn_MOD_DEC_USE_COUNT(void)
+{
+ MOD_DEC_USE_COUNT;
+ isdn_unlock_drivers();
+}
+
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
void
isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
@@ -1976,8 +1989,6 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
/*
* Open the device code.
- * MOD_INC_USE_COUNT make sure that the driver memory is not freed
- * while the device is in use.
*/
static int
isdn_open(struct inode *ino, struct file *filep)
@@ -1990,7 +2001,6 @@ isdn_open(struct inode *ino, struct file *filep)
infostruct *p;
if ((p = (infostruct *) kmalloc(sizeof(infostruct), GFP_KERNEL))) {
- MOD_INC_USE_COUNT;
p->next = (char *) dev->infochain;
p->private = (char *) &(filep->private_data);
dev->infochain = p;
@@ -2011,21 +2021,21 @@ isdn_open(struct inode *ino, struct file *filep)
return -ENODEV;
if (!(dev->drv[drvidx]->online & (1 << chidx)))
return -ENODEV;
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return 0;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
if (drvidx < 0)
return -ENODEV;
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return 0;
}
#ifdef CONFIG_ISDN_PPP
if (minor <= ISDN_MINOR_PPPMAX) {
int ret;
if (!(ret = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep)))
- isdn_MOD_INC_USE_COUNT();
+ isdn_lock_drivers();
return ret;
}
#endif
@@ -2037,11 +2047,11 @@ isdn_close(struct inode *ino, struct file *filep)
{
uint minor = MINOR(ino->i_rdev);
+ lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
infostruct *p = dev->infochain;
infostruct *q = NULL;
- MOD_DEC_USE_COUNT;
while (p) {
if (p->private == (char *) &(filep->private_data)) {
if (q)
@@ -2049,31 +2059,38 @@ isdn_close(struct inode *ino, struct file *filep)
else
dev->infochain = (infostruct *) (p->next);
kfree(p);
+ unlock_kernel();
return 0;
}
q = p;
p = (infostruct *) (p->next);
}
printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
+ unlock_kernel();
return 0;
}
- isdn_MOD_DEC_USE_COUNT();
- if (minor < ISDN_MINOR_CTRL)
+ isdn_unlock_drivers();
+ if (minor < ISDN_MINOR_CTRL) {
+ unlock_kernel();
return 0;
+ }
if (minor <= ISDN_MINOR_CTRLMAX) {
if (dev->profd == current)
dev->profd = NULL;
+ unlock_kernel();
return 0;
}
#ifdef CONFIG_ISDN_PPP
if (minor <= ISDN_MINOR_PPPMAX)
isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
#endif
+ unlock_kernel();
return 0;
}
static struct file_operations isdn_fops =
{
+ owner: THIS_MODULE,
llseek: isdn_lseek,
read: isdn_read,
write: isdn_write,
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index ff6f18ee1..10421b00d 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -25,6 +25,7 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
@@ -516,6 +517,7 @@ static int adb_release(struct inode *inode, struct file *file)
struct adbdev_state *state = file->private_data;
unsigned long flags;
+ lock_kernel();
if (state) {
file->private_data = NULL;
spin_lock_irqsave(&state->lock, flags);
@@ -528,6 +530,7 @@ static int adb_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&state->lock, flags);
}
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 9ca4a9ae8..efec54db0 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -31,6 +31,7 @@
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/cuda.h>
+#include <linux/smp_lock.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
@@ -1539,6 +1540,7 @@ static int pmu_release(struct inode *inode, struct file *file)
struct pmu_private *pp = file->private_data;
unsigned long flags;
+ lock_kernel();
if (pp != 0) {
file->private_data = 0;
spin_lock_irqsave(&all_pvt_lock, flags);
@@ -1546,6 +1548,7 @@ static int pmu_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&all_pvt_lock, flags);
kfree(pp);
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/mtd/Config.in b/drivers/mtd/Config.in
index e2af3489a..5f7622572 100644
--- a/drivers/mtd/Config.in
+++ b/drivers/mtd/Config.in
@@ -1,59 +1,67 @@
+
+# $Id: Config.in,v 1.20 2000/07/13 12:40:46 scote1 Exp $
+
mainmenu_option next_comment
comment 'Memory Technology Devices (MTD)'
tristate 'Memory Technology Device (MTD) support' CONFIG_MTD
if [ "$CONFIG_MTD" != "n" ]; then
- dep_tristate 'M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD
- dep_tristate 'M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD
- dep_tristate 'M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD
- if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
- define_bool CONFIG_MTD_DOCPROBE y
- else
- if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
- define_bool CONFIG_MTD_DOCPROBE m
- else
- define_bool CONFIG_MTD_DOCPROBE n
- fi
- fi
- dep_tristate 'Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD
- dep_tristate 'Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD
- if [ "$CONFIG_MTD_PMC551" != "n" ]; then
- bool 'PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
- fi
- dep_tristate 'Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD
+ dep_tristate ' M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD
+ dep_tristate ' M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD
+ dep_tristate ' M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD
+ if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
+ define_tristate CONFIG_MTD_DOCPROBE y
+ else
+ if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
+ define_tristate CONFIG_MTD_DOCPROBE m
+ else
+ define_tristate CONFIG_MTD_DOCPROBE n
+ fi
+ fi
+ dep_tristate ' Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD
+ dep_tristate ' Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD
+ if [ "$CONFIG_MTD_PMC551" != "n" ]; then
+ bool ' PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
+ fi
+ dep_tristate ' Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD
+ if [ "$CONFIG_MTD_MTDRAM" != "n" ]; then
+ int 'Device size in kB' CONFIG_MTDRAM_TOTAL_SIZE 4096
+ int 'Size of the erase sectors in kB' CONFIG_MTDRAM_ERASE_SIZE 128
+ fi
-mainmenu_option next_comment
comment 'MTD drivers for mapped chips'
+ dep_tristate ' Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
+ dep_tristate ' CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
+ dep_tristate ' CFI support for AMD/Fujitsu Standard Command Set chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI
- dep_tristate 'Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD
- dep_tristate 'CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_CFI
- define_bool CONFIG_MTD_JEDEC n
- define_bool CONFIG_MTD_RAM n
- define_bool CONFIG_MTD_ROM n
-mainmenu_option next_comment
-comment 'Drivers for chip mappings'
+# These will later become config-options
+define_bool CONFIG_MTD_JEDEC n
+define_bool CONFIG_MTD_RAM n
+define_bool CONFIG_MTD_ROM n
- dep_tristate 'Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
- if [ "$CONFIG_MTD_PHYSMAP" != "n" ]; then
- hex ' Physical start location of flash chip mapping (0x8000000)' CONFIG_MTD_PHYSMAP_START 0x8000000
- hex ' Physical length of flash chip mapping (0x4000000)' CONFIG_MTD_PHYSMAP_LEN 0x4000000
- fi
- dep_tristate 'Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
- dep_tristate 'Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
- dep_tristate 'Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
- dep_tristate 'Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
- dep_tristate 'Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
+ dep_tristate ' Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI
+ if [ "$CONFIG_MTD_PHYSMAP" != "n" ]; then
+ hex 'Physical start location of flash chip mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
+ hex 'Physical length of flash chip mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
+ fi
+
+comment 'Drivers for chip mappings'
+ dep_tristate ' Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
+ dep_tristate ' Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
+ dep_tristate ' Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
+ dep_tristate ' Flash chip mapping on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI
+ dep_tristate ' Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
+ dep_tristate ' Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-mainmenu_option next_comment
comment 'User modules and translation layers for MTD devices'
- dep_tristate 'Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
- dep_tristate 'Pseudo-blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
- dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
- dep_tristate 'NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
- if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then
- bool 'Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW
- fi
+ dep_tristate ' Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD
+ dep_tristate ' Pseudo-blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
+ dep_tristate ' FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
+ dep_tristate ' NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
+ if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then
+ bool ' Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW
+ fi
fi
endmenu
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 53a3906f8..6030b63b3 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,189 +1,110 @@
-# $Id: Makefile,v 1.20 2000/07/04 08:58:10 dwmw2 Exp $
-
-# Uncomment this to enable the DBG macro (see mtd.h)
-#CFLAGS+= -DZDBG
+#
+# Makefile for the memory technology device drivers.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+# $Id: Makefile,v 1.22 2000/07/14 08:10:52 dwmw2 Exp $
ifndef CONFIG_MTD
+
# We're being invoked outside a normal kernel build. Fake it
EXTRA_CFLAGS= -I$(shell pwd)/../include
-HWDRIVERS = slram.o docprobe.o doc1000.o nora.o physmap.o rpxlite.o vmax301.o octagon-5066.o pmc551.o mtdram.o
-USERDRIVERS = ftl.o nftl.o mtdblock.o mtdchar.o
-MIX_OBJS = mtdcore.o mapped.o doc2000.o doc2001.o cfi_probe.o cfi_cmdset_0001.o
-MI_OBJS = $(HWDRIVERS) $(USERDRIVERS)
-CFLAGS_nftl.o := -DCONFIG_NFTL_RW
-else
-
-O_TARGET := mtdlink.o
-SUB_DIRS :=
-ALL_SUB_DIRS :=
-MOD_LIST_NAME := MTD_MODULES
-
-
-ifeq ($(CONFIG_MTD),y)
- OX_OBJS += mtdcore.o mapped.o
-else
- ifeq ($(CONFIG_MTD),m)
- MX_OBJS += mtdcore.o mapped.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_NORA),y)
- O_OBJS += nora.o
-else
- ifeq ($(CONFIG_MTD_NORA),m)
- M_OBJS += nora.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_RPXLITE),y)
- O_OBJS += rpxlite.o
-else
- ifeq ($(CONFIG_MTD_RPXLITE),m)
- M_OBJS += rpxlite.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_PHYSMAP),y)
- O_OBJS += physmap.o
-else
- ifeq ($(CONFIG_MTD_PHYSMAP),m)
- M_OBJS += physmap.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_CFI),y)
- OX_OBJS += cfi_probe.o
-else
- ifeq ($(CONFIG_MTD_CFI),m)
- MX_OBJS += cfi_probe.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_CFI_INTELEXT),y)
- OX_OBJS += cfi_cmdset_0001.o
-else
- ifeq ($(CONFIG_MTD_CFI_INTELEXT),m)
- MX_OBJS += cfi_cmdset_0001.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_DOC1000),y)
- O_OBJS += doc1000.o
-else
- ifeq ($(CONFIG_MTD_DOC1000),m)
- M_OBJS += doc1000.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_DOC2000),y)
- OX_OBJS += doc2000.o
-else
- ifeq ($(CONFIG_MTD_DOC2000),m)
- MX_OBJS += doc2000.o
- endif
-endif
+MIX_OBJS = mtdcore.o doc2000.o doc2001.o cfi_probe.o cfi_cmdset_0001.o \
+ map_ram.o map_rom.o cfi_cmdset_0002.o
+MI_OBJS = doc1000.o docprobe.o slram.o pmc551.o mtdram.o physmap.o \
+ nora.o octagon-5066.o pnc2000.o rpxlite.o vmax301.o mtdchar.o \
+ mtdblock.o ftl.o nftl.o
-ifeq ($(CONFIG_MTD_DOC2001),y)
- OX_OBJS += doc2001.o
-else
- ifeq ($(CONFIG_MTD_DOC2001),m)
- MX_OBJS += doc2001.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_DOCPROBE),y)
- O_OBJS += docprobe.o
-else
- ifeq ($(CONFIG_MTD_DOCPROBE),m)
- M_OBJS += docprobe.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_SLRAM),y)
- O_OBJS += slram.o
-else
- ifeq ($(CONFIG_MTD_SLRAM),m)
- M_OBJS += slram.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_OCTAGON),y)
- O_OBJS += octagon-5066.o
-else
- ifeq ($(CONFIG_MTD_OCTAGON),m)
- M_OBJS += octagon-5066.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_PMC551),y)
- O_OBJS += pmc551.o
-else
- ifeq ($(CONFIG_MTD_PMC551),m)
- M_OBJS += pmc551.o
- endif
-endif
-
-ifeq ($(CONFIG_MTD_PMC551_BUGFIX),y)
- CFLAGS_pmc551.o += -DPMC551_DRAM_BUG
-endif
-
-ifeq ($(CONFIG_MTD_VMAX),y)
- O_OBJS += vmax301.o
-else
- ifeq ($(CONFIG_MTD_VMAX),m)
- M_OBJS += vmax301.o
- endif
-endif
+CFLAGS_nftl.o := -DCONFIG_NFTL_RW
+CFLAGS_mtdram.o := -DCONFIG_MTDRAM_TOTAL_SIZE=4096 -DCONFIG_MTDRAM_ERASE_SIZE=128
+CFLAGS_physmap.o := -DCONFIG_MTD_PHYSMAP_START=0x8000000 -DCONFIG_MTD_PHYSMAP_LEN=0x4000000
-ifeq ($(CONFIG_MTD_MIXMEM),y)
- O_OBJS += mixmem.o
-else
- ifeq ($(CONFIG_MTD_MIXMEM),m)
- M_OBJS += mixmem.o
- endif
-endif
+else
-ifeq ($(CONFIG_MTD_MTDRAM),y)
- O_OBJS += mtdram.o
-else
- ifeq ($(CONFIG_MTD_MTDRAM),m)
- M_OBJS += mtdram.o
- endif
-endif
+O_OBJS :=
+OX_OBJS :=
+M_OBJS :=
+MX_OBJS :=
-ifeq ($(CONFIG_FTL),y)
- O_OBJS += ftl.o
-else
- ifeq ($(CONFIG_FTL),m)
- M_OBJS += ftl.o
- endif
-endif
+# Object file lists.
-ifeq ($(CONFIG_NFTL),y)
- O_OBJS += nftl.o
-else
- ifeq ($(CONFIG_NFTL),m)
- M_OBJS += nftl.o
- endif
-endif
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
-ifeq ($(CONFIG_MTD_BLOCK),y)
- O_OBJS += mtdblock.o
-else
- ifeq ($(CONFIG_MTD_BLOCK),m)
- M_OBJS += mtdblock.o
- endif
-endif
+O_TARGET := mtdlink.o
+SUB_DIRS :=
+ALL_SUB_DIRS :=
+MOD_SUB_DIRS :=
+MOD_LIST_NAME := MTD_MODULES
+export-objs := mtdcore.o doc2000.o doc2001.o cfi_probe.o cfi_cmdset_0001.o cfi_cmdset_0002.o
+list-multi :=
+
+# MTD devices
+obj-$(CONFIG_MTD) += mtdcore.o
+obj-$(CONFIG_MTD_DOC1000) += doc1000.o
+obj-$(CONFIG_MTD_DOC2000) += doc2000.o
+obj-$(CONFIG_MTD_DOC2001) += doc2001.o
+obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o
+obj-$(CONFIG_MTD_SLRAM) += slram.o
+obj-$(CONFIG_MTD_PMC551) += pmc551.o
+obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
+
+# Chip drivers
+obj-$(CONFIG_MTD_JEDEC) += jedec.o
+obj-$(CONFIG_MTD_RAM) += map_ram.o
+obj-$(CONFIG_MTD_ROM) += map_rom.o
+obj-$(CONFIG_MTD_CFI) += cfi_probe.o
+obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
+obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
+
+# Chip mappings
+obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
+obj-$(CONFIG_MTD_MIXMEM) += mixmem.o
+obj-$(CONFIG_MTD_NORA) += nora.o
+obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
+obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
+obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
+obj-$(CONFIG_MTD_VMAX) += vmax301.o
+
+# Users
+obj-$(CONFIG_MTD_CHAR) += mtdchar.o
+obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
+obj-$(CONFIG_FTL) += ftl.o
+obj-$(CONFIG_NFTL) += nftl.o
+
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are the intermediate files used to build the multi's.
+
+multi-y := $(filter $(list-multi), $(obj-y))
+multi-m := $(filter $(list-multi), $(obj-m))
+int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
+
+# Files that are both resident and modular: remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+int-m := $(filter-out $(int-y), $(int-m))
+
+# Take multi-part drivers out of obj-y and put components in.
+
+obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-ifeq ($(CONFIG_MTD_CHAR),y)
- O_OBJS += mtdchar.o
-else
- ifeq ($(CONFIG_MTD_CHAR),m)
- M_OBJS += mtdchar.o
- endif
-endif
endif
diff --git a/drivers/mtd/cfi_cmdset_0001.c b/drivers/mtd/cfi_cmdset_0001.c
index 713d8ab05..8c26d43b4 100644
--- a/drivers/mtd/cfi_cmdset_0001.c
+++ b/drivers/mtd/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.20 2000/07/04 07:36:43 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.21 2000/07/13 10:36:14 dwmw2 Exp $
*/
#include <linux/module.h>
@@ -455,13 +455,9 @@ static inline int do_write_1_by_16_oneword(struct map_info *map, struct flchip *
chip->word_write_time--;
if (!chip->word_write_time)
chip->word_write_time++;
- else
- printk("decreasing word_write_time to %d µs\n", chip->word_write_time);
}
- if (z > 100) {
+ if (z > 1)
chip->word_write_time++;
- printk("increasing word_write_time to %d µs\n", chip->word_write_time);
- }
/* Done and happy. */
chip->state = FL_STATUS;
diff --git a/drivers/mtd/cfi_cmdset_0002.c b/drivers/mtd/cfi_cmdset_0002.c
new file mode 100644
index 000000000..d2736c024
--- /dev/null
+++ b/drivers/mtd/cfi_cmdset_0002.c
@@ -0,0 +1,610 @@
+/*
+ * Common Flash Interface support:
+ * AMD & Fujitsu Extended Vendor Command Set (ID 0x0002)
+ *
+ * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
+ *
+ * This code is GPL
+ *
+ * $Id: cfi_cmdset_0002.c,v 1.1 2000/07/11 12:32:09 dwmw2 Exp $
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi.h>
+
+#if LINUX_VERSION_CODE < 0x20300
+#define set_current_state(x) current->state = (x);
+#endif
+
+static int cfi_amdext_read_2_by_16 (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_amdext_write_2_by_16(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+static int cfi_amdext_erase_2_by_16 (struct mtd_info *, struct erase_info *);
+static void cfi_amdext_sync (struct mtd_info *);
+static int cfi_amdext_suspend (struct mtd_info *);
+static void cfi_amdext_resume (struct mtd_info *);
+
+static void cfi_amdext_destroy(struct mtd_info *);
+
+void cfi_cmdset_0002(struct map_info *, int, unsigned long);
+EXPORT_SYMBOL(cfi_cmdset_0002);
+
+struct mtd_info *cfi_amdext_setup (struct map_info *);
+
+void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ int i;
+// struct cfi_pri_intelext *extp;
+
+ __u16 adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;
+
+ printk(" Amd/Fujitsu Extended Query Table at 0x%4.4X\n", adr);
+
+
+ /* If there was an old setup function, decrease its use count */
+ if (cfi->cmdset_setup)
+ put_module_symbol((unsigned long)cfi->cmdset_setup);
+ if (cfi->cmdset_priv)
+ kfree(cfi->cmdset_priv);
+
+ for (i=0; i< cfi->numchips; i++) {
+ cfi->chips[i].word_write_time = 128;
+ cfi->chips[i].buffer_write_time = 128;
+ cfi->chips[i].erase_time = 1024;
+ }
+
+
+ cfi->cmdset_setup = cfi_amdext_setup;
+// cfi->cmdset_priv = extp;
+ MOD_INC_USE_COUNT; /* So the setup function is still there
+ * by the time it's called */
+
+ return;
+}
+
+struct mtd_info *cfi_amdext_setup(struct map_info *map)
+{
+ struct cfi_private *cfi = map->fldrv_priv;
+ struct mtd_info *mtd;
+
+ mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
+ printk("number of CFI chips: %d\n", cfi->numchips);
+
+ if (!mtd) {
+ printk("Failed to allocate memory for MTD device\n");
+ kfree(cfi->cmdset_priv);
+ return NULL;
+ }
+
+ memset(mtd, 0, sizeof(*mtd));
+ mtd->priv = map;
+ mtd->type = MTD_NORFLASH;
+ mtd->erasesize = 0x20000; /* FIXME */
+ /* Also select the correct geometry setup too */
+ mtd->size = (1 << cfi->cfiq.DevSize) * cfi->numchips * cfi->interleave;
+ mtd->erase = cfi_amdext_erase_2_by_16;
+ mtd->read = cfi_amdext_read_2_by_16;
+ mtd->write = cfi_amdext_write_2_by_16;
+ mtd->sync = cfi_amdext_sync;
+ mtd->suspend = cfi_amdext_suspend;
+ mtd->resume = cfi_amdext_resume;
+ mtd->flags = MTD_CAP_NORFLASH;
+ map->fldrv_destroy = cfi_amdext_destroy;
+ mtd->name = map->name;
+ return mtd;
+}
+
+static inline int do_read_2_by_16_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long timeo = jiffies + HZ;
+
+ retry:
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state != FL_READY){
+printk("Waiting for chip to read, status = %d\n", chip->state);
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+
+ spin_unlock_bh(chip->mutex);
+
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+
+ if(signal_pending(current))
+ return -EINTR;
+
+ timeo = jiffies + HZ;
+
+ goto retry;
+ }
+
+ adr += chip->start;
+
+// map->write32(map, cpu_to_le32(0x00F000F0), adr);
+
+ chip->state = FL_READY;
+
+ map->copy_from(map, buf, adr, len);
+
+ wake_up(&chip->wq);
+ spin_unlock_bh(chip->mutex);
+
+ return 0;
+}
+
+static int cfi_amdext_read_2_by_16 (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ unsigned long ofs;
+ int chipnum;
+ int ret = 0;
+
+ /* ofs: offset within the first chip that the first read should start */
+
+ chipnum = (from >> cfi->chipshift);
+ chipnum /= (cfi->interleave);
+ ofs = from - (chipnum << cfi->chipshift) * (cfi->interleave);
+
+ *retlen = 0;
+
+ while (len) {
+ unsigned long thislen;
+
+ if (chipnum >= cfi->numchips)
+ break;
+
+ if (((len + ofs -1) >> cfi->chipshift) / (cfi->interleave))
+ thislen = (1<<cfi->chipshift) * (cfi->interleave) - ofs;
+ else
+ thislen = len;
+
+ ret = do_read_2_by_16_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
+ if (ret)
+ break;
+
+ *retlen += thislen;
+ len -= thislen;
+ buf += thislen;
+
+ ofs = 0;
+ chipnum++;
+ }
+ return ret;
+}
+
+static inline int do_write_2_by_16_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum)
+{
+ unsigned long timeo = jiffies + HZ;
+ unsigned int Last[4];
+ unsigned long Count = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ int ret = 0;
+
+ retry:
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state != FL_READY){
+printk("Waiting for chip to write, status = %d\n", chip->state);
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+
+ spin_unlock_bh(chip->mutex);
+
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+printk("Wake up to write:\n");
+ if(signal_pending(current))
+ return -EINTR;
+
+ timeo = jiffies + HZ;
+
+ goto retry;
+ }
+
+ chip->state = FL_WRITING;
+
+ adr += chip->start;
+
+ map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
+ map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
+ map->write32(map, cpu_to_le32(0x00A000A0), 0x555 *4);
+ map->write32(map, cpu_to_le32(datum), adr);
+
+ spin_unlock_bh(chip->mutex);
+ udelay(chip->word_write_time);
+ spin_lock_bh(chip->mutex);
+
+ Last[0] = map->read32(map, adr);
+ Last[1] = map->read32(map, adr);
+ Last[2] = map->read32(map, adr);
+
+ for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
+ udelay(10);
+
+ Last[Count % 4] = map->read32(map, adr);
+ }
+
+ if (Last[(Count - 1) % 4] != datum){
+ map->write32(map, cpu_to_le32(0x00F000F0), adr);
+ ret = -EIO;
+ }
+
+ chip->state = FL_READY;
+ wake_up(&chip->wq);
+ spin_unlock_bh(chip->mutex);
+
+ return ret;
+}
+
+
+static int cfi_amdext_write_2_by_16 (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ int ret = 0;
+ int chipnum;
+ unsigned long ofs;
+
+ *retlen = 0;
+
+ chipnum = (to >> cfi->chipshift);
+ chipnum /= cfi->interleave;
+ ofs = to - (chipnum << cfi->chipshift) * cfi->interleave;
+
+ while(len > 3) {
+
+ ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum],
+ ofs, *(__u32 *)buf);
+ if (ret)
+ return ret;
+
+ ofs += 4;
+ buf += 4;
+ (*retlen) += 4;
+ len -= 4;
+
+ if ((ofs >> cfi->chipshift) / cfi->interleave) {
+ chipnum ++;
+ ofs = 0;
+ if (chipnum == cfi->numchips)
+ return 0;
+ }
+ }
+
+ if (len) {
+ unsigned int tmp;
+
+ /* Final byte to write */
+#if defined(__LITTLE_ENDIAN)
+ tmp = map->read32(map, ofs);
+
+ tmp = 0xffffffff >> (len*8);
+ tmp = tmp << (len*8);
+
+ tmp |= *(__u32 *)(buf);
+
+ ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum],
+ ofs, tmp);
+
+#elif defined(__BIG_ENDIAN)
+#error not support big endian yet
+#else
+#error define a sensible endianness
+#endif
+
+ if (ret)
+ return ret;
+
+ (*retlen)+=len;
+ }
+
+ return 0;
+}
+
+
+static inline int do_erase_2_by_16_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
+{
+ unsigned int status;
+ unsigned long timeo = jiffies + HZ;
+ DECLARE_WAITQUEUE(wait, current);
+
+ retry:
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state != FL_READY){
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+
+ spin_unlock_bh(chip->mutex);
+
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+
+ if(signal_pending(current))
+ return -EINTR;
+
+ timeo = jiffies + HZ;
+
+ goto retry;
+ }
+
+ chip->state = FL_ERASING;
+
+ adr += chip->start;
+
+ map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
+ map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
+ map->write32(map, cpu_to_le32(0x00800080), 0x555 *4);
+ map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4);
+ map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4);
+ map->write32(map, cpu_to_le32(0x00300030), adr);
+
+
+ timeo = jiffies + (HZ*20);
+
+ spin_unlock_bh(chip->mutex);
+ schedule_timeout(HZ);
+ spin_lock_bh(chip->mutex);
+
+ /* FIXME. Use a timer to check this, and return immediately. */
+ /* Once the state machine's known to be working I'll do that */
+
+ while ( ( (status = le32_to_cpu(map->read32(map, 0x00))) & 0x80808080 ) != 0x80808080 ) {
+ static int z=0;
+
+ if (chip->state != FL_ERASING) {
+ /* Someone's suspended the erase. Sleep */
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue(&chip->wq, &wait);
+
+ spin_unlock_bh(chip->mutex);
+ printk("erase suspended. Sleeping\n");
+
+ schedule();
+ remove_wait_queue(&chip->wq, &wait);
+
+ if (signal_pending(current))
+ return -EINTR;
+
+ timeo = jiffies + (HZ*2); /* FIXME */
+ spin_lock_bh(chip->mutex);
+ continue;
+ }
+
+ /* OK Still waiting */
+ if (time_after(jiffies, timeo)) {
+ chip->state = FL_READY;
+ spin_unlock_bh(chip->mutex);
+ printk("waiting for erase to complete timed out.");
+ return -EIO;
+ }
+
+ /* Latency issues. Drop the lock, wait a while and retry */
+ spin_unlock_bh(chip->mutex);
+
+ z++;
+ if ( 0 && !(z % 100 ))
+ printk("chip not ready yet after erase. looping\n");
+
+ udelay(1);
+
+ spin_lock_bh(chip->mutex);
+ continue;
+ }
+
+ /* Done and happy. */
+ chip->state = FL_READY;
+ wake_up(&chip->wq);
+ spin_unlock_bh(chip->mutex);
+ printk("erase ret OK\n");
+ return 0;
+}
+
+static int cfi_amdext_erase_2_by_16 (struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ unsigned long adr, len;
+ int chipnum, ret = 0;
+
+//printk("erase : 0x%x 0x%x 0x%x\n", instr->addr, instr->len, mtd->size);
+
+ if (instr->addr & (mtd->erasesize - 1))
+ return -EINVAL;
+
+ if (instr->len & (mtd->erasesize -1))
+ return -EINVAL;
+
+ if ((instr->len + instr->addr) > mtd->size)
+ return -EINVAL;
+
+ chipnum = instr->addr >> cfi->chipshift;
+ chipnum /= cfi->interleave;
+ adr = instr->addr - (chipnum << cfi->chipshift) * (cfi->interleave);
+ len = instr->len;
+
+printk("erase : 0x%x 0x%x 0x%x\n", adr, len, chipnum, mtd->size);
+
+ while(len) {
+//printk("erase : 0x%x 0x%x 0x%x 0x%x\n", chipnum, adr, len, cfi->chipshift);
+ ret = do_erase_2_by_16_oneblock(map, &cfi->chips[chipnum], adr);
+
+ if (ret)
+ return ret;
+
+ adr += mtd->erasesize;
+ len -= mtd->erasesize;
+
+ if ((adr >> cfi->chipshift) / (cfi->interleave)) {
+ adr = 0;
+ chipnum++;
+
+ if (chipnum >= cfi->numchips)
+ break;
+ }
+ }
+
+ if (instr->callback)
+ instr->callback(instr);
+
+ return 0;
+}
+
+
+
+static void cfi_amdext_sync (struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ int i;
+ struct flchip *chip;
+ int ret = 0;
+ DECLARE_WAITQUEUE(wait, current);
+printk("sync\n");
+
+ for (i=0; !ret && i<cfi->numchips; i++) {
+ chip = &cfi->chips[i];
+
+ retry:
+ spin_lock_bh(chip->mutex);
+
+ switch(chip->state) {
+ case FL_READY:
+ case FL_STATUS:
+ case FL_CFI_QUERY:
+ case FL_JEDEC_QUERY:
+ chip->oldstate = chip->state;
+ chip->state = FL_SYNCING;
+ /* No need to wake_up() on this state change -
+ * as the whole point is that nobody can do anything
+ * with the chip now anyway.
+ */
+ spin_unlock_bh(chip->mutex);
+ break;
+
+ default:
+ /* Not an idle state */
+ add_wait_queue(&chip->wq, &wait);
+
+ spin_unlock_bh(chip->mutex);
+ schedule();
+
+ goto retry;
+ }
+ }
+
+ /* Unlock the chips again */
+
+ for (i--; i >=0; i--) {
+ chip = &cfi->chips[i];
+
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state == FL_SYNCING) {
+ chip->state = chip->oldstate;
+ wake_up(&chip->wq);
+ }
+ spin_unlock_bh(chip->mutex);
+ }
+printk("sync end\n");
+}
+
+
+static int cfi_amdext_suspend(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ int i;
+ struct flchip *chip;
+ int ret = 0;
+//printk("suspend\n");
+
+ for (i=0; !ret && i<cfi->numchips; i++) {
+ chip = &cfi->chips[i];
+
+ spin_lock_bh(chip->mutex);
+
+ switch(chip->state) {
+ case FL_READY:
+ case FL_STATUS:
+ case FL_CFI_QUERY:
+ case FL_JEDEC_QUERY:
+ chip->oldstate = chip->state;
+ chip->state = FL_PM_SUSPENDED;
+ /* No need to wake_up() on this state change -
+ * as the whole point is that nobody can do anything
+ * with the chip now anyway.
+ */
+ spin_unlock_bh(chip->mutex);
+ break;
+
+ default:
+ ret = -EAGAIN;
+ break;
+ }
+ }
+
+ /* Unlock the chips again */
+
+ for (i--; i >=0; i--) {
+ chip = &cfi->chips[i];
+
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state == FL_PM_SUSPENDED) {
+ chip->state = chip->oldstate;
+ wake_up(&chip->wq);
+ }
+ spin_unlock_bh(chip->mutex);
+ }
+
+ return ret;
+}
+
+static void cfi_amdext_resume(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ int i;
+ struct flchip *chip;
+//printk("resume\n");
+
+ for (i=0; i<cfi->numchips; i++) {
+
+ chip = &cfi->chips[i];
+
+ spin_lock_bh(chip->mutex);
+
+ if (chip->state == FL_PM_SUSPENDED) {
+ chip->state = chip->oldstate;
+ wake_up(&chip->wq);
+ }
+ else
+ printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
+
+ spin_unlock_bh(chip->mutex);
+ }
+}
+
+static void cfi_amdext_destroy(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ kfree(cfi->cmdset_priv);
+ kfree(cfi);
+}
+
diff --git a/drivers/mtd/doc2000.c b/drivers/mtd/doc2000.c
index 8385648d1..eeb49a4eb 100644
--- a/drivers/mtd/doc2000.c
+++ b/drivers/mtd/doc2000.c
@@ -2,7 +2,7 @@
/* Linux driver for Disk-On-Chip 2000 */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.c,v 1.23 2000/07/03 10:01:38 dwmw2 Exp $ */
+/* $Id: doc2000.c,v 1.24 2000/07/13 10:03:31 dwmw2 Exp $ */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -36,7 +36,7 @@ static struct mtd_info *doc2klist = NULL;
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-int _DoC_WaitReady (unsigned long docptr)
+static int _DoC_WaitReady (unsigned long docptr)
{
//long c=-1;
short c=-1;
@@ -148,7 +148,7 @@ static inline int DoC_SelectFloor(unsigned long docptr, int floor)
/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
{
int mfr, id, chipshift=0;
char *mfrname=NULL, *idname=NULL;
@@ -302,7 +302,7 @@ int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-void DoC_ScanChips(struct DiskOnChip *this)
+static void DoC_ScanChips(struct DiskOnChip *this)
{
int floor, chip;
int numchips[MAX_FLOORS];
diff --git a/drivers/mtd/doc2001.c b/drivers/mtd/doc2001.c
index 9f63b0b22..26a107722 100644
--- a/drivers/mtd/doc2001.c
+++ b/drivers/mtd/doc2001.c
@@ -1,8 +1,7 @@
-
/* Linux driver for Disk-On-Chip Millennium */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2001.c,v 1.4 2000/07/03 10:01:38 dwmw2 Exp $ */
+/* $Id: doc2001.c,v 1.7 2000/07/13 10:41:39 dwmw2 Exp $ */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -21,305 +20,238 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/doc2000.h>
-
-
-//#define PRERELEASE
-#if 0
-static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eecbuf);
-static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf);
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf);
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, const u_char *buf);
+static struct {
+ char * name;
+ int manufacture_id;
+ int model_id;
+ int chipshift;
+} nand_flash_ids[] = {
+ {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21},
+ {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22},
+ {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24},
+ {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25},
+ {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22},
+ {"Toshiba TC58V64DC", NAND_MFR_TOSHIBA, 0xe6, 23},
+ {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21},
+ {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21},
+ {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24},
+ {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25},
+ {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22},
+ {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23},
+ {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21},
+ {NULL,}
+};
+
+static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf);
+static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf);
+static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf, u_char *eecbuf);
+static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf, u_char *eccbuf);
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+ size_t *retlen, u_char *buf);
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+ size_t *retlen, const u_char *buf);
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-#endif
static struct mtd_info *docmillist = NULL;
-/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-
-int _DoC_WaitReady (unsigned long docptr)
+static void DoC_Delay(unsigned long docptr, unsigned short cycles)
{
- //long c=-1;
- short c=-1;
+ volatile char dummy;
+ int i;
- DEBUG(2,"_DoC_WaitReady called for out-of-line wait\n");
+ for (i = 0; i < cycles; i++)
+ dummy = ReadDOC(docptr, NOP);
+}
+
+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
+static int _DoC_WaitReady(unsigned long docptr)
+{
+ unsigned short c = 0xffff;
/* Out-of-line routine to wait for chip response */
while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
;
- if (c == 0)
- DEBUG(2, "_DoC_WaitReady timed out.\n");
-
- return (c==0);
+ return (c == 0);
}
-static inline int DoC_WaitReady(unsigned long docptr)
+static __inline__ int DoC_WaitReady(unsigned long docptr)
{
/* This is inline, to optimise the common case, where it's ready instantly */
- volatile char dummy;
int ret = 0;
- /* Out-of-line routine to wait for chip response */
- /* TPW: Add 4 reads - see Software Requirement 2.3.2 */
- dummy = ReadDOC(docptr, CDSNControl);
- dummy = ReadDOC(docptr, CDSNControl);
- dummy = ReadDOC(docptr, CDSNControl);
- dummy = ReadDOC(docptr, CDSNControl);
-
+ /* 4 read form NOP register should be issued in prior to the read from CDSNControl
+ see Software Requirement 11.4 item 2. */
+ DoC_Delay(docptr, 4);
+
if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
- ret = _DoC_WaitReady(docptr); /* Call the out-of-line routine to wait */
-
- /* TPW: Add 2 reads - see Software Requirement 2.3.2 */
- dummy = ReadDOC(docptr, CDSNControl);
- dummy = ReadDOC(docptr, CDSNControl);
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(docptr);
+
+ /* issue 2 read from NOP register after reading from CDSNControl register
+ see Software Requirement 11.4 item 2. */
+ DoC_Delay(docptr, 2);
return ret;
}
-
-/* DoC_Command: Send a flash command to the flash chip */
-
-static inline int DoC_Command(unsigned long docptr, unsigned char command, unsigned char xtraflags)
+/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to bypass
+ the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after
+ writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+static __inline__ void DoC_Command(unsigned long docptr, unsigned char command,
+ unsigned char xtraflags)
{
/* Assert the CLE (Command Latch Enable) line to the flash chip */
- WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE,
- docptr, CDSNControl);
+ WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(docptr, 4);
/* Send the command */
- WriteDOC(command, docptr, 2k_CDSN_IO);
+ WriteDOC(command, docptr, CDSNSlowIO);
+ WriteDOC(command, docptr, Mil_CDSN_IO);
/* Lower the CLE line */
- WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-
- /* Wait for the chip to respond */
- return DoC_WaitReady(docptr);
+ WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(docptr, 4);
}
-/* DoC_Address: Set the current address for the flash chip */
-
-static inline int DoC_Address (unsigned long docptr, int numbytes, unsigned long ofs,
+/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to bypass
+ the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after
+ writing to CDSN Control register, see Software Requirement 11.4 item 3. */
+static __inline__ void DoC_Address (unsigned long docptr, int numbytes, unsigned long ofs,
unsigned char xtraflags1, unsigned char xtraflags2)
{
/* Assert the ALE (Address Latch Enable line to the flash chip */
- WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE,
- docptr, CDSNControl);
+ WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(docptr, 4);
/* Send the address */
- /* Three cases:
- numbytes == 1: Send single byte, bits 0-7.
- numbytes == 2: Send bits 9-16 followed by 17-23
- numbytes == 3: Send 0-7, 9-16, then 17-23
- */
- if (numbytes != 2)
- WriteDOC(ofs & 0xff, docptr, 2k_CDSN_IO);
-
- if (numbytes != 1) {
- WriteDOC((ofs >> 9) & 0xff, docptr, 2k_CDSN_IO);
- WriteDOC((ofs >> 17) & 0xff, docptr, 2k_CDSN_IO);
- }
+ switch (numbytes)
+ {
+ case 1:
+ /* Send single byte, bits 0-7. */
+ WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+ WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
+ break;
+ case 2:
+ /* Send bits 9-16 followed by 17-23 */
+ WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO);
+ WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO);
+ WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
+ WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
+ break;
+ case 3:
+ /* Send 0-7, 9-16, then 17-23 */
+ WriteDOC(ofs & 0xff, docptr, CDSNSlowIO);
+ WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
+ WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO);
+ WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO);
+ WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO);
+ WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
+ break;
+ default:
+ return;
+ }
+
/* Lower the ALE line */
- WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
-
- /* Wait for the chip to respond */
- return DoC_WaitReady(docptr);
+ WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
+ DoC_Delay(docptr, 4);
}
/* DoC_SelectChip: Select a given flash chip within the current floor */
-
-static inline int DoC_SelectChip(unsigned long docptr, int chip)
+static int DoC_SelectChip(unsigned long docptr, int chip)
{
/* Select the individual flash chip requested */
- WriteDOC( chip, docptr, CDSNDeviceSelect);
-
+ WriteDOC(chip, docptr, CDSNDeviceSelect);
+ DoC_Delay(docptr, 4);
+
/* Wait for it to be ready */
return DoC_WaitReady(docptr);
}
/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-
-static inline int DoC_SelectFloor(unsigned long docptr, int floor)
+static int DoC_SelectFloor(unsigned long docptr, int floor)
{
/* Select the floor (bank) of chips required */
- WriteDOC( floor, docptr, FloorSelect);
+ WriteDOC(floor, docptr, FloorSelect);
/* Wait for the chip to be ready */
return DoC_WaitReady(docptr);
}
-
-/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
{
- int mfr, id, chipshift=0;
- char *mfrname=NULL, *idname=NULL;
+ int mfr, id, i;
+ volatile char dummy;
- /* Page in the required floor/chip */
+ /* Page in the required floor/chip
+ FIXME: is this supported by Millennium ?? */
DoC_SelectFloor(doc->virtadr, floor);
DoC_SelectChip(doc->virtadr, chip);
- /* Reset the chip */
- if (DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP)) {
- DEBUG(2, "DoC_Command (reset) for %d,%d returned true\n", floor,chip);
- return 0;
- }
-
+ /* Reset the chip, see Software Requirement 11.4 item 1. */
+ DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
+ DoC_WaitReady(doc->virtadr);
+
/* Read the NAND chip ID: 1. Send ReadID command */
- if(DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP)) {
- DEBUG(2,"DoC_Command (ReadID) for %d,%d returned true\n", floor,chip);
- return 0;
- }
+ DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
+
+ /* Read the NAND chip ID: 2. Send address byte zero */
+ DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
+
+ /* Read the manufacturer and device id codes of the flash device through
+ CDSN Slow IO register see Software Requirement 11.4 item 5.*/
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc->virtadr, 2);
+ mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO);
+
+ dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
+ DoC_Delay(doc->virtadr, 2);
+ id = ReadDOC(doc->virtadr, Mil_CDSN_IO);
- /* Read the NAND chip ID: 2. Send address byte zero
- */
- DoC_Address(doc->virtadr, 1, 0, CDSN_CTRL_WP, 0);
-
- /* Read the manufacturer and device id codes from the device */
- mfr = ReadDOC(doc->virtadr, 2k_CDSN_IO);
- id = ReadDOC(doc->virtadr, 2k_CDSN_IO);
-
/* No response - return failure */
if (mfr == 0xff || mfr == 0)
return 0;
-
- /* Check it's the same as the first chip we identified.
- * M-Systems say that any given DiskOnChip device should only
- * contain _one_ type of flash part, although that's not a
- * hardware restriction. */
- if (doc->mfr) {
- if (doc->mfr == mfr && doc->id == id)
- return 1; /* This is another the same the first */
- else
- printk(KERN_WARNING "Flash chip at floor %d, chip %d is different:\n",
- floor, chip);
- }
-
- /* Print (and store if first time) the manufacturer and ID codes. */
-
- switch(mfr) {
- case NAND_MFR_TOSHIBA: /* Toshiba */
- mfrname = "Toshiba";
-
- switch(id) {
- case 0x64:
- idname = "TC5816BDC";
- chipshift = 21;
- break;
-
- case 0x6b:
- idname = "TC5832DC";
- chipshift = 22;
- break;
-
- case 0x73:
- idname = "TH58V128DC";
- chipshift = 24;
- break;
-
- case 0x75:
- idname = "TC58256FT/DC";
- chipshift = 25;
- break;
-
- case 0xe5:
- idname = "TC58V32DC";
- chipshift = 22;
- break;
-
- case 0xe6:
- idname = "TC58V64DC";
- chipshift = 23;
- break;
-
- case 0xea:
- idname = "TC58V16BDC";
- chipshift = 21;
- break;
- }
- break; /* End of Toshiba parts */
-
- case NAND_MFR_SAMSUNG: /* Samsung */
- mfrname = "Samsung";
-
- switch(id) {
- case 0x64:
- idname = "KM29N16000";
- chipshift = 21;
-
- case 0x73:
- idname = "KM29U128T";
- chipshift = 24;
- break;
-
- case 0x75:
- idname = "KM29U256T";
- chipshift = 25;
- break;
- case 0xe3:
- idname = "KM29W32000";
- chipshift = 22;
- break;
-
- case 0xe6:
- idname = "KM29U64000";
- chipshift = 23;
- break;
-
- case 0xea:
- idname = "KM29W16000";
- chipshift = 21;
- break;
- }
- break; /* End of Samsung parts */
- }
-
- /* If we've identified it fully, print the full names */
- if (idname) {
-#ifdef PRERELEASE
- DEBUG(1, "Flash chip found: %2.2X %2.2X (%s %s)\n",
- mfr,id,mfrname,idname);
-#endif
- /* If this is the first chip, store the id codes */
- if (!doc->mfr) {
+ /* FIXME: to deal with mulit-flash on multi-Millennium case more carefully */
+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+ if (mfr == nand_flash_ids[i].manufacture_id &&
+ id == nand_flash_ids[i].model_id) {
+ printk(KERN_INFO "Flash chip found: Manufacture ID: %2.2X, "
+ "Chip ID: %2.2X (%s)\n",
+ mfr, id, nand_flash_ids[i].name);
doc->mfr = mfr;
doc->id = id;
- doc->chipshift = chipshift;
- return 1;
+ doc->chipshift = nand_flash_ids[i].chipshift;
+ break;
}
- return 0;
}
- /* We haven't fully identified the chip. Print as much as we know. */
- if (mfrname)
- printk(KERN_WARNING "Unknown %s flash chip found: %2.2X %2.2X\n", mfrname,
- id, mfr);
+ if (nand_flash_ids[i].name == NULL)
+ return 0;
else
- printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n", id, mfr);
-
- printk(KERN_WARNING "Please report to David.Woodhouse@mvhi.com\n");
- return 0;
+ return 1;
}
/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-
-void DoC_ScanChips(struct DiskOnChip *this)
+static void DoC_ScanChips(struct DiskOnChip *this)
{
int floor, chip;
- int numchips[MAX_FLOORS];
- int ret = 1;
+ int numchips[MAX_FLOORS_MIL];
+ int ret;
this->numchips = 0;
this->mfr = 0;
this->id = 0;
/* For each floor, find the number of valid chips it contains */
- for (floor = 0 ; floor < MAX_FLOORS ; floor++) {
- ret = 1;
- numchips[floor]=0;
- for (chip = 0 ; chip < MAX_CHIPS && ret != 0; chip++ ) {
-
+ for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) {
+ numchips[floor] = 0;
+ for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) {
ret = DoC_IdentChip(this, floor, chip);
if (ret) {
numchips[floor]++;
@@ -327,7 +259,6 @@ void DoC_ScanChips(struct DiskOnChip *this)
}
}
}
-
/* If there are none at all that we recognise, bail */
if (!this->numchips) {
printk("No flash chips recognised.\n");
@@ -341,11 +272,9 @@ void DoC_ScanChips(struct DiskOnChip *this)
return;
}
- ret = 0;
-
/* Fill out the chip array with {floor, chipno} for each
* detected chip in the device. */
- for (floor = 0; floor < MAX_FLOORS; floor++) {
+ for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
for (chip = 0 ; chip < numchips[floor] ; chip++) {
this->chips[ret].floor = floor;
this->chips[ret].chip = chip;
@@ -357,14 +286,14 @@ void DoC_ScanChips(struct DiskOnChip *this)
/* Calculate and print the total size of the device */
this->totlen = this->numchips * (1 << this->chipshift);
-
- printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld Mb\n", this->numchips ,
- this->totlen >> 20);
+ printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld Mbytes\n",
+ this->numchips ,this->totlen >> 20);
}
static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
{
int tmp1, tmp2, retval;
+
if (doc1->physadr == doc2->physadr)
return 1;
@@ -392,21 +321,19 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
return retval;
}
-
void DoCMil_init(struct mtd_info *mtd)
{
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
struct DiskOnChip *old = NULL;
/* We must avoid being called twice for the same device. */
-
if (docmillist)
old = (struct DiskOnChip *)docmillist->priv;
while (old) {
if (DoCMil_is_alias(this, old)) {
- printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at 0x%lX - already configured\n",
- this->physadr);
+ printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
+ "0x%lX - already configured\n", this->physadr);
iounmap((void *)this->virtadr);
kfree(mtd);
return;
@@ -418,14 +345,9 @@ void DoCMil_init(struct mtd_info *mtd)
}
mtd->name = "DiskOnChip Millennium";
- printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",this->physadr);
+ printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",
+ this->physadr);
-#if 1
- printk("Unfortunately, we don't have support for the DiskOnChip Millennium yet.\n");
- iounmap((void *)this->virtadr);
- kfree(mtd);
- return;
-#else
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
mtd->size = 0;
@@ -445,8 +367,7 @@ void DoCMil_init(struct mtd_info *mtd)
mtd->sync = NULL;
this->totlen = 0;
- this->numchips = 0;
-
+ this->numchips = 0;
this->curfloor = -1;
this->curchip = -1;
@@ -463,78 +384,90 @@ void DoCMil_init(struct mtd_info *mtd)
add_mtd_device(mtd);
return;
}
-#endif
}
-
EXPORT_SYMBOL(DoCMil_init);
-#if 0
-static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+
+static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
{
/* Just a special case of doc_read_ecc */
return doc_read_ecc(mtd, from, len, retlen, buf, NULL);
}
-static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf)
+static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf, u_char *eccbuf)
{
+ int i;
+ volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
- int di=0; /* Yes, DI is a hangover from when I was disassembling the binary driver */
- unsigned long docptr;
- struct Nand *mychip;
-
- docptr = this->virtadr;
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[from >> (this->chipshift)];
/* Don't allow read past end of device */
if (from >= this->totlen)
return -EINVAL;
-
+
/* Don't allow a single read to cross a 512-byte block boundary */
- if (from + len > ( (from | 0x1ff) + 1))
+ if (from + len > ((from | 0x1ff) + 1))
len = ((from | 0x1ff) + 1) - from;
/* Find the chip which is to be used and select it */
- mychip = &this->chips[from >> (this->chipshift)];
-
if (this->curfloor != mychip->floor) {
DoC_SelectFloor(docptr, mychip->floor);
DoC_SelectChip(docptr, mychip->chip);
- }
- else if (this->curchip != mychip->chip) {
+ } else if (this->curchip != mychip->chip) {
DoC_SelectChip(docptr, mychip->chip);
}
-
this->curfloor = mychip->floor;
this->curchip = mychip->chip;
-
if (eccbuf) {
- /* Prime the ECC engine */
- WriteDOC ( DOC_ECC_RESET, docptr, ECCConf);
- WriteDOC ( DOC_ECC_EN, docptr, ECCConf);
+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_EN, docptr, ECCConf);
+ } else {
+ /* disable the ECC engine, FIXME: is this correct ?? */
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
}
+ /* issue the Read0 or Read1 command depend on which half of the page
+ we are accessing. Polling the Flash Ready bit after issue 3 bytes
+ address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
- DoC_Address(docptr, 3, from, CDSN_CTRL_WP , CDSN_CTRL_ECC_IO);
+ DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
+ DoC_WaitReady(docptr);
- for (di=0; di < len ; di++) {
- buf[di] = ReadDOC(docptr, 2k_CDSN_IO);
+ /* Read the data via the internal pipeline through CDSN IO register,
+ see Pipelined Read Operations 11.3 */
+ dummy = ReadDOC(docptr, ReadPipeInit);
+ for (i = 0; i < len-1; i++) {
+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
}
+ buf[i] = ReadDOC(docptr, LastDataRead);
/* Let the caller know we completed it */
*retlen = len;
if (eccbuf) {
- /* Read the ECC data through the DiskOnChip ECC logic */
- for (di=0; di<6; di++) {
- eccbuf[di] = ReadDOC(docptr, 2k_CDSN_IO);
+ /* FIXME: are we reading the ECC from the ECC logic of DOC or
+ the spare data space on the flash chip i.e. How do we
+ control the Spare Area Enable bit of the flash ?? */
+ /* Read the ECC data through the DiskOnChip ECC logic
+ see Reed-Solomon EDC/ECC 11.1 */
+ dummy = ReadDOC(docptr, ReadPipeInit);
+ for (i = 0; i < 5; i++) {
+ eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO);
}
-
+ eccbuf[i] = ReadDOC(docptr, LastDataRead);
+
/* Flush the pipeline */
- (void) ReadDOC(docptr, 2k_ECCStatus);
- (void) ReadDOC(docptr, 2k_ECCStatus);
-
+ dummy = ReadDOC(docptr, ECCConf);
+ dummy = ReadDOC(docptr, ECCConf);
+
/* Check the ECC Status */
- if (ReadDOC(docptr, 2k_ECCStatus) & 0x80) {
+ if (ReadDOC(docptr, ECCConf) & 0x80) {
/* There was an ECC error */
printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
@@ -548,41 +481,40 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *
#ifdef PSYCHO_DEBUG
else
printk("ECC OK at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
- (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], eccbuf[4],
- eccbuf[5]);
+ (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+ eccbuf[4], eccbuf[5]);
#endif
-
/* Reset the ECC engine */
WriteDOC(DOC_ECC_RESV, docptr , ECCConf);
-
}
return 0;
}
-static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
{
static char as[6];
return doc_write_ecc(mtd, to, len, retlen, buf, as);
}
-static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf)
+static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf, u_char *eccbuf)
{
+ int i;
+ volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
- int di=0;
- unsigned long docptr;
- struct Nand *mychip;
-
- docptr = this->virtadr;
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[to >> (this->chipshift)];
/* Don't allow write past end of device */
if (to >= this->totlen)
return -EINVAL;
-#if 0
+
+#if 0
/* Don't allow a single write to cross a 512-byte block boundary */
if (to + len > ( (to | 0x1ff) + 1))
len = ((to | 0x1ff) + 1) - to;
-
#else
/* Don't allow writes which aren't exactly one block */
if (to & 0x1ff || len != 0x200)
@@ -590,8 +522,6 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *r
#endif
/* Find the chip which is to be used and select it */
- mychip = &this->chips[to >> (this->chipshift)];
-
if (this->curfloor != mychip->floor) {
DoC_SelectFloor(docptr, mychip->floor);
DoC_SelectChip(docptr, mychip->chip);
@@ -599,61 +529,75 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *r
else if (this->curchip != mychip->chip) {
DoC_SelectChip(docptr, mychip->chip);
}
-
this->curfloor = mychip->floor;
this->curchip = mychip->chip;
-
- /* Set device to main plane of flash */
+
+ /* Reset the chip, see Software Requirement 11.4 item 1. */
DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
+ DoC_WaitReady(docptr);
+ /* Set device to main plane of flash */
DoC_Command(docptr, NAND_CMD_READ0, CDSN_CTRL_WP);
if (eccbuf) {
- /* Prime the ECC engine */
- WriteDOC ( DOC_ECC_RESET, docptr, ECCConf);
- WriteDOC ( DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
+ } else {
+ /* disable the ECC engine, FIXME: is this correct ?? */
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
}
- DoC_Command(docptr, NAND_CMD_SEQIN, 0);
- DoC_Address(docptr, 3, to, 0, CDSN_CTRL_ECC_IO);
+ /* issue the Serial Data In command to initial the Page Program process */
+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+ DoC_Address(docptr, 3, to, 0x00, 0x00);
- for (di=0; di < len ; di++) {
- WriteDOC(buf[di], docptr, 2k_CDSN_IO);
+ /* Write the data via the internal pipeline through CDSN IO register,
+ see Pipelined Write Operations 11.2 */
+ for (i = 0; i < len; i++) {
+ WriteDOC(buf[i], docptr, Mil_CDSN_IO);
}
-
+ WriteDOC(0x00, docptr, WritePipeTerm);
if (eccbuf) {
- WriteDOC( CDSN_CTRL_ECC_IO | CDSN_CTRL_CE , docptr, CDSNControl );
-
-#if 1
- /* eduardp@m-sys.com says this shouldn't be necessary,
- * but it doesn't actually work without it, so I've
- * left it in for now. dwmw2.
- */
-
- WriteDOC( 0, docptr, 2k_CDSN_IO);
- WriteDOC( 0, docptr, 2k_CDSN_IO);
- WriteDOC( 0, docptr, 2k_CDSN_IO);
-#endif
+ /* Write ECC data to flash, the ECC info is generated by the DiskOnChip DECC logic
+ see Reed-Solomon EDC/ECC 11.1 */
+ WriteDOC(0, docptr, NOP);
+ WriteDOC(0, docptr, NOP);
+ WriteDOC(0, docptr, NOP);
+
/* Read the ECC data through the DiskOnChip ECC logic */
- for (di=0; di<6; di++) {
- eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
+ for (i = 0; i < 6; i++) {
+ eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
}
+
+ /* Write the ECC data to flash */
+ for (i = 0; i < 6; i++) {
+ WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO);
+ }
+ WriteDOC(0x00, docptr, WritePipeTerm);
+
#ifdef PSYCHO_DEBUG
printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
- (long) to, eccbuf[0], eccbuf[1], eccbuf[2],
- eccbuf[3], eccbuf[4], eccbuf[5] );
+ (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
+ eccbuf[4], eccbuf[5]);
#endif
+
/* Reset the ECC engine */
WriteDOC(DOC_ECC_RESV, docptr , ECCConf);
-
}
- DoC_Command(docptr, NAND_CMD_PAGEPROG, 0);
-
- DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
- /* There's an implicit DoC_WaitReady() in DoC_Command */
+ /* Commit the Page Program command and wait for ready
+ see Software Requirement 11.4 item 1.*/
+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+ DoC_WaitReady(docptr);
- if (ReadDOC(docptr, 2k_CDSN_IO) & 1) {
+ /* Read the status of the flash device through CDSN Slow IO register
+ see Software Requirement 11.4 item 5.*/
+ DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(docptr, 2);
+ if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
printk("Error programming flash\n");
/* Error in programming */
*retlen = 0;
@@ -666,19 +610,18 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *r
return 0;
}
-
-
-static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf)
+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+ size_t *retlen, u_char *buf)
{
- struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+ volatile char dummy;
int i;
- unsigned long docptr;
- struct Nand *mychip;
-
- docptr = this->virtadr;
-
- mychip = &this->chips[ofs >> this->chipshift];
-
+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
+
+ /* FIXME: should we restrict the access between 512 to 527 ?? */
+
+ /* Find the chip which is to be used and select it */
if (this->curfloor != mychip->floor) {
DoC_SelectFloor(docptr, mychip->floor);
DoC_SelectChip(docptr, mychip->chip);
@@ -688,35 +631,43 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *re
}
this->curfloor = mychip->floor;
this->curchip = mychip->chip;
-
-
-
+
+ /* FIXME: should we disable ECC engine in this way ?? */
+ /* disable the ECC engine, FIXME: is this correct ?? */
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
+
+ /* issue the Read2 command to read the Spare Data Area.
+ Polling the Flash Ready bit after issue 3 bytes address in
+ Sequence Read Mode, see Software Requirement 11.4 item 1.*/
DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
- DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0);
-
- for (i=0; i<len; i++)
- buf[i] = ReadDOC(docptr, 2k_CDSN_IO);
-
+ DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0x00);
+ DoC_WaitReady(docptr);
+
+ /* Read the data out via the internal pipeline through CDSN IO register,
+ see Pipelined Read Operations 11.3 */
+ dummy = ReadDOC(docptr, ReadPipeInit);
+ for (i = 0; i < len-1; i++) {
+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
+ }
+ buf[i] = ReadDOC(docptr, LastDataRead);
+
*retlen = len;
- return 0;
+ return 0;
}
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, const u_char *buf)
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+ size_t *retlen, const u_char *buf)
{
- struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
int i;
- unsigned long docptr;
- struct Nand *mychip;
-
- // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
- // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
+ volatile char dummy;
+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
- docptr = this->virtadr;
-
- mychip = &this->chips[ofs >> this->chipshift];
-
- if (this->curfloor != mychip->floor) {
+ /* Find the chip which is to be used and select it */
+ if (this->curfloor != mychip->floor) {
DoC_SelectFloor(docptr, mychip->floor);
DoC_SelectChip(docptr, mychip->chip);
}
@@ -725,49 +676,63 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *r
}
this->curfloor = mychip->floor;
this->curchip = mychip->chip;
-
- DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
- DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
- DoC_Command(docptr, NAND_CMD_SEQIN, 0);
- DoC_Address(docptr, 3, ofs, 0, 0);
-
- for (i=0; i<len; i++)
- WriteDOC(buf[i], docptr, 2k_CDSN_IO);
+ /* FIXME: should we disable ECC engine in this way ?? */
+ /* disable the ECC engine, FIXME: is this correct ?? */
+ WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
+ WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
- DoC_Command(docptr, NAND_CMD_PAGEPROG, 0);
- DoC_Command(docptr, NAND_CMD_STATUS, 0);
- /* DoC_WaitReady() is implicit in DoC_Command */
+ /* Reset the chip, see Software Requirement 11.4 item 1. */
+ DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
+ DoC_WaitReady(docptr);
+ /* issue the Read2 command to read the Spare Data Area. */
+ DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
- if (ReadDOC(docptr, 2k_CDSN_IO) & 1) {
+ /* issue the Serial Data In command to initial the Page Program process */
+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
+ DoC_Address(docptr, 3, ofs, 0x00, 0x00);
+
+ /* Write the data via the internal pipeline through CDSN IO register,
+ see Pipelined Write Operations 11.2 */
+ for (i = 0; i < len; i++)
+ WriteDOC(buf[i], docptr, Mil_CDSN_IO);
+ WriteDOC(0x00, docptr, WritePipeTerm);
+
+ /* Commit the Page Program command and wait for ready
+ see Software Requirement 11.4 item 1.*/
+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
+ DoC_WaitReady(docptr);
+
+ /* Read the status of the flash device through CDSN Slow IO register
+ see Software Requirement 11.4 item 5.*/
+ DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(docptr, 2);
+ if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
printk("Error programming oob data\n");
- /* There was an error */
*retlen = 0;
return -EIO;
}
*retlen = len;
- return 0;
+ return 0;
}
-
int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
{
+ volatile char dummy;
struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
unsigned long ofs = instr->addr;
unsigned long len = instr->len;
- unsigned long docptr;
- struct Nand *mychip;
-
- if(len != mtd->erasesize)
- printk(KERN_WARNING "Erase not right size (%lx != %lx)n", len, mtd->erasesize);
-
+ unsigned long docptr = this->virtadr;
+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
- docptr = this->virtadr;
-
- mychip = &this->chips[ofs >> this->chipshift];
-
+ if (len != mtd->erasesize)
+ printk(KERN_WARNING "Erase not right size (%lx != %lx)n",
+ len, mtd->erasesize);
+
+ /* Find the chip which is to be used and select it */
if (this->curfloor != mychip->floor) {
DoC_SelectFloor(docptr, mychip->floor);
DoC_SelectChip(docptr, mychip->chip);
@@ -780,32 +745,35 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
instr->state = MTD_ERASE_PENDING;
- DoC_Command(docptr, NAND_CMD_ERASE1, 0);
- DoC_Address(docptr, 2, ofs, 0, 0);
- DoC_Command(docptr, NAND_CMD_ERASE2, 0);
+ /* issue the Erase Setup command */
+ DoC_Command(docptr, NAND_CMD_ERASE1, 0x00);
+ DoC_Address(docptr, 2, ofs, 0x00, 0x00);
+
+ /* Commit the Erase Start command and wait for ready
+ see Software Requirement 11.4 item 1.*/
+ DoC_Command(docptr, NAND_CMD_ERASE2, 0x00);
+ DoC_WaitReady(docptr);
instr->state = MTD_ERASING;
+ /* Read the status of the flash device through CDSN Slow IO register
+ see Software Requirement 11.4 item 5.*/
DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
-
- if (ReadDOC(docptr, 2k_CDSN_IO) & 1) {
- printk("Error writing\n");
+ dummy = ReadDOC(docptr, CDSNSlowIO);
+ DoC_Delay(docptr, 2);
+ if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
+ printk("Error Erasing\n");
/* There was an error */
instr->state = MTD_ERASE_FAILED;
- }
- else
+ } else
instr->state = MTD_ERASE_DONE;
if (instr->callback)
instr->callback(instr);
-
+
return 0;
}
-
-
-#endif
-
/****************************************************************************
*
* Module stuff
diff --git a/drivers/mtd/docprobe.c b/drivers/mtd/docprobe.c
index 5feb64901..7ab0a2d74 100644
--- a/drivers/mtd/docprobe.c
+++ b/drivers/mtd/docprobe.c
@@ -3,7 +3,7 @@
/* Probe routines common to all DoC devices */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: docprobe.c,v 1.8 2000/06/26 20:40:53 dwmw2 Exp $ */
+/* $Id: docprobe.c,v 1.10 2000/07/13 14:23:20 dwmw2 Exp $ */
@@ -206,7 +206,7 @@ static void DoC_Probe(unsigned long physadr)
case DOC_ChipID_DocMil:
name="Millennium";
#ifdef CONFIG_MTD_DOC2001
- initroutine = &DocMil_init;
+ initroutine = &DoCMil_init;
#elif CONFIG_MODULES
initroutinedynamic=1;
initroutine = (void *)get_module_symbol(NULL, "DoCMil_init");
@@ -252,7 +252,7 @@ int __init init_doc(void)
printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n");
#ifdef PRERELEASE
- printk(KERN_INFO "$Id: docprobe.c,v 1.8 2000/06/26 20:40:53 dwmw2 Exp $\n");
+ printk(KERN_INFO "$Id: docprobe.c,v 1.10 2000/07/13 14:23:20 dwmw2 Exp $\n");
#endif
for (i=0; doc_locations[i]; i++) {
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index a69ec9e65..d94d86ff7 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,7 +1,7 @@
/*
* Direct MTD block device access
*
- * $Id: mtdblock.c,v 1.16 2000/06/23 09:34:58 dwmw2 Exp $
+ * $Id: mtdblock.c,v 1.17 2000/07/13 14:25:54 dwmw2 Exp $
*/
#ifdef MTDBLOCK_DEBUG
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index d0e79a431..11413556f 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -63,21 +63,16 @@ static int mtd_open(struct inode *inode, struct file *file)
if ((file->f_mode & 2) && (minor & 1))
return -EACCES;
- MOD_INC_USE_COUNT;
-
mtd = get_mtd_device(NULL, devnum);
- if (!mtd) {
- MOD_DEC_USE_COUNT;
+ if (!mtd)
return -ENODEV;
- }
file->private_data = mtd;
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
- MOD_DEC_USE_COUNT;
return -EACCES;
}
@@ -100,7 +95,6 @@ static release_t mtd_close(struct inode *inode,
put_mtd_device(mtd);
- MOD_DEC_USE_COUNT;
release_return(0);
} /* mtd_close */
@@ -362,7 +356,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
} /* memory_ioctl */
static struct file_operations mtd_fops = {
-
+ owner: THIS_MODULE,
llseek: mtd_lseek, /* lseek */
read: mtd_read, /* read */
write: mtd_write, /* write */
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 7403b6b94..b3f0157eb 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
/*
- * $Id: mtdcore.c,v 1.8 2000/06/27 13:40:05 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.13 2000/07/13 14:27:37 dwmw2 Exp $
*
* Core registration and callback routines for MTD
* drivers and users.
@@ -44,9 +44,18 @@ extern int init_doc1000(void);
#ifdef CONFIG_MTD_DOCPROBE
extern int init_doc(void);
#endif
+#ifdef CONFIG_MTD_PHYSMAP
+extern int init_physmap(void);
+#endif
+#ifdef CONFIG_MTD_RPXLITE
+extern int init_rpxlite(void);
+#endif
#ifdef CONFIG_MTD_OCTAGON
extern int init_octagon5066(void);
#endif
+#ifdef CONFIG_MTD_PNC2000
+extern int init_pnc2000(void);
+#endif
#ifdef CONFIG_MTD_VMAX
extern int init_vmax301(void);
#endif
@@ -76,11 +85,18 @@ extern int init_mtdchar(void);
static DECLARE_MUTEX(mtd_table_mutex);
-
static struct mtd_info *mtd_table[MAX_MTD_DEVICES];
-
static struct mtd_notifier *mtd_notifiers = NULL;
+/**
+ * add_mtd_device - register an MTD device
+ * @mtd: pointer to new MTD device info structure
+ *
+ * Add a device to the list of MTD devices present in the system, and
+ * notify each currently active MTD 'user' of its arrival. Returns
+ * zero on success or 1 on failure, which currently will only happen
+ * if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
+ */
int add_mtd_device(struct mtd_info *mtd)
{
@@ -109,6 +125,15 @@ int add_mtd_device(struct mtd_info *mtd)
return 1;
}
+/**
+ * del_mtd_device - unregister an MTD device
+ * @mtd: pointer to MTD device info structure
+ *
+ * Remove a device from the list of MTD devices present in the system,
+ * and notify each currently active MTD 'user' of its departure.
+ * Returns zero on success or 1 on failure, which currently will happen
+ * if the requested device does not appear to be present in the list.
+ */
int del_mtd_device (struct mtd_info *mtd)
{
@@ -137,7 +162,14 @@ int del_mtd_device (struct mtd_info *mtd)
return 1;
}
-
+/**
+ * register_mtd_user - register a 'user' of MTD devices.
+ * @new: pointer to notifier info structure
+ *
+ * Registers a pair of callbacks function to be called upon addition
+ * or removal of MTD devices. Causes the 'add' callback to be immediately
+ * invoked for each MTD device currently present in the system.
+ */
void register_mtd_user (struct mtd_notifier *new)
{
@@ -157,7 +189,15 @@ void register_mtd_user (struct mtd_notifier *new)
up(&mtd_table_mutex);
}
-
+/**
+ * register_mtd_user - unregister a 'user' of MTD devices.
+ * @new: pointer to notifier info structure
+ *
+ * Removes a callback function pair from the list of 'users' to be
+ * notified upon addition or removal of MTD devices. Causes the
+ * 'remove' callback to be immediately invoked for each MTD device
+ * currently present in the system.
+ */
int unregister_mtd_user (struct mtd_notifier *old)
{
@@ -187,13 +227,17 @@ int unregister_mtd_user (struct mtd_notifier *old)
}
-/* get_mtd_device():
- * Prepare to use an MTD device referenced either by number or address.
+/**
+ * __get_mtd_device - obtain a validated handle for an MTD device
+ * @mtd: last known address of the required MTD device
+ * @num: internal device number of the required MTD device
*
- * If <num> == -1, search the table for an MTD device located at <mtd>.
- * If <mtd> == NULL, return the MTD device with number <num>.
- * If both are set, return the MTD device with number <num> _only_ if it
- * is located at <mtd>.
+ * Given a number and NULL address, return the num'th entry in the device
+ * table, if any. Given an address and num == -1, search the device table
+ * for a device with that address and return if it's still present. Given
+ * both, return the num'th driver only if its address matches. Return NULL
+ * if not. get_mtd_device() increases the use count, but
+ * __get_mtd_device() doesn't - you should generally use get_mtd_device().
*/
struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num)
@@ -224,12 +268,45 @@ EXPORT_SYMBOL(register_mtd_user);
EXPORT_SYMBOL(unregister_mtd_user);
/*====================================================================*/
-/* /proc/mtd support */
+/* Power management code */
+
+#ifdef CONFIG_PM
+
+#include <linux/pm.h>
+
+static struct pm_dev *mtd_pm_dev = NULL;
+
+static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+ int ret = 0, i;
+
+ if (down_trylock(&mtd_table_mutex))
+ return -EAGAIN;
+ if (rqst == PM_SUSPEND) {
+ for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
+ if (mtd_table[i] && mtd_table[i]->suspend)
+ ret = mtd_table[i]->suspend(mtd_table[i]);
+ }
+ } else i = MAX_MTD_DEVICES-1;
+
+ if (rqst == PM_RESUME || ret) {
+ for ( ; i >= 0; i--) {
+ if (mtd_table[i] && mtd_table[i]->resume)
+ mtd_table[i]->resume(mtd_table[i]);
+ }
+ }
+ up(&mtd_table_mutex);
+ return ret;
+}
+#endif
+
+/*====================================================================*/
+/* Support for /proc/mtd */
#ifdef CONFIG_PROC_FS
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-struct proc_dir_entry *proc_mtd;
+static struct proc_dir_entry *proc_mtd;
#endif
static inline int mtd_proc_info (char *buf, int i)
@@ -292,10 +369,10 @@ struct proc_dir_entry mtd_proc_entry = {
};
#endif
-#endif
+#endif /* CONFIG_PROC_FS */
/*====================================================================*/
-
+/* Init code */
#if LINUX_VERSION_CODE < 0x20300
@@ -315,9 +392,18 @@ static inline void init_others(void)
* Theoretically all other DiskOnChip
* devices too. */
#endif
+#ifdef CONFIG_MTD_PHYSMAP
+ init_physmap();
+#endif
+#ifdef CONFIG_MTD_RPXLITE
+ init_rpxlite();
+#endif
#ifdef CONFIG_MTD_OCTAGON
init_octagon5066();
#endif
+#ifdef CONFIG_MTD_PNC2000
+ init_pnc2000();
+#endif
#ifdef CONFIG_MTD_VMAX
init_vmax301();
#endif
@@ -374,13 +460,21 @@ mod_init_t init_mtd(void)
#if LINUX_VERSION_CODE < 0x20300
init_others();
#endif
-
+#ifdef CONFIG_PM
+ mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
+#endif
return 0;
}
mod_exit_t cleanup_mtd(void)
{
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
+#ifdef CONFIG_PM
+ if (mtd_pm_dev) {
+ pm_unregister(mtd_pm_dev);
+ mtd_pm_dev = NULL;
+ }
+#endif
#ifdef CONFIG_PROC_FS
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
if (proc_mtd)
diff --git a/drivers/mtd/mtdram.c b/drivers/mtd/mtdram.c
index 674435272..33f3a8116 100644
--- a/drivers/mtd/mtdram.c
+++ b/drivers/mtd/mtdram.c
@@ -1,6 +1,6 @@
/*
* mtdram - a test mtd device
- * $Id: mtdram.c,v 1.13 2000/07/03 10:01:38 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.15 2000/07/13 12:40:46 scote1 Exp $
* Author: Alexander Larsson <alex@cendio.se>
*
* Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
@@ -17,8 +17,8 @@
#include <linux/mtd/mtd.h>
-#define MTDRAM_TOTAL_SIZE 1024*1024*8
-#define MTDRAM_ERASE_SIZE 4*1024
+#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
+#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
// We could store these in the mtd structure, but we only support 1 device..
diff --git a/drivers/mtd/nftl.c b/drivers/mtd/nftl.c
index 182ec5a96..e7040863f 100644
--- a/drivers/mtd/nftl.c
+++ b/drivers/mtd/nftl.c
@@ -2,7 +2,7 @@
/* Linux driver for NAND Flash Translation Layer */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@infradead.org> */
-/* $Id: nftl.c,v 1.35 2000/07/06 14:35:01 dwmw2 Exp $ */
+/* $Id: nftl.c,v 1.36 2000/07/13 14:14:20 dwmw2 Exp $ */
/*
The contents of this file are distributed under the GNU Public
@@ -1293,7 +1293,7 @@ int __init init_nftl(void)
printk(KERN_NOTICE "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n");
#ifdef PRERELEASE
- printk(KERN_INFO"$Id: nftl.c,v 1.35 2000/07/06 14:35:01 dwmw2 Exp $\n");
+ printk(KERN_INFO"$Id: nftl.c,v 1.36 2000/07/13 14:14:20 dwmw2 Exp $\n");
#endif
if (register_blkdev(NFTL_MAJOR, "nftl", &nftl_fops)){
diff --git a/drivers/mtd/nora.c b/drivers/mtd/nora.c
index a92e47734..9304d7e62 100644
--- a/drivers/mtd/nora.c
+++ b/drivers/mtd/nora.c
@@ -1,5 +1,5 @@
/*
- * $Id: nora.c,v 1.11 2000/07/04 16:42:50 dwmw2 Exp $
+ * $Id: nora.c,v 1.12 2000/07/13 10:32:33 dwmw2 Exp $
*
* This is so simple I love it.
*/
@@ -125,7 +125,7 @@ static struct mtd_info nora_mtds[4] = { /* boot, kernel, ramdisk, fs */
{
type: MTD_NORFLASH,
flags: MTD_CAP_NORFLASH,
- size: 0x1a0000,
+ size: 0x0a0000,
erasesize: 0x20000,
name: "NORA kernel",
module: THIS_MODULE,
@@ -140,9 +140,9 @@ static struct mtd_info nora_mtds[4] = { /* boot, kernel, ramdisk, fs */
{
type: MTD_NORFLASH,
flags: MTD_CAP_NORFLASH,
- size: 0xe00000,
+ size: 0xf00000,
erasesize: 0x20000,
- name: "NORA ramdisk",
+ name: "NORA root filesystem",
module: THIS_MODULE,
erase: nora_mtd_erase,
read: nora_mtd_read,
@@ -150,14 +150,14 @@ static struct mtd_info nora_mtds[4] = { /* boot, kernel, ramdisk, fs */
suspend: nora_mtd_suspend,
resume: nora_mtd_resume,
sync: nora_mtd_sync,
- priv: (void *)0x200000
+ priv: (void *)0x100000
},
{
type: MTD_NORFLASH,
flags: MTD_CAP_NORFLASH,
size: 0x1000000,
erasesize: 0x20000,
- name: "NORA filesystem",
+ name: "NORA main filesystem",
module: THIS_MODULE,
erase: nora_mtd_erase,
read: nora_mtd_read,
diff --git a/drivers/mtd/octagon-5066.c b/drivers/mtd/octagon-5066.c
index 167e0da13..b184cd0e7 100644
--- a/drivers/mtd/octagon-5066.c
+++ b/drivers/mtd/octagon-5066.c
@@ -1,4 +1,4 @@
-// $Id: octagon-5066.c,v 1.9 2000/07/03 10:01:38 dwmw2 Exp $
+// $Id: octagon-5066.c,v 1.10 2000/07/13 14:04:23 dwmw2 Exp $
/* ######################################################################
Octagon 5066 MTD Driver.
@@ -56,8 +56,8 @@ static inline void oct5066_page(struct map_info *map, unsigned long ofs)
{
__u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
- if (page_n_dev != byte);
- __oct5066_page(map, byte);
+ if (page_n_dev != byte)
+ __oct5066_page(map, byte);
}
diff --git a/drivers/mtd/pmc551.c b/drivers/mtd/pmc551.c
index 98d5c3069..fdc80cbcf 100644
--- a/drivers/mtd/pmc551.c
+++ b/drivers/mtd/pmc551.c
@@ -1,5 +1,5 @@
/*
- * $Id: pmc551.c,v 1.7 2000/07/03 10:01:38 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.8 2000/07/14 07:53:31 dwmw2 Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
@@ -53,6 +53,7 @@
* hang w/ a reboot beeing the only chance at recover.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/uaccess.h>
@@ -343,7 +344,7 @@ out:
*/
static u32 fixup_pmc551 (struct pci_dev *dev)
{
-#ifdef PMC551_DRAM_BUG
+#ifdef CONFIG_MTD_PMC551_BUGFIX
u32 dram_data;
#endif
u32 size, dcmd;
@@ -362,7 +363,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
* row mux values. We fix them here, but this will break other
* memory configurations.
*/
-#ifdef PMC551_DRAM_BUG
+#ifdef CONFIG_MTD_PMC551_BUGFIX
pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
@@ -386,7 +387,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
-#endif /* PMC551_DRAM_BUG */
+#endif /* CONFIG_MTD_PMC551_BUGFIX */
/*
* Oops .. something went wrong
@@ -550,7 +551,7 @@ int __init init_pmc551(void)
printk(KERN_NOTICE "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n");
- printk(KERN_INFO "$Id: pmc551.c,v 1.7 2000/07/03 10:01:38 dwmw2 Exp $\n");
+ printk(KERN_INFO "$Id: pmc551.c,v 1.8 2000/07/14 07:53:31 dwmw2 Exp $\n");
if(!pci_present()) {
printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
diff --git a/drivers/mtd/pnc2000.c b/drivers/mtd/pnc2000.c
new file mode 100644
index 000000000..4e4b052a7
--- /dev/null
+++ b/drivers/mtd/pnc2000.c
@@ -0,0 +1,210 @@
+/*
+ * pnc2000.c - mapper for Photron PNC-2000 board.
+ *
+ * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
+ *
+ * This code is GPL
+ *
+ * $Id: pnc2000.c,v 1.1 2000/07/12 09:34:32 dwmw2 Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+
+#define WINDOW_ADDR 0xbf000000
+#define WINDOW_SIZE 0x00400000
+
+/*
+ * MAP DRIVER STUFF
+ */
+
+__u8 pnc_read8(struct map_info *map, unsigned long ofs)
+{
+ return *(__u8 *)(WINDOW_ADDR + ofs);
+}
+
+__u16 pnc_read16(struct map_info *map, unsigned long ofs)
+{
+ return *(__u16 *)(WINDOW_ADDR + ofs);
+}
+
+__u32 pnc_read32(struct map_info *map, unsigned long ofs)
+{
+ return *(volatile unsigned int *)(WINDOW_ADDR + ofs);
+}
+
+void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+ memcpy(to, (void *)(WINDOW_ADDR + from), len);
+}
+
+void pnc_write8(struct map_info *map, __u8 d, unsigned long adr)
+{
+ *(__u8 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_write16(struct map_info *map, __u16 d, unsigned long adr)
+{
+ *(__u16 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_write32(struct map_info *map, __u32 d, unsigned long adr)
+{
+ *(__u32 *)(WINDOW_ADDR + adr) = d;
+}
+
+void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+ memcpy((void *)(WINDOW_ADDR + to), from, len);
+}
+
+struct map_info pnc_map = {
+ "PNC-2000",
+ WINDOW_SIZE,
+ 4,
+ pnc_read8,
+ pnc_read16,
+ pnc_read32,
+ pnc_copy_from,
+ pnc_write8,
+ pnc_write16,
+ pnc_write32,
+ pnc_copy_to,
+ 0,
+ 0
+};
+
+
+/*
+ * MTD 'PARTITIONING' STUFF
+ */
+
+/*
+ * This is the _real_ MTD device for which all the others are just
+ * auto-relocating aliases.
+ */
+static struct mtd_info *mymtd;
+
+/*
+ * MTD methods which simply translate the effective address and pass through
+ * to the _real_ device.
+ */
+
+static int pnc_mtd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ return mymtd->read(mymtd, from + (unsigned long)mtd->priv, len, retlen, buf);
+}
+
+static int pnc_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
+{
+ return mymtd->write(mymtd, to + (unsigned long)mtd->priv, len, retlen, buf);
+}
+
+static int pnc_mtd_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+ instr->addr += (unsigned long)mtd->priv;
+ return mymtd->erase(mymtd, instr);
+}
+
+static void pnc_mtd_sync (struct mtd_info *mtd)
+{
+ mymtd->sync(mymtd);
+}
+
+static int pnc_mtd_suspend (struct mtd_info *mtd)
+{
+ return mymtd->suspend(mymtd);
+}
+
+static void pnc_mtd_resume (struct mtd_info *mtd)
+{
+ mymtd->resume(mymtd);
+}
+
+
+static struct mtd_info pnc_mtds[3] = { /* boot, kernel, fs */
+ {
+ type: MTD_NORFLASH,
+ flags: MTD_CAP_NORFLASH,
+ size: 0x20000,
+ erasesize: 0x20000,
+ name: "PNC-2000 boot firmware",
+ module: THIS_MODULE,
+ erase: pnc_mtd_erase,
+ read: pnc_mtd_read,
+ write: pnc_mtd_write,
+ suspend: pnc_mtd_suspend,
+ resume: pnc_mtd_resume,
+ sync: pnc_mtd_sync,
+ priv: (void *)0
+ },
+ {
+ type: MTD_NORFLASH,
+ flags: MTD_CAP_NORFLASH,
+ size: 0x1a0000,
+ erasesize: 0x20000,
+ name: "PNC-2000 kernel",
+ module: THIS_MODULE,
+ erase: pnc_mtd_erase,
+ read: pnc_mtd_read,
+ write: pnc_mtd_write,
+ suspend: pnc_mtd_suspend,
+ resume: pnc_mtd_resume,
+ sync: pnc_mtd_sync,
+ priv: (void *)0x20000
+ },
+ {
+ type: MTD_NORFLASH,
+ flags: MTD_CAP_NORFLASH,
+ size: 0x240000,
+ erasesize: 0x20000,
+ name: "PNC-2000 filesystem",
+ module: THIS_MODULE,
+ erase: pnc_mtd_erase,
+ read: pnc_mtd_read,
+ write: pnc_mtd_write,
+ suspend: pnc_mtd_suspend,
+ resume: pnc_mtd_resume,
+ sync: pnc_mtd_sync,
+ priv: (void *)0x1c0000
+ }
+};
+
+#if LINUX_VERSION_CODE < 0x20300
+#ifdef MODULE
+#define init_pnc init_module
+#define cleanup_pnc cleanup_module
+#endif
+#endif
+
+int __init init_pnc(void)
+{
+ printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+
+ mymtd = do_cfi_probe(&pnc_map);
+ if (mymtd) {
+ mymtd->module = THIS_MODULE;
+
+ add_mtd_device(&pnc_mtds[0]); /* boot */
+ add_mtd_device(&pnc_mtds[1]); /* kernel */
+ add_mtd_device(&pnc_mtds[2]); /* file system */
+ return 0;
+ }
+
+ return -ENXIO;
+}
+
+static void __exit cleanup_pnc(void)
+{
+ if (mymtd) {
+ del_mtd_device(&pnc_mtds[2]);
+ del_mtd_device(&pnc_mtds[1]);
+ del_mtd_device(&pnc_mtds[0]);
+ map_destroy(mymtd);
+ }
+}
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index b0d8e73d4..275ef3296 100644
--- a/drivers/net/atari_bionet.c
+++ b/drivers/net/atari_bionet.c
@@ -158,7 +158,7 @@ static int bionet_close(struct net_device *dev);
static struct net_device_stats *net_get_stats(struct net_device *dev);
static void bionet_tick(unsigned long);
-static struct timer_list bionet_timer = { NULL, NULL, 0, 0, bionet_tick };
+static struct timer_list bionet_timer = { function: bionet_tick };
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index f9b1eef79..6aeb737d5 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -168,7 +168,7 @@ static void pamsnet_tick(unsigned long);
static void pamsnet_intr(int irq, void *data, struct pt_regs *fp);
-static struct timer_list pamsnet_timer = { NULL, NULL, 0, 0, pamsnet_tick };
+static struct timer_list pamsnet_timer = { function: amsnet_tick };
#define STRAM_ADDR(a) (((a) & 0xff000000) == 0)
diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c
index e136e0132..b749908bd 100644
--- a/drivers/net/de4x5.c
+++ b/drivers/net/de4x5.c
@@ -3271,6 +3271,7 @@ srom_map_media(struct net_device *dev)
case ANS:
lp->media = ANS;
+ lp->fdx = lp->params.fdx;
break;
default:
diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c
index f8075373e..46f37e946 100644
--- a/drivers/net/pcmcia/xircom_tulip_cb.c
+++ b/drivers/net/pcmcia/xircom_tulip_cb.c
@@ -3010,7 +3010,8 @@ static void set_rx_mode(struct net_device *dev)
/* Same setup recently queued, we need not add it. */
} else {
unsigned long flags;
- unsigned int entry, dummy = -1;
+ unsigned int entry;
+ int dummy = -1;
save_flags(flags); cli();
entry = tp->cur_tx++ % TX_RING_SIZE;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index e43e3b394..f59653eef 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -41,6 +41,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <net/slhc_vj.h>
#include <asm/atomic.h>
@@ -319,6 +320,7 @@ static int ppp_release(struct inode *inode, struct file *file)
{
struct ppp_file *pf = (struct ppp_file *) file->private_data;
+ lock_kernel();
if (pf != 0) {
file->private_data = 0;
if (atomic_dec_and_test(&pf->refcnt)) {
@@ -332,6 +334,7 @@ static int ppp_release(struct inode *inode, struct file *file)
}
}
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c
index 1a6da6e79..8ecc46db2 100644
--- a/drivers/net/sk_g16.c
+++ b/drivers/net/sk_g16.c
@@ -632,6 +632,8 @@ static int __init SK_init_module (void)
if (!SK_dev)
return -ENOMEM;
+ SK_dev->base_addr = io;
+
rc = SK_init (SK_dev);
if (rc) {
unregister_netdev (SK_dev);
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 9079f8113..4f6252383 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -19,8 +19,6 @@
*/
-static const char version[] = "Linux Tulip driver version 0.9.7 (June 17, 2000)\n";
-
#include <linux/module.h>
#include "tulip.h"
#include <linux/pci.h>
@@ -29,6 +27,9 @@ static const char version[] = "Linux Tulip driver version 0.9.7 (June 17, 2000)\
#include <linux/delay.h>
#include <asm/unaligned.h>
+static char version[] __devinitdata =
+ "Linux Tulip driver version 0.9.8 (July 13, 2000)\n";
+
/* A few user-configurable values. */
@@ -948,7 +949,8 @@ static void set_rx_mode(struct net_device *dev)
if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
/* Same setup recently queued, we need not add it. */
} else {
- unsigned int entry, dummy = -1;
+ unsigned int entry;
+ int dummy = -1;
/* Now add this frame to the Tx list. */
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index d45f0ccfd..371153a47 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -175,6 +175,7 @@ ifeq ($(CONFIG_SDLA),y)
else
ifeq ($(CONFIG_SDLA),m)
M_OBJS += sdla.o
+ endif
endif
ifeq ($(CONFIG_VENDOR_SANGOMA),y)
@@ -194,8 +195,6 @@ ifeq ($(CONFIG_VENDOR_SANGOMA),y)
endif
endif
-endif
-
ifeq ($(CONFIG_VENDOR_SANGOMA),m)
MX_OBJS += sdladrv.o
M_OBJS += wanpipe.o
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index dc0b212f5..be015f195 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -93,6 +93,7 @@
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#undef COSA_SLOW_IO /* for testing purposes only */
#undef REALLY_SLOW_IO
@@ -977,13 +978,16 @@ static int cosa_open(struct inode *inode, struct file *file)
static int cosa_release(struct inode *inode, struct file *file)
{
struct channel_data *channel = (struct channel_data *)file->private_data;
- struct cosa_data *cosa = channel->cosa;
+ struct cosa_data *cosa;
unsigned long flags;
+ lock_kernel();
+ cosa = channel->cosa;
spin_lock_irqsave(&cosa->lock, flags);
cosa->usage--;
channel->usage--;
spin_unlock_irqrestore(&cosa->lock, flags);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index eff2559d0..207c9e21c 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -13,6 +13,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 2000/07/13 acme remove useless #ifdef MODULE and crap
+* #if KERNEL_VERSION > blah
* 2000/07/06 acme __exit at cyclomx_cleanup
* 2000/04/02 acme dprintk and cycx_debug
* module_init/module_exit
@@ -50,22 +52,18 @@
unsigned int cycx_debug = 0;
-#ifdef MODULE
MODULE_AUTHOR("Arnaldo Carvalho de Melo");
MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "cyclomx debug level");
-#endif
/* Defines & Macros */
#define DRV_VERSION 0 /* version number */
-#define DRV_RELEASE 8 /* release (minor version) number */
+#define DRV_RELEASE 9 /* release (minor version) number */
#define MAX_CARDS 1 /* max number of adapters */
-#ifndef CONFIG_CYCLOMX_CARDS /* configurable option */
#define CONFIG_CYCLOMX_CARDS 1
-#endif
/* Function Prototypes */
@@ -225,11 +223,7 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf)
card->hw.dpmsize = CYCX_WINDOWSIZE;
card->hw.fwid = CFID_X25_2X;
card->lock = SPIN_LOCK_UNLOCKED;
-#if LINUX_VERSION_CODE >= 0x020300
init_waitqueue_head(&card->wait_stats);
-#else
- card->wait_stats = NULL;
-#endif
err = cycx_setup(&card->hw, conf->data, conf->data_size);
if (err) {
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog
index d408c8796..34446db01 100644
--- a/drivers/parport/ChangeLog
+++ b/drivers/parport/ChangeLog
@@ -1,4 +1,40 @@
-2000-06-30 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c: Documentation for parport_{get,port}_port,
+ parport_find_{number,base}.
+
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c (parport_unregister_device): Remove unneeded locking
+ (test cad==dev).
+ (parport_claim): Likewise.
+ (parport_find_number): New function.
+
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c (parport_register_port): Hold the parportlist_lock while
+ looking for a free parport number.
+ (parport_register_driver): Make sure that attach can block.
+ (attach_driver_chain): Likewise.
+
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c (call_driver_chain): Do reference counting things.
+ (parport_get_port): New function.
+ (parport_put_port): New function.
+ (parport_register_port): Initialise reference count to zero.
+ (parport_unregister_port): Check reference count rather than
+ driver list to see if we can free the port.
+
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c: Clarifications in doc comments.
+
+2000-07-12 Tim Waugh <twaugh@redhat.com>
+
+ * share.c (parport_unregister_port): Fix typo in comment.
+
+2000-07-11 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
* parport_pc.c: Support for the full range of Timedia cards.
diff --git a/drivers/parport/init.c b/drivers/parport/init.c
index 416ca51cb..90280e371 100644
--- a/drivers/parport/init.c
+++ b/drivers/parport/init.c
@@ -180,6 +180,10 @@ EXPORT_SYMBOL(parport_unregister_driver);
EXPORT_SYMBOL(parport_register_device);
EXPORT_SYMBOL(parport_unregister_device);
EXPORT_SYMBOL(parport_enumerate);
+EXPORT_SYMBOL(parport_get_port);
+EXPORT_SYMBOL(parport_put_port);
+EXPORT_SYMBOL(parport_find_number);
+EXPORT_SYMBOL(parport_find_base);
EXPORT_SYMBOL(parport_negotiate);
EXPORT_SYMBOL(parport_write);
EXPORT_SYMBOL(parport_read);
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index 9fe0bb4be..92618e7b4 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -88,17 +88,57 @@ static struct parport_operations dead_ops = {
dead_read /* byte */
};
-static void call_driver_chain(int attach, struct parport *port)
+/* Call attach(port) for each registered driver. */
+static void attach_driver_chain(struct parport *port)
{
struct parport_driver *drv;
+ void (**attach) (struct parport *);
+ int count = 0, i;
+
+ /* This is complicated because attach() must be able to block,
+ * but we can't let it do that while we're holding a
+ * spinlock. */
spin_lock (&driverlist_lock);
- for (drv = driver_chain; drv; drv = drv->next) {
- if (attach)
- drv->attach (port);
- else
- drv->detach (port);
+ for (drv = driver_chain; drv; drv = drv->next)
+ count++;
+ spin_unlock (&driverlist_lock);
+
+ /* Drivers can unregister here; that's okay. If they register
+ * they'll be given an attach during parport_register_driver,
+ * so that's okay too. The only worry is that someone might
+ * get given an attach twice if they registered just before
+ * this function gets called. */
+
+ /* Hmm, this could be fixed with a generation number..
+ * FIXME */
+
+ attach = kmalloc (sizeof (void(*)(struct parport *)) * count,
+ GFP_KERNEL);
+ if (!attach) {
+ printk (KERN_WARNING "parport: not enough memory to attach\n");
+ return;
}
+
+ spin_lock (&driverlist_lock);
+ for (i = 0, drv = driver_chain; drv && i < count; drv = drv->next)
+ attach[i++] = drv->attach;
+ spin_unlock (&driverlist_lock);
+
+ for (count = 0; count < i; count++)
+ (*attach[i]) (port);
+
+ kfree (attach);
+}
+
+/* Call detach(port) for each registered driver. */
+static void detach_driver_chain(struct parport *port)
+{
+ struct parport_driver *drv;
+
+ spin_lock (&driverlist_lock);
+ for (drv = driver_chain; drv; drv = drv->next)
+ drv->detach (port);
spin_unlock (&driverlist_lock);
}
@@ -121,27 +161,62 @@ static void get_lowlevel_driver (void)
* The @drv structure is allocated by the caller and must not be
* deallocated until after calling parport_unregister_driver().
*
+ * The driver's attach() function may block. The port that
+ * attach() is given will be valid for the duration of the
+ * callback, but if the driver wants to take a copy of the
+ * pointer it must call parport_get_port() to do so. Calling
+ * parport_register_device() on that port will do this for you.
+ *
+ * The driver's detach() function may not block. The port that
+ * detach() is given will be valid for the duration of the
+ * callback, but if the driver wants to take a copy of the
+ * pointer it must call parport_get_port() to do so.
+ *
* Returns 0 on success. Currently it always succeeds.
**/
int parport_register_driver (struct parport_driver *drv)
{
struct parport *port;
+ struct parport **ports;
+ int count = 0, i;
- spin_lock (&driverlist_lock);
- drv->next = driver_chain;
- driver_chain = drv;
- spin_unlock (&driverlist_lock);
+ if (!portlist)
+ get_lowlevel_driver ();
/* We have to take the portlist lock for this to be sure
* that port is valid for the duration of the callback. */
+
+ /* This is complicated by the fact that attach must be allowed
+ * to block, so we can't be holding any spinlocks when we call
+ * it. But we need to hold a spinlock to iterate over the
+ * list of ports.. */
+
spin_lock (&parportlist_lock);
for (port = portlist; port; port = port->next)
- drv->attach (port);
+ count++;
spin_unlock (&parportlist_lock);
- if (!portlist)
- get_lowlevel_driver ();
+ ports = kmalloc (sizeof (struct parport *) * count, GFP_KERNEL);
+ if (!ports)
+ printk (KERN_WARNING "parport: not enough memory to attach\n");
+ else {
+ spin_lock (&parportlist_lock);
+ for (i = 0, port = portlist; port && i < count;
+ port = port->next)
+ ports[i++] = port;
+ spin_unlock (&parportlist_lock);
+
+ for (count = 0; count < i; count++)
+ drv->attach (ports[count]);
+
+ kfree (ports);
+ }
+
+ spin_lock (&driverlist_lock);
+ drv->next = driver_chain;
+ driver_chain = drv;
+ spin_unlock (&driverlist_lock);
return 0;
}
@@ -162,6 +237,11 @@ int parport_register_driver (struct parport_driver *drv)
* If the caller's attach() function can block, it is their
* responsibility to make sure to wait for it to exit before
* unloading.
+ *
+ * All the driver's detach() calls are guaranteed to have
+ * finished by the time this function returns.
+ *
+ * The driver's detach() call is not allowed to block.
**/
void parport_unregister_driver (struct parport_driver *arg)
@@ -194,6 +274,57 @@ void parport_unregister_driver (struct parport_driver *arg)
}
}
+static void free_port (struct parport *port)
+{
+ int d;
+ for (d = 0; d < 5; d++) {
+ if (port->probe_info[d].class_name)
+ kfree (port->probe_info[d].class_name);
+ if (port->probe_info[d].mfr)
+ kfree (port->probe_info[d].mfr);
+ if (port->probe_info[d].model)
+ kfree (port->probe_info[d].model);
+ if (port->probe_info[d].cmdset)
+ kfree (port->probe_info[d].cmdset);
+ if (port->probe_info[d].description)
+ kfree (port->probe_info[d].description);
+ }
+
+ kfree(port->name);
+ kfree(port);
+}
+
+/**
+ * parport_get_port - increment a port's reference count
+ * @port: the port
+ *
+ * This ensure's that a struct parport pointer remains valid
+ * until the matching parport_put_port() call.
+ **/
+
+struct parport *parport_get_port (struct parport *port)
+{
+ atomic_inc (&port->ref_count);
+ return port;
+}
+
+/**
+ * parport_put_port - decrement a port's reference count
+ * @port: the port
+ *
+ * This should be called once for each call to parport_get_port(),
+ * once the port is no longer needed.
+ **/
+
+void parport_put_port (struct parport *port)
+{
+ if (atomic_dec_and_test (&port->ref_count))
+ /* Can destroy it now. */
+ free_port (port);
+
+ return;
+}
+
/**
* parport_enumerate - return a list of the system's parallel ports
*
@@ -260,6 +391,8 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
}
/* Search for the lowest free parport number. */
+
+ spin_lock_irq (&parportlist_lock);
for (portnum = 0; ; portnum++) {
struct parport *itr = portlist;
while (itr) {
@@ -274,6 +407,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
/* Got to the end of the list. */
break;
}
+ spin_unlock_irq (&parportlist_lock);
/* Init our structure */
memset(tmp, 0, sizeof(struct parport));
@@ -296,6 +430,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma,
tmp->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
init_MUTEX_LOCKED (&tmp->ieee1284.irq); /* actually a semaphore at 0 */
tmp->spintime = parport_default_spintime;
+ atomic_set (&tmp->ref_count, 1);
name = kmalloc(15, GFP_KERNEL);
if (!name) {
@@ -372,27 +507,7 @@ void parport_announce_port (struct parport *port)
#endif
/* Let drivers know that a new port has arrived. */
- call_driver_chain (1, port);
-}
-
-static void free_port (struct parport *port)
-{
- int d;
- for (d = 0; d < 5; d++) {
- if (port->probe_info[d].class_name)
- kfree (port->probe_info[d].class_name);
- if (port->probe_info[d].mfr)
- kfree (port->probe_info[d].mfr);
- if (port->probe_info[d].model)
- kfree (port->probe_info[d].model);
- if (port->probe_info[d].cmdset)
- kfree (port->probe_info[d].cmdset);
- if (port->probe_info[d].description)
- kfree (port->probe_info[d].description);
- }
-
- kfree(port->name);
- kfree(port);
+ attach_driver_chain (port);
}
/**
@@ -421,7 +536,7 @@ void parport_unregister_port(struct parport *port)
port->ops = &dead_ops;
/* Spread the word. */
- call_driver_chain (0, port);
+ detach_driver_chain (port);
#ifdef CONFIG_PARPORT_1284
/* Forget the IEEE1284.3 topology of the port. */
@@ -431,7 +546,7 @@ void parport_unregister_port(struct parport *port)
spin_lock(&parportlist_lock);
/* We are protected from other people changing the list, but
- * they can see see it (using parport_enumerate). So be
+ * they can still see it (using parport_enumerate). So be
* careful about the order of writes.. */
if (portlist == port) {
if ((portlist = port->next) == NULL)
@@ -449,8 +564,7 @@ void parport_unregister_port(struct parport *port)
spin_unlock(&parportlist_lock);
/* Yes, parport_enumerate _is_ unsafe. Don't use it. */
- if (!port->devices)
- free_port (port);
+ parport_put_port (port);
}
/**
@@ -552,6 +666,7 @@ parport_register_device(struct parport *port, const char *name,
parport_register_device.. */
inc_parport_count();
port->ops->inc_use_count();
+ parport_get_port (port);
tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL);
if (tmp == NULL) {
@@ -623,6 +738,7 @@ parport_register_device(struct parport *port, const char *name,
out:
dec_parport_count();
port->ops->dec_use_count();
+ parport_put_port (port);
return NULL;
}
@@ -636,7 +752,6 @@ parport_register_device(struct parport *port, const char *name,
void parport_unregister_device(struct pardevice *dev)
{
struct parport *port;
- unsigned long flags;
#ifdef PARPORT_PARANOID
if (dev == NULL) {
@@ -649,14 +764,11 @@ void parport_unregister_device(struct pardevice *dev)
port = dev->port->physport;
- read_lock_irqsave (&port->cad_lock, flags);
if (port->cad == dev) {
- read_unlock_irqrestore (&port->cad_lock, flags);
printk(KERN_DEBUG "%s: %s forgot to release port\n",
port->name, dev->name);
parport_release (dev);
}
- read_unlock_irqrestore (&port->cad_lock, flags);
spin_lock(&port->pardevice_lock);
if (dev->next)
@@ -676,11 +788,7 @@ void parport_unregister_device(struct pardevice *dev)
dec_parport_count();
port->ops->dec_use_count();
-
- /* If this was the last device on a port that's already gone away,
- * free up the resources. */
- if (port->ops == &dead_ops && !port->devices)
- free_port (port);
+ parport_put_port (port);
/* Yes, that's right, someone _could_ still have a pointer to
* port, if they used parport_enumerate. That's why they
@@ -689,6 +797,56 @@ void parport_unregister_device(struct pardevice *dev)
}
/**
+ * parport_find_number - find a parallel port by number
+ * @number: parallel port number
+ *
+ * This returns the parallel port with the specified number, or
+ * %NULL if there is none.
+ *
+ * There is an implicit parport_get_port() done already; to throw
+ * away the reference to the port that parport_find_number()
+ * gives you, use parport_put_port().
+ */
+
+struct parport *parport_find_number (int number)
+{
+ struct parport *port, *result = NULL;
+ spin_lock (&parportlist_lock);
+ for (port = portlist; port; port = port->next)
+ if (port->number == number) {
+ result = parport_get_port (port);
+ break;
+ }
+ spin_unlock (&parportlist_lock);
+ return result;
+}
+
+/**
+ * parport_find_base - find a parallel port by base address
+ * @base: base I/O address
+ *
+ * This returns the parallel port with the specified base
+ * address, or %NULL if there is none.
+ *
+ * There is an implicit parport_get_port() done already; to throw
+ * away the reference to the port that parport_find_base()
+ * gives you, use parport_put_port().
+ */
+
+struct parport *parport_find_base (unsigned long base)
+{
+ struct parport *port, *result = NULL;
+ spin_lock (&parportlist_lock);
+ for (port = portlist; port; port = port->next)
+ if (port->base == base) {
+ result = parport_get_port (port);
+ break;
+ }
+ spin_unlock (&parportlist_lock);
+ return result;
+}
+
+/**
* parport_claim - claim access to a parallel port device
* @dev: pointer to structure representing a device on the port
*
@@ -706,14 +864,11 @@ int parport_claim(struct pardevice *dev)
struct parport *port = dev->port->physport;
unsigned long flags;
- read_lock_irqsave (&port->cad_lock, flags);
if (port->cad == dev) {
- read_unlock_irqrestore (&port->cad_lock, flags);
printk(KERN_INFO "%s: %s already owner\n",
dev->port->name,dev->name);
return 0;
}
- read_unlock_irqrestore (&port->cad_lock, flags);
/* Preempt any current device */
write_lock_irqsave (&port->cad_lock, flags);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 11e4330c5..f536e42cb 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -42,6 +42,7 @@
#include <linux/mm.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/ioctl.h>
#include <linux/proc_fs.h>
@@ -561,7 +562,6 @@ static int ds_open(struct inode *inode, struct file *file)
user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
if (!user) return -ENOMEM;
- MOD_INC_USE_COUNT;
user->event_tail = user->event_head = 0;
user->next = s->user;
user->user_magic = USER_MAGIC;
@@ -584,10 +584,11 @@ static int ds_release(struct inode *inode, struct file *file)
DEBUG(0, "ds_release(socket %d)\n", i);
if ((i >= sockets) || (sockets == 0))
return 0;
+ lock_kernel();
s = &socket_table[i];
user = file->private_data;
if (CHECK_USER(user))
- return 0;
+ goto out;
/* Unlink user data structure */
if ((file->f_flags & O_ACCMODE) != O_RDONLY)
@@ -596,12 +597,12 @@ static int ds_release(struct inode *inode, struct file *file)
for (link = &s->user; *link; link = &(*link)->next)
if (*link == user) break;
if (link == NULL)
- return 0;
+ goto out;
*link = user->next;
user->user_magic = 0;
kfree(user);
-
- MOD_DEC_USE_COUNT;
+out:
+ unlock_kernel();
return 0;
} /* ds_release */
@@ -854,12 +855,13 @@ static int ds_ioctl(struct inode * inode, struct file * file,
/*====================================================================*/
static struct file_operations ds_fops = {
- open: ds_open,
- release: ds_release,
- ioctl: ds_ioctl,
- read: ds_read,
- write: ds_write,
- poll: ds_poll,
+ owner: THIS_MODULE,
+ open: ds_open,
+ release: ds_release,
+ ioctl: ds_ioctl,
+ read: ds_read,
+ write: ds_write,
+ poll: ds_poll,
};
EXPORT_SYMBOL(register_pccard_driver);
diff --git a/drivers/pnp/isapnp_proc.c b/drivers/pnp/isapnp_proc.c
index 3472225b8..ee4c2aee3 100644
--- a/drivers/pnp/isapnp_proc.c
+++ b/drivers/pnp/isapnp_proc.c
@@ -187,10 +187,12 @@ static int isapnp_info_entry_release(struct inode *inode, struct file *file)
if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL)
return -EINVAL;
mode = file->f_flags & O_ACCMODE;
+ lock_kernel();
if (mode == O_WRONLY)
isapnp_info_write(buffer);
vfree(buffer->buffer);
kfree(buffer);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/audio/audio.c b/drivers/sbus/audio/audio.c
index be7e9de06..6ee5c6d3c 100644
--- a/drivers/sbus/audio/audio.c
+++ b/drivers/sbus/audio/audio.c
@@ -24,6 +24,7 @@
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/tqueue.h>
#include <linux/major.h>
@@ -1910,6 +1911,7 @@ static int sparcaudio_release(struct inode * inode, struct file * file)
struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
SPARCAUDIO_DEVICE_SHIFT)];
+ lock_kernel();
if (file->f_mode & FMODE_READ) {
/* Stop input */
drv->ops->stop_input(drv);
@@ -1951,11 +1953,13 @@ static int sparcaudio_release(struct inode * inode, struct file * file)
kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
wake_up_interruptible(&drv->open_wait);
+ unlock_kernel();
return 0;
}
static struct file_operations sparcaudio_fops = {
+ owner: THIS_MODULE,
llseek: sparcaudio_lseek,
read: sparcaudio_read,
write: sparcaudio_write,
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index ebe9928c2..56f9d38af 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -16,6 +16,7 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/major.h>
@@ -456,10 +457,13 @@ static int bpp_open(struct inode *inode, struct file *f)
static int bpp_release(struct inode *inode, struct file *f)
{
unsigned minor = MINOR(inode->i_rdev);
+
+ lock_kernel();
instances[minor].opened = 0;
if (instances[minor].mode != COMPATIBILITY)
terminate(minor);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 8bdee5e04..7a03036b6 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -13,6 +13,7 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -37,23 +38,28 @@ flash_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long addr;
unsigned long size;
+ lock_kernel();
if (flash.read_base == flash.write_base) {
addr = flash.read_base;
size = flash.read_size;
} else {
if ((vma->vm_flags & VM_READ) &&
- (vma->vm_flags & VM_WRITE))
+ (vma->vm_flags & VM_WRITE)) {
+ unlock_kernel();
return -EINVAL;
-
+ }
if (vma->vm_flags & VM_READ) {
addr = flash.read_base;
size = flash.read_size;
} else if (vma->vm_flags & VM_WRITE) {
addr = flash.write_base;
size = flash.write_size;
- } else
+ } else {
+ unlock_kernel();
return -ENXIO;
+ }
}
+ unlock_kernel();
if ((vma->vm_pgoff << PAGE_SHIFT) > size)
return -ENXIO;
@@ -121,7 +127,9 @@ flash_open(struct inode *inode, struct file *file)
static int
flash_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
flash.busy = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index b01f26969..f87850b2c 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -35,6 +35,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/string.h>
+#include <linux/smp_lock.h>
/*
* <linux/blk.h> is controlled from the outside with these definitions.
@@ -504,7 +505,9 @@ static int jsfd_open(struct inode *inode, struct file *file)
static int jsf_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
jsf0.busy = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c
index 93673e3b8..ecce4db4b 100644
--- a/drivers/sbus/char/pcikbd.c
+++ b/drivers/sbus/char/pcikbd.c
@@ -24,6 +24,7 @@
#include <linux/kbd_kern.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/ebus.h>
@@ -745,9 +746,10 @@ static int aux_release(struct inode * inode, struct file * file)
{
unsigned long flags;
+ lock_kernel();
aux_fasync(-1, file, 0);
if (--aux_count)
- return 0;
+ goto out;
spin_lock_irqsave(&pcikbd_lock, flags);
@@ -760,6 +762,8 @@ static int aux_release(struct inode * inode, struct file * file)
poll_aux_status();
spin_unlock_irqrestore(&pcikbd_lock, flags);
+out:
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index bda9e3a26..7a02f543f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -19,6 +19,7 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/mostek.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -129,7 +130,9 @@ static int rtc_open(struct inode *inode, struct file *file)
static int rtc_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
rtc_busy = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index 8004569ab..191194287 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/sysrq.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/kbio.h>
@@ -1527,16 +1528,15 @@ kbd_open (struct inode *i, struct file *f)
static int
kbd_close (struct inode *i, struct file *f)
{
- if (--kbd_active)
- return 0;
-
- if (kbd_redirected)
- kbd_table [kbd_redirected-1].kbdmode = VC_XLATE;
-
- kbd_redirected = 0;
- kbd_opened = 0;
-
- kbd_fasync (-1, f, 0);
+ lock_kernel();
+ if (!--kbd_active) {
+ if (kbd_redirected)
+ kbd_table [kbd_redirected-1].kbdmode = VC_XLATE;
+ kbd_redirected = 0;
+ kbd_opened = 0;
+ kbd_fasync (-1, f, 0);
+ }
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c
index 46d335c2a..b9dd25653 100644
--- a/drivers/sbus/char/sunmouse.c
+++ b/drivers/sbus/char/sunmouse.c
@@ -49,6 +49,7 @@
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -411,8 +412,10 @@ static int sun_mouse_fasync (int fd, struct file *filp, int on)
static int
sun_mouse_close(struct inode *inode, struct file *file)
{
+ lock_kernel();
sun_mouse_fasync (-1, file, 0);
sunmouse.active--;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index eed298c6e..7b7a59ea2 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -21,6 +21,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/fs.h>
+#include <linux/smp_lock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -203,16 +204,19 @@ static int vfc_open(struct inode *inode, struct file *file)
return 0;
}
-static void vfc_release(struct inode *inode,struct file *file)
+static int vfc_release(struct inode *inode,struct file *file)
{
struct vfc_dev *dev;
+ lock_kernel();
dev = vfc_get_dev_ptr(MINOR(inode->i_rdev));
- if (dev == NULL)
- return;
- if (!dev->busy)
- return;
+ if (!dev || !dev->busy) {
+ unlock_kernel();
+ return -EINVAL;
+ }
dev->busy = 0;
+ unlock_kernel();
+ return 0;
}
static int vfc_debug(struct vfc_dev *dev, int cmd, unsigned long arg)
@@ -606,10 +610,12 @@ static int vfc_mmap(struct inode *inode, struct file *file,
unsigned int map_size, ret, map_offset;
struct vfc_dev *dev;
+ lock_kernel();
dev = vfc_get_dev_ptr(MINOR(inode->i_rdev));
- if(dev == NULL)
+ if(dev == NULL) {
+ unlock_kernel();
return -ENODEV;
-
+ }
map_size = vma->vm_end - vma->vm_start;
if(map_size > sizeof(struct vfc_regs))
map_size = sizeof(struct vfc_regs);
@@ -619,6 +625,7 @@ static int vfc_mmap(struct inode *inode, struct file *file,
map_offset = (unsigned int) (long)dev->phys_regs;
ret = io_remap_page_range(vma->vm_start, map_offset, map_size,
vma->vm_page_prot, dev->which_io);
+ unlock_kernel();
if(ret)
return -EAGAIN;
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 518f1e26e..b4ebd88f3 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -48,7 +48,6 @@ static struct ctrl_inquiry {
} *fcs __initdata = { 0 };
static int fcscount __initdata = 0;
static atomic_t fcss __initdata = ATOMIC_INIT(0);
-static struct timer_list fc_timer __initdata = { function: NULL };
DECLARE_MUTEX_LOCKED(fc_sem);
static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
@@ -92,6 +91,7 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
int i, retry, nplutos;
fc_channel *fc;
Scsi_Device dev;
+ struct timer_list fc_timer = { function: pluto_detect_timeout };
tpnt->proc_name = "pluto";
fcscount = 0;
@@ -121,7 +121,6 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
memset (fcs, 0, sizeof (struct ctrl_inquiry) * fcscount);
memset (&dev, 0, sizeof(dev));
atomic_set (&fcss, fcscount);
- fc_timer.function = pluto_detect_timeout;
i = 0;
for_each_online_fc_channel(fc) {
@@ -192,7 +191,7 @@ int __init pluto_detect(Scsi_Host_Template *tpnt)
if (!atomic_read(&fcss))
break; /* All fc channels have answered us */
}
- del_timer(&fc_timer);
+ del_timer_sync(&fc_timer);
PLND(("Finished search\n"))
for (i = 0, nplutos = 0; i < fcscount; i++) {
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 056b2f1b5..fd705d425 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -138,6 +138,10 @@ static struct dev_info device_list[] =
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
{"TOSHIBA","CDROM","*", BLIST_ISROM},
{"MegaRAID", "LD", "*", BLIST_FORCELUN},
+ {"DGC", "RAID", "*", BLIST_SPARSELUN}, // Dell PV 650F (tgt @ LUN 0)
+ {"DGC", "DISK", "*", BLIST_SPARSELUN}, // Dell PV 650F (no tgt @ LUN 0)
+ {"DELL", "PV530F", "*", BLIST_SPARSELUN}, // Dell PV 530F
+ {"SONY", "TSL", "*", BLIST_FORCELUN}, // DDS3 & DDS4 autoloaders
/*
* Must be at end of list...
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4bfdc59f4..4ac3dbcfb 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -52,6 +52,7 @@
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -304,8 +305,6 @@ static int sg_open(struct inode * inode, struct file * filp)
if (sdp->device->host->hostt->module)
__MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
- if (sg_template.module)
- __MOD_INC_USE_COUNT(sg_template.module);
return 0;
}
@@ -315,8 +314,11 @@ static int sg_release(struct inode * inode, struct file * filp)
Sg_device * sdp;
Sg_fd * sfp;
- if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp)))
+ lock_kernel();
+ if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) {
+ unlock_kernel();
return -ENXIO;
+ }
SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
sg_fasync(-1, filp, 0); /* remove filp from async notification list */
sg_remove_sfp(sdp, sfp);
@@ -325,10 +327,9 @@ static int sg_release(struct inode * inode, struct file * filp)
if (sdp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
- if(sg_template.module)
- __MOD_DEC_USE_COUNT(sg_template.module);
sdp->exclude = 0;
wake_up_interruptible(&sdp->o_excl_wait);
+ unlock_kernel();
return 0;
}
@@ -1094,13 +1095,14 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
}
static struct file_operations sg_fops = {
- read: sg_read,
- write: sg_write,
- poll: sg_poll,
- ioctl: sg_ioctl,
- open: sg_open,
- release: sg_release,
- fasync: sg_fasync,
+ owner: THIS_MODULE,
+ read: sg_read,
+ write: sg_write,
+ poll: sg_poll,
+ ioctl: sg_ioctl,
+ open: sg_open,
+ release: sg_release,
+ fasync: sg_fasync,
};
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index a605233c0..2ac10c832 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -31,6 +31,7 @@
#include <linux/ioctl.h>
#include <linux/fcntl.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#include <asm/system.h>
@@ -620,8 +621,6 @@ static int scsi_tape_open(struct inode *inode, struct file *filp)
if (STp->device->host->hostt->module)
__MOD_INC_USE_COUNT(STp->device->host->hostt->module);
- if (st_template.module)
- __MOD_INC_USE_COUNT(st_template.module);
if (mode != STp->current_mode) {
DEBC(printk(ST_DEB_MSG "st%d: Mode change from %d to %d.\n",
@@ -859,8 +858,6 @@ static int scsi_tape_open(struct inode *inode, struct file *filp)
STp->in_use = 0;
if (STp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
- if (st_template.module)
- __MOD_DEC_USE_COUNT(st_template.module);
return retval;
}
@@ -995,6 +992,7 @@ static int scsi_tape_close(struct inode *inode, struct file *filp)
int dev;
dev = TAPE_NR(devt);
+ lock_kernel();
read_lock(&st_dev_arr_lock);
STp = scsi_tapes[dev];
read_unlock(&st_dev_arr_lock);
@@ -1010,8 +1008,7 @@ static int scsi_tape_close(struct inode *inode, struct file *filp)
STp->in_use = 0;
if (STp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(STp->device->host->hostt->module);
- if (st_template.module)
- __MOD_DEC_USE_COUNT(st_template.module);
+ unlock_kernel();
return result;
}
@@ -3428,6 +3425,7 @@ __setup("st=", st_setup);
static struct file_operations st_fops =
{
+ owner: THIS_MODULE,
read: st_read,
write: st_write,
ioctl: st_ioctl,
diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c
index a060e9895..62ca3c5e6 100644
--- a/drivers/sgi/char/graphics.c
+++ b/drivers/sgi/char/graphics.c
@@ -33,6 +33,7 @@
#include <linux/mman.h>
#include <linux/malloc.h>
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "gconsole.h"
#include "graphics.h"
@@ -194,6 +195,7 @@ sgi_graphics_close (struct inode *inode, struct file *file)
int board = GRAPHICS_CARD (inode->i_rdev);
/* Tell the rendering manager that one client is going away */
+ lock_kernel();
rrm_close (inode, file);
/* Was this file handle from the board owner?, clear it */
@@ -203,6 +205,7 @@ sgi_graphics_close (struct inode *inode, struct file *file)
(*cards [board].g_reset_console)();
enable_gconsole ();
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
index 03eab91e2..1438030b3 100644
--- a/drivers/sgi/char/shmiq.c
+++ b/drivers/sgi/char/shmiq.c
@@ -329,9 +329,12 @@ shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma)
size = vma->vm_end - vma->vm_start;
start = vma->vm_start;
+ lock_kernel();
mem = (unsigned long) shmiqs [minor].shmiq_vaddr = vmalloc_uncached (size);
- if (!mem)
+ if (!mem) {
+ unlock_kernel();
return -EINVAL;
+ }
/* Prevent the swapper from considering these pages for swap and touching them */
vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
@@ -345,6 +348,7 @@ shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma)
shmiqs [minor].tail = 0;
/* Init the shared memory input queue */
memset (shmiqs [minor].shmiq_vaddr, 0, size);
+ unlock_kernel();
return error;
}
diff --git a/drivers/sgi/char/streamable.c b/drivers/sgi/char/streamable.c
index 1f354d80f..1d2a65c2a 100644
--- a/drivers/sgi/char/streamable.c
+++ b/drivers/sgi/char/streamable.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/shmiq.h>
#include <asm/keyboard.h>
@@ -50,20 +51,6 @@ get_sioc (struct strioctl *sioc, unsigned long arg)
/* /dev/gfx device */
static int
-sgi_gfx_open (struct inode *inode, struct file *file)
-{
- printk ("GFX: Opened by %d\n", current->pid);
- return 0;
-}
-
-static int
-sgi_gfx_close (struct inode *inode, struct file *file)
-{
- printk ("GFX: Closed by %d\n", current->pid);
- return 0;
-}
-
-static int
sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
printk ("GFX: ioctl 0x%x %ld called\n", cmd, arg);
@@ -73,8 +60,6 @@ sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigne
struct file_operations sgi_gfx_fops = {
ioctl: sgi_gfx_ioctl,
- open: sgi_gfx_open,
- release: sgi_gfx_close,
};
static struct miscdevice dev_gfx = {
@@ -236,7 +221,9 @@ sgi_mouse_open (struct inode *inode, struct file *file)
static int
sgi_mouse_close (struct inode *inode, struct file *filp)
{
+ lock_kernel();
mouse_opened = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sgi/char/usema.c b/drivers/sgi/char/usema.c
index c9fbe87d4..4ae9d2e2b 100644
--- a/drivers/sgi/char/usema.c
+++ b/drivers/sgi/char/usema.c
@@ -163,17 +163,10 @@ sgi_usemaclone_open(struct inode *inode, struct file *filp)
return 0;
}
-static int
-sgi_usemaclone_release(struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
struct file_operations sgi_usemaclone_fops = {
poll: sgi_usemaclone_poll,
ioctl: sgi_usemaclone_ioctl,
open: sgi_usemaclone_open,
- release: sgi_usemaclone_release,
};
static struct miscdevice dev_usemaclone = {
diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c
index 3b5639054..cc55d508e 100644
--- a/drivers/sound/cmpci.c
+++ b/drivers/sound/cmpci.c
@@ -114,6 +114,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1397,29 +1398,35 @@ static int cm_mmap(struct file *file, struct vm_area_struct *vma)
{
struct cm_state *s = (struct cm_state *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(s, 1)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(s, 0)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
db->mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1771,6 +1778,7 @@ static int cm_release(struct inode *inode, struct file *file)
struct cm_state *s = (struct cm_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1785,6 +1793,7 @@ static int cm_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
@@ -2021,6 +2030,7 @@ static int cm_midi_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
__set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&s->midi.owait, &wait);
@@ -2058,6 +2068,7 @@ static int cm_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
@@ -2212,6 +2223,7 @@ static int cm_dmfm_release(struct inode *inode, struct file *file)
unsigned int regb;
VALIDATE_STATE(s);
+ lock_kernel();
down(&s->open_sem);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
@@ -2222,6 +2234,7 @@ static int cm_dmfm_release(struct inode *inode, struct file *file)
}
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/dmasound/dmasound_core.c b/drivers/sound/dmasound/dmasound_core.c
index da60c783b..1d8804b36 100644
--- a/drivers/sound/dmasound/dmasound_core.c
+++ b/drivers/sound/dmasound/dmasound_core.c
@@ -111,6 +111,7 @@
#include <linux/sound.h>
#include <linux/init.h>
#include <linux/soundcard.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -501,8 +502,10 @@ static int mixer_open(struct inode *inode, struct file *file)
static int mixer_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
mixer.busy = 0;
dmasound.mach.release();
+ unlock_kernel();
return 0;
}
static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
@@ -905,6 +908,7 @@ static int sq_release(struct inode *inode, struct file *file)
{
int rc = 0;
+ lock_kernel();
if (write_sq.busy)
rc = sq_fsync(file, file->f_dentry);
dmasound.soft = dmasound.dsp;
@@ -923,6 +927,7 @@ static int sq_release(struct inode *inode, struct file *file)
/* Wake up a process waiting for the queue being released.
* Note: There may be several processes waiting for a call
* to open() returning. */
+ unlock_kernel();
return rc;
}
@@ -1141,8 +1146,10 @@ static int state_open(struct inode *inode, struct file *file)
static int state_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
state.busy = 0;
dmasound.mach.release();
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/emu10k1/audio.c b/drivers/sound/emu10k1/audio.c
index 06f84dfc3..9e2ee24d1 100644
--- a/drivers/sound/emu10k1/audio.c
+++ b/drivers/sound/emu10k1/audio.c
@@ -36,6 +36,8 @@
#include "cardwi.h"
#include "recmgr.h"
#include "audio.h"
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
static void calculate_ofrag(struct woinst *);
static void calculate_ifrag(struct wiinst *);
@@ -890,6 +892,7 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
if (vma_get_pgoff(vma) != 0)
return -ENXIO;
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
struct woinst *woinst = wave_dev->woinst;
struct wave_out *wave_out;
@@ -907,6 +910,7 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
if (emu10k1_waveout_open(wave_dev) != CTSTATUS_SUCCESS) {
spin_unlock_irqrestore(&woinst->lock, flags);
ERROR();
+ unlock_kernel();
return -EINVAL;
}
@@ -921,12 +925,14 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
if (size > (PAGE_SIZE * wave_out->wavexferbuf->numpages)) {
spin_unlock_irqrestore(&woinst->lock, flags);
+ unlock_kernel();
return -EINVAL;
}
for (i = 0; i < wave_out->wavexferbuf->numpages; i++) {
if (remap_page_range(vma->vm_start + (i * PAGE_SIZE), virt_to_phys(wave_out->pagetable[i]), PAGE_SIZE, vma->vm_page_prot)) {
spin_unlock_irqrestore(&woinst->lock, flags);
+ unlock_kernel();
return -EAGAIN;
}
}
@@ -944,6 +950,7 @@ static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
wiinst->mapped = 1;
spin_unlock_irqrestore(&wiinst->lock, flags);
}
+ unlock_kernel();
return 0;
}
@@ -1098,9 +1105,11 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
static int emu10k1_audio_release(struct inode *inode, struct file *file)
{
struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
- struct emu10k1_card *card = wave_dev->card;
+ struct emu10k1_card *card;
unsigned long flags;
+ lock_kernel();
+ card = wave_dev->card;
DPF(2, "emu10k1_audio_release()\n");
if (file->f_mode & FMODE_WRITE) {
@@ -1171,6 +1180,7 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file)
kfree(wave_dev);
wake_up_interruptible(&card->open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/emu10k1/midi.c b/drivers/sound/emu10k1/midi.c
index 04b1424a8..d7e0a4a87 100644
--- a/drivers/sound/emu10k1/midi.c
+++ b/drivers/sound/emu10k1/midi.c
@@ -32,6 +32,8 @@
#define __NO_VERSION__
#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "hwaccess.h"
@@ -183,8 +185,10 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
static int emu10k1_midi_release(struct inode *inode, struct file *file)
{
struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
- struct emu10k1_card *card = midi_dev->card;
+ struct emu10k1_card *card;
+ lock_kernel();
+ card = midi_dev->card;
DPF(2, "emu10k1_midi_release()\n");
if (file->f_mode & FMODE_WRITE) {
@@ -227,6 +231,7 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file)
card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
up(&card->open_sem);
wake_up_interruptible(&card->open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c
index 47d1d875f..ae004f10f 100644
--- a/drivers/sound/es1370.c
+++ b/drivers/sound/es1370.c
@@ -149,6 +149,7 @@
#include <linux/malloc.h>
#include <linux/soundcard.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/init.h>
@@ -1306,24 +1307,38 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
- if ((ret = prog_dmabuf_dac2(s)) != 0)
+ if ((ret = prog_dmabuf_dac2(s)) != 0) {
+ unlock_kernel();
return ret;
+ }
db = &s->dma_dac2;
} else if (vma->vm_flags & VM_READ) {
- if ((ret = prog_dmabuf_adc(s)) != 0)
+ if ((ret = prog_dmabuf_adc(s)) != 0) {
+ unlock_kernel();
return ret;
+ }
db = &s->dma_adc;
- } else
+ } else {
+ unlock_kernel();
return -EINVAL;
- if (vma->vm_pgoff != 0)
+ }
+ if (vma->vm_pgoff != 0) {
+ unlock_kernel();
return -EINVAL;
+ }
size = vma->vm_end - vma->vm_start;
- if (size > (PAGE_SIZE << db->buforder))
+ if (size > (PAGE_SIZE << db->buforder)) {
+ unlock_kernel();
return -EINVAL;
- if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+ }
+ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
+ unlock_kernel();
return -EAGAIN;
+ }
db->mapped = 1;
+ unlock_kernel();
return 0;
}
@@ -1717,6 +1732,7 @@ static int es1370_release(struct inode *inode, struct file *file)
struct es1370_state *s = (struct es1370_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac2(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1733,6 +1749,7 @@ static int es1370_release(struct inode *inode, struct file *file)
wake_up(&s->open_wait);
up(&s->open_sem);
return 0;
+ unlock_kernel();
}
static /*const*/ struct file_operations es1370_audio_fops = {
@@ -1850,17 +1867,23 @@ static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma)
VALIDATE_STATE(s);
if (!(vma->vm_flags & VM_WRITE))
return -EINVAL;
+ lock_kernel();
if ((ret = prog_dmabuf_dac1(s)) != 0)
- return ret;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
s->dma_dac1.mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2122,6 +2145,7 @@ static int es1370_release_dac(struct inode *inode, struct file *file)
struct es1370_state *s = (struct es1370_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
drain_dac1(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
stop_dac1(s);
@@ -2129,6 +2153,7 @@ static int es1370_release_dac(struct inode *inode, struct file *file)
s->open_mode &= ~FMODE_DAC;
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2366,6 +2391,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
@@ -2399,6 +2425,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c
index 109ac71c0..58d7923ab 100644
--- a/drivers/sound/es1371.c
+++ b/drivers/sound/es1371.c
@@ -121,6 +121,7 @@
#include <linux/bitops.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -1494,24 +1495,38 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
- if ((ret = prog_dmabuf_dac2(s)) != 0)
+ if ((ret = prog_dmabuf_dac2(s)) != 0) {
+ unlock_kernel();
return ret;
+ }
db = &s->dma_dac2;
} else if (vma->vm_flags & VM_READ) {
- if ((ret = prog_dmabuf_adc(s)) != 0)
+ if ((ret = prog_dmabuf_adc(s)) != 0) {
+ unlock_kernel();
return ret;
+ }
db = &s->dma_adc;
- } else
+ } else {
+ unlock_kernel();
return -EINVAL;
- if (vma->vm_pgoff != 0)
+ }
+ if (vma->vm_pgoff != 0) {
+ unlock_kernel();
return -EINVAL;
+ }
size = vma->vm_end - vma->vm_start;
- if (size > (PAGE_SIZE << db->buforder))
+ if (size > (PAGE_SIZE << db->buforder)) {
+ unlock_kernel();
return -EINVAL;
- if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+ }
+ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) {
+ unlock_kernel();
return -EAGAIN;
+ }
db->mapped = 1;
+ unlock_kernel();
return 0;
}
@@ -1903,6 +1918,7 @@ static int es1371_release(struct inode *inode, struct file *file)
struct es1371_state *s = (struct es1371_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac2(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1917,6 +1933,7 @@ static int es1371_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
@@ -2035,17 +2052,23 @@ static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma)
VALIDATE_STATE(s);
if (!(vma->vm_flags & VM_WRITE))
return -EINVAL;
+ lock_kernel();
if ((ret = prog_dmabuf_dac1(s)) != 0)
- return ret;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
s->dma_dac1.mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2297,6 +2320,7 @@ static int es1371_release_dac(struct inode *inode, struct file *file)
struct es1371_state *s = (struct es1371_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
drain_dac1(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
stop_dac1(s);
@@ -2304,6 +2328,7 @@ static int es1371_release_dac(struct inode *inode, struct file *file)
s->open_mode &= ~FMODE_DAC;
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
@@ -2540,6 +2565,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file)
unsigned count, tmo;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
@@ -2573,6 +2599,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c
index cfc89d3ee..e2e0c3b12 100644
--- a/drivers/sound/esssolo1.c
+++ b/drivers/sound/esssolo1.c
@@ -90,6 +90,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1192,29 +1193,35 @@ static int solo1_mmap(struct file *file, struct vm_area_struct *vma)
{
struct solo1_state *s = (struct solo1_state *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_dac(s)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf_adc(s)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
db->mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1510,6 +1517,7 @@ static int solo1_release(struct inode *inode, struct file *file)
struct solo1_state *s = (struct solo1_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1527,6 +1535,7 @@ static int solo1_release(struct inode *inode, struct file *file)
s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -1881,6 +1890,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
@@ -1914,6 +1924,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2083,6 +2094,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
unsigned int regb;
VALIDATE_STATE(s);
+ lock_kernel();
down(&s->open_sem);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
@@ -2094,6 +2106,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
release_region(s->sbbase, FMSYNTH_EXTENT);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c
index f04636a65..792f670af 100644
--- a/drivers/sound/i810_audio.c
+++ b/drivers/sound/i810_audio.c
@@ -76,6 +76,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1227,29 +1228,34 @@ static int i810_mmap(struct file *file, struct vm_area_struct *vma)
{
struct i810_state *state = (struct i810_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(state, 0)) != 0)
- return ret;
+ goto out;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(state, 1)) != 0)
- return ret;
+ goto out;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << dmabuf->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
dmabuf->mapped = 1;
-
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1608,6 +1614,7 @@ static int i810_release(struct inode *inode, struct file *file)
struct i810_state *state = (struct i810_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
i810_clear_tail(state);
drain_dac(state, file->f_flags & O_NONBLOCK);
@@ -1632,6 +1639,7 @@ static int i810_release(struct inode *inode, struct file *file)
kfree(state->card->states[state->virt]);
state->card->states[state->virt] = NULL;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c
index cd5a2bc27..cc54f784c 100644
--- a/drivers/sound/maestro.c
+++ b/drivers/sound/maestro.c
@@ -197,6 +197,8 @@
#include <linux/version.h>
#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
@@ -2422,13 +2424,14 @@ static int ess_mmap(struct file *file, struct vm_area_struct *vma)
{
struct ess_state *s = (struct ess_state *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(s, 1)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else
#if 0
@@ -2436,20 +2439,25 @@ static int ess_mmap(struct file *file, struct vm_area_struct *vma)
we can turn this back on. */
if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(s, 0)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
} else
#endif
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (SILLY_OFFSET(vma) != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
db->mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2985,6 +2993,7 @@ ess_release(struct inode *inode, struct file *file)
struct ess_state *s = (struct ess_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -3006,6 +3015,7 @@ ess_release(struct inode *inode, struct file *file)
}
up(&s->open_sem);
wake_up(&s->open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/msnd.h b/drivers/sound/msnd.h
index 219a6bfe0..7b361921e 100644
--- a/drivers/sound/msnd.h
+++ b/drivers/sound/msnd.h
@@ -160,13 +160,6 @@
# define inb inb_p
#endif
-#ifdef LINUX20
-# define __initfunc(f) f
-# define __initdata /* nothing */
-# define spin_lock_irqsave(junk,flags) do { save_flags(flags); cli(); } while (0)
-# define spin_unlock_irqrestore(junk,flags) do { restore_flags(flags); } while (0)
-#endif
-
/* JobQueueStruct */
#define JQS_wStart 0x00
#define JQS_wSize 0x02
@@ -236,9 +229,7 @@ typedef struct multisound_dev {
wait_queue_head_t writeblock;
wait_queue_head_t readblock;
wait_queue_head_t writeflush;
-#ifndef LINUX20
spinlock_t lock;
-#endif
int nresets;
unsigned long recsrc;
int left_levels[16];
@@ -250,8 +241,6 @@ typedef struct multisound_dev {
int rec_sample_size, rec_sample_rate, rec_channels;
int rec_ndelay;
BYTE bCurrentMidiPatch;
- void (*inc_ref)(void);
- void (*dec_ref)(void);
/* Digital audio FIFOs */
msnd_fifo DAPF, DARF;
diff --git a/drivers/sound/msnd_pinnacle.c b/drivers/sound/msnd_pinnacle.c
index b220433ce..91c7d2306 100644
--- a/drivers/sound/msnd_pinnacle.c
+++ b/drivers/sound/msnd_pinnacle.c
@@ -35,16 +35,12 @@
#include <linux/config.h>
#include <linux/version.h>
-#if LINUX_VERSION_CODE < 0x020101
-# define LINUX20
-#endif
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/types.h>
#include <linux/delay.h>
-#ifndef LINUX20
-# include <linux/init.h>
-#endif
+#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/irq.h>
#include <asm/io.h>
#include "sound_config.h"
@@ -747,16 +743,6 @@ static void set_default_audio_parameters(void)
set_default_rec_audio_parameters();
}
-static void mod_inc_ref(void)
-{
- MOD_INC_USE_COUNT;
-}
-
-static void mod_dec_ref(void)
-{
- MOD_DEC_USE_COUNT;
-}
-
static int dev_open(struct inode *inode, struct file *file)
{
int minor = MINOR(inode->i_rdev);
@@ -789,43 +775,23 @@ static int dev_open(struct inode *inode, struct file *file)
} else
err = -EINVAL;
- if (err >= 0)
- mod_inc_ref();
-
return err;
}
-#ifdef LINUX20
-static void dev_release(struct inode *inode, struct file *file)
-#else
static int dev_release(struct inode *inode, struct file *file)
-#endif
{
int minor = MINOR(inode->i_rdev);
-#ifndef LINUX20
int err = 0;
-#endif
- if (minor == dev.dsp_minor) {
-#ifndef LINUX20
- err =
-#endif
- dsp_release(file);
- }
+ lock_kernel();
+ if (minor == dev.dsp_minor)
+ err = dsp_release(file);
else if (minor == dev.mixer_minor) {
/* nothing */
- }
-#ifndef LINUX20
- else
+ } else
err = -EINVAL;
-
- if (err >= 0)
-#endif
- mod_dec_ref();
-
-#ifndef LINUX20
+ unlock_kernel();
return err;
-#endif
}
static __inline__ int pack_DARQ_to_DARF(register int bank)
@@ -1002,30 +968,18 @@ static int dsp_write(const char *buf, size_t len)
return len - count;
}
-#ifdef LINUX20
-static int dev_read(struct inode *inode, struct file *file, char *buf, int count)
-{
- int minor = MINOR(inode->i_rdev);
-#else
static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
{
int minor = MINOR(file->f_dentry->d_inode->i_rdev);
-#endif
if (minor == dev.dsp_minor)
return dsp_read(buf, count);
else
return -EINVAL;
}
-#ifdef LINUX20
-static int dev_write(struct inode *inode, struct file *file, const char *buf, int count)
-{
- int minor = MINOR(inode->i_rdev);
-#else
static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off)
{
int minor = MINOR(file->f_dentry->d_inode->i_rdev);
-#endif
if (minor == dev.dsp_minor)
return dsp_write(buf, count);
else
@@ -1042,15 +996,8 @@ static __inline__ void eval_dsp_msg(register WORD wMessage)
if (pack_DAPF_to_DAPQ(0) <= 0) {
if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
-#ifdef LINUX20
- if (test_bit(F_WRITEFLUSH, &dev.flags)) {
- clear_bit(F_WRITEFLUSH, &dev.flags);
- wake_up_interruptible(&dev.writeflush);
- }
-#else
if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
wake_up_interruptible(&dev.writeflush);
-#endif
}
clear_bit(F_WRITING, &dev.flags);
}
@@ -1122,6 +1069,7 @@ static void intr(int irq, void *dev_id, struct pt_regs *regs)
}
static struct file_operations dev_fileops = {
+ owner: THIS_MODULE,
read: dev_read,
write: dev_write,
ioctl: dev_ioctl,
@@ -1881,8 +1829,6 @@ int __init msnd_pinnacle_init(void)
dev.recsrc = 0;
dev.dspq_data_buff = DSPQ_DATA_BUFF;
dev.dspq_buff_size = DSPQ_BUFF_SIZE;
- dev.inc_ref = mod_inc_ref;
- dev.dec_ref = mod_dec_ref;
if (write_ndelay == -1)
write_ndelay = CONFIG_MSND_WRITE_NDELAY;
if (write_ndelay)
@@ -1898,9 +1844,7 @@ int __init msnd_pinnacle_init(void)
init_waitqueue_head(&dev.writeflush);
msnd_fifo_init(&dev.DAPF);
msnd_fifo_init(&dev.DARF);
-#ifndef LINUX20
spin_lock_init(&dev.lock);
-#endif
printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize);
if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) {
printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n");
diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c
index c9c66a73f..8a082552a 100644
--- a/drivers/sound/sonicvibes.c
+++ b/drivers/sound/sonicvibes.c
@@ -108,6 +108,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1509,29 +1510,35 @@ static int sv_mmap(struct file *file, struct vm_area_struct *vma)
{
struct sv_state *s = (struct sv_state *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(s);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(s, 1)) != 0)
- return ret;
+ goto out;
db = &s->dma_dac;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(s, 0)) != 0)
- return ret;
+ goto out;
db = &s->dma_adc;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
db->mapped = 1;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1907,6 +1914,7 @@ static int sv_release(struct inode *inode, struct file *file)
struct sv_state *s = (struct sv_state *)file->private_data;
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
down(&s->open_sem);
@@ -1921,6 +1929,7 @@ static int sv_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2167,6 +2176,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
+ lock_kernel();
if (file->f_mode & FMODE_WRITE) {
add_wait_queue(&s->midi.owait, &wait);
for (;;) {
@@ -2200,6 +2210,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
@@ -2363,6 +2374,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
unsigned int regb;
VALIDATE_STATE(s);
+ lock_kernel();
down(&s->open_sem);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
@@ -2373,6 +2385,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
}
wake_up(&s->open_wait);
up(&s->open_sem);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 0351fe7ce..d56b8f77f 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -270,6 +270,7 @@ static int sound_release(struct inode *inode, struct file *file)
{
int dev = MINOR(inode->i_rdev);
+ lock_kernel();
DEB(printk("sound_release(dev=%d)\n", dev));
switch (dev & 0x0f) {
case SND_DEV_CTL:
@@ -297,6 +298,7 @@ static int sound_release(struct inode *inode, struct file *file)
notifier_call_chain(&sound_locker, 0, 0);
lock_depth--;
+ unlock_kernel();
return 0;
}
@@ -449,29 +451,35 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n");
return -EINVAL;
}
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */
dmap = audio_devs[dev]->dmap_out;
else if (vma->vm_flags & VM_READ)
dmap = audio_devs[dev]->dmap_in;
else {
printk(KERN_ERR "Sound: Undefined mmap() access\n");
+ unlock_kernel();
return -EINVAL;
}
if (dmap == NULL) {
printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n");
+ unlock_kernel();
return -EIO;
}
if (dmap->raw_buf == NULL) {
printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n");
+ unlock_kernel();
return -EIO;
}
if (dmap->mapping_flags) {
printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n");
+ unlock_kernel();
return -EIO;
}
if (vma->vm_pgoff != 0) {
printk(KERN_ERR "Sound: mmap() offset must be 0.\n");
+ unlock_kernel();
return -EINVAL;
}
size = vma->vm_end - vma->vm_start;
@@ -481,8 +489,10 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
}
if (remap_page_range(vma->vm_start, virt_to_phys(dmap->raw_buf),
vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
+ vma->vm_page_prot)) {
+ unlock_kernel();
return -EAGAIN;
+ }
dmap->mapping_flags |= DMA_MAP_MAPPED;
@@ -492,6 +502,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
memset(dmap->raw_buf,
dmap->neutral_byte,
dmap->bytes_in_use);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c
index 6e2b70791..f19cb1740 100644
--- a/drivers/sound/trident.c
+++ b/drivers/sound/trident.c
@@ -107,6 +107,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -1560,30 +1561,35 @@ static int trident_mmap(struct file *file, struct vm_area_struct *vma)
{
struct trident_state *state = (struct trident_state *)file->private_data;
struct dmabuf *dmabuf = &state->dmabuf;
- int ret;
+ int ret = -EINVAL;
unsigned long size;
VALIDATE_STATE(state);
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf(state, 0)) != 0)
- return ret;
+ goto out;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf(state, 1)) != 0)
- return ret;
- } else
- return -EINVAL;
+ goto out;
+ } else
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << dmabuf->buforder))
- return -EINVAL;
+ goto out;
+ ret = -EAGAIN;
if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
size, vma->vm_page_prot))
- return -EAGAIN;
+ goto out;
dmabuf->mapped = 1;
-
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2009,9 +2015,12 @@ static int trident_open(struct inode *inode, struct file *file)
static int trident_release(struct inode *inode, struct file *file)
{
struct trident_state *state = (struct trident_state *)file->private_data;
- struct trident_card *card = state->card;
- struct dmabuf *dmabuf = &state->dmabuf;
+ struct trident_card *card;
+ struct dmabuf *dmabuf;
+ lock_kernel();
+ card = state->card;
+ dmabuf = &state->dmabuf;
VALIDATE_STATE(state);
if (file->f_mode & FMODE_WRITE) {
@@ -2038,6 +2047,7 @@ static int trident_release(struct inode *inode, struct file *file)
/* we're covered by the open_sem */
up(&card->open_sem);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c
index ab14427d6..be3b1c9ca 100644
--- a/drivers/sound/via82cxxx_audio.c
+++ b/drivers/sound/via82cxxx_audio.c
@@ -30,6 +30,7 @@
#include <linux/poll.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
@@ -2207,6 +2208,7 @@ static int via_dsp_release(struct inode *inode, struct file *file)
card = file->private_data;
assert (card != NULL);
+ lock_kernel();
if (file->f_mode & FMODE_READ)
via_chan_free (card, &card->ch_in);
@@ -2220,6 +2222,7 @@ static int via_dsp_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore (&card->lock, flags);
wake_up (&card->open_wait);
+ unlock_kernel();
DPRINTK("EXIT, returning 0\n");
return 0;
diff --git a/drivers/sound/vwsnd.c b/drivers/sound/vwsnd.c
index 19cca5ee0..d46abd569 100644
--- a/drivers/sound/vwsnd.c
+++ b/drivers/sound/vwsnd.c
@@ -84,10 +84,9 @@
* Locking Notes
*
* INC_USE_COUNT and DEC_USE_COUNT keep track of the number of
- * open descriptors to this driver. When the driver is compiled
- * as a module, they call MOD_{INC,DEC}_USE_COUNT; otherwise they
- * bump vwsnd_use_count. The global device list, vwsnd_dev_list,
- * is immutable when the IN_USE is true.
+ * open descriptors to this driver. They store it in vwsnd_use_count.
+ * The global device list, vwsnd_dev_list, is immutable when the IN_USE
+ * is true.
*
* devc->open_lock is a semaphore that is used to enforce the
* single reader/single writer rule for /dev/audio. The rule is
@@ -141,6 +140,7 @@
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/fixmap.h>
#include <asm/cobalt.h>
#include <asm/semaphore.h>
@@ -1517,22 +1517,12 @@ typedef struct vwsnd_dev {
static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */
-#ifdef MODULE
-
-# define INC_USE_COUNT MOD_INC_USE_COUNT
-# define DEC_USE_COUNT MOD_DEC_USE_COUNT
-# define IN_USE MOD_IN_USE
-
-#else
-
static atomic_t vwsnd_use_count = ATOMIC_INIT(0);
# define INC_USE_COUNT (atomic_inc(&vwsnd_use_count))
# define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count))
# define IN_USE (atomic_read(&vwsnd_use_count) != 0)
-#endif
-
/*
* Lithium can only DMA multiples of 32 bytes. Its DMA buffer may
* be up to 8 Kb. This driver always uses 8 Kb.
@@ -2998,6 +2988,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
vwsnd_port_t *wport = NULL, *rport = NULL;
int err = 0;
+ lock_kernel();
down(&devc->io_sema);
{
DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
@@ -3023,13 +3014,14 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
}
up(&devc->open_sema);
wake_up(&devc->open_wait);
- DBGDO(if (IN_USE)) /* see hack in vwsnd_mixer_release() */
- DEC_USE_COUNT;
+ DEC_USE_COUNT;
DBGR();
+ unlock_kernel();
return err;
}
static struct file_operations vwsnd_audio_fops = {
+ owner: THIS_MODULE,
llseek: vwsnd_audio_llseek,
read: vwsnd_audio_read,
write: vwsnd_audio_write,
@@ -3069,15 +3061,7 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file)
static int vwsnd_mixer_release(struct inode *inode, struct file *file)
{
DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
-
- /*
- * hack -- opening/closing the mixer device zeroes use count
- * so driver can be unloaded.
- * Use only while debugging module, and then use it carefully.
- */
-
- DBGDO(while (IN_USE))
- DEC_USE_COUNT;
+ DEC_USE_COUNT;
return 0;
}
@@ -3234,6 +3218,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
}
static struct file_operations vwsnd_mixer_fops = {
+ owner: THIS_MODULE,
llseek: vwsnd_mixer_llseek,
ioctl: vwsnd_mixer_ioctl,
open: vwsnd_mixer_open,
@@ -3429,8 +3414,6 @@ static int unload_vwsnd(struct address_info *hw_config)
DBGE("()\n");
- if (IN_USE)
- return -EBUSY;
devcp = &vwsnd_dev_list;
while ((devc = *devcp)) {
if (devc->audio_minor == hw_config->slots[0]) {
diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c
index a8f826031..3fb7cce2e 100644
--- a/drivers/sound/wavfront.c
+++ b/drivers/sound/wavfront.c
@@ -67,6 +67,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/fcntl.h>
#include <linux/ioport.h>
@@ -1959,8 +1960,10 @@ wavefront_open (struct inode *inode, struct file *file)
static int
wavefront_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
dev.opened = 0;
dev.debug = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 043d57bbc..47485dbde 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -50,6 +50,7 @@ static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.4 1999/12/16 22:18:36 root Exp root
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/segment.h>
@@ -1056,6 +1057,7 @@ int ixj_release(struct inode *inode, struct file *file_p)
if (ixjdebug > 0)
printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
+ lock_kernel();
daa_set_mode(board, SOP_PU_SLEEP);
ixj_set_port(board, PORT_POTS);
aec_stop(board);
@@ -1189,6 +1191,7 @@ int ixj_release(struct inode *inode, struct file *file_p)
j->rec_frame_size = j->play_frame_size = 0;
ixj_fasync(-1, file_p, 0); // remove from list of async notification
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in
index 55b8b1df5..7e29c7807 100644
--- a/drivers/usb/Config.in
+++ b/drivers/usb/Config.in
@@ -28,6 +28,9 @@ comment 'USB Controllers'
comment 'USB Devices'
dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
dep_tristate ' USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ dep_tristate ' Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
+ fi
dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
dep_tristate ' USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
dep_tristate ' USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
@@ -68,7 +71,6 @@ comment 'USB Devices'
dep_tristate ' USB ADMtek Pegasus-based device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET
dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB
dep_tristate ' D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV
- dep_tristate ' Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
fi
diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c
index 67f1635a6..4560ad602 100644
--- a/drivers/usb/audio.c
+++ b/drivers/usb/audio.c
@@ -171,6 +171,7 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
@@ -1944,10 +1945,13 @@ static int usb_audio_open_mixdev(struct inode *inode, struct file *file)
static int usb_audio_release_mixdev(struct inode *inode, struct file *file)
{
struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data;
- struct usb_audio_state *s = ms->state;
+ struct usb_audio_state *s;
+ lock_kernel();
+ s = ms->state;
down(&open_sem);
release(s);
+ unlock_kernel();
return 0;
}
@@ -2283,23 +2287,28 @@ static int usb_audio_mmap(struct file *file, struct vm_area_struct *vma)
{
struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
struct dmabuf *db;
- int ret;
+ int ret = -EINVAL;
+ lock_kernel();
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_out(as)) != 0)
- return ret;
+ goto out;
db = &as->usbout.dma;
} else if (vma->vm_flags & VM_READ) {
if ((ret = prog_dmabuf_in(as)) != 0)
- return ret;
+ goto out;
db = &as->usbin.dma;
} else
- return -EINVAL;
+ goto out;
+ ret = -EINVAL;
if (vma->vm_pgoff != 0)
- return -EINVAL;
+ goto out;
- return dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
+ ret = dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot);
+out:
+ unlock_kernel();
+ return ret;
}
static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2615,10 +2624,13 @@ static int usb_audio_open(struct inode *inode, struct file *file)
static int usb_audio_release(struct inode *inode, struct file *file)
{
struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
- struct usb_audio_state *s = as->state;
- struct usb_device *dev = s->usbdev;
+ struct usb_audio_state *s;
+ struct usb_device *dev;
struct usb_interface *iface;
+ lock_kernel();
+ s = as->state;
+ dev = s->usbdev;
if (file->f_mode & FMODE_WRITE)
drain_out(as, file->f_flags & O_NONBLOCK);
down(&open_sem);
@@ -2643,6 +2655,7 @@ static int usb_audio_release(struct inode *inode, struct file *file)
as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
release(s);
wake_up(&open_wait);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c
index aaea67a4c..bd7be69e8 100644
--- a/drivers/usb/bluetooth.c
+++ b/drivers/usb/bluetooth.c
@@ -1,11 +1,15 @@
/*
- * bluetooth.c Version 0.1
+ * bluetooth.c Version 0.2
*
* Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
*
* USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
*
*
+ * (07/11/2000) Version 0.2 gkh
+ * Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe
+ * function.
+ *
* (07/09/2000) Version 0.1 gkh
* Initial release. Has support for sending ACL data (which is really just
* a HCI frame.) Raw HCI commands and HCI events are not supported.
@@ -619,6 +623,7 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum)
memset(bluetooth, 0, sizeof(struct usb_bluetooth));
+ bluetooth->magic = USB_BLUETOOTH_MAGIC;
bluetooth->dev = dev;
bluetooth->minor = minor;
bluetooth->tqueue.routine = bluetooth_softint;
@@ -676,6 +681,8 @@ static void * usb_bluetooth_probe(struct usb_device *dev, unsigned int ifnum)
tty_register_devfs (&bluetooth_tty_driver, 0, minor);
info("Bluetooth converter now attached to ttyBLUE%d (or usb/ttblue/%d for devfs)", minor, minor);
+ bluetooth_table[minor] = bluetooth;
+
return bluetooth; /* success */
probe_error:
diff --git a/drivers/usb/dabusb.c b/drivers/usb/dabusb.c
index 8b1df4edf..9b3bc24fa 100644
--- a/drivers/usb/dabusb.c
+++ b/drivers/usb/dabusb.c
@@ -38,6 +38,7 @@
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/usb.h>
+#include <linux/smp_lock.h>
#include "dabusb.h"
#include "dabfirmware.h"
@@ -613,6 +614,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
dbg("dabusb_release");
+ lock_kernel();
down (&s->mutex);
dabusb_stop (s);
dabusb_free_buffers (s);
@@ -626,6 +628,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
wake_up (&s->remove_ok);
s->opened = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/dc2xx.c b/drivers/usb/dc2xx.c
index 4fcfa640c..bb960a4af 100644
--- a/drivers/usb/dc2xx.c
+++ b/drivers/usb/dc2xx.c
@@ -60,6 +60,7 @@
#include <linux/module.h>
#undef DEBUG
#include <linux/usb.h>
+#include <linux/smp_lock.h>
@@ -298,10 +299,12 @@ static int camera_release (struct inode *inode, struct file *file)
kfree (camera->buf);
/* If camera was unplugged with open file ... */
+ lock_kernel();
if (!camera->dev) {
minor_data [camera->subminor] = NULL;
kfree (camera);
}
+ unlock_kernel();
dbg ("close");
diff --git a/drivers/usb/devices.c b/drivers/usb/devices.c
index c99f86973..df02bcf2a 100644
--- a/drivers/usb/devices.c
+++ b/drivers/usb/devices.c
@@ -45,6 +45,9 @@
* up an eventual usbd
* 2000-01-04: Thomas Sailer <sailer@ife.ee.ethz.ch>
* Turned into its own filesystem
+ * 2000-07-05: Ashley Montanaro <ashley@compsoc.man.ac.uk>
+ * Converted file reading routine to dump to buffer once
+ * per device, not per bus
*
* $Id: devices.c,v 1.5 2000/01/11 13:58:21 tom Exp $
*/
@@ -367,23 +370,40 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de
/*****************************************************************/
-static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev,
- struct usb_bus *bus, int level, int index, int count)
+/* This is a recursive function. Parameters:
+ * buffer - the user-space buffer to write data into
+ * nbytes - the maximum number of bytes to write
+ * skip_bytes - the number of bytes to skip before writing anything
+ * file_offset - the offset into the devices file on completion
+ */
+static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
+ struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
{
int chix;
- int cnt = 0;
+ int ret, cnt = 0;
int parent_devnum = 0;
-
+ char *pages_start, *data_end;
+ unsigned int length;
+ ssize_t total_written = 0;
+
+ /* don't bother with anything else if we're not writing any data */
+ if (*nbytes <= 0)
+ return 0;
+
if (level > MAX_TOPO_LEVEL)
- return start;
+ return total_written;
+ /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
+ if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
+ return -ENOMEM;
+
if (usbdev->parent && usbdev->parent->devnum != -1)
parent_devnum = usbdev->parent->devnum;
/*
* So the root hub's parent is 0 and any device that is
* plugged into the root hub has a parent of 0.
*/
- start += sprintf(start, format_topo, bus->busnum, level, parent_devnum, index, count,
- usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
+ data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, index, count,
+ usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
/*
* level = topology-tier level;
* parent_devnum = parent device number;
@@ -392,30 +412,58 @@ static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev,
*/
/* If this is the root hub, display the bandwidth information */
if (level == 0)
- start += sprintf(start, format_bandwidth, bus->bandwidth_allocated,
+ data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
FRAME_TIME_MAX_USECS_ALLOC,
(100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC,
bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs);
- start = usb_dump_desc(start, end, usbdev);
- if (start > end)
- return start + sprintf(start, "(truncated)\n");
+
+ data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev);
+
+ if (data_end > (pages_start + (2 * PAGE_SIZE) - 256))
+ data_end += sprintf(data_end, "(truncated)\n");
+
+ length = data_end - pages_start;
+ /* if we can start copying some data to the user */
+ if (length > *skip_bytes) {
+ length -= *skip_bytes;
+ if (length > *nbytes)
+ length = *nbytes;
+ if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) {
+ free_pages((unsigned long)pages_start, 1);
+
+ if (total_written == 0)
+ return -EFAULT;
+ return total_written;
+ }
+ *nbytes -= length;
+ *file_offset += length;
+ total_written += length;
+ *buffer += length;
+ *skip_bytes = 0;
+ } else
+ *skip_bytes -= length;
+
+ free_pages((unsigned long)pages_start, 1);
+
/* Now look at all of this device's children. */
for (chix = 0; chix < usbdev->maxchild; chix++) {
- if (start > end)
- return start;
- if (usbdev->children[chix])
- start = usb_device_dump(start, end, usbdev->children[chix], bus, level + 1, chix, ++cnt);
+ if (usbdev->children[chix]) {
+ ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, usbdev->children[chix],
+ bus, level + 1, chix, ++cnt);
+ if (ret == -EFAULT)
+ return total_written;
+ total_written += ret;
+ }
}
- return start;
+ return total_written;
}
static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
{
struct list_head *buslist;
struct usb_bus *bus;
- char *page, *end;
- ssize_t ret = 0;
- unsigned int pos, len;
+ ssize_t ret, total_written = 0;
+ loff_t skip_bytes = *ppos;
if (*ppos < 0)
return -EINVAL;
@@ -423,34 +471,18 @@ static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff
return 0;
if (!access_ok(VERIFY_WRITE, buf, nbytes))
return -EFAULT;
- if (!(page = (char*) __get_free_pages(GFP_KERNEL,1)))
- return -ENOMEM;
- pos = *ppos;
+
/* enumerate busses */
for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {
/* print devices for this bus */
bus = list_entry(buslist, struct usb_bus, bus_list);
- end = usb_device_dump(page, page + (2*PAGE_SIZE - 256), bus->root_hub, bus, 0, 0, 0);
- len = end - page;
- if (len > pos) {
- len -= pos;
- if (len > nbytes)
- len = nbytes;
- if (copy_to_user(buf, page + pos, len)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- nbytes -= len;
- buf += len;
- ret += len;
- pos = 0;
- *ppos += len;
- } else
- pos -= len;
+ /* recurse through all children of the root hub */
+ ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
+ if (ret < 0)
+ return ret;
+ total_written += ret;
}
- free_pages((unsigned long)page, 1);
- return ret;
+ return total_written;
}
/* Kernel lock for "lastev" protection */
diff --git a/drivers/usb/evdev.c b/drivers/usb/evdev.c
index 7eca5e304..e11327cef 100644
--- a/drivers/usb/evdev.c
+++ b/drivers/usb/evdev.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
+#include <linux/smp_lock.h>
struct evdev {
int exist;
@@ -91,8 +92,10 @@ static int evdev_fasync(int fd, struct file *file, int on)
static int evdev_release(struct inode * inode, struct file * file)
{
struct evdev_list *list = file->private_data;
- struct evdev_list **listptr = &list->evdev->list;
+ struct evdev_list **listptr;
+ lock_kernel();
+ listptr = &list->evdev->list;
evdev_fasync(-1, file, 0);
while (*listptr && (*listptr != list))
@@ -110,6 +113,7 @@ static int evdev_release(struct inode * inode, struct file * file)
}
kfree(list);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/joydev.c b/drivers/usb/joydev.c
index 5349d515c..2210ad0d1 100644
--- a/drivers/usb/joydev.c
+++ b/drivers/usb/joydev.c
@@ -44,6 +44,7 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#define JOYDEV_MINOR_BASE 0
#define JOYDEV_MINORS 32
@@ -160,8 +161,10 @@ static int joydev_fasync(int fd, struct file *file, int on)
static int joydev_release(struct inode * inode, struct file * file)
{
struct joydev_list *list = file->private_data;
- struct joydev_list **listptr = &list->joydev->list;
+ struct joydev_list **listptr;
+ lock_kernel();
+ listptr = &list->joydev->list;
joydev_fasync(-1, file, 0);
while (*listptr && (*listptr != list))
@@ -179,6 +182,7 @@ static int joydev_release(struct inode * inode, struct file * file)
}
kfree(list);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c
index dc578df33..80a1ebbf4 100644
--- a/drivers/usb/mdc800.c
+++ b/drivers/usb/mdc800.c
@@ -76,6 +76,7 @@
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <linux/usb.h>
@@ -582,6 +583,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
int retval=0;
dbg ("Mustek MDC800 device closed.");
+ lock_kernel();
if (mdc800->open && (mdc800->state != NOT_CONNECTED))
{
mdc800->open=0;
@@ -593,6 +595,7 @@ static int mdc800_device_release (struct inode* inode, struct file *file)
{
retval=-EIO;
}
+ unlock_kernel();
return retval;
}
diff --git a/drivers/usb/mousedev.c b/drivers/usb/mousedev.c
index 5c871a88d..ea5ad301b 100644
--- a/drivers/usb/mousedev.c
+++ b/drivers/usb/mousedev.c
@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/config.h>
+#include <linux/smp_lock.h>
#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
#define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
@@ -159,8 +160,10 @@ static int mousedev_fasync(int fd, struct file *file, int on)
static int mousedev_release(struct inode * inode, struct file * file)
{
struct mousedev_list *list = file->private_data;
- struct mousedev_list **listptr = &list->mousedev->list;
+ struct mousedev_list **listptr;
+ lock_kernel();
+ listptr = &list->mousedev->list;
mousedev_fasync(-1, file, 0);
while (*listptr && (*listptr != list))
@@ -197,6 +200,7 @@ static int mousedev_release(struct inode * inode, struct file * file)
}
kfree(list);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/printer.c b/drivers/usb/printer.c
index 4dc11aee0..987f1a8b5 100644
--- a/drivers/usb/printer.c
+++ b/drivers/usb/printer.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/init.h>
@@ -167,17 +168,19 @@ static int usblp_open(struct inode *inode, struct file *file)
if (minor < 0 || minor >= USBLP_MINORS)
return -ENODEV;
+ lock_kernel();
usblp = usblp_table[minor];
+ retval = -ENODEV;
if (!usblp || !usblp->dev)
- return -ENODEV;
+ goto out;
+ retval = -EBUSY;
if (usblp->used)
- return -EBUSY;
+ goto out;
- if ((retval = usblp_check_status(usblp))) {
- return retval;
- }
+ if ((retval = usblp_check_status(usblp)))
+ goto out;
usblp->used = 1;
file->private_data = usblp;
@@ -189,8 +192,9 @@ static int usblp_open(struct inode *inode, struct file *file)
usblp->readcount = 0;
usb_submit_urb(&usblp->readurb);
}
-
- return 0;
+out:
+ unlock_kernel();
+ return retval;
}
static int usblp_release(struct inode *inode, struct file *file)
diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c
index 3fba783e0..9c650cfdc 100644
--- a/drivers/usb/usb.c
+++ b/drivers/usb/usb.c
@@ -58,8 +58,6 @@ static struct usb_driver *usb_minors[16];
int usb_register(struct usb_driver *new_driver)
{
- struct list_head *tmp;
-
if (new_driver->fops != NULL) {
if (usb_minors[new_driver->minor/16]) {
err("error registering %s driver", new_driver->name);
@@ -75,13 +73,22 @@ int usb_register(struct usb_driver *new_driver)
/* Add it to the list of known drivers */
list_add(&new_driver->driver_list, &usb_driver_list);
- /*
- * We go through all existing devices, and see if any of them would
- * be acceptable to the new driver.. This is done using a depth-first
- * search for devices without a registered driver already, then
- * running 'probe' with each of the drivers registered on every one
- * of these.
- */
+ usb_scan_devices();
+
+ return 0;
+}
+
+/*
+ * We go through all existing devices, and see if any of them would
+ * be acceptable to the new driver.. This is done using a depth-first
+ * search for devices without a registered driver already, then
+ * running 'probe' with each of the drivers registered on every one
+ * of these.
+ */
+void usb_scan_devices(void)
+{
+ struct list_head *tmp;
+
tmp = usb_bus_list.next;
while (tmp != &usb_bus_list) {
struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list);
@@ -89,7 +96,6 @@ int usb_register(struct usb_driver *new_driver)
tmp = tmp->next;
usb_check_support(bus->root_hub);
}
- return 0;
}
/*
@@ -1772,6 +1778,7 @@ EXPORT_SYMBOL(usb_ifnum_to_if);
EXPORT_SYMBOL(usb_register);
EXPORT_SYMBOL(usb_deregister);
+EXPORT_SYMBOL(usb_scan_devices);
EXPORT_SYMBOL(usb_alloc_bus);
EXPORT_SYMBOL(usb_free_bus);
EXPORT_SYMBOL(usb_register_bus);
diff --git a/drivers/video/fbcon-mac.c b/drivers/video/fbcon-mac.c
index 0b3e816e7..2d021dd87 100644
--- a/drivers/video/fbcon-mac.c
+++ b/drivers/video/fbcon-mac.c
@@ -100,8 +100,8 @@ void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
err_buf[cnt] = 0x700 | err_str[cnt];
fbcon_mac_putcs(p->conp, p, err_buf, len, 0, 0);
/* pause for the user */
- for(cnt = 0; cnt < 50000; cnt++)
- udelay(100);
+ printk( "ERROR: shift algorithm...\n" );
+ mdelay(5000);
return;
}
}
@@ -318,12 +318,25 @@ void fbcon_mac_revc(struct display *p, int xx, int yy)
}
}
+static inline void plot_helper(u8 *dest, u8 bit, int bw)
+{
+ switch (bw) {
+ case PIXEL_BLACK_MAC:
+ fb_writeb( fb_readb(dest) | bit, dest );
+ break;
+ case PIXEL_WHITE_MAC:
+ fb_writeb( fb_readb(dest) & (~bit), dest );
+ break;
+ case PIXEL_INVERT_MAC:
+ fb_writeb( fb_readb(dest) ^ bit, dest );
+ break;
+ default:
+ printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+ }
+}
+
/*
* plot_pixel_mac
- *
- * bw == 0 = black
- * 1 = white
- * 2 = invert
*/
static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
{
@@ -333,10 +346,8 @@ static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
/* There *are* 68k Macs that support more than 832x624, you know :-) */
if (pixel_x < 0 || pixel_y < 0 || pixel_x >= p->var.xres || pixel_y >= p->var.yres) {
- int cnt;
printk ("ERROR: pixel_x == %d, pixel_y == %d", pixel_x, pixel_y);
- for(cnt = 0; cnt < 100000; cnt++)
- udelay(100);
+ mdelay(1000);
return;
}
@@ -344,90 +355,36 @@ static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
case 1:
dest = (u8 *) ((pixel_x >> 3) + p->screen_base + pixel_y * p->next_line);
bit = 0x80 >> (pixel_x & 7);
- switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest |= bit;
- break;
- case PIXEL_WHITE_MAC:
- *dest &= ~bit;
- break;
- case PIXEL_INVERT_MAC:
- *dest ^= bit;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
- }
+ plot_helper(dest, bit, bw);
break;
case 2:
dest = (u8 *) ((pixel_x >> 2) + p->screen_base + pixel_y * p->next_line);
bit = 0xC0 >> ((pixel_x & 3) << 1);
- switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest |= bit;
- break;
- case PIXEL_WHITE_MAC:
- *dest &= ~bit;
- break;
- case PIXEL_INVERT_MAC:
- *dest ^= bit;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
- }
+ plot_helper(dest, bit, bw);
break;
case 4:
- dest = (u8 *) ((pixel_x / 2) + p->screen_base + pixel_y * p->next_line);
+ dest = (u8 *) ((pixel_x >> 1) + p->screen_base + pixel_y * p->next_line);
bit = 0xF0 >> ((pixel_x & 1) << 2);
- switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest |= bit;
- break;
- case PIXEL_WHITE_MAC:
- *dest &= ~bit;
- break;
- case PIXEL_INVERT_MAC:
- *dest ^= bit;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
- }
+ plot_helper(dest, bit, bw);
break;
case 8:
dest = (u8 *) (pixel_x + p->screen_base + pixel_y * p->next_line);
bit = 0xFF;
- switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest |= bit;
- break;
- case PIXEL_WHITE_MAC:
- *dest &= ~bit;
- break;
- case PIXEL_INVERT_MAC:
- *dest ^= bit;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
- }
+ plot_helper(dest, bit, bw);
break;
+/* FIXME: You can't access framebuffer directly like this! */
case 16:
dest16 = (u16 *) ((pixel_x *2) + p->screen_base + pixel_y * p->next_line);
pix16 = 0xFFFF;
switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest16 = ~pix16;
- break;
- case PIXEL_WHITE_MAC:
- *dest16 = pix16;
- break;
- case PIXEL_INVERT_MAC:
- *dest16 ^= pix16;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+ case PIXEL_BLACK_MAC: *dest16 = ~pix16; break;
+ case PIXEL_WHITE_MAC: *dest16 = pix16; break;
+ case PIXEL_INVERT_MAC: *dest16 ^= pix16; break;
+ default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
}
break;
@@ -435,17 +392,10 @@ static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y)
dest32 = (u32 *) ((pixel_x *4) + p->screen_base + pixel_y * p->next_line);
pix32 = 0xFFFFFFFF;
switch (bw) {
- case PIXEL_BLACK_MAC:
- *dest32 = ~pix32;
- break;
- case PIXEL_WHITE_MAC:
- *dest32 = pix32;
- break;
- case PIXEL_INVERT_MAC:
- *dest32 ^= pix32;
- break;
- default:
- printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
+ case PIXEL_BLACK_MAC: *dest32 = ~pix32; break;
+ case PIXEL_WHITE_MAC: *dest32 = pix32; break;
+ case PIXEL_INVERT_MAC: *dest32 ^= pix32; break;
+ default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n");
}
break;
}
@@ -497,7 +447,7 @@ static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
*/
struct display_switch fbcon_mac = {
- fbcon_mac_setup, fbcon_mac_bmove, fbcon_mac_clear, fbcon_mac_putc,
+ fbcon_mac_setup, fbcon_redraw_bmove, fbcon_redraw_clear, fbcon_mac_putc,
fbcon_mac_putcs, fbcon_mac_revc, NULL, NULL, NULL, FONTWIDTHRANGE(1,8)
};
diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c
index c2611d0a6..bf74fa162 100644
--- a/drivers/video/fbcon.c
+++ b/drivers/video/fbcon.c
@@ -1124,6 +1124,15 @@ static void fbcon_redraw(struct vc_data *conp, struct display *p,
}
}
+void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+ int height, int width)
+{
+ int x, y;
+ for (y=0; y<height; y++)
+ for (x=0; x<width; x++)
+ fbcon_putc(conp, ' ', sy+y, sx+x);
+}
+
/* This cannot be used together with ypan or ywrap */
void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w)
{
@@ -2422,5 +2431,6 @@ struct display_switch fbcon_dummy = {
EXPORT_SYMBOL(fb_display);
EXPORT_SYMBOL(fbcon_redraw_bmove);
+EXPORT_SYMBOL(fbcon_redraw_clear);
EXPORT_SYMBOL(fbcon_dummy);
EXPORT_SYMBOL(fb_con);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2ab527f02..30bd06d32 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/malloc.h>
@@ -473,8 +474,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
off = vma->vm_pgoff << PAGE_SHIFT;
if (!fb)
return -ENODEV;
- if (fb->fb_mmap)
- return fb->fb_mmap(info, file, vma);
+ if (fb->fb_mmap) {
+ int res;
+ lock_kernel();
+ res = fb->fb_mmap(info, file, vma);
+ unlock_kernel();
+ return res;
+ }
#if defined(__sparc__) && !defined(__sparc_v9__)
/* Should never get here, all fb drivers should have their own
@@ -483,6 +489,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
#else
/* !sparc32... */
+ lock_kernel();
fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
/* frame buffer memory */
@@ -497,6 +504,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
start = fix.mmio_start;
len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);
}
+ unlock_kernel();
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
return -EINVAL;
@@ -612,12 +620,15 @@ static int
fb_release(struct inode *inode, struct file *file)
{
int fbidx = GET_FB_IDX(inode->i_rdev);
- struct fb_info *info = registered_fb[fbidx];
+ struct fb_info *info;
+ lock_kernel();
+ info = registered_fb[fbidx];
if (info->fbops->fb_release)
info->fbops->fb_release(info,1);
if (info->fbops->owner)
__MOD_DEC_USE_COUNT(info->fbops->owner);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 261ce3d3c..c465bafc7 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -30,6 +30,7 @@
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
+#include <video/fbcon-mac.h>
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
@@ -220,8 +221,13 @@ static void vesafb_set_disp(int con)
break;
#endif
default:
+#ifdef FBCON_HAS_MAC
+ sw = &fbcon_mac;
+ break;
+#else
sw = &fbcon_dummy;
return;
+#endif
}
memcpy(&vesafb_sw, sw, sizeof(*sw));
display->dispsw = &vesafb_sw;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9a034ca60..02a2b2758 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -635,6 +635,7 @@ int blkdev_put(struct block_device *bdev, int kind)
kdev_t rdev = to_kdev_t(bdev->bd_dev); /* this should become bdev */
down(&bdev->bd_sem);
/* syncing will go here */
+ lock_kernel();
if (kind == BDEV_FILE || kind == BDEV_FS)
fsync_dev(rdev);
if (atomic_dec_and_test(&bdev->bd_openers)) {
@@ -653,6 +654,7 @@ int blkdev_put(struct block_device *bdev, int kind)
if (!atomic_read(&bdev->bd_openers))
bdev->bd_op = NULL; /* we can't rely on driver being */
/* kind to stay around. */
+ unlock_kernel();
up(&bdev->bd_sem);
return ret;
}
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index f5c53fac2..e53933710 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -635,6 +635,7 @@ int coda_release(struct inode *i, struct file *f)
unsigned short cflags = coda_flags_to_cflags(flags);
struct coda_cred *cred;
+ lock_kernel();
ENTRY;
coda_vfs_stat.release++;
@@ -655,6 +656,7 @@ int coda_release(struct inode *i, struct file *f)
CODA_FREE(cred, sizeof(*cred));
CDEBUG(D_FILE, "coda_release: result: %d\n", error);
+ unlock_kernel();
return error;
}
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c
index dd2636895..711beee06 100644
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -16,6 +16,8 @@
#include <linux/locks.h>
#include <asm/segment.h>
#include <linux/string.h>
+#define __NO_VERSION__
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/coda.h>
@@ -26,8 +28,6 @@
/* pioctl ops */
static int coda_ioctl_permission(struct inode *inode, int mask);
-static int coda_ioctl_open(struct inode *i, struct file *f);
-static int coda_ioctl_release(struct inode *i, struct file *f);
static int coda_pioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg);
@@ -39,9 +39,8 @@ struct inode_operations coda_ioctl_inode_operations =
};
struct file_operations coda_ioctl_operations = {
+ owner: THIS_MODULE,
ioctl: coda_pioctl,
- open: coda_ioctl_open,
- release: coda_ioctl_release,
};
/* the coda pioctl inode ops */
@@ -52,24 +51,6 @@ static int coda_ioctl_permission(struct inode *inode, int mask)
return 0;
}
-/* The pioctl file ops*/
-int coda_ioctl_open(struct inode *i, struct file *f)
-{
- ENTRY;
-
- CDEBUG(D_PIOCTL, "File inode number: %ld\n",
- f->f_dentry->d_inode->i_ino);
-
- EXIT;
- return 0;
-}
-
-int coda_ioctl_release(struct inode *i, struct file *f)
-{
- return 0;
-}
-
-
static int coda_pioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long user_data)
{
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 695e4158c..c475b73ac 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -292,6 +292,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
ENTRY;
/* first opener, initialize */
+ lock_kernel();
if (!vcp->vc_inuse++) {
INIT_LIST_HEAD(&vcp->vc_pending);
INIT_LIST_HEAD(&vcp->vc_processing);
@@ -301,6 +302,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
CDEBUG(D_PSDEV, "inuse: %d\n", vcp->vc_inuse);
EXIT;
+ unlock_kernel();
return 0;
}
@@ -312,13 +314,18 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
struct list_head *lh, *next;
ENTRY;
+ lock_kernel();
if ( !vcp->vc_inuse ) {
+ unlock_kernel();
printk("psdev_release: Not open.\n");
return -1;
}
CDEBUG(D_PSDEV, "psdev_release: inuse %d\n", vcp->vc_inuse);
- if (--vcp->vc_inuse) return 0;
+ if (--vcp->vc_inuse) {
+ unlock_kernel();
+ return 0;
+ }
/* Wakeup clients so they can return. */
CDEBUG(D_PSDEV, "wake up pending clients\n");
@@ -347,6 +354,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
CDEBUG(D_PSDEV, "Done.\n");
EXIT;
+ unlock_kernel();
return 0;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 0f9c59c6c..8c27b5f94 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -933,6 +933,9 @@ void d_move(struct dentry * dentry, struct dentry * target)
/**
* d_path - return the path of a dentry
* @dentry: dentry to report
+ * @vfsmnt: vfsmnt to which the dentry belongs
+ * @root: root dentry
+ * @rootmnt: vfsmnt to which the root dentry belongs
* @buffer: buffer to return value in
* @buflen: buffer length
*
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 494cb270a..38a773d72 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -3311,7 +3311,12 @@ static int devfsd_close (struct inode *inode, struct file *file)
{
struct fs_info *fs_info = inode->i_sb->u.generic_sbp;
- if (fs_info->devfsd_file != file) return 0;
+ lock_kernel();
+ if (fs_info->devfsd_file != file)
+ {
+ unlock_kernel();
+ return 0;
+ }
fs_info->devfsd_event_mask = 0;
fs_info->devfsd_file = NULL;
if (fs_info->devfsd_buffer)
@@ -3322,6 +3327,7 @@ static int devfsd_close (struct inode *inode, struct file *file)
fs_info->devfsd_buffer = NULL;
fs_info->devfsd_task = NULL;
wake_up (&fs_info->revalidate_wait_queue);
+ unlock_kernel();
return 0;
} /* End Function devfsd_close */
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index d2c137e2c..f591203c4 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
static loff_t ext2_file_lseek(struct file *, loff_t, int);
static int ext2_open_file (struct inode *, struct file *);
@@ -73,8 +74,11 @@ static loff_t ext2_file_lseek(
*/
static int ext2_release_file (struct inode * inode, struct file * filp)
{
- if (filp->f_mode & FMODE_WRITE)
+ if (filp->f_mode & FMODE_WRITE) {
+ lock_kernel();
ext2_discard_prealloc (inode);
+ unlock_kernel();
+ }
return 0;
}
diff --git a/fs/file_table.c b/fs/file_table.c
index a64bef65c..2eaceae07 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -124,11 +124,8 @@ static void __fput(struct file *filp)
struct vfsmount * mnt = filp->f_vfsmnt;
struct inode * inode = dentry->d_inode;
- if (filp->f_op && filp->f_op->release) {
- lock_kernel();
+ if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode, filp);
- unlock_kernel();
- }
fops_put(filp->f_op);
filp->f_dentry = NULL;
filp->f_vfsmnt = NULL;
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
index 51d519d7f..15db6e936 100644
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -7,11 +7,15 @@
*/
#include "hpfs_fn.h"
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
int hpfs_dir_release(struct inode *inode, struct file *filp)
{
+ lock_kernel();
hpfs_del_pos(inode, &filp->f_pos);
/*hpfs_write_if_changed(inode);*/
+ unlock_kernel();
return 0;
}
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index f284e3d42..fb5f566e7 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -24,7 +24,9 @@ int hpfs_open(struct inode *i, struct file *f)
int hpfs_file_release(struct inode *inode, struct file *file)
{
+ lock_kernel();
hpfs_write_if_changed(inode);
+ unlock_kernel();
return 0;
}
diff --git a/fs/inode.c b/fs/inode.c
index 28fbd0098..62acffd58 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -261,6 +261,7 @@ static void sync_all_inodes(void)
/**
* write_inode_now - write an inode to disk
* @inode: inode to write to disk
+ * @sync: whether the write should be synchronous or not
*
* This function commits an inode to disk immediately if it is
* dirty. This is primarily needed by knfsd.
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index e088d7fba..1447554ed 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -8,7 +8,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: inode-v23.c,v 1.16 2000/07/06 14:38:10 dwmw2 Exp $
+ * $Id: inode-v23.c,v 1.17 2000/07/06 20:35:19 prumpf Exp $
*
*
* Ported to Linux 2.3.x and MTD:
@@ -1453,7 +1453,6 @@ static struct inode_operations jffs_file_inode_operations =
static struct file_operations jffs_dir_operations =
{
- read: generic_read_dir,
readdir: jffs_readdir,
};
@@ -1533,16 +1532,19 @@ jffs_delete_inode(struct inode *inode)
inode->i_size = 0;
- unlock_kernel();
clear_inode(inode);
+ unlock_kernel();
}
void
jffs_write_super(struct super_block *sb)
{
#ifdef USE_GC
- jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
+ struct jffs_control *c = (struct jffs_control *)sb->u.generic_sbp;
+
+ if(!c->fmc->no_call_gc)
+ jffs_garbage_collect(c);
#endif
}
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index b2644ba5e..4484af07d 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -10,14 +10,13 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: jffs_fm.c,v 1.6 2000/06/30 14:13:03 dwmw2 Exp $
+ * $Id: jffs_fm.c,v 1.8 2000/07/13 13:15:33 scote1 Exp $
*
* Ported to Linux 2.3.x and MTD:
* Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
*
*/
#define __NO_VERSION__
-#include <linux/config.h>
#include <linux/malloc.h>
#include <linux/blkdev.h>
#include <linux/jffs.h>
@@ -68,7 +67,7 @@ jffs_build_begin(struct jffs_control *c, kdev_t dev)
fmc->used_size = 0;
fmc->dirty_size = 0;
- fmc->sector_size = 65536;
+ fmc->sector_size = mtd->erasesize;
fmc->max_chunk_size = fmc->sector_size >> 1;
fmc->min_free_size = (fmc->sector_size << 1) - fmc->max_chunk_size;
fmc->mtd = mtd;
@@ -614,13 +613,16 @@ jffs_flash_erasable_size(struct mtd_info *mtd, __u32 offset, __u32 size)
ssize = mtd->erasesize;
if (offset % ssize) {
+ printk(KERN_WARNING "jffs_flash_erasable_size() given non-aligned offset %lx (erasesize %lx)\n", offset, ssize);
/* The offset is not sector size aligned. */
return -1;
}
else if (offset > mtd->size) {
+ printk(KERN_WARNING "jffs_flash_erasable_size given offset off the end of device (%lx > %lx)\n", offset, mtd->size);
return -2;
}
else if (offset + size > mtd->size) {
+ printk(KERN_WARNING "jffs_flash_erasable_size() given length which runs off the end of device (ofs %lx + len %lx = %lx, > %lx)\n", offset,size, offset+size, mtd->size);
return -3;
}
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index c5923a78e..171f0cb51 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -87,7 +87,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
int result;
char *start = server->packet;
poll_table wait_table;
- struct poll_table_entry entry;
int init_timeout, max_timeout;
int timeout;
int retrans;
@@ -136,8 +135,7 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
break;
}
re_select:
- wait_table.nr = 0;
- wait_table.entry = &entry;
+ poll_initwait(&wait_table);
/* mb() is not necessary because ->poll() will serialize
instructions adding the wait_table waitqueues in the
waitqueue-head before going to calculate the mask-retval. */
@@ -154,13 +152,16 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
timeout = max_timeout;
}
timed_out = !schedule_timeout(timeout);
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ poll_freewait(&wait_table);
current->state = TASK_RUNNING;
if (signal_pending(current)) {
result = -ERESTARTSYS;
break;
}
+ if(wait_table.error) {
+ result = wait_table.error;
+ break;
+ }
if (timed_out) {
if (n < retrans)
continue;
@@ -179,9 +180,8 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
major_timeout_seen = 1;
continue;
}
- } else if (wait_table.nr) {
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ } else {
+ poll_freewait(&wait_table);
}
current->state = TASK_RUNNING;
@@ -262,7 +262,6 @@ static int do_ncp_rpc_call(struct ncp_server *server, int size,
static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
poll_table wait_table;
- struct poll_table_entry entry;
struct file *file;
struct socket *sock;
int init_timeout;
@@ -281,16 +280,14 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
init_timeout = 0x7FFF0000;
while (len) {
- wait_table.nr = 0;
- wait_table.entry = &entry;
+ poll_initwait(&wait_table);
/* mb() is not necessary because ->poll() will serialize
instructions adding the wait_table waitqueues in the
waitqueue-head before going to calculate the mask-retval. */
__set_current_state(TASK_INTERRUPTIBLE);
if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
init_timeout = schedule_timeout(init_timeout);
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ poll_freewait(&wait_table);
current->state = TASK_RUNNING;
if (signal_pending(current)) {
return -ERESTARTSYS;
@@ -298,9 +295,11 @@ static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
if (!init_timeout) {
return -EIO;
}
- } else if (wait_table.nr) {
- remove_wait_queue(entry.wait_address, &entry.wait);
- fput(file);
+ if(wait_table.error) {
+ return wait_table.error;
+ }
+ } else {
+ poll_freewait(&wait_table);
}
current->state = TASK_RUNNING;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 4ef5569fc..993dcc1a4 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -897,11 +897,15 @@ int nfs_open(struct inode *inode, struct file *filp)
int nfs_release(struct inode *inode, struct file *filp)
{
- struct rpc_auth *auth = NFS_CLIENT(inode)->cl_auth;
- struct rpc_cred *cred = nfs_file_cred(filp);
+ struct rpc_auth *auth;
+ struct rpc_cred *cred;
+ lock_kernel();
+ auth = NFS_CLIENT(inode)->cl_auth;
+ cred = nfs_file_cred(filp);
if (cred)
rpcauth_releasecred(auth, cred);
+ unlock_kernel();
return 0;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7a144d707..2cdec3ec8 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -317,7 +317,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap)
if (err)
goto out_nfserr;
if (EX_ISSYNC(fhp->fh_export))
- write_inode_now(inode, 0);
+ write_inode_now(inode, 1);
err = 0;
out:
return err;
@@ -894,7 +894,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (EX_ISSYNC(fhp->fh_export)) {
nfsd_sync_dir(dentry);
- write_inode_now(dchild->d_inode, 0);
+ write_inode_now(dchild->d_inode, 1);
}
@@ -1140,7 +1140,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
| S_IFLNK;
err = notify_change(dnew, iap);
if (!err && EX_ISSYNC(fhp->fh_export))
- write_inode_now(dentry->d_inode, 0);
+ write_inode_now(dentry->d_inode, 1);
}
}
} else
@@ -1200,7 +1200,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
if (!err) {
if (EX_ISSYNC(ffhp->fh_export)) {
nfsd_sync_dir(ddir);
- write_inode_now(dest, 0);
+ write_inode_now(dest, 1);
}
} else {
if (err == -EXDEV && rqstp->rq_vers == 2)
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 3b875a445..430f7b412 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -13,6 +13,7 @@
#include <linux/locks.h>
#include <linux/init.h>
#include <linux/malloc.h>
+#include <linux/smp_lock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -507,6 +508,7 @@ int property_release (struct inode *inode, struct file *filp)
if (!op)
return 0;
+ lock_kernel();
node = nodes[(u16)((long)inode->u.generic_ip)].node;
if ((u16)((long)inode->u.generic_ip) == aliases) {
if ((op->flag & OPP_DIRTY) && (op->flag & OPP_STRING)) {
@@ -548,6 +550,7 @@ int property_release (struct inode *inode, struct file *filp)
op->name);
}
}
+ unlock_kernel();
kfree (filp->private_data);
return 0;
}
diff --git a/fs/pipe.c b/fs/pipe.c
index 12c160a1a..ef51478a1 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -8,7 +8,6 @@
#include <linux/file.h>
#include <linux/poll.h>
#include <linux/malloc.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -366,14 +365,12 @@ pipe_write_open(struct inode *inode, struct file *filp)
static int
pipe_rdwr_open(struct inode *inode, struct file *filp)
{
- lock_kernel();
down(PIPE_SEM(*inode));
if (filp->f_mode & FMODE_READ)
PIPE_READERS(*inode)++;
if (filp->f_mode & FMODE_WRITE)
PIPE_WRITERS(*inode)++;
up(PIPE_SEM(*inode));
- unlock_kernel();
return 0;
}
diff --git a/fs/select.c b/fs/select.c
index a9fd61953..be09afdd7 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -31,14 +31,15 @@
* understand what I'm doing here, then you understand how the linux
* sleep/wakeup mechanism works.
*
- * Two very simple procedures, poll_wait() and free_wait() make all the
+ * Two very simple procedures, poll_wait() and poll_freewait() make all the
* work. poll_wait() is an inline-function defined in <linux/poll.h>,
* as all select/poll functions have to call it to add an entry to the
* poll table.
*/
-static void free_wait(struct poll_table_page * p)
+void poll_freewait(poll_table* pt)
{
+ struct poll_table_page * p = pt->table;
while (p) {
struct poll_table_entry * entry;
struct poll_table_page *old;
@@ -66,6 +67,7 @@ void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table
new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL);
if (!new_table) {
p->error = -ENOMEM;
+ __set_current_state(TASK_RUNNING);
return;
}
new_table->nr = 0;
@@ -160,9 +162,10 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
return retval;
n = retval;
- table.error = 0;
- table.table = NULL;
+ poll_initwait(&table);
wait = &table;
+ if (!__timeout)
+ wait = NULL;
retval = 0;
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
@@ -201,11 +204,15 @@ int do_select(int n, fd_set_bits *fds, long *timeout)
wait = NULL;
if (retval || !__timeout || signal_pending(current))
break;
+ if(table.error) {
+ retval = table.error;
+ break;
+ }
__timeout = schedule_timeout(__timeout);
}
current->state = TASK_RUNNING;
- free_wait(table.table);
+ poll_freewait(&table);
/*
* Up-to-date the caller timeout.
@@ -354,18 +361,22 @@ static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
struct pollfd *fds[], poll_table *wait, long timeout)
{
int count = 0;
+ poll_table* pt = wait;
for (;;) {
unsigned int i;
set_current_state(TASK_INTERRUPTIBLE);
for (i=0; i < nchunks; i++)
- do_pollfd(POLLFD_PER_PAGE, fds[i], &wait, &count);
+ do_pollfd(POLLFD_PER_PAGE, fds[i], &pt, &count);
if (nleft)
- do_pollfd(nleft, fds[nchunks], &wait, &count);
- wait = NULL;
+ do_pollfd(nleft, fds[nchunks], &pt, &count);
+ pt = NULL;
if (count || !timeout || signal_pending(current))
break;
+ if(wait->error) {
+ return wait->error;
+ }
timeout = schedule_timeout(timeout);
}
current->state = TASK_RUNNING;
@@ -376,7 +387,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
{
int i, j, fdcount, err;
struct pollfd **fds;
- poll_table table;
+ poll_table table, *wait;
int nchunks, nleft;
/* Do a sanity check on nfds ... */
@@ -391,10 +402,12 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
}
- table.error = 0;
- table.table = NULL;
- err = -ENOMEM;
+ poll_initwait(&table);
+ wait = &table;
+ if (!timeout)
+ wait = NULL;
+ err = -ENOMEM;
fds = NULL;
if (nfds != 0) {
fds = (struct pollfd **)kmalloc(
@@ -429,7 +442,7 @@ asmlinkage long sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
goto out_fds1;
}
- fdcount = do_poll(nfds, nchunks, nleft, fds, &table, timeout);
+ fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout);
/* OK, now copy the revents fields back to user space. */
for(i=0; i < nchunks; i++)
@@ -452,6 +465,6 @@ out_fds:
if (nfds != 0)
kfree(fds);
out:
- free_wait(table.table);
+ poll_freewait(&table);
return err;
}
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 2c3b96638..247bae08f 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -343,8 +343,10 @@ smb_file_open(struct inode *inode, struct file * file)
static int
smb_file_release(struct inode *inode, struct file * file)
{
+ lock_kernel();
if (!--inode->u.smbfs_i.openers)
smb_close(inode);
+ unlock_kernel();
return 0;
}
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 94597406d..662647088 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -38,6 +38,7 @@
#include <linux/string.h> /* memset */
#include <linux/errno.h>
#include <linux/locks.h>
+#include <linux/smp_lock.h>
#include "udf_i.h"
#include "udf_sb.h"
@@ -296,8 +297,11 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
*/
static int udf_release_file(struct inode * inode, struct file * filp)
{
- if (filp->f_mode & FMODE_WRITE)
+ if (filp->f_mode & FMODE_WRITE) {
+ lock_kernel();
udf_discard_prealloc(inode);
+ unlock_kernel();
+ }
return 0;
}
diff --git a/include/asm-mips64/sn/klconfig.h b/include/asm-mips64/sn/klconfig.h
index 493582fc5..1c79d7ee0 100644
--- a/include/asm-mips64/sn/klconfig.h
+++ b/include/asm-mips64/sn/klconfig.h
@@ -11,8 +11,6 @@
#ifndef _ASM_SN_KLCONFIG_H
#define _ASM_SN_KLCONFIG_H
-#include <linux/config.h>
-
/*
* The KLCONFIG structures store info about the various BOARDs found
* during Hardware Discovery. In addition, it stores info about the
@@ -29,6 +27,7 @@
* that offsets of existing fields do not change.
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <asm/sn/types.h>
#if defined(CONFIG_SGI_IP27)
@@ -37,29 +36,25 @@
// XXX Stolen from <sys/SN/router.h>:
#define MAX_ROUTER_PORTS (6) /* Max. number of ports on a router */
#include <asm/sn/sn0/sn0_fru.h>
-#include <asm/sn/agent.h>
//#include <sys/graph.h>
-#include <asm/arc/types.h>
-#include <asm/arc/hinv.h>
//#include <sys/xtalk/xbow.h>
-#if defined(CONFIG_SGI_IO)
-// The hack file has to be before vector and after sn0_fru....
-#include <asm/hack.h>
-#include <asm/sn/vector.h>
-#include <asm/xtalk/xtalk.h>
-#endif /* CONFIG_SGI_IO */
#elif defined(CONFIG_SGI_IP35)
-#include <asm/hack.h>
#include <asm/sn/sn1/addrs.h>
-#include <asm/sn/vector.h>
#include <sys/sn/router.h>
-#include <asm/sn/agent.h>
#include <sys/graph.h>
+#include <asm/xtalk/xbow.h>
+#endif /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
+#if defined(CONFIG_SGI_IP27) || defined(CONFIG_SGI_IP35)
+#include <asm/sn/agent.h>
#include <asm/arc/types.h>
#include <asm/arc/hinv.h>
-#include <asm/xtalk/xbow.h>
+#if defined(CONFIG_SGI_IO) || defined(CONFIG_SGI_IP35)
+// The hack file has to be before vector and after sn0_fru....
+#include <asm/hack.h>
+#include <asm/sn/vector.h>
#include <asm/xtalk/xtalk.h>
-#endif /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
+#endif /* CONFIG_SGI_IO || CONFIG_SGI_IP35 */
+#endif /* CONFIG_SGI_IP27 || CONFIG_SGI_IP35 */
#define KLCFGINFO_MAGIC 0xbeedbabe
diff --git a/include/asm-ppc/backlight.h b/include/asm-ppc/backlight.h
new file mode 100644
index 000000000..db315e677
--- /dev/null
+++ b/include/asm-ppc/backlight.h
@@ -0,0 +1,28 @@
+/*
+ * Routines for handling backlight control on PowerBooks
+ *
+ * For now, implementation resides in arch/ppc/kernel/pmac_support.c
+ *
+ */
+#ifndef __ASM_PPC_BACKLIGHT_H
+#define __ASM_PPC_BACKLIGHT_H
+
+/* Abstract values */
+#define BACKLIGHT_OFF 0
+#define BACKLIGHT_MIN 1
+#define BACKLIGHT_MAX 0xf
+
+struct backlight_controller {
+ int (*set_enable)(int enable, int level, void *data);
+ int (*set_level)(int level, void *data);
+};
+
+extern void register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type);
+extern void unregister_backlight_controller(struct backlight_controller *ctrler, void *data);
+
+extern int set_backlight_enable(int enable);
+extern int get_backlight_enable(void);
+extern int set_backlight_level(int level);
+extern int get_backlight_level(void);
+
+#endif \ No newline at end of file
diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h
index 78d73b532..c9f2d2eac 100644
--- a/include/asm-ppc/feature.h
+++ b/include/asm-ppc/feature.h
@@ -45,6 +45,7 @@ enum system_feature {
FEATURE_IDE2_reset,
FEATURE_Mediabay_IDE_switch, /* MB IDE bus switch */
FEATURE_Mediabay_content, /* MB content indicator enable */
+ FEATURE_Airport_reset, /* Is it actually a reset ? */
FEATURE_last,
};
@@ -70,4 +71,20 @@ extern int feature_clear(struct device_node* device, enum system_feature f);
extern void feature_init(void);
+/*
+ * Additional functions related to Core99 machines
+ */
+extern void feature_set_gmac_power(struct device_node* device, int power);
+
+extern void feature_set_usb_power(struct device_node* device, int power);
+
+extern void feature_set_firewire_power(struct device_node* device, int power);
+
+/*
+ * Sleep related functions. At term, they should be high-priority notifiers
+ */
+extern void feature_prepare_for_sleep(void);
+
+extern void feature_wake_up(void);
+
#endif /* __ASM_PPC_FEATURE_H */
diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h
index 0c5a1090d..239580395 100644
--- a/include/asm-ppc/hardirq.h
+++ b/include/asm-ppc/hardirq.h
@@ -4,24 +4,38 @@
#include <linux/config.h>
#include <asm/smp.h>
-extern unsigned int local_irq_count[NR_CPUS];
+typedef struct {
+ unsigned int __local_irq_count;
+ unsigned int __local_bh_count;
+ atomic_t __nmi_counter;
+ unsigned int __pad[5];
+} ____cacheline_aligned irq_cpustat_t;
+
+extern irq_cpustat_t irq_stat [NR_CPUS];
+
+/*
+ * Simple wrappers reducing source bloat
+ */
+#define local_irq_count(cpu) (irq_stat[(cpu)].__local_irq_count)
+#define local_bh_count(cpu) (irq_stat[(cpu)].__local_bh_count)
+#define nmi_counter(cpu) (irq_stat[(cpu)].__nmi_counter)
/*
* Are we in an interrupt context? Either doing bottom half
* or hardware interrupt processing?
*/
#define in_interrupt() ({ int __cpu = smp_processor_id(); \
- (local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+ (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
-#define in_irq() (local_irq_count[smp_processor_id()] != 0)
+#define in_irq() (local_irq_count(smp_processor_id()) != 0)
#ifndef CONFIG_SMP
-#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0)
+#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0)
#define hardirq_endlock(cpu) do { } while (0)
-#define hardirq_enter(cpu) (local_irq_count[cpu]++)
-#define hardirq_exit(cpu) (local_irq_count[cpu]--)
+#define hardirq_enter(cpu) (local_irq_count(cpu)++)
+#define hardirq_exit(cpu) (local_irq_count(cpu)--)
#define synchronize_irq() do { } while (0)
@@ -46,7 +60,7 @@ static inline void hardirq_enter(int cpu)
{
unsigned int loops = 10000000;
- ++local_irq_count[cpu];
+ ++local_irq_count(cpu);
atomic_inc(&global_irq_count);
while (test_bit(0,&global_irq_lock)) {
if (smp_processor_id() == global_irq_holder) {
@@ -68,7 +82,7 @@ static inline void hardirq_enter(int cpu)
static inline void hardirq_exit(int cpu)
{
atomic_dec(&global_irq_count);
- --local_irq_count[cpu];
+ --local_irq_count(cpu);
}
static inline int hardirq_trylock(int cpu)
diff --git a/include/asm-ppc/heathrow.h b/include/asm-ppc/heathrow.h
index 84a862670..647c63261 100644
--- a/include/asm-ppc/heathrow.h
+++ b/include/asm-ppc/heathrow.h
@@ -13,36 +13,35 @@
* Bits in feature control register.
* Bits postfixed with a _N are in inverse logic
*/
-#define HRW_MODEM_POWER_N 1 /* turns off modem power */
-#define HRW_BAY_POWER_N 2
-#define HRW_BAY_PCI_ENABLE 4
-#define HRW_BAY_IDE_ENABLE 8
-#define HRW_BAY_FLOPPY_ENABLE 0x10
-#define HRW_IDE0_ENABLE 0x20
-#define HRW_IDE0_RESET_N 0x40
-#define HRW_BAY_RESET_N 0x80
-#define HRW_IOBUS_ENABLE 0x100 /* Internal IDE ? */
-#define HRW_SCC_ENABLE 0x200
-#define HRW_MESH_ENABLE 0x400
-#define HRW_SWIM_ENABLE 0x800
-#define HRW_SOUND_POWER_N 0x1000
-#define HRW_SOUND_CLK_ENABLE 0x2000
-#define HRW_SCCA_IO 0x4000
-#define HRW_SCCB_IO 0x8000
-#define HRW_PORT_OR_DESK_VIA_N 0x10000 /* This one is 0 on PowerBook */
-#define HRW_PWM_MON_ID_N 0x20000 /* ??? (0) */
-#define HRW_HOOK_MB_CNT_N 0x40000 /* ??? (0) */
-#define HRW_SWIM_CLONE_FLOPPY 0x80000 /* ??? (0) */
-#define HRW_AUD_RUN22 0x100000 /* ??? (1) */
-#define HRW_SCSI_LINK_MODE 0x200000 /* Read ??? (1) */
-#define HRW_ARB_BYPASS 0x400000 /* ??? (0 on main, 1 on gatwick) */
-#define HRW_IDE1_RESET_N 0x800000 /* Media bay */
-#define HRW_SLOW_SCC_PCLK 0x1000000 /* ??? (0) */
-#define HRW_RESET_SCC 0x2000000 /* perhaps? */
-#define HRW_MFDC_CELL_ENABLE 0x4000000 /* ??? (0) */
-#define HRW_USE_MFDC 0x8000000 /* ??? (0) */
+#define HRW_RESET_SCC 0x00000001 /* Named in_use_led in OF ??? */
+#define HRW_BAY_POWER_N 0x00000002
+#define HRW_BAY_PCI_ENABLE 0x00000004
+#define HRW_BAY_IDE_ENABLE 0x00000008
+#define HRW_BAY_FLOPPY_ENABLE 0x00000010
+#define HRW_IDE0_ENABLE 0x00000020
+#define HRW_IDE0_RESET_N 0x00000040
+#define HRW_BAY_RESET_N 0x00000080
+#define HRW_IOBUS_ENABLE 0x00000100 /* Internal IDE ? */
+#define HRW_SCC_ENABLE 0x00000200
+#define HRW_MESH_ENABLE 0x00000400
+#define HRW_SWIM_ENABLE 0x00000800
+#define HRW_SOUND_POWER_N 0x00001000
+#define HRW_SOUND_CLK_ENABLE 0x00002000
+#define HRW_SCCA_IO 0x00004000
+#define HRW_SCCB_IO 0x00008000
+#define HRW_PORT_OR_DESK_VIA_N 0x00010000 /* This one is 0 on PowerBook */
+#define HRW_PWM_MON_ID_N 0x00020000 /* ??? (0) */
+#define HRW_HOOK_MB_CNT_N 0x00040000 /* ??? (0) */
+#define HRW_SWIM_CLONE_FLOPPY 0x00080000 /* ??? (0) */
+#define HRW_AUD_RUN22 0x00100000 /* ??? (1) */
+#define HRW_SCSI_LINK_MODE 0x00200000 /* Read ??? (1) */
+#define HRW_ARB_BYPASS 0x00400000 /* ??? (0 on main, 1 on gatwick) */
+#define HRW_IDE1_RESET_N 0x00800000 /* Media bay */
+#define HRW_SLOW_SCC_PCLK 0x01000000 /* ??? (0) */
+#define HRW_MODEM_POWER_N 0x02000000 /* Used by internal modem on wallstreet */
+#define HRW_MFDC_CELL_ENABLE 0x04000000 /* ??? (0) */
+#define HRW_USE_MFDC 0x08000000 /* ??? (0) */
#define HRW_BMAC_IO_ENABLE 0x60000000 /* two bits, not documented in OF */
#define HRW_BMAC_RESET 0x80000000 /* not documented in OF */
-
#define PADD_MODEM_POWER_N 0x00000001 /* modem power on paddington */
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index 5e7b1b578..108004ae2 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -74,6 +74,11 @@ struct machdep_calls {
unsigned char dev_fn, unsigned char offset, unsigned int val);
void (*pcibios_fixup)(void);
void (*pcibios_fixup_bus)(struct pci_bus *);
+
+ void* (*pci_dev_io_base)(unsigned char bus, unsigned char devfn);
+ void* (*pci_dev_mem_base)(unsigned char bus, unsigned char devfn);
+ int (*pci_dev_root_bridge)(unsigned char bus, unsigned char devfn);
+
/* this is for modules, since _machine can be a define -- Cort */
int ppc_machine;
};
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 2befa81ba..db327b76a 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -32,6 +32,14 @@
#include <asm/rpxclassic.h>
#endif
+#if (defined(CONFIG_TQM860) || defined(CONFIG_TQM860L))
+#include <asm/tqm860.h>
+#endif
+
+#ifdef CONFIG_TQM8xxL
+#include <asm/tqm8xxL.h>
+#endif
+
/* I need this to get pt_regs.......
*/
#include <asm/ptrace.h>
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index 47a2cc87d..ca893118a 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -6,9 +6,22 @@ void pmac_find_bridges(void);
/*
* pci_io_base returns the memory address at which you can access
* the I/O space for PCI bus number `bus' (or NULL on error).
+ *
+ * NOTE: This doesn't handle the new Uni-N chip which requires
+ * per-device io_base.
*/
void *pci_io_base(unsigned int bus);
+/* This version handles the new Uni-N host bridge, the iobase is now
+ * a per-device thing. I also added the memory base so PReP can
+ * be fixed to return 0xc0000000 (I didn't actually implement it)
+ */
+void *pci_dev_io_base(unsigned char bus, unsigned char devfn);
+void *pci_dev_mem_base(unsigned char bus, unsigned char devfn);
+
+/* Returns the root-bridge number (Uni-N number) of a device */
+int pci_dev_root_bridge(unsigned char bus, unsigned char devfn);
+
/*
* pci_device_loc returns the bus number and device/function number
* for a device on a PCI bus, given its device_node struct.
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index 26fe498dc..a9da1b195 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -1,6 +1,13 @@
#ifndef __PPC_PCI_H
#define __PPC_PCI_H
+/* Values for the `which' argument to sys_pciconfig_iobase syscall. */
+#define IOBASE_BRIDGE_NUMBER 0
+#define IOBASE_MEMORY 1
+#define IOBASE_IO 2
+
+#ifdef __KERNEL__
+
/* Can be used to override the logic in pci_scan_bus for skipping
* already-configured bus numbers - to be used for buggy BIOSes
* or architectures with incomplete PCI setup by the loader.
@@ -95,4 +102,6 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask)
#define sg_dma_address(sg) (virt_to_bus((sg)->address))
#define sg_dma_len(sg) ((sg)->length)
+#endif /* __KERNEL__ */
+
#endif /* __PPC_PCI_H */
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index 86a086e79..a0a96d937 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -10,7 +10,6 @@
#include <linux/config.h>
#include <asm/ptrace.h>
-#include <asm/residual.h>
#include <asm/types.h>
/* Machine State Register (MSR) Fields */
@@ -505,6 +504,8 @@
#define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */
#define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */
#define _MACH_8260 0x00002000 /* Generic 8260 */
+#define _MACH_tqm860 0x00004000 /* TQM860/L */
+#define _MACH_tqm8xxL 0x00008000 /* TQM8xxL */
/* see residual.h for these */
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 70ff81302..a3d6e5d22 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -89,4 +89,7 @@ extern void prom_drawstring(const char *c);
extern void prom_drawhex(unsigned long v);
extern void prom_drawchar(char c);
+extern void map_bootx_text(void);
+
+
#endif /* _PPC_PROM_H */
diff --git a/include/asm-ppc/softirq.h b/include/asm-ppc/softirq.h
index 550b46192..f23ed416b 100644
--- a/include/asm-ppc/softirq.h
+++ b/include/asm-ppc/softirq.h
@@ -6,9 +6,9 @@
extern unsigned int local_bh_count[NR_CPUS];
-#define local_bh_disable() do { local_bh_count[smp_processor_id()]++; barrier(); } while (0)
-#define local_bh_enable() do { barrier(); local_bh_count[smp_processor_id()]--; } while (0)
+#define local_bh_disable() do { local_bh_count(smp_processor_id())++; barrier(); } while (0)
+#define local_bh_enable() do { barrier(); local_bh_count(smp_processor_id())--; } while (0)
-#define in_softirq() (local_bh_count[smp_processor_id()] != 0)
+#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
#endif /* __ASM_SOFTIRQ_H */
diff --git a/arch/ppc/kernel/time.h b/include/asm-ppc/time.h
index 05d791546..05d791546 100644
--- a/arch/ppc/kernel/time.h
+++ b/include/asm-ppc/time.h
diff --git a/include/asm-ppc/tqm860.h b/include/asm-ppc/tqm860.h
new file mode 100644
index 000000000..a42b7b277
--- /dev/null
+++ b/include/asm-ppc/tqm860.h
@@ -0,0 +1,65 @@
+
+/*
+ * A collection of structures, addresses, and values associated with
+ * the TQ Systems TQM860 modules. This was originally created for the
+ * MBX860, and probably needs revisions for other boards (like the 821).
+ * When this file gets out of control, we can split it up into more
+ * meaningful pieces.
+ *
+ * Based on mbx.h, Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * Copyright (c) 1999 Wolfgang Denk (wd@denx.de)
+ */
+#ifndef __MACH_TQM860_DEFS
+#define __MACH_TQM860_DEFS
+
+/* A Board Information structure that is given to a program when
+ * EPPC-Bug starts it up.
+ */
+typedef struct bd_info {
+ unsigned long bi_memstart; /* start of DRAM memory */
+ unsigned long bi_memsize; /* size of DRAM memory in bytes */
+ unsigned long bi_flashstart; /* start of FLASH memory */
+ unsigned long bi_flashsize; /* size of FLASH memory */
+ unsigned long bi_flashoffset; /* reserved area for startup monitor */
+ unsigned long bi_sramstart; /* start of SRAM memory */
+ unsigned long bi_sramsize; /* size of SRAM memory */
+ unsigned long bi_immr_base; /* base of IMMR register */
+ unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
+ unsigned long bi_ip_addr; /* IP Address */
+ unsigned char bi_enetaddr[6]; /* Ethernet adress */
+ unsigned char bi_reserved[2]; /* -- just for alignment -- */
+ unsigned long bi_putchar; /* Addr of monitor putchar() to Console */
+ unsigned long bi_intfreq; /* Internal Freq, in MHz */
+ unsigned long bi_busfreq; /* Bus Freq, in MHz */
+ unsigned long bi_baudrate; /* Console Baudrate */
+} bd_t;
+
+/* Configuration options for TQ Systems TQM860 mini module
+ */
+
+#define TQM_RESET_ADDR 0x40000100 /* Monitor Reset Entry */
+
+#define TQM_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */
+#define TQM_IMAP_SIZE (64 * 1024) /* size of mapped area */
+
+#define TQM_CLOCKRATE 50 /* 50 MHz Clock */
+#define TQM_BAUDRATE 115200 /* Console baud rate */
+#define TQM_IP_ADDR 0x0A000063 /* IP addr: 10.0.0.99 */
+
+#define TQM_SERVER_IP "10.0.0.3" /* NFS server IP addr */
+#define TQM_SERVER_DIR "/LinuxPPC" /* NFS exported root */
+
+#define IMAP_ADDR TQM_IMMR_BASE /* physical base address of IMMR area */
+#define IMAP_SIZE TQM_IMAP_SIZE /* mapped size of IMMR area */
+
+/* We don't use the 8259.
+*/
+#define NR_8259_INTS 0
+
+/* Generic 8xx type
+*/
+#define _MACH_8xx (_MACH_tqm860)
+
+#endif /* __MACH_TQM860_DEFS */
+
diff --git a/include/asm-ppc/tqm8xxL.h b/include/asm-ppc/tqm8xxL.h
new file mode 100644
index 000000000..e51e98080
--- /dev/null
+++ b/include/asm-ppc/tqm8xxL.h
@@ -0,0 +1,66 @@
+
+/*
+ * A collection of structures, addresses, and values associated with
+ * the TQ Systems TQM850L modules. This was originally created for the
+ * MBX860, and probably needs revisions for other boards (like the 821).
+ * When this file gets out of control, we can split it up into more
+ * meaningful pieces.
+ *
+ * Based on mbx.h, Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+ *
+ * Copyright (c) 1999 Wolfgang Denk (wd@denx.de)
+ */
+#ifndef __MACH_TQM8xxL_DEFS
+#define __MACH_TQM8xxL_DEFS
+
+/* A Board Information structure that is given to a program when
+ * EPPC-Bug starts it up.
+ */
+typedef struct bd_info {
+ unsigned long bi_memstart; /* start of DRAM memory */
+ unsigned long bi_memsize; /* size of DRAM memory in bytes */
+ unsigned long bi_flashstart; /* start of FLASH memory */
+ unsigned long bi_flashsize; /* size of FLASH memory */
+ unsigned long bi_flashoffset; /* reserved area for startup monitor */
+ unsigned long bi_sramstart; /* start of SRAM memory */
+ unsigned long bi_sramsize; /* size of SRAM memory */
+ unsigned long bi_immr_base; /* base of IMMR register */
+ unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
+ unsigned long bi_ip_addr; /* IP Address */
+ unsigned char bi_enetaddr[6]; /* Ethernet adress */
+ unsigned char bi_reserved[2]; /* -- just for alignment -- */
+ unsigned long bi_putchar; /* Addr of monitor putchar() to Console */
+ unsigned long bi_intfreq; /* Internal Freq, in MHz */
+ unsigned long bi_busfreq; /* Bus Freq, in MHz */
+ unsigned long bi_baudrate; /* Console Baudrate */
+} bd_t;
+
+/* Configuration options for TQ Systems TQM850L mini module
+ */
+
+#define TQM_RESET_ADDR 0x40000100 /* Monitor Reset Entry */
+
+#define TQM_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */
+#define TQM_IMAP_SIZE (64 * 1024) /* size of mapped area */
+
+#define TQM_CLOCKRATE 50 /* 50 MHz Clock */
+/*#define TQM_BAUDRATE 115200 */ /* Console baud rate */
+#define TQM_BAUDRATE 38400 /* Console baud rate */
+#define TQM_IP_ADDR 0x0A000063 /* IP addr: 10.0.0.99 */
+
+#define TQM_SERVER_IP "10.0.0.2" /* NFS server IP addr */
+#define TQM_SERVER_DIR "/LinuxPPC" /* NFS exported root */
+
+#define IMAP_ADDR TQM_IMMR_BASE /* physical base address of IMMR area */
+#define IMAP_SIZE TQM_IMAP_SIZE /* mapped size of IMMR area */
+
+/* We don't use the 8259.
+*/
+#define NR_8259_INTS 0
+
+/* Generic 8xx type
+*/
+#define _MACH_8xx (_MACH_tqm8xxL)
+
+#endif /* __MACH_TQM8xxL_DEFS */
+
diff --git a/include/asm-ppc/ucontext.h b/include/asm-ppc/ucontext.h
index 12d444cb1..3d60332a3 100644
--- a/include/asm-ppc/ucontext.h
+++ b/include/asm-ppc/ucontext.h
@@ -7,6 +7,7 @@ struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
+ struct sigcontext_struct uc_mcontext;
sigset_t uc_sigmask; /* mask last for extensibility */
};
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
index 4c64c151a..db4e6499b 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -201,6 +201,10 @@
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
+#define __NR_sys_pciconfig_read 198
+#define __NR_sys_pciconfig_write 199
+#define __NR_sys_pciconfig_iobase 200
+#define __NR_multiplexer 201
#define __NR(n) #n
diff --git a/include/asm-ppc/vga.h b/include/asm-ppc/vga.h
index d7ead205f..69e3d7f9a 100644
--- a/include/asm-ppc/vga.h
+++ b/include/asm-ppc/vga.h
@@ -21,12 +21,12 @@
* <linux/vt_buffer.h> has already done the right job for us.
*/
-extern inline void scr_writew(u16 val, u16 *addr)
+extern inline void scr_writew(u16 val, volatile u16 *addr)
{
st_le16(addr, val);
}
-extern inline u16 scr_readw(const u16 *addr)
+extern inline u16 scr_readw(volatile const u16 *addr)
{
return ld_le16(addr);
}
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index eea4560fc..28c5e47db 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -22,7 +22,7 @@ typedef s390_regs elf_gregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
-#define elf_check_arch(x) ((x)->elf_machine == EM_S390)
+#define elf_check_arch(x) ((x)->e_machine == EM_S390)
/*
* These are used to set parameters in the core dumps.
diff --git a/include/asm-sparc/asm_offsets.h b/include/asm-sparc/asm_offsets.h
index d6c868ff0..3c2d94ff6 100644
--- a/include/asm-sparc/asm_offsets.h
+++ b/include/asm-sparc/asm_offsets.h
@@ -79,112 +79,112 @@
#define AOFF_task_pidhash_pprev 0x00000094
#define ASIZ_task_pidhash_pprev 0x00000004
#define AOFF_task_wait_chldexit 0x00000098
-#define ASIZ_task_wait_chldexit 0x00000014
-#define AOFF_task_vfork_sem 0x000000ac
+#define ASIZ_task_wait_chldexit 0x0000000c
+#define AOFF_task_vfork_sem 0x000000a4
#define ASIZ_task_vfork_sem 0x00000004
-#define AOFF_task_rt_priority 0x000000b0
+#define AOFF_task_rt_priority 0x000000a8
#define ASIZ_task_rt_priority 0x00000004
-#define AOFF_task_it_real_value 0x000000b4
+#define AOFF_task_it_real_value 0x000000ac
#define ASIZ_task_it_real_value 0x00000004
-#define AOFF_task_it_prof_value 0x000000b8
+#define AOFF_task_it_prof_value 0x000000b0
#define ASIZ_task_it_prof_value 0x00000004
-#define AOFF_task_it_virt_value 0x000000bc
+#define AOFF_task_it_virt_value 0x000000b4
#define ASIZ_task_it_virt_value 0x00000004
-#define AOFF_task_it_real_incr 0x000000c0
+#define AOFF_task_it_real_incr 0x000000b8
#define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000c4
+#define AOFF_task_it_prof_incr 0x000000bc
#define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000c8
+#define AOFF_task_it_virt_incr 0x000000c0
#define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer 0x000000cc
+#define AOFF_task_real_timer 0x000000c4
#define ASIZ_task_real_timer 0x00000014
-#define AOFF_task_times 0x000000e0
+#define AOFF_task_times 0x000000d8
#define ASIZ_task_times 0x00000010
-#define AOFF_task_start_time 0x000000f0
+#define AOFF_task_start_time 0x000000e8
#define ASIZ_task_start_time 0x00000004
-#define AOFF_task_per_cpu_utime 0x000000f4
+#define AOFF_task_per_cpu_utime 0x000000ec
#define ASIZ_task_per_cpu_utime 0x00000004
-#define AOFF_task_min_flt 0x000000fc
+#define AOFF_task_min_flt 0x000000f4
#define ASIZ_task_min_flt 0x00000004
-#define AOFF_task_maj_flt 0x00000100
+#define AOFF_task_maj_flt 0x000000f8
#define ASIZ_task_maj_flt 0x00000004
-#define AOFF_task_nswap 0x00000104
+#define AOFF_task_nswap 0x000000fc
#define ASIZ_task_nswap 0x00000004
-#define AOFF_task_cmin_flt 0x00000108
+#define AOFF_task_cmin_flt 0x00000100
#define ASIZ_task_cmin_flt 0x00000004
-#define AOFF_task_cmaj_flt 0x0000010c
+#define AOFF_task_cmaj_flt 0x00000104
#define ASIZ_task_cmaj_flt 0x00000004
-#define AOFF_task_cnswap 0x00000110
+#define AOFF_task_cnswap 0x00000108
#define ASIZ_task_cnswap 0x00000004
-#define AOFF_task_uid 0x00000118
+#define AOFF_task_uid 0x00000110
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x0000011c
+#define AOFF_task_euid 0x00000114
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x00000120
+#define AOFF_task_suid 0x00000118
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000124
+#define AOFF_task_fsuid 0x0000011c
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000128
+#define AOFF_task_gid 0x00000120
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x0000012c
+#define AOFF_task_egid 0x00000124
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000130
+#define AOFF_task_sgid 0x00000128
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000134
+#define AOFF_task_fsgid 0x0000012c
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000138
+#define AOFF_task_ngroups 0x00000130
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x0000013c
+#define AOFF_task_groups 0x00000134
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000001bc
+#define AOFF_task_cap_effective 0x000001b4
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000001c0
+#define AOFF_task_cap_inheritable 0x000001b8
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000001c4
+#define AOFF_task_cap_permitted 0x000001bc
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000001cc
+#define AOFF_task_user 0x000001c4
#define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x000001d0
+#define AOFF_task_rlim 0x000001c8
#define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math 0x00000220
+#define AOFF_task_used_math 0x00000218
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000222
+#define AOFF_task_comm 0x0000021a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000234
+#define AOFF_task_link_count 0x0000022c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000238
+#define AOFF_task_tty 0x00000230
#define ASIZ_task_tty 0x00000004
-#define AOFF_task_semundo 0x0000023c
+#define AOFF_task_semundo 0x00000234
#define ASIZ_task_semundo 0x00000004
-#define AOFF_task_semsleeping 0x00000240
+#define AOFF_task_semsleeping 0x00000238
#define ASIZ_task_semsleeping 0x00000004
-#define AOFF_task_thread 0x00000248
+#define AOFF_task_thread 0x00000240
#define ASIZ_task_thread 0x00000380
-#define AOFF_task_fs 0x000005c8
+#define AOFF_task_fs 0x000005c0
#define ASIZ_task_fs 0x00000004
-#define AOFF_task_files 0x000005cc
+#define AOFF_task_files 0x000005c4
#define ASIZ_task_files 0x00000004
-#define AOFF_task_sigmask_lock 0x000005d0
+#define AOFF_task_sigmask_lock 0x000005c8
#define ASIZ_task_sigmask_lock 0x00000004
-#define AOFF_task_sig 0x000005d4
+#define AOFF_task_sig 0x000005cc
#define ASIZ_task_sig 0x00000004
-#define AOFF_task_signal 0x000005d8
+#define AOFF_task_signal 0x000005d0
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000005e0
+#define AOFF_task_blocked 0x000005d8
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x000005e8
+#define AOFF_task_sigqueue 0x000005e0
#define ASIZ_task_sigqueue 0x00000004
-#define AOFF_task_sigqueue_tail 0x000005ec
+#define AOFF_task_sigqueue_tail 0x000005e4
#define ASIZ_task_sigqueue_tail 0x00000004
-#define AOFF_task_sas_ss_sp 0x000005f0
+#define AOFF_task_sas_ss_sp 0x000005e8
#define ASIZ_task_sas_ss_sp 0x00000004
-#define AOFF_task_sas_ss_size 0x000005f4
+#define AOFF_task_sas_ss_size 0x000005ec
#define ASIZ_task_sas_ss_size 0x00000004
-#define AOFF_task_parent_exec_id 0x000005f8
+#define AOFF_task_parent_exec_id 0x000005f0
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x000005fc
+#define AOFF_task_self_exec_id 0x000005f4
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000600
+#define AOFF_task_alloc_lock 0x000005f8
#define ASIZ_task_alloc_lock 0x00000004
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000004
@@ -201,48 +201,48 @@
#define AOFF_mm_map_count 0x00000018
#define ASIZ_mm_map_count 0x00000004
#define AOFF_mm_mmap_sem 0x0000001c
-#define ASIZ_mm_mmap_sem 0x00000020
-#define AOFF_mm_page_table_lock 0x0000003c
+#define ASIZ_mm_mmap_sem 0x00000014
+#define AOFF_mm_page_table_lock 0x00000030
#define ASIZ_mm_page_table_lock 0x00000004
-#define AOFF_mm_context 0x00000040
+#define AOFF_mm_context 0x00000034
#define ASIZ_mm_context 0x00000004
-#define AOFF_mm_start_code 0x00000044
+#define AOFF_mm_start_code 0x00000038
#define ASIZ_mm_start_code 0x00000004
-#define AOFF_mm_end_code 0x00000048
+#define AOFF_mm_end_code 0x0000003c
#define ASIZ_mm_end_code 0x00000004
-#define AOFF_mm_start_data 0x0000004c
+#define AOFF_mm_start_data 0x00000040
#define ASIZ_mm_start_data 0x00000004
-#define AOFF_mm_end_data 0x00000050
+#define AOFF_mm_end_data 0x00000044
#define ASIZ_mm_end_data 0x00000004
-#define AOFF_mm_start_brk 0x00000054
+#define AOFF_mm_start_brk 0x00000048
#define ASIZ_mm_start_brk 0x00000004
-#define AOFF_mm_brk 0x00000058
+#define AOFF_mm_brk 0x0000004c
#define ASIZ_mm_brk 0x00000004
-#define AOFF_mm_start_stack 0x0000005c
+#define AOFF_mm_start_stack 0x00000050
#define ASIZ_mm_start_stack 0x00000004
-#define AOFF_mm_arg_start 0x00000060
+#define AOFF_mm_arg_start 0x00000054
#define ASIZ_mm_arg_start 0x00000004
-#define AOFF_mm_arg_end 0x00000064
+#define AOFF_mm_arg_end 0x00000058
#define ASIZ_mm_arg_end 0x00000004
-#define AOFF_mm_env_start 0x00000068
+#define AOFF_mm_env_start 0x0000005c
#define ASIZ_mm_env_start 0x00000004
-#define AOFF_mm_env_end 0x0000006c
+#define AOFF_mm_env_end 0x00000060
#define ASIZ_mm_env_end 0x00000004
-#define AOFF_mm_rss 0x00000070
+#define AOFF_mm_rss 0x00000064
#define ASIZ_mm_rss 0x00000004
-#define AOFF_mm_total_vm 0x00000074
+#define AOFF_mm_total_vm 0x00000068
#define ASIZ_mm_total_vm 0x00000004
-#define AOFF_mm_locked_vm 0x00000078
+#define AOFF_mm_locked_vm 0x0000006c
#define ASIZ_mm_locked_vm 0x00000004
-#define AOFF_mm_def_flags 0x0000007c
+#define AOFF_mm_def_flags 0x00000070
#define ASIZ_mm_def_flags 0x00000004
-#define AOFF_mm_cpu_vm_mask 0x00000080
+#define AOFF_mm_cpu_vm_mask 0x00000074
#define ASIZ_mm_cpu_vm_mask 0x00000004
-#define AOFF_mm_swap_cnt 0x00000084
+#define AOFF_mm_swap_cnt 0x00000078
#define ASIZ_mm_swap_cnt 0x00000004
-#define AOFF_mm_swap_address 0x00000088
+#define AOFF_mm_swap_address 0x0000007c
#define ASIZ_mm_swap_address 0x00000004
-#define AOFF_mm_segments 0x0000008c
+#define AOFF_mm_segments 0x00000080
#define ASIZ_mm_segments 0x00000004
#define AOFF_thread_uwinmask 0x00000000
#define ASIZ_thread_uwinmask 0x00000004
@@ -360,112 +360,112 @@
#define AOFF_task_pidhash_pprev 0x00000094
#define ASIZ_task_pidhash_pprev 0x00000004
#define AOFF_task_wait_chldexit 0x00000098
-#define ASIZ_task_wait_chldexit 0x00000018
-#define AOFF_task_vfork_sem 0x000000b0
+#define ASIZ_task_wait_chldexit 0x00000010
+#define AOFF_task_vfork_sem 0x000000a8
#define ASIZ_task_vfork_sem 0x00000004
-#define AOFF_task_rt_priority 0x000000b4
+#define AOFF_task_rt_priority 0x000000ac
#define ASIZ_task_rt_priority 0x00000004
-#define AOFF_task_it_real_value 0x000000b8
+#define AOFF_task_it_real_value 0x000000b0
#define ASIZ_task_it_real_value 0x00000004
-#define AOFF_task_it_prof_value 0x000000bc
+#define AOFF_task_it_prof_value 0x000000b4
#define ASIZ_task_it_prof_value 0x00000004
-#define AOFF_task_it_virt_value 0x000000c0
+#define AOFF_task_it_virt_value 0x000000b8
#define ASIZ_task_it_virt_value 0x00000004
-#define AOFF_task_it_real_incr 0x000000c4
+#define AOFF_task_it_real_incr 0x000000bc
#define ASIZ_task_it_real_incr 0x00000004
-#define AOFF_task_it_prof_incr 0x000000c8
+#define AOFF_task_it_prof_incr 0x000000c0
#define ASIZ_task_it_prof_incr 0x00000004
-#define AOFF_task_it_virt_incr 0x000000cc
+#define AOFF_task_it_virt_incr 0x000000c4
#define ASIZ_task_it_virt_incr 0x00000004
-#define AOFF_task_real_timer 0x000000d0
+#define AOFF_task_real_timer 0x000000c8
#define ASIZ_task_real_timer 0x00000014
-#define AOFF_task_times 0x000000e4
+#define AOFF_task_times 0x000000dc
#define ASIZ_task_times 0x00000010
-#define AOFF_task_start_time 0x000000f4
+#define AOFF_task_start_time 0x000000ec
#define ASIZ_task_start_time 0x00000004
-#define AOFF_task_per_cpu_utime 0x000000f8
+#define AOFF_task_per_cpu_utime 0x000000f0
#define ASIZ_task_per_cpu_utime 0x00000080
-#define AOFF_task_min_flt 0x000001f8
+#define AOFF_task_min_flt 0x000001f0
#define ASIZ_task_min_flt 0x00000004
-#define AOFF_task_maj_flt 0x000001fc
+#define AOFF_task_maj_flt 0x000001f4
#define ASIZ_task_maj_flt 0x00000004
-#define AOFF_task_nswap 0x00000200
+#define AOFF_task_nswap 0x000001f8
#define ASIZ_task_nswap 0x00000004
-#define AOFF_task_cmin_flt 0x00000204
+#define AOFF_task_cmin_flt 0x000001fc
#define ASIZ_task_cmin_flt 0x00000004
-#define AOFF_task_cmaj_flt 0x00000208
+#define AOFF_task_cmaj_flt 0x00000200
#define ASIZ_task_cmaj_flt 0x00000004
-#define AOFF_task_cnswap 0x0000020c
+#define AOFF_task_cnswap 0x00000204
#define ASIZ_task_cnswap 0x00000004
-#define AOFF_task_uid 0x00000214
+#define AOFF_task_uid 0x0000020c
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x00000218
+#define AOFF_task_euid 0x00000210
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x0000021c
+#define AOFF_task_suid 0x00000214
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000220
+#define AOFF_task_fsuid 0x00000218
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000224
+#define AOFF_task_gid 0x0000021c
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000228
+#define AOFF_task_egid 0x00000220
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x0000022c
+#define AOFF_task_sgid 0x00000224
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000230
+#define AOFF_task_fsgid 0x00000228
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000234
+#define AOFF_task_ngroups 0x0000022c
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000238
+#define AOFF_task_groups 0x00000230
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000002b8
+#define AOFF_task_cap_effective 0x000002b0
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000002bc
+#define AOFF_task_cap_inheritable 0x000002b4
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000002c0
+#define AOFF_task_cap_permitted 0x000002b8
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000002c8
+#define AOFF_task_user 0x000002c0
#define ASIZ_task_user 0x00000004
-#define AOFF_task_rlim 0x000002cc
+#define AOFF_task_rlim 0x000002c4
#define ASIZ_task_rlim 0x00000050
-#define AOFF_task_used_math 0x0000031c
+#define AOFF_task_used_math 0x00000314
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x0000031e
+#define AOFF_task_comm 0x00000316
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000330
+#define AOFF_task_link_count 0x00000328
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000334
+#define AOFF_task_tty 0x0000032c
#define ASIZ_task_tty 0x00000004
-#define AOFF_task_semundo 0x00000338
+#define AOFF_task_semundo 0x00000330
#define ASIZ_task_semundo 0x00000004
-#define AOFF_task_semsleeping 0x0000033c
+#define AOFF_task_semsleeping 0x00000334
#define ASIZ_task_semsleeping 0x00000004
-#define AOFF_task_thread 0x00000340
+#define AOFF_task_thread 0x00000338
#define ASIZ_task_thread 0x00000380
-#define AOFF_task_fs 0x000006c0
+#define AOFF_task_fs 0x000006b8
#define ASIZ_task_fs 0x00000004
-#define AOFF_task_files 0x000006c4
+#define AOFF_task_files 0x000006bc
#define ASIZ_task_files 0x00000004
-#define AOFF_task_sigmask_lock 0x000006c8
+#define AOFF_task_sigmask_lock 0x000006c0
#define ASIZ_task_sigmask_lock 0x00000008
-#define AOFF_task_sig 0x000006d0
+#define AOFF_task_sig 0x000006c8
#define ASIZ_task_sig 0x00000004
-#define AOFF_task_signal 0x000006d4
+#define AOFF_task_signal 0x000006cc
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000006dc
+#define AOFF_task_blocked 0x000006d4
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x000006e4
+#define AOFF_task_sigqueue 0x000006dc
#define ASIZ_task_sigqueue 0x00000004
-#define AOFF_task_sigqueue_tail 0x000006e8
+#define AOFF_task_sigqueue_tail 0x000006e0
#define ASIZ_task_sigqueue_tail 0x00000004
-#define AOFF_task_sas_ss_sp 0x000006ec
+#define AOFF_task_sas_ss_sp 0x000006e4
#define ASIZ_task_sas_ss_sp 0x00000004
-#define AOFF_task_sas_ss_size 0x000006f0
+#define AOFF_task_sas_ss_size 0x000006e8
#define ASIZ_task_sas_ss_size 0x00000004
-#define AOFF_task_parent_exec_id 0x000006f4
+#define AOFF_task_parent_exec_id 0x000006ec
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x000006f8
+#define AOFF_task_self_exec_id 0x000006f0
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x000006fc
+#define AOFF_task_alloc_lock 0x000006f4
#define ASIZ_task_alloc_lock 0x00000008
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000004
@@ -482,48 +482,48 @@
#define AOFF_mm_map_count 0x00000018
#define ASIZ_mm_map_count 0x00000004
#define AOFF_mm_mmap_sem 0x0000001c
-#define ASIZ_mm_mmap_sem 0x00000024
-#define AOFF_mm_page_table_lock 0x00000040
+#define ASIZ_mm_mmap_sem 0x00000018
+#define AOFF_mm_page_table_lock 0x00000034
#define ASIZ_mm_page_table_lock 0x00000008
-#define AOFF_mm_context 0x00000048
+#define AOFF_mm_context 0x0000003c
#define ASIZ_mm_context 0x00000004
-#define AOFF_mm_start_code 0x0000004c
+#define AOFF_mm_start_code 0x00000040
#define ASIZ_mm_start_code 0x00000004
-#define AOFF_mm_end_code 0x00000050
+#define AOFF_mm_end_code 0x00000044
#define ASIZ_mm_end_code 0x00000004
-#define AOFF_mm_start_data 0x00000054
+#define AOFF_mm_start_data 0x00000048
#define ASIZ_mm_start_data 0x00000004
-#define AOFF_mm_end_data 0x00000058
+#define AOFF_mm_end_data 0x0000004c
#define ASIZ_mm_end_data 0x00000004
-#define AOFF_mm_start_brk 0x0000005c
+#define AOFF_mm_start_brk 0x00000050
#define ASIZ_mm_start_brk 0x00000004
-#define AOFF_mm_brk 0x00000060
+#define AOFF_mm_brk 0x00000054
#define ASIZ_mm_brk 0x00000004
-#define AOFF_mm_start_stack 0x00000064
+#define AOFF_mm_start_stack 0x00000058
#define ASIZ_mm_start_stack 0x00000004
-#define AOFF_mm_arg_start 0x00000068
+#define AOFF_mm_arg_start 0x0000005c
#define ASIZ_mm_arg_start 0x00000004
-#define AOFF_mm_arg_end 0x0000006c
+#define AOFF_mm_arg_end 0x00000060
#define ASIZ_mm_arg_end 0x00000004
-#define AOFF_mm_env_start 0x00000070
+#define AOFF_mm_env_start 0x00000064
#define ASIZ_mm_env_start 0x00000004
-#define AOFF_mm_env_end 0x00000074
+#define AOFF_mm_env_end 0x00000068
#define ASIZ_mm_env_end 0x00000004
-#define AOFF_mm_rss 0x00000078
+#define AOFF_mm_rss 0x0000006c
#define ASIZ_mm_rss 0x00000004
-#define AOFF_mm_total_vm 0x0000007c
+#define AOFF_mm_total_vm 0x00000070
#define ASIZ_mm_total_vm 0x00000004
-#define AOFF_mm_locked_vm 0x00000080
+#define AOFF_mm_locked_vm 0x00000074
#define ASIZ_mm_locked_vm 0x00000004
-#define AOFF_mm_def_flags 0x00000084
+#define AOFF_mm_def_flags 0x00000078
#define ASIZ_mm_def_flags 0x00000004
-#define AOFF_mm_cpu_vm_mask 0x00000088
+#define AOFF_mm_cpu_vm_mask 0x0000007c
#define ASIZ_mm_cpu_vm_mask 0x00000004
-#define AOFF_mm_swap_cnt 0x0000008c
+#define AOFF_mm_swap_cnt 0x00000080
#define ASIZ_mm_swap_cnt 0x00000004
-#define AOFF_mm_swap_address 0x00000090
+#define AOFF_mm_swap_address 0x00000084
#define ASIZ_mm_swap_address 0x00000004
-#define AOFF_mm_segments 0x00000094
+#define AOFF_mm_segments 0x00000088
#define ASIZ_mm_segments 0x00000004
#define AOFF_thread_uwinmask 0x00000000
#define ASIZ_thread_uwinmask 0x00000004
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index af8d4a2d4..59a57452c 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -8,7 +8,6 @@
#ifndef _SPARC_BITOPS_H
#define _SPARC_BITOPS_H
-#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/byteorder.h>
diff --git a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
index fbeaebf2e..436d1a9ad 100644
--- a/include/asm-sparc/elf.h
+++ b/include/asm-sparc/elf.h
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.21 2000/04/14 09:59:04 davem Exp $ */
+/* $Id: elf.h,v 1.22 2000/07/12 01:27:08 davem Exp $ */
#ifndef __ASMSPARC_ELF_H
#define __ASMSPARC_ELF_H
diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h
index 421814863..e191ef259 100644
--- a/include/asm-sparc64/asm_offsets.h
+++ b/include/asm-sparc64/asm_offsets.h
@@ -85,114 +85,114 @@
#define AOFF_task_pidhash_pprev 0x000000f8
#define ASIZ_task_pidhash_pprev 0x00000008
#define AOFF_task_wait_chldexit 0x00000100
-#define ASIZ_task_wait_chldexit 0x00000028
-#define AOFF_task_vfork_sem 0x00000128
+#define ASIZ_task_wait_chldexit 0x00000018
+#define AOFF_task_vfork_sem 0x00000118
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000130
+#define AOFF_task_rt_priority 0x00000120
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000138
+#define AOFF_task_it_real_value 0x00000128
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000140
+#define AOFF_task_it_prof_value 0x00000130
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000148
+#define AOFF_task_it_virt_value 0x00000138
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000150
+#define AOFF_task_it_real_incr 0x00000140
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000158
+#define AOFF_task_it_prof_incr 0x00000148
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000160
+#define AOFF_task_it_virt_incr 0x00000150
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000168
+#define AOFF_task_real_timer 0x00000158
#define ASIZ_task_real_timer 0x00000028
-#define AOFF_task_times 0x00000190
+#define AOFF_task_times 0x00000180
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001b0
+#define AOFF_task_start_time 0x000001a0
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001b8
+#define AOFF_task_per_cpu_utime 0x000001a8
#define ASIZ_task_per_cpu_utime 0x00000008
-#define AOFF_task_min_flt 0x000001c8
+#define AOFF_task_min_flt 0x000001b8
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000001d0
+#define AOFF_task_maj_flt 0x000001c0
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000001d8
+#define AOFF_task_nswap 0x000001c8
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000001e0
+#define AOFF_task_cmin_flt 0x000001d0
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000001e8
+#define AOFF_task_cmaj_flt 0x000001d8
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000001f0
+#define AOFF_task_cnswap 0x000001e0
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x000001fc
+#define AOFF_task_uid 0x000001ec
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x00000200
+#define AOFF_task_euid 0x000001f0
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x00000204
+#define AOFF_task_suid 0x000001f4
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000208
+#define AOFF_task_fsuid 0x000001f8
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x0000020c
+#define AOFF_task_gid 0x000001fc
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000210
+#define AOFF_task_egid 0x00000200
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000214
+#define AOFF_task_sgid 0x00000204
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000218
+#define AOFF_task_fsgid 0x00000208
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x0000021c
+#define AOFF_task_ngroups 0x0000020c
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000220
+#define AOFF_task_groups 0x00000210
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x000002a0
+#define AOFF_task_cap_effective 0x00000290
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x000002a4
+#define AOFF_task_cap_inheritable 0x00000294
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000002a8
+#define AOFF_task_cap_permitted 0x00000298
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000002b0
+#define AOFF_task_user 0x000002a0
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000002b8
+#define AOFF_task_rlim 0x000002a8
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000358
+#define AOFF_task_used_math 0x00000348
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x0000035a
+#define AOFF_task_comm 0x0000034a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x0000036c
+#define AOFF_task_link_count 0x0000035c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000370
+#define AOFF_task_tty 0x00000360
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000378
+#define AOFF_task_semundo 0x00000368
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000380
+#define AOFF_task_semsleeping 0x00000370
#define ASIZ_task_semsleeping 0x00000008
-#define AOFF_task_thread 0x00000390
+#define AOFF_task_thread 0x00000380
#define ASIZ_task_thread 0x00000450
-#define AOFF_task_fs 0x000007e0
+#define AOFF_task_fs 0x000007d0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000007e8
+#define AOFF_task_files 0x000007d8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000007f0
+#define AOFF_task_sigmask_lock 0x000007e0
#define ASIZ_task_sigmask_lock 0x00000004
-#define AOFF_task_sig 0x000007f8
+#define AOFF_task_sig 0x000007e8
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x00000800
+#define AOFF_task_signal 0x000007f0
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000808
+#define AOFF_task_blocked 0x000007f8
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000810
+#define AOFF_task_sigqueue 0x00000800
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000818
+#define AOFF_task_sigqueue_tail 0x00000808
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000820
+#define AOFF_task_sas_ss_sp 0x00000810
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000828
+#define AOFF_task_sas_ss_size 0x00000818
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000830
+#define AOFF_task_parent_exec_id 0x00000820
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000834
+#define AOFF_task_self_exec_id 0x00000824
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000838
+#define AOFF_task_alloc_lock 0x00000828
#define ASIZ_task_alloc_lock 0x00000004
-#define ASIZ_task 0x00000840
+#define ASIZ_task 0x00000830
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -208,50 +208,50 @@
#define AOFF_mm_map_count 0x00000028
#define ASIZ_mm_map_count 0x00000004
#define AOFF_mm_mmap_sem 0x00000030
-#define ASIZ_mm_mmap_sem 0x00000038
-#define AOFF_mm_page_table_lock 0x00000068
+#define ASIZ_mm_mmap_sem 0x00000020
+#define AOFF_mm_page_table_lock 0x00000050
#define ASIZ_mm_page_table_lock 0x00000004
-#define AOFF_mm_context 0x00000070
+#define AOFF_mm_context 0x00000058
#define ASIZ_mm_context 0x00000008
-#define AOFF_mm_start_code 0x00000078
+#define AOFF_mm_start_code 0x00000060
#define ASIZ_mm_start_code 0x00000008
-#define AOFF_mm_end_code 0x00000080
+#define AOFF_mm_end_code 0x00000068
#define ASIZ_mm_end_code 0x00000008
-#define AOFF_mm_start_data 0x00000088
+#define AOFF_mm_start_data 0x00000070
#define ASIZ_mm_start_data 0x00000008
-#define AOFF_mm_end_data 0x00000090
+#define AOFF_mm_end_data 0x00000078
#define ASIZ_mm_end_data 0x00000008
-#define AOFF_mm_start_brk 0x00000098
+#define AOFF_mm_start_brk 0x00000080
#define ASIZ_mm_start_brk 0x00000008
-#define AOFF_mm_brk 0x000000a0
+#define AOFF_mm_brk 0x00000088
#define ASIZ_mm_brk 0x00000008
-#define AOFF_mm_start_stack 0x000000a8
+#define AOFF_mm_start_stack 0x00000090
#define ASIZ_mm_start_stack 0x00000008
-#define AOFF_mm_arg_start 0x000000b0
+#define AOFF_mm_arg_start 0x00000098
#define ASIZ_mm_arg_start 0x00000008
-#define AOFF_mm_arg_end 0x000000b8
+#define AOFF_mm_arg_end 0x000000a0
#define ASIZ_mm_arg_end 0x00000008
-#define AOFF_mm_env_start 0x000000c0
+#define AOFF_mm_env_start 0x000000a8
#define ASIZ_mm_env_start 0x00000008
-#define AOFF_mm_env_end 0x000000c8
+#define AOFF_mm_env_end 0x000000b0
#define ASIZ_mm_env_end 0x00000008
-#define AOFF_mm_rss 0x000000d0
+#define AOFF_mm_rss 0x000000b8
#define ASIZ_mm_rss 0x00000008
-#define AOFF_mm_total_vm 0x000000d8
+#define AOFF_mm_total_vm 0x000000c0
#define ASIZ_mm_total_vm 0x00000008
-#define AOFF_mm_locked_vm 0x000000e0
+#define AOFF_mm_locked_vm 0x000000c8
#define ASIZ_mm_locked_vm 0x00000008
-#define AOFF_mm_def_flags 0x000000e8
+#define AOFF_mm_def_flags 0x000000d0
#define ASIZ_mm_def_flags 0x00000008
-#define AOFF_mm_cpu_vm_mask 0x000000f0
+#define AOFF_mm_cpu_vm_mask 0x000000d8
#define ASIZ_mm_cpu_vm_mask 0x00000008
-#define AOFF_mm_swap_cnt 0x000000f8
+#define AOFF_mm_swap_cnt 0x000000e0
#define ASIZ_mm_swap_cnt 0x00000008
-#define AOFF_mm_swap_address 0x00000100
+#define AOFF_mm_swap_address 0x000000e8
#define ASIZ_mm_swap_address 0x00000008
-#define AOFF_mm_segments 0x00000108
+#define AOFF_mm_segments 0x000000f0
#define ASIZ_mm_segments 0x00000008
-#define ASIZ_mm 0x00000110
+#define ASIZ_mm 0x000000f8
#define AOFF_thread_ksp 0x00000000
#define ASIZ_thread_ksp 0x00000008
#define AOFF_thread_wstate 0x00000008
@@ -379,114 +379,114 @@
#define AOFF_task_pidhash_pprev 0x000000f8
#define ASIZ_task_pidhash_pprev 0x00000008
#define AOFF_task_wait_chldexit 0x00000100
-#define ASIZ_task_wait_chldexit 0x00000028
-#define AOFF_task_vfork_sem 0x00000128
+#define ASIZ_task_wait_chldexit 0x00000018
+#define AOFF_task_vfork_sem 0x00000118
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000130
+#define AOFF_task_rt_priority 0x00000120
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000138
+#define AOFF_task_it_real_value 0x00000128
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000140
+#define AOFF_task_it_prof_value 0x00000130
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000148
+#define AOFF_task_it_virt_value 0x00000138
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000150
+#define AOFF_task_it_real_incr 0x00000140
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000158
+#define AOFF_task_it_prof_incr 0x00000148
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000160
+#define AOFF_task_it_virt_incr 0x00000150
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000168
+#define AOFF_task_real_timer 0x00000158
#define ASIZ_task_real_timer 0x00000028
-#define AOFF_task_times 0x00000190
+#define AOFF_task_times 0x00000180
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001b0
+#define AOFF_task_start_time 0x000001a0
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001b8
+#define AOFF_task_per_cpu_utime 0x000001a8
#define ASIZ_task_per_cpu_utime 0x00000100
-#define AOFF_task_min_flt 0x000003b8
+#define AOFF_task_min_flt 0x000003a8
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000003c0
+#define AOFF_task_maj_flt 0x000003b0
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000003c8
+#define AOFF_task_nswap 0x000003b8
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000003d0
+#define AOFF_task_cmin_flt 0x000003c0
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000003d8
+#define AOFF_task_cmaj_flt 0x000003c8
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000003e0
+#define AOFF_task_cnswap 0x000003d0
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x000003ec
+#define AOFF_task_uid 0x000003dc
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x000003f0
+#define AOFF_task_euid 0x000003e0
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000003f4
+#define AOFF_task_suid 0x000003e4
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x000003f8
+#define AOFF_task_fsuid 0x000003e8
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x000003fc
+#define AOFF_task_gid 0x000003ec
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000400
+#define AOFF_task_egid 0x000003f0
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x00000404
+#define AOFF_task_sgid 0x000003f4
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000408
+#define AOFF_task_fsgid 0x000003f8
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x0000040c
+#define AOFF_task_ngroups 0x000003fc
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000410
+#define AOFF_task_groups 0x00000400
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x00000490
+#define AOFF_task_cap_effective 0x00000480
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x00000494
+#define AOFF_task_cap_inheritable 0x00000484
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x00000498
+#define AOFF_task_cap_permitted 0x00000488
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000004a0
+#define AOFF_task_user 0x00000490
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000004a8
+#define AOFF_task_rlim 0x00000498
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000548
+#define AOFF_task_used_math 0x00000538
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x0000054a
+#define AOFF_task_comm 0x0000053a
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x0000055c
+#define AOFF_task_link_count 0x0000054c
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000560
+#define AOFF_task_tty 0x00000550
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000568
+#define AOFF_task_semundo 0x00000558
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000570
+#define AOFF_task_semsleeping 0x00000560
#define ASIZ_task_semsleeping 0x00000008
-#define AOFF_task_thread 0x00000580
+#define AOFF_task_thread 0x00000570
#define ASIZ_task_thread 0x00000450
-#define AOFF_task_fs 0x000009d0
+#define AOFF_task_fs 0x000009c0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000009d8
+#define AOFF_task_files 0x000009c8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000009e0
+#define AOFF_task_sigmask_lock 0x000009d0
#define ASIZ_task_sigmask_lock 0x00000001
-#define AOFF_task_sig 0x000009e8
+#define AOFF_task_sig 0x000009d8
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x000009f0
+#define AOFF_task_signal 0x000009e0
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x000009f8
+#define AOFF_task_blocked 0x000009e8
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000a00
+#define AOFF_task_sigqueue 0x000009f0
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000a08
+#define AOFF_task_sigqueue_tail 0x000009f8
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000a10
+#define AOFF_task_sas_ss_sp 0x00000a00
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000a18
+#define AOFF_task_sas_ss_size 0x00000a08
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000a20
+#define AOFF_task_parent_exec_id 0x00000a10
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000a24
+#define AOFF_task_self_exec_id 0x00000a14
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000a28
+#define AOFF_task_alloc_lock 0x00000a18
#define ASIZ_task_alloc_lock 0x00000001
-#define ASIZ_task 0x00000a30
+#define ASIZ_task 0x00000a20
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -502,50 +502,50 @@
#define AOFF_mm_map_count 0x00000028
#define ASIZ_mm_map_count 0x00000004
#define AOFF_mm_mmap_sem 0x00000030
-#define ASIZ_mm_mmap_sem 0x00000038
-#define AOFF_mm_page_table_lock 0x00000068
+#define ASIZ_mm_mmap_sem 0x00000020
+#define AOFF_mm_page_table_lock 0x00000050
#define ASIZ_mm_page_table_lock 0x00000001
-#define AOFF_mm_context 0x00000070
+#define AOFF_mm_context 0x00000058
#define ASIZ_mm_context 0x00000008
-#define AOFF_mm_start_code 0x00000078
+#define AOFF_mm_start_code 0x00000060
#define ASIZ_mm_start_code 0x00000008
-#define AOFF_mm_end_code 0x00000080
+#define AOFF_mm_end_code 0x00000068
#define ASIZ_mm_end_code 0x00000008
-#define AOFF_mm_start_data 0x00000088
+#define AOFF_mm_start_data 0x00000070
#define ASIZ_mm_start_data 0x00000008
-#define AOFF_mm_end_data 0x00000090
+#define AOFF_mm_end_data 0x00000078
#define ASIZ_mm_end_data 0x00000008
-#define AOFF_mm_start_brk 0x00000098
+#define AOFF_mm_start_brk 0x00000080
#define ASIZ_mm_start_brk 0x00000008
-#define AOFF_mm_brk 0x000000a0
+#define AOFF_mm_brk 0x00000088
#define ASIZ_mm_brk 0x00000008
-#define AOFF_mm_start_stack 0x000000a8
+#define AOFF_mm_start_stack 0x00000090
#define ASIZ_mm_start_stack 0x00000008
-#define AOFF_mm_arg_start 0x000000b0
+#define AOFF_mm_arg_start 0x00000098
#define ASIZ_mm_arg_start 0x00000008
-#define AOFF_mm_arg_end 0x000000b8
+#define AOFF_mm_arg_end 0x000000a0
#define ASIZ_mm_arg_end 0x00000008
-#define AOFF_mm_env_start 0x000000c0
+#define AOFF_mm_env_start 0x000000a8
#define ASIZ_mm_env_start 0x00000008
-#define AOFF_mm_env_end 0x000000c8
+#define AOFF_mm_env_end 0x000000b0
#define ASIZ_mm_env_end 0x00000008
-#define AOFF_mm_rss 0x000000d0
+#define AOFF_mm_rss 0x000000b8
#define ASIZ_mm_rss 0x00000008
-#define AOFF_mm_total_vm 0x000000d8
+#define AOFF_mm_total_vm 0x000000c0
#define ASIZ_mm_total_vm 0x00000008
-#define AOFF_mm_locked_vm 0x000000e0
+#define AOFF_mm_locked_vm 0x000000c8
#define ASIZ_mm_locked_vm 0x00000008
-#define AOFF_mm_def_flags 0x000000e8
+#define AOFF_mm_def_flags 0x000000d0
#define ASIZ_mm_def_flags 0x00000008
-#define AOFF_mm_cpu_vm_mask 0x000000f0
+#define AOFF_mm_cpu_vm_mask 0x000000d8
#define ASIZ_mm_cpu_vm_mask 0x00000008
-#define AOFF_mm_swap_cnt 0x000000f8
+#define AOFF_mm_swap_cnt 0x000000e0
#define ASIZ_mm_swap_cnt 0x00000008
-#define AOFF_mm_swap_address 0x00000100
+#define AOFF_mm_swap_address 0x000000e8
#define ASIZ_mm_swap_address 0x00000008
-#define AOFF_mm_segments 0x00000108
+#define AOFF_mm_segments 0x000000f0
#define ASIZ_mm_segments 0x00000008
-#define ASIZ_mm 0x00000110
+#define ASIZ_mm 0x000000f8
#define AOFF_thread_ksp 0x00000000
#define ASIZ_thread_ksp 0x00000008
#define AOFF_thread_wstate 0x00000008
@@ -671,114 +671,114 @@
#define AOFF_task_pidhash_pprev 0x000000f8
#define ASIZ_task_pidhash_pprev 0x00000008
#define AOFF_task_wait_chldexit 0x00000100
-#define ASIZ_task_wait_chldexit 0x00000030
-#define AOFF_task_vfork_sem 0x00000130
+#define ASIZ_task_wait_chldexit 0x00000020
+#define AOFF_task_vfork_sem 0x00000120
#define ASIZ_task_vfork_sem 0x00000008
-#define AOFF_task_rt_priority 0x00000138
+#define AOFF_task_rt_priority 0x00000128
#define ASIZ_task_rt_priority 0x00000008
-#define AOFF_task_it_real_value 0x00000140
+#define AOFF_task_it_real_value 0x00000130
#define ASIZ_task_it_real_value 0x00000008
-#define AOFF_task_it_prof_value 0x00000148
+#define AOFF_task_it_prof_value 0x00000138
#define ASIZ_task_it_prof_value 0x00000008
-#define AOFF_task_it_virt_value 0x00000150
+#define AOFF_task_it_virt_value 0x00000140
#define ASIZ_task_it_virt_value 0x00000008
-#define AOFF_task_it_real_incr 0x00000158
+#define AOFF_task_it_real_incr 0x00000148
#define ASIZ_task_it_real_incr 0x00000008
-#define AOFF_task_it_prof_incr 0x00000160
+#define AOFF_task_it_prof_incr 0x00000150
#define ASIZ_task_it_prof_incr 0x00000008
-#define AOFF_task_it_virt_incr 0x00000168
+#define AOFF_task_it_virt_incr 0x00000158
#define ASIZ_task_it_virt_incr 0x00000008
-#define AOFF_task_real_timer 0x00000170
+#define AOFF_task_real_timer 0x00000160
#define ASIZ_task_real_timer 0x00000028
-#define AOFF_task_times 0x00000198
+#define AOFF_task_times 0x00000188
#define ASIZ_task_times 0x00000020
-#define AOFF_task_start_time 0x000001b8
+#define AOFF_task_start_time 0x000001a8
#define ASIZ_task_start_time 0x00000008
-#define AOFF_task_per_cpu_utime 0x000001c0
+#define AOFF_task_per_cpu_utime 0x000001b0
#define ASIZ_task_per_cpu_utime 0x00000100
-#define AOFF_task_min_flt 0x000003c0
+#define AOFF_task_min_flt 0x000003b0
#define ASIZ_task_min_flt 0x00000008
-#define AOFF_task_maj_flt 0x000003c8
+#define AOFF_task_maj_flt 0x000003b8
#define ASIZ_task_maj_flt 0x00000008
-#define AOFF_task_nswap 0x000003d0
+#define AOFF_task_nswap 0x000003c0
#define ASIZ_task_nswap 0x00000008
-#define AOFF_task_cmin_flt 0x000003d8
+#define AOFF_task_cmin_flt 0x000003c8
#define ASIZ_task_cmin_flt 0x00000008
-#define AOFF_task_cmaj_flt 0x000003e0
+#define AOFF_task_cmaj_flt 0x000003d0
#define ASIZ_task_cmaj_flt 0x00000008
-#define AOFF_task_cnswap 0x000003e8
+#define AOFF_task_cnswap 0x000003d8
#define ASIZ_task_cnswap 0x00000008
-#define AOFF_task_uid 0x000003f4
+#define AOFF_task_uid 0x000003e4
#define ASIZ_task_uid 0x00000004
-#define AOFF_task_euid 0x000003f8
+#define AOFF_task_euid 0x000003e8
#define ASIZ_task_euid 0x00000004
-#define AOFF_task_suid 0x000003fc
+#define AOFF_task_suid 0x000003ec
#define ASIZ_task_suid 0x00000004
-#define AOFF_task_fsuid 0x00000400
+#define AOFF_task_fsuid 0x000003f0
#define ASIZ_task_fsuid 0x00000004
-#define AOFF_task_gid 0x00000404
+#define AOFF_task_gid 0x000003f4
#define ASIZ_task_gid 0x00000004
-#define AOFF_task_egid 0x00000408
+#define AOFF_task_egid 0x000003f8
#define ASIZ_task_egid 0x00000004
-#define AOFF_task_sgid 0x0000040c
+#define AOFF_task_sgid 0x000003fc
#define ASIZ_task_sgid 0x00000004
-#define AOFF_task_fsgid 0x00000410
+#define AOFF_task_fsgid 0x00000400
#define ASIZ_task_fsgid 0x00000004
-#define AOFF_task_ngroups 0x00000414
+#define AOFF_task_ngroups 0x00000404
#define ASIZ_task_ngroups 0x00000004
-#define AOFF_task_groups 0x00000418
+#define AOFF_task_groups 0x00000408
#define ASIZ_task_groups 0x00000080
-#define AOFF_task_cap_effective 0x00000498
+#define AOFF_task_cap_effective 0x00000488
#define ASIZ_task_cap_effective 0x00000004
-#define AOFF_task_cap_inheritable 0x0000049c
+#define AOFF_task_cap_inheritable 0x0000048c
#define ASIZ_task_cap_inheritable 0x00000004
-#define AOFF_task_cap_permitted 0x000004a0
+#define AOFF_task_cap_permitted 0x00000490
#define ASIZ_task_cap_permitted 0x00000004
-#define AOFF_task_user 0x000004a8
+#define AOFF_task_user 0x00000498
#define ASIZ_task_user 0x00000008
-#define AOFF_task_rlim 0x000004b0
+#define AOFF_task_rlim 0x000004a0
#define ASIZ_task_rlim 0x000000a0
-#define AOFF_task_used_math 0x00000550
+#define AOFF_task_used_math 0x00000540
#define ASIZ_task_used_math 0x00000002
-#define AOFF_task_comm 0x00000552
+#define AOFF_task_comm 0x00000542
#define ASIZ_task_comm 0x00000010
-#define AOFF_task_link_count 0x00000564
+#define AOFF_task_link_count 0x00000554
#define ASIZ_task_link_count 0x00000004
-#define AOFF_task_tty 0x00000568
+#define AOFF_task_tty 0x00000558
#define ASIZ_task_tty 0x00000008
-#define AOFF_task_semundo 0x00000570
+#define AOFF_task_semundo 0x00000560
#define ASIZ_task_semundo 0x00000008
-#define AOFF_task_semsleeping 0x00000578
+#define AOFF_task_semsleeping 0x00000568
#define ASIZ_task_semsleeping 0x00000008
-#define AOFF_task_thread 0x00000580
+#define AOFF_task_thread 0x00000570
#define ASIZ_task_thread 0x00000450
-#define AOFF_task_fs 0x000009d0
+#define AOFF_task_fs 0x000009c0
#define ASIZ_task_fs 0x00000008
-#define AOFF_task_files 0x000009d8
+#define AOFF_task_files 0x000009c8
#define ASIZ_task_files 0x00000008
-#define AOFF_task_sigmask_lock 0x000009e0
+#define AOFF_task_sigmask_lock 0x000009d0
#define ASIZ_task_sigmask_lock 0x0000000c
-#define AOFF_task_sig 0x000009f0
+#define AOFF_task_sig 0x000009e0
#define ASIZ_task_sig 0x00000008
-#define AOFF_task_signal 0x000009f8
+#define AOFF_task_signal 0x000009e8
#define ASIZ_task_signal 0x00000008
-#define AOFF_task_blocked 0x00000a00
+#define AOFF_task_blocked 0x000009f0
#define ASIZ_task_blocked 0x00000008
-#define AOFF_task_sigqueue 0x00000a08
+#define AOFF_task_sigqueue 0x000009f8
#define ASIZ_task_sigqueue 0x00000008
-#define AOFF_task_sigqueue_tail 0x00000a10
+#define AOFF_task_sigqueue_tail 0x00000a00
#define ASIZ_task_sigqueue_tail 0x00000008
-#define AOFF_task_sas_ss_sp 0x00000a18
+#define AOFF_task_sas_ss_sp 0x00000a08
#define ASIZ_task_sas_ss_sp 0x00000008
-#define AOFF_task_sas_ss_size 0x00000a20
+#define AOFF_task_sas_ss_size 0x00000a10
#define ASIZ_task_sas_ss_size 0x00000008
-#define AOFF_task_parent_exec_id 0x00000a28
+#define AOFF_task_parent_exec_id 0x00000a18
#define ASIZ_task_parent_exec_id 0x00000004
-#define AOFF_task_self_exec_id 0x00000a2c
+#define AOFF_task_self_exec_id 0x00000a1c
#define ASIZ_task_self_exec_id 0x00000004
-#define AOFF_task_alloc_lock 0x00000a30
+#define AOFF_task_alloc_lock 0x00000a20
#define ASIZ_task_alloc_lock 0x0000000c
-#define ASIZ_task 0x00000a40
+#define ASIZ_task 0x00000a30
#define AOFF_mm_mmap 0x00000000
#define ASIZ_mm_mmap 0x00000008
#define AOFF_mm_mmap_avl 0x00000008
@@ -794,50 +794,50 @@
#define AOFF_mm_map_count 0x00000028
#define ASIZ_mm_map_count 0x00000004
#define AOFF_mm_mmap_sem 0x00000030
-#define ASIZ_mm_mmap_sem 0x00000040
-#define AOFF_mm_page_table_lock 0x00000070
+#define ASIZ_mm_mmap_sem 0x00000028
+#define AOFF_mm_page_table_lock 0x00000058
#define ASIZ_mm_page_table_lock 0x0000000c
-#define AOFF_mm_context 0x00000080
+#define AOFF_mm_context 0x00000068
#define ASIZ_mm_context 0x00000008
-#define AOFF_mm_start_code 0x00000088
+#define AOFF_mm_start_code 0x00000070
#define ASIZ_mm_start_code 0x00000008
-#define AOFF_mm_end_code 0x00000090
+#define AOFF_mm_end_code 0x00000078
#define ASIZ_mm_end_code 0x00000008
-#define AOFF_mm_start_data 0x00000098
+#define AOFF_mm_start_data 0x00000080
#define ASIZ_mm_start_data 0x00000008
-#define AOFF_mm_end_data 0x000000a0
+#define AOFF_mm_end_data 0x00000088
#define ASIZ_mm_end_data 0x00000008
-#define AOFF_mm_start_brk 0x000000a8
+#define AOFF_mm_start_brk 0x00000090
#define ASIZ_mm_start_brk 0x00000008
-#define AOFF_mm_brk 0x000000b0
+#define AOFF_mm_brk 0x00000098
#define ASIZ_mm_brk 0x00000008
-#define AOFF_mm_start_stack 0x000000b8
+#define AOFF_mm_start_stack 0x000000a0
#define ASIZ_mm_start_stack 0x00000008
-#define AOFF_mm_arg_start 0x000000c0
+#define AOFF_mm_arg_start 0x000000a8
#define ASIZ_mm_arg_start 0x00000008
-#define AOFF_mm_arg_end 0x000000c8
+#define AOFF_mm_arg_end 0x000000b0
#define ASIZ_mm_arg_end 0x00000008
-#define AOFF_mm_env_start 0x000000d0
+#define AOFF_mm_env_start 0x000000b8
#define ASIZ_mm_env_start 0x00000008
-#define AOFF_mm_env_end 0x000000d8
+#define AOFF_mm_env_end 0x000000c0
#define ASIZ_mm_env_end 0x00000008
-#define AOFF_mm_rss 0x000000e0
+#define AOFF_mm_rss 0x000000c8
#define ASIZ_mm_rss 0x00000008
-#define AOFF_mm_total_vm 0x000000e8
+#define AOFF_mm_total_vm 0x000000d0
#define ASIZ_mm_total_vm 0x00000008
-#define AOFF_mm_locked_vm 0x000000f0
+#define AOFF_mm_locked_vm 0x000000d8
#define ASIZ_mm_locked_vm 0x00000008
-#define AOFF_mm_def_flags 0x000000f8
+#define AOFF_mm_def_flags 0x000000e0
#define ASIZ_mm_def_flags 0x00000008
-#define AOFF_mm_cpu_vm_mask 0x00000100
+#define AOFF_mm_cpu_vm_mask 0x000000e8
#define ASIZ_mm_cpu_vm_mask 0x00000008
-#define AOFF_mm_swap_cnt 0x00000108
+#define AOFF_mm_swap_cnt 0x000000f0
#define ASIZ_mm_swap_cnt 0x00000008
-#define AOFF_mm_swap_address 0x00000110
+#define AOFF_mm_swap_address 0x000000f8
#define ASIZ_mm_swap_address 0x00000008
-#define AOFF_mm_segments 0x00000118
+#define AOFF_mm_segments 0x00000100
#define ASIZ_mm_segments 0x00000008
-#define ASIZ_mm 0x00000120
+#define ASIZ_mm 0x00000108
#define AOFF_thread_ksp 0x00000000
#define ASIZ_thread_ksp 0x00000008
#define AOFF_thread_wstate 0x00000008
diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
index 8a5404930..7e3adf02f 100644
--- a/include/asm-sparc64/elf.h
+++ b/include/asm-sparc64/elf.h
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.24 2000/04/14 09:59:04 davem Exp $ */
+/* $Id: elf.h,v 1.25 2000/07/12 01:27:08 davem Exp $ */
#ifndef __ASM_SPARC64_ELF_H
#define __ASM_SPARC64_ELF_H
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 85ae21c9d..5a53d342d 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -7,6 +7,7 @@
#include <asm/atomic.h>
#include <asm/bitops.h>
#include <asm/system.h>
+#include <linux/wait.h>
struct semaphore {
atomic_t count;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5610b7fe2..4f00239bf 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -151,7 +151,7 @@ extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
extern void generic_unplug_device(void *data);
-extern int generic_make_request(request_queue_t *q, int rw,
+extern void generic_make_request(request_queue_t *q, int rw,
struct buffer_head * bh);
extern request_queue_t *blk_get_queue(kdev_t dev);
extern void blkdev_release_request(struct request *);
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
index 983295c18..555d38fbe 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -13,6 +13,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
+* 2000/07/13 acme remove crap #if KERNEL_VERSION > blah
* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
* and cyclomx_close to cyclomx_mod_dec_use_count
* 1999/05/19 acme wait_queue_head_t wait_stats(support for 2.3.*)
@@ -58,11 +59,7 @@ typedef struct cycx {
spinlock_t lock;
char in_isr; /* interrupt-in-service flag */
char buff_int_mode_unbusy; /* flag for carrying out dev_tint */
-#if (LINUX_VERSION_CODE >= 0x20300)
wait_queue_head_t wait_stats; /* to wait for the STATS indication */
-#else
- struct wait_queue* wait_stats; /* to wait for the STATS indication */
-#endif
u32 mbox; /* -> mailbox */
void (*isr)(struct cycx* card); /* interrupt service routine */
int (*exec)(struct cycx* card, void* u_cmd, void* u_data);
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index c10a1778e..0ed87cdb4 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -2,42 +2,41 @@
/* Linux driver for Disk-On-Chip 2000 */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.h,v 1.7 2000/06/26 20:40:53 dwmw2 Exp $ */
+/* $Id: doc2000.h,v 1.8 2000/07/10 15:46:29 dwmw2 Exp $ */
#ifndef __MTD_DOC2000_H__
#define __MTD_DOC2000_H__
#include <linux/mtd/mtd.h>
-
-#define DoC_M_CDSN_IO 0x800
#define DoC_Sig1 0
#define DoC_Sig2 1
-#define DoC_ChipID 0x1000
-#define DoC_DOCStatus 0x1001
-#define DoC_DOCControl 0x1002
-#define DoC_FloorSelect 0x1003
-#define DoC_CDSNControl 0x1004
-#define DoC_CDSNDeviceSelect 0x1005
-#define DoC_ECCConf 0x1006
-#define DoC_2k_ECCStatus 0x1007
-
-#define DoC_CDSNSlowIO 0x100d
-#define DoC_ECCSyndrome0 0x1010
-#define DoC_ECCSyndrome1 0x1011
-#define DoC_ECCSyndrome2 0x1012
-#define DoC_ECCSyndrome3 0x1013
-#define DoC_ECCSyndrome4 0x1014
-#define DoC_ECCSyndrome5 0x1015
-#define DoC_AliasResolution 0x101b
-#define DoC_ConfigInput 0x101c
-#define DoC_ReadPipeInit 0x101d
-#define DoC_WritePipeTerm 0x101e
-#define DoC_LastDataRead 0x101f
-#define DoC_NOP 0x1020
-
-#define DoC_2k_CDSN_IO 0x1800
+#define DoC_ChipID 0x1000
+#define DoC_DOCStatus 0x1001
+#define DoC_DOCControl 0x1002
+#define DoC_FloorSelect 0x1003
+#define DoC_CDSNControl 0x1004
+#define DoC_CDSNDeviceSelect 0x1005
+#define DoC_ECCConf 0x1006
+#define DoC_2k_ECCStatus 0x1007
+
+#define DoC_CDSNSlowIO 0x100d
+#define DoC_ECCSyndrome0 0x1010
+#define DoC_ECCSyndrome1 0x1011
+#define DoC_ECCSyndrome2 0x1012
+#define DoC_ECCSyndrome3 0x1013
+#define DoC_ECCSyndrome4 0x1014
+#define DoC_ECCSyndrome5 0x1015
+#define DoC_AliasResolution 0x101b
+#define DoC_ConfigInput 0x101c
+#define DoC_ReadPipeInit 0x101d
+#define DoC_WritePipeTerm 0x101e
+#define DoC_LastDataRead 0x101f
+#define DoC_NOP 0x1020
+
+#define DoC_Mil_CDSN_IO 0x0800
+#define DoC_2k_CDSN_IO 0x1800
/* How to access the device?
* On ARM, it'll be mmap'd directly with 32-bit wide accesses.
@@ -54,33 +53,36 @@
#define ReadDOC(adr, reg) readb(((unsigned long)adr) + DoC_##reg)
#define WriteDOC(d, adr, reg) writeb(d, ((unsigned long)adr) + DoC_##reg)
#endif
-#define DOC_MODE_RESET 0
-#define DOC_MODE_NORMAL 1
-#define DOC_MODE_RESERVED1 2
-#define DOC_MODE_RESERVED2 3
-
-#define DOC_MODE_MDWREN 4
-#define DOC_MODE_CLR_ERR 0x80
-
-#define DOC_ChipID_Doc2k 0x20
-#define DOC_ChipID_DocMil 0x30
-
-#define CDSN_CTRL_FR_B 0x80
-#define CDSN_CTRL_ECC_IO 0x20
-#define CDSN_CTRL_FLASH_IO 0x10
-#define CDSN_CTRL_WP 8
-#define CDSN_CTRL_ALE 4
-#define CDSN_CTRL_CLE 2
-#define CDSN_CTRL_CE 1
-
-#define DOC_ECC_RESET 0
-#define DOC_ECC_ERROR 0x80
-#define DOC_ECC_RW 0x20
-#define DOC_ECC__EN 0x08
-#define DOC_TOGGLE_BIT 0x04
-#define DOC_ECC_RESV 0x02
+
+#define DOC_MODE_RESET 0
+#define DOC_MODE_NORMAL 1
+#define DOC_MODE_RESERVED1 2
+#define DOC_MODE_RESERVED2 3
+
+#define DOC_MODE_MDWREN 4
+#define DOC_MODE_CLR_ERR 0x80
+
+#define DOC_ChipID_Doc2k 0x20
+#define DOC_ChipID_DocMil 0x30
+
+#define CDSN_CTRL_FR_B 0x80
+#define CDSN_CTRL_ECC_IO 0x20
+#define CDSN_CTRL_FLASH_IO 0x10
+#define CDSN_CTRL_WP 0x08
+#define CDSN_CTRL_ALE 0x04
+#define CDSN_CTRL_CLE 0x02
+#define CDSN_CTRL_CE 0x01
+
+#define DOC_ECC_RESET 0
+#define DOC_ECC_ERROR 0x80
+#define DOC_ECC_RW 0x20
+#define DOC_ECC__EN 0x08
+#define DOC_TOGGLE_BIT 0x04
+#define DOC_ECC_RESV 0x02
+#define DOC_ECC_IGNORE 0x01
/* We have to also set the reserved bit 1 for enable */
#define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
+#define DOC_ECC_DIS (DOC_ECC_IGNORE | DOC_ECC_RESV)
struct Nand {
char floor, chip;
@@ -92,6 +94,9 @@ struct Nand {
#define MAX_FLOORS 4
#define MAX_CHIPS 4
+#define MAX_FLOORS_MIL 4
+#define MAX_CHIPS_MIL 1
+
struct DiskOnChip {
unsigned long physadr;
unsigned long virtadr;
diff --git a/include/linux/netfilter_ipv4/ip_nat_core.h b/include/linux/netfilter_ipv4/ip_nat_core.h
index 28735e0c1..e34e08331 100644
--- a/include/linux/netfilter_ipv4/ip_nat_core.h
+++ b/include/linux/netfilter_ipv4/ip_nat_core.h
@@ -16,10 +16,10 @@ extern unsigned int do_bindings(struct ip_conntrack *ct,
extern struct list_head protos;
-extern void icmp_reply_translation(struct sk_buff *skb,
- struct ip_conntrack *conntrack,
- unsigned int hooknum,
- int dir);
+extern unsigned int icmp_reply_translation(struct sk_buff *skb,
+ struct ip_conntrack *conntrack,
+ unsigned int hooknum,
+ int dir);
extern void replace_in_hashes(struct ip_conntrack *conntrack,
struct ip_nat_info *info);
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index c1d6ff312..362f07bee 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -280,7 +280,7 @@ struct ipt_get_entries
unsigned int size;
/* The entries. */
- unsigned char entries[0];
+ struct ipt_entry entrytable[0];
};
/* Standard return verdict, or do jump. */
diff --git a/include/linux/netfilter_ipv4/ipt_REJECT.h b/include/linux/netfilter_ipv4/ipt_REJECT.h
index eeafdf468..ad195e435 100644
--- a/include/linux/netfilter_ipv4/ipt_REJECT.h
+++ b/include/linux/netfilter_ipv4/ipt_REJECT.h
@@ -6,7 +6,10 @@ enum ipt_reject_with {
IPT_ICMP_HOST_UNREACHABLE,
IPT_ICMP_PROT_UNREACHABLE,
IPT_ICMP_PORT_UNREACHABLE,
- IPT_ICMP_ECHOREPLY
+ IPT_ICMP_ECHOREPLY,
+ IPT_ICMP_NET_PROHIBITED,
+ IPT_ICMP_HOST_PROHIBITED,
+ IPT_TCP_RESET
};
struct ipt_reject_info {
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index f3617397c..0716ae947 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -286,7 +286,7 @@ struct ip6t_get_entries
unsigned int size;
/* The entries. */
- unsigned char entries[0];
+ struct ip6t_entry entrytable[0];
};
/* Standard return verdict, or do jump. */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 294464b65..27d813e9d 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -309,6 +309,7 @@ struct parport {
rwlock_t cad_lock;
int spintime;
+ atomic_t ref_count;
};
#define DEFAULT_SPIN_TIME 500 /* us */
@@ -337,12 +338,9 @@ void parport_announce_port (struct parport *port);
/* Unregister a port. */
extern void parport_unregister_port(struct parport *port);
-/* parport_in_use returns nonzero if there are devices attached to a
- port. */
-#define parport_in_use(x) ((x)->devices != NULL)
-
/* parport_enumerate returns a pointer to the linked list of all the
- ports in this machine. */
+ ports in this machine. DON'T USE THIS. Use
+ parport_register_driver instead. */
struct parport *parport_enumerate(void);
/* Register a new high-level driver. */
@@ -351,6 +349,15 @@ extern int parport_register_driver (struct parport_driver *);
/* Unregister a high-level driver. */
extern void parport_unregister_driver (struct parport_driver *);
+/* If parport_register_driver doesn't fit your needs, perhaps
+ * parport_find_xxx does. */
+extern struct parport *parport_find_number (int);
+extern struct parport *parport_find_base (unsigned long);
+
+/* Reference counting for ports. */
+extern struct parport *parport_get_port (struct parport *);
+extern void parport_put_port (struct parport *);
+
/* parport_register_device declares that a device is connected to a
port, and tells the kernel all it needs to know.
- pf is the preemption function (may be NULL for no callback)
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 04ae938be..a53a165b1 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1061,6 +1061,10 @@
#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */
#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */
+#define PCI_VENDOR_ID_SYBA 0x1592
+#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
+#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783
+
#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
diff --git a/include/linux/poll.h b/include/linux/poll.h
index bc0fcde22..64b5df671 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -38,22 +38,13 @@ extern inline void poll_wait(struct file * filp, wait_queue_head_t * wait_addres
__pollwait(filp, wait_address, p);
}
-/*
- * For the kernel fd_set we use a fixed set-size for allocation purposes.
- * This set-size doesn't necessarily bear any relation to the size the user
- * uses, but should preferably obviously be larger than any possible user
- * size (NR_OPEN bits).
- *
- * We need 6 bitmaps (in/out/ex for both incoming and outgoing), and we
- * allocate one page for all the bitmaps. Thus we have 8*PAGE_SIZE bits,
- * to be divided by 6. And we'd better make sure we round to a full
- * long-word (in fact, we'll round to 64 bytes).
- */
-
+static inline void poll_initwait(poll_table* pt)
+{
+ pt->error = 0;
+ pt->table = NULL;
+}
+extern void poll_freewait(poll_table* pt);
-#define KFDS_64BLOCK ((PAGE_SIZE/(6*64))*64)
-#define KFDS_NR (KFDS_64BLOCK*8 > NR_OPEN ? NR_OPEN : KFDS_64BLOCK*8)
-typedef unsigned long kernel_fd_set[KFDS_NR/__NFDBITS];
/*
* Scaleable version of the fd_set.
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 1b1d3f902..885687193 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -551,6 +551,7 @@ extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned if
extern int usb_register(struct usb_driver *);
extern void usb_deregister(struct usb_driver *);
+extern void usb_scan_devices(void);
/* used these for multi-interface device registration */
extern void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface *iface, void* priv);
diff --git a/include/video/fbcon.h b/include/video/fbcon.h
index 796b8f96b..e5f26faa4 100644
--- a/include/video/fbcon.h
+++ b/include/video/fbcon.h
@@ -229,6 +229,7 @@ extern int set_all_vcs(int fbidx, struct fb_ops *fb,
#endif
+extern void fbcon_redraw_clear(struct vc_data *, struct display *, int, int, int, int);
extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 63595484d..32e548315 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -235,6 +235,7 @@ EXPORT_SYMBOL(vfs_rename);
EXPORT_SYMBOL(vfs_statfs);
EXPORT_SYMBOL(generic_read_dir);
EXPORT_SYMBOL(__pollwait);
+EXPORT_SYMBOL(poll_freewait);
EXPORT_SYMBOL(ROOT_DEV);
EXPORT_SYMBOL(__find_get_page);
EXPORT_SYMBOL(__find_lock_page);
diff --git a/kernel/sched.c b/kernel/sched.c
index 38e792167..2f35e928a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -233,7 +233,7 @@ static void reschedule_idle(struct task_struct * p, unsigned long flags)
* its preferred CPU. (this is a shortcut):
*/
tsk = cpu_curr(best_cpu);
- if (preemption_goodness(tsk, p, best_cpu) > 1)
+ if (preemption_goodness(tsk, p, best_cpu) > 0)
goto preempt_now;
}
@@ -290,7 +290,7 @@ send_now_idle:
* altogether, tsk->need_resched is actively watched by the
* idle thread.
*/
- if (!tsk->need_resched)
+ if ((tsk->processor != current->processor) && !tsk->need_resched)
smp_send_reschedule(tsk->processor);
tsk->need_resched = 1;
spin_unlock_irqrestore(&runqueue_lock, flags);
@@ -436,10 +436,7 @@ signed long schedule_timeout(signed long timeout)
add_timer(&timer);
schedule();
- del_timer(&timer);
- /* RED-PEN. Timer may be running now on another cpu.
- * Pray that process will not exit enough fastly.
- */
+ del_timer_sync(&timer);
timeout = expire - jiffies;
diff --git a/mm/memory.c b/mm/memory.c
index de7dc07f8..83f1586d4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -373,12 +373,12 @@ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long s
spin_unlock(&mm->page_table_lock);
/*
* Update rss for the mm_struct (not necessarily current->mm)
+ * Notice that rss is an unsigned long.
*/
- if (mm->rss > 0) {
+ if (mm->rss > freed)
mm->rss -= freed;
- if (mm->rss < 0)
- mm->rss = 0;
- }
+ else
+ mm->rss = 0;
}
diff --git a/mm/slab.c b/mm/slab.c
index a24e46582..a31f0f7e7 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1966,7 +1966,7 @@ int slabinfo_read_proc (char *page, char **start, off_t off,
#define MAX_SLABINFO_WRITE 128
/**
* slabinfo_write_proc - SMP tuning for the slab allocator
- * @file:
+ * @file: unused
* @buffer: user buffer
* @count: data len
* @data: unused
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f19721ee5..c43456da6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -548,9 +548,9 @@ static int do_try_to_free_pages(unsigned int gfp_mask)
if (!--count)
goto done;
}
- /* We return 1 if we are freed some page, or
- * there are no memory pressure remaining */
- return (count != FREE_COUNT || !memory_pressure());
+ /* Return 1 if any page is freed, or
+ * there are no more memory pressure */
+ return (count < FREE_COUNT || !memory_pressure());
done:
return 1;
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index 69d8b726d..1c79056bb 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
#include <asm/uaccess.h>
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index 7f9b9e82b..c372ab029 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -261,11 +261,11 @@ void nf_debug_ip_finish_output2(struct sk_buff *skb)
if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING)
| (1 << NF_IP_FORWARD)
| (1 << NF_IP_POST_ROUTING))) {
- /* Fragments will have no owners, but still
- may be local */
- if (!(skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET))
- || skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING))){
+ /* Fragments, entunnelled packets, TCP RSTs
+ generated by ipt_REJECT will have no
+ owners, but still may be local */
+ if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
+ | (1 << NF_IP_POST_ROUTING))){
printk("ip_finish_output:"
" bad unowned skb = %p: ",skb);
debug_print_hooks_ip(skb->nf_debug);
@@ -512,7 +512,6 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
info->indev, info->outdev, &elem,
info->okfn);
}
- br_read_unlock_bh(BR_NETPROTO_LOCK);
switch (verdict) {
case NF_ACCEPT:
@@ -527,6 +526,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
kfree_skb(skb);
break;
}
+ br_read_unlock_bh(BR_NETPROTO_LOCK);
/* Release those devices we held, or Alexey will kill me. */
if (info->indev) dev_put(info->indev);
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index d97558a24..a2bc39398 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -104,7 +104,7 @@ static void dn_run_flush(unsigned long dummy);
static struct dn_rt_hash_bucket *dn_rt_hash_table;
static unsigned dn_rt_hash_mask;
-static struct timer_list dn_route_timer = { function: NULL };
+static struct timer_list dn_route_timer;
static struct timer_list dn_rt_flush_timer = { function: dn_run_flush };
int decnet_dst_gc_interval = 2;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 47e7fb01b..14ebb46e1 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -551,6 +551,7 @@ static inline struct ip_conntrack *
resolve_normal_ct(struct sk_buff *skb,
struct ip_conntrack_protocol *proto,
int *set_reply,
+ unsigned int hooknum,
enum ip_conntrack_info *ctinfo)
{
struct ip_conntrack_tuple tuple;
@@ -573,6 +574,21 @@ resolve_normal_ct(struct sk_buff *skb,
if (DIRECTION(h) == IP_CT_DIR_REPLY) {
/* Reply on unconfirmed connection => unclassifiable */
if (!(h->ctrack->status & IPS_CONFIRMED)) {
+ /* Exception: local TCP RSTs (generated by
+ REJECT target). */
+ if (hooknum == NF_IP_LOCAL_OUT
+ && h->tuple.dst.protonum == IPPROTO_TCP) {
+ const struct tcphdr *tcph
+ = (const struct tcphdr *)
+ ((u_int32_t *)skb->nh.iph
+ + skb->nh.iph->ihl);
+ if (tcph->rst) {
+ *ctinfo = IP_CT_ESTABLISHED
+ + IP_CT_IS_REPLY;
+ *set_reply = 0;
+ goto set_skb;
+ }
+ }
DEBUGP("Reply on unconfirmed connection\n");
ip_conntrack_put(h->ctrack);
return NULL;
@@ -598,6 +614,7 @@ resolve_normal_ct(struct sk_buff *skb,
}
*set_reply = 0;
}
+ set_skb:
skb->nfct = &h->ctrack->infos[*ctinfo];
return h->ctrack;
}
@@ -669,7 +686,7 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
&& icmp_error_track(*pskb, &ctinfo, hooknum))
return NF_ACCEPT;
- if (!(ct = resolve_normal_ct(*pskb, proto, &set_reply, &ctinfo)))
+ if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo)))
/* Not valid part of a connection */
return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 77db6572f..486683bec 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -169,11 +169,15 @@ static unsigned int ip_confirm(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- /* We've seen it coming out the other side: confirm */
+ /* We've seen it coming out the other side: confirm (only if
+ new packet: REJECT can generate TCP RESET response, or ICMP
+ errors) */
if ((*pskb)->nfct) {
struct ip_conntrack *ct
= (struct ip_conntrack *)(*pskb)->nfct->master;
- if (!(ct->status & IPS_CONFIRMED))
+ /* ctinfo is the index of the nfct inside the conntrack */
+ if ((*pskb)->nfct - ct->infos == IP_CT_NEW
+ && !(ct->status & IPS_CONFIRMED))
ip_conntrack_confirm(ct);
}
return NF_ACCEPT;
@@ -191,7 +195,8 @@ static unsigned int ip_refrag(unsigned int hooknum,
if ((*pskb)->nfct) {
struct ip_conntrack *ct
= (struct ip_conntrack *)(*pskb)->nfct->master;
- if (!(ct->status & IPS_CONFIRMED))
+ if ((*pskb)->nfct - ct->infos == IP_CT_NEW
+ && !(ct->status & IPS_CONFIRMED))
ip_conntrack_confirm(ct);
}
diff --git a/net/ipv4/netfilter/ip_fw_compat.c b/net/ipv4/netfilter/ip_fw_compat.c
index 6f0503e05..3c8c2e851 100644
--- a/net/ipv4/netfilter/ip_fw_compat.c
+++ b/net/ipv4/netfilter/ip_fw_compat.c
@@ -71,7 +71,8 @@ confirm_connection(struct sk_buff *skb)
struct ip_conntrack *ct
= (struct ip_conntrack *)skb->nfct->master;
- if (!(ct->status & IPS_CONFIRMED))
+ if (skb->nfct - ct->infos == IP_CT_NEW
+ && !(ct->status & IPS_CONFIRMED))
ip_conntrack_confirm(ct);
}
}
diff --git a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c
index 1e6721174..ce3180d39 100644
--- a/net/ipv4/netfilter/ip_fw_compat_masq.c
+++ b/net/ipv4/netfilter/ip_fw_compat_masq.c
@@ -105,7 +105,7 @@ check_for_masq_error(struct sk_buff *skb)
/* Wouldn't be here if not tracked already => masq'ed ICMP
ping or error related to masq'd connection */
IP_NF_ASSERT(ct);
- if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
+ if (ctinfo == IP_CT_RELATED) {
icmp_reply_translation(skb, ct, NF_IP_PRE_ROUTING,
CTINFO2DIR(ctinfo));
icmp_reply_translation(skb, ct, NF_IP_POST_ROUTING,
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index a07749ecb..c8bf259b9 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -735,7 +735,7 @@ do_bindings(struct ip_conntrack *ct,
} else return NF_ACCEPT;
}
-void
+unsigned int
icmp_reply_translation(struct sk_buff *skb,
struct ip_conntrack *conntrack,
unsigned int hooknum,
@@ -749,6 +749,22 @@ icmp_reply_translation(struct sk_buff *skb,
struct ip_nat_info *info = &conntrack->nat.info;
IP_NF_ASSERT(skb->len >= iph->ihl*4 + sizeof(struct icmphdr));
+ /* Must be RELATED */
+ IP_NF_ASSERT(skb->nfct - (struct ip_conntrack *)skb->nfct->master
+ == IP_CT_RELATED
+ || skb->nfct - (struct ip_conntrack *)skb->nfct->master
+ == IP_CT_RELATED+IP_CT_IS_REPLY);
+
+ /* Redirects on non-null nats must be dropped, else they'll
+ start talking to each other without our translation, and be
+ confused... --RR */
+ if (hdr->type == ICMP_REDIRECT) {
+ /* Don't care about races here. */
+ if (info->initialized
+ != ((1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST))
+ || info->num_manips != 0)
+ return NF_DROP;
+ }
DEBUGP("icmp_reply_translation: translating error %p hook %u dir %s\n",
skb, hooknum, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
@@ -810,6 +826,8 @@ icmp_reply_translation(struct sk_buff *skb,
hdr->checksum = 0;
hdr->checksum = ip_compute_csum((unsigned char *)hdr,
sizeof(*hdr) + datalen);
+
+ return NF_ACCEPT;
}
int ip_nat_helper_register(struct ip_nat_helper *me)
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 11e16e25e..3334a64c2 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -84,9 +84,8 @@ ip_nat_fn(unsigned int hooknum,
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
- icmp_reply_translation(*pskb, ct, hooknum,
- CTINFO2DIR(ctinfo));
- return NF_ACCEPT;
+ return icmp_reply_translation(*pskb, ct, hooknum,
+ CTINFO2DIR(ctinfo));
}
/* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
case IP_CT_NEW:
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 792ae1552..39574b7d4 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -244,7 +244,7 @@ static int ipq_set_verdict(ipq_queue_t *q,
{
ipq_queue_element_t *e;
- if (v->value < 0 || v->value > NF_MAX_VERDICT)
+ if (v->value > NF_MAX_VERDICT)
return -EINVAL;
e = ipq_dequeue(q, id_cmp, v->id);
if (e == NULL)
@@ -309,10 +309,9 @@ static inline int dev_cmp(ipq_queue_element_t *e, unsigned long ifindex)
if (e->info->indev->ifindex == ifindex)
return 1;
if (e->info->outdev)
- if (e->info->outdev->ifindex == ifindex);
+ if (e->info->outdev->ifindex == ifindex)
return 1;
return 0;
-
}
/* Drop any queued packets associated with device ifindex */
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 3105f5a18..40b19760b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1029,7 +1029,7 @@ get_entries(const struct ipt_get_entries *entries,
t->private->number);
if (entries->size == t->private->size)
ret = copy_entries_to_user(t->private->size,
- t, uptr->entries);
+ t, uptr->entrytable);
else {
duprintf("get_entries: I've got %u not %u!\n",
t->private->size,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 220cdb568..c63e95fe8 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -7,6 +7,7 @@
#include <linux/ip.h>
#include <net/icmp.h>
#include <net/ip.h>
+#include <net/tcp.h>
struct in_device;
#include <net/route.h>
#include <linux/netfilter_ipv4/ip_tables.h>
@@ -18,6 +19,113 @@ struct in_device;
#define DEBUGP(format, args...)
#endif
+/* Send RST reply */
+static void send_reset(struct sk_buff *oldskb)
+{
+ struct sk_buff *nskb;
+ struct tcphdr *tcph;
+ struct rtable *rt;
+ unsigned int tcplen;
+ int needs_ack;
+
+ /* Clone skb (skb is about to be dropped, so we don't care) */
+ nskb = skb_clone(oldskb, GFP_ATOMIC);
+ if (!nskb)
+ return;
+
+ /* This packet will not be the same as the other: clear nf fields */
+ nf_conntrack_put(nskb->nfct);
+ nskb->nfct = NULL;
+ nskb->nfcache = 0;
+#ifdef CONFIG_NETFILTER_DEBUG
+ nskb->nf_debug = 0;
+#endif
+
+ /* IP header checks: fragment, too short. */
+ if (nskb->nh.iph->frag_off & htons(IP_OFFSET)
+ || nskb->len < (nskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
+ goto free_nskb;
+
+ tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
+ tcplen = nskb->len - nskb->nh.iph->ihl*4;
+
+ /* Check checksum. */
+ if (tcp_v4_check(tcph, tcplen, nskb->nh.iph->saddr,
+ nskb->nh.iph->daddr,
+ csum_partial((char *)tcph, tcplen, 0)) != 0)
+ goto free_nskb;
+
+ /* No RST for RST. */
+ if (tcph->rst)
+ goto free_nskb;
+
+ nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
+ tcph->source = xchg(&tcph->dest, tcph->source);
+
+ /* Truncate to length (no data) */
+ tcph->doff = sizeof(struct tcphdr)/4;
+ skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
+
+ if (tcph->ack) {
+ needs_ack = 0;
+ tcph->seq = tcph->ack_seq;
+ tcph->ack_seq = 0;
+ } else {
+ needs_ack = 1;
+ tcph->seq = 0;
+ tcph->ack_seq = htonl(ntohl(tcph->seq) + tcph->syn + tcph->fin
+ + tcplen - (tcph->doff<<2));
+ }
+
+ /* Reset flags */
+ ((u_int8_t *)tcph)[13] = 0;
+ tcph->rst = 1;
+ if (needs_ack)
+ tcph->ack = 1;
+
+ tcph->window = 0;
+ tcph->urg_ptr = 0;
+
+ /* Adjust TCP checksum */
+ tcph->check = 0;
+ tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
+ nskb->nh.iph->saddr,
+ nskb->nh.iph->daddr,
+ csum_partial((char *)tcph,
+ sizeof(struct tcphdr), 0));
+
+ /* Adjust IP TTL, DF */
+ nskb->nh.iph->ttl = MAXTTL;
+ /* Set DF, id = 0 */
+ nskb->nh.iph->frag_off = htons(IP_DF);
+ nskb->nh.iph->id = 0;
+
+ /* Adjust IP checksum */
+ nskb->nh.iph->check = 0;
+ nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
+ nskb->nh.iph->ihl);
+
+ /* Routing */
+ if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
+ RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
+ 0) != 0)
+ goto free_nskb;
+
+ dst_release(nskb->dst);
+ nskb->dst = &rt->u.dst;
+
+ /* "Never happens" */
+ if (nskb->len > nskb->dst->pmtu)
+ goto free_nskb;
+
+ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+ ip_finish_output);
+ return;
+
+ free_nskb:
+ kfree_skb(nskb);
+}
+
static unsigned int reject(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
@@ -43,6 +151,12 @@ static unsigned int reject(struct sk_buff **pskb,
case IPT_ICMP_PORT_UNREACHABLE:
icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
break;
+ case IPT_ICMP_NET_PROHIBITED:
+ icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0);
+ break;
+ case IPT_ICMP_HOST_PROHIBITED:
+ icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
+ break;
case IPT_ICMP_ECHOREPLY: {
struct icmphdr *icmph = (struct icmphdr *)
((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
@@ -64,6 +178,9 @@ static unsigned int reject(struct sk_buff **pskb,
}
}
break;
+ case IPT_TCP_RESET:
+ send_reset(*pskb);
+ break;
}
return NF_DROP;
@@ -96,7 +213,7 @@ static int check(const char *tablename,
/* Only allow these for packet filtering. */
if (strcmp(tablename, "filter") != 0) {
- DEBUGP("REJECT: bad table `%s'.\n", table);
+ DEBUGP("REJECT: bad table `%s'.\n", tablename);
return 0;
}
if ((hook_mask & ~((1 << NF_IP_LOCAL_IN)
@@ -118,6 +235,18 @@ static int check(const char *tablename,
DEBUGP("REJECT: ECHOREPLY illegal for non-ping\n");
return 0;
}
+ } else if (rejinfo->with == IPT_TCP_RESET) {
+ /* Must specify that it's a TCP packet */
+ if (e->ip.proto != IPPROTO_TCP
+ || (e->ip.invflags & IPT_INV_PROTO)) {
+ DEBUGP("REJECT: TCP_RESET illegal for non-tcp\n");
+ return 0;
+ }
+ /* Only for local input. Rest is too dangerous. */
+ if ((hook_mask & ~(1 << NF_IP_LOCAL_IN)) != 0) {
+ DEBUGP("REJECT: TCP_RESET only from INPUT\n");
+ return 0;
+ }
}
return 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 282024cc9..46f5e57e8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.208 2000/05/03 06:37:06 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.209 2000/07/12 03:49:30 davem Exp $
*
* IPv4 specific functions
*
@@ -69,8 +69,8 @@ extern int sysctl_ip_dynaddr;
#define ICMP_MIN_LENGTH 8
/* Socket used for sending RSTs */
-struct inode tcp_inode;
-struct socket *tcp_socket=&tcp_inode.u.socket_i;
+static struct inode tcp_inode;
+static struct socket *tcp_socket=&tcp_inode.u.socket_i;
void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
struct sk_buff *skb);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index dea475feb..b3ba4383d 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1075,7 +1075,7 @@ get_entries(const struct ip6t_get_entries *entries,
t->private->number);
if (entries->size == t->private->size)
ret = copy_entries_to_user(t->private->size,
- t, uptr->entries);
+ t, uptr->entrytable);
else {
duprintf("get_entries: I've got %u not %u!\n",
t->private->size,
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 190551d79..01000f862 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: reassembly.c,v 1.18 2000/07/07 22:29:42 davem Exp $
+ * $Id: reassembly.c,v 1.19 2000/07/11 22:35:24 davem Exp $
*
* Based on: net/ipv4/ip_fragment.c
*
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index 5decebd98..fde6788c3 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
#include <asm/segment.h>
@@ -389,12 +390,15 @@ static int irda_open( struct inode * inode, struct file *file)
{
IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+ lock_kernel();
if (irda.in_use) {
+ unlock_kernel();
IRDA_DEBUG(0, __FUNCTION__
"(), irmanager is already running!\n");
return -1;
}
irda.in_use = TRUE;
+ unlock_kernel();
return 0;
}
@@ -446,7 +450,9 @@ static int irda_close(struct inode *inode, struct file *file)
{
IRDA_DEBUG(4, __FUNCTION__ "()\n");
+ lock_kernel();
irda.in_use = FALSE;
+ unlock_kernel();
return 0;
}
diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c
index d0e187aee..bc1b378fc 100644
--- a/net/netlink/netlink_dev.c
+++ b/net/netlink/netlink_dev.c
@@ -26,6 +26,7 @@
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
+#include <linux/smp_lock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -138,10 +139,13 @@ out:
static int netlink_release(struct inode * inode, struct file * file)
{
unsigned int minor = MINOR(inode->i_rdev);
- struct socket *sock = netlink_user[minor];
+ struct socket *sock;
+ lock_kernel();
+ sock = netlink_user[minor];
netlink_user[minor] = NULL;
open_map &= ~(1<<minor);
+ unlock_kernel();
sock_release(sock);
return 0;
}
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index bb6b3a291..dc9f11aa7 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1751,11 +1751,12 @@ cbq_destroy(struct Qdisc* sch)
static void cbq_put(struct Qdisc *sch, unsigned long arg)
{
- struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data;
struct cbq_class *cl = (struct cbq_class*)arg;
if (--cl->refcnt == 0) {
#ifdef CONFIG_NET_CLS_POLICE
+ struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data;
+
spin_lock_bh(&sch->dev->queue_lock);
if (q->rx_class == cl)
q->rx_class = NULL;
diff --git a/net/socket.c b/net/socket.c
index 4cd725731..2b5426991 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -702,10 +702,8 @@ int sock_close(struct inode *inode, struct file *filp)
printk(KERN_DEBUG "sock_close: NULL inode\n");
return 0;
}
- unlock_kernel();
sock_fasync(-1, filp, 0);
sock_release(socki_lookup(inode));
- lock_kernel();
return 0;
}
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index a4bba58e9..3fcf7464c 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -177,7 +177,7 @@ void unix_gc(void)
* Avoid a recursive GC.
*/
- if(!down_trylock(&unix_gc_sem))
+ if (down_trylock(&unix_gc_sem))
return;
read_lock(&unix_table_lock);
diff --git a/scripts/Menuconfig b/scripts/Menuconfig
index c59053f1f..77d919b51 100644
--- a/scripts/Menuconfig
+++ b/scripts/Menuconfig
@@ -1441,7 +1441,7 @@ then
if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
echo "*** Next, you must run 'make dep'."
else
- echo "*** Next, you may run 'make zImage', 'make zdisk', or 'make zlilo.'"
+ echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'."
fi
echo
else