]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.133pre3 2.1.133pre3
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:42 +0000 (15:17 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:42 +0000 (15:17 -0500)
151 files changed:
CREDITS
Documentation/Configure.help
MAINTAINERS
arch/alpha/defconfig
arch/alpha/kernel/irq.c
arch/arm/kernel/ecard.c
arch/arm/kernel/hw-ebsa285.c
arch/arm/kernel/irq.c
arch/i386/config.in
arch/i386/defconfig
arch/i386/kernel/mtrr.c
arch/i386/kernel/time.c
arch/i386/kernel/traps.c
arch/i386/lib/Makefile
arch/i386/lib/checksum.S [new file with mode: 0644]
arch/i386/lib/checksum.c [deleted file]
arch/i386/lib/delay.c
arch/i386/lib/old-checksum.c [new file with mode: 0644]
arch/i386/lib/usercopy.c
arch/i386/mm/init.c
arch/mips/kernel/irq.c
arch/ppc/8xx_io/uart.c
arch/ppc/apus_defconfig
arch/ppc/chrp_defconfig
arch/ppc/common_defconfig
arch/ppc/config.in
arch/ppc/defconfig
arch/ppc/kernel/Makefile
arch/ppc/lib/Makefile
arch/ppc/mbx_defconfig
arch/ppc/pmac_defconfig
arch/ppc/prep_defconfig
arch/sparc/ap1000/util.c
drivers/acorn/block/fd1772.c
drivers/acorn/net/ether1.c
drivers/acorn/scsi/acornscsi.c
drivers/acorn/scsi/fas216.c
drivers/ap1000/ddv_util.c
drivers/block/genhd.c
drivers/block/ide-cd.c
drivers/block/ide-cd.h
drivers/block/ide-floppy.c
drivers/block/ide-probe.c
drivers/block/ll_rw_blk.c
drivers/block/paride/pg.c
drivers/block/paride/pseudo.h
drivers/cdrom/cdrom.c
drivers/char/Config.in
drivers/char/Makefile
drivers/char/isicom.c
drivers/char/radio-gemtek.c [new file with mode: 0644]
drivers/char/serial.c
drivers/char/tpqic02.c
drivers/char/videodev.c
drivers/isdn/avmb1/b1lli.c
drivers/isdn/hisax/callc.c
drivers/macintosh/macserial.c
drivers/macintosh/via-pmu.c
drivers/net/3c523.c
drivers/net/Config.in
drivers/pci/oldproc.c
drivers/sbus/char/bpp.c
drivers/sbus/char/sab82532.c
drivers/sbus/char/su.c
drivers/scsi/README.tmscsim
drivers/scsi/advansys.c
drivers/scsi/dc390.h
drivers/scsi/g_NCR5380.c
drivers/scsi/gdth.c
drivers/scsi/i91uscsi.c
drivers/scsi/scsi_error.c
drivers/scsi/scsiiom.c
drivers/scsi/st.c
drivers/scsi/tmscsim.c
drivers/scsi/tmscsim.h
drivers/sound/Config.in
drivers/sound/ad1848.c
drivers/sound/cs4232.c
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/lowlevel/Config.in
drivers/sound/opl3sa.c
drivers/sound/sb.h
drivers/sound/sb_common.c
drivers/sound/sb_mixer.c
drivers/sound/sb_mixer.h
drivers/sound/softoss_rs.c
drivers/sound/sonicvibes.c
drivers/sound/trix.c
fs/Config.in
fs/binfmt_misc.c
fs/buffer.c
fs/devices.c
fs/fat/file.c
fs/file_table.c
fs/hfs/ChangeLog
fs/hfs/bdelete.c
fs/hfs/extent.c
fs/hfs/hfs.h
fs/hfs/inode.c
fs/hfs/mdb.c
fs/hfs/sysdep.c
fs/lockd/host.c
fs/lockd/svc.c
fs/locks.c
fs/namei.c
fs/ncpfs/inode.c
fs/nfs/dir.c
fs/nfsd/nfsfh.c
fs/open.c
fs/read_write.c
fs/smbfs/inode.c
include/asm-alpha/machvec.h
include/asm-alpha/pgtable.h
include/asm-alpha/softirq.h
include/asm-alpha/spinlock.h
include/asm-i386/bitops.h
include/asm-i386/checksum.h
include/asm-i386/posix_types.h
include/asm-i386/smplock.h
include/asm-i386/system.h
include/asm-i386/uaccess.h
include/asm-ppc/softirq.h
include/linux/atalk.h
include/linux/file.h
include/linux/fs.h
include/linux/genhd.h
include/linux/hfs_fs_i.h
include/linux/ipc.h
include/linux/ipx.h
include/linux/module.h
include/linux/msdos_fs_sb.h
include/linux/sem.h
include/linux/swap.h
include/linux/videodev.h
include/net/sock.h
include/video/fbcon.h
ipc/sem.c
kernel/ksyms.c
kernel/module.c
kernel/sched.c
mm/page_io.c
net/appletalk/aarp.c
net/appletalk/ddp.c
net/bridge/br.c
net/ipv6/af_inet6.c
net/ipx/af_ipx.c
net/sched/sch_api.c
net/sunrpc/auth.c
net/sunrpc/xprt.c
scripts/Menuconfig

diff --git a/CREDITS b/CREDITS
index b1fe938a917583b8c4fbf61cd55643147c288e67..7a0675d46124abd0fecddea49213d01ab6bee051 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -84,6 +84,14 @@ S: 20 Ames Street
 S: Cambridge, Massachusetts 02139
 S: USA
 
+N: Jens Axboe
+E: axboe@image.dk
+D: Linux CD-ROM maintainer
+D: jiffies wrap fixes + schedule timeouts depending on HZ == 100
+S: Peter Bangs Vej 258, 2TH
+S: 2500 Valby
+S: Denmark
+
 N: John Aycock
 E: aycock@cpsc.ucalgary.ca
 D: Adaptec 274x driver
index 8567a867360f07ccf34a8bc329f5e84bfe8eae8b..9470b48650db3dfa855fe4c4df2a17b9656df88c 100644 (file)
@@ -21,7 +21,7 @@
 #
 # Information about what a kernel is, what it does, how to patch and
 # compile it and much more is contained in the Kernel-HOWTO, available
-# via FTP (user: anonymous) from sunsite.unc.edu in the directory
+# via FTP (user: anonymous) from metalab.unc.edu in the directory
 # /pub/Linux/docs/HOWTO. Before you start compiling, make sure that
 # you have the necessary versions of all programs and libraries
 # required to compile and run this kernel; they are listed in the file
@@ -80,6 +80,29 @@ CONFIG_EXPERIMENTAL
   you say Y here, you will be offered the choice of using features or
   drivers that are currently considered to be in the alpha-test phase.
 
+Symmetric Multi Processing
+CONFIG_SMP
+  This enables support for systems with more than one CPU.  If you have a
+  system with only one CPU, like most personal computers, say N.  If you
+  have a system with more than one CPU, say Y.
+
+  A non-SMP kernel will run on any machine, but will use only one CPU of
+  a multi-CPU machine.  An SMP kernel will run on many, but not all,
+  single-CPU machines.  On a single-CPU machine, a non-SMP kernel
+  will run faster than an SMP kernel.
+
+  People using multiprocessor machines should also say Y to "Enhanced
+  Real Time Clock Support", below.  The "Advanced Power Management"
+  code will be disabled in an SMP kernel.
+
+  If you don't know what to do here, say N.
+  
+  See also: Documentation/SMP.txt, Documentation/smp.tex,
+  Documentation/smp.txt, and Documentation/IO-APIC.txt.  Also see the
+  SMP-FAQ on the WWW at http://www.irisa.fr/prive/mentre/smp-faq/ (to
+  browse the WWW, you need to have access to a machine on the Internet
+  that has a program like lynx or netscape).
+  
 Kernel math emulation
 CONFIG_MATH_EMULATION
   Linux can emulate a math coprocessor (used for floating point
@@ -97,7 +120,7 @@ CONFIG_MATH_EMULATION
   loader (lilo or loadlin) about how to pass options to the kernel at
   boot time. The lilo procedure is also explained in the SCSI-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) This means that it is a
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) This means that it is a
   good idea to say Y here if you intend to use this kernel on
   different machines. More information about the internals of Linux
   math coprocessor emulation can be found in
@@ -238,11 +261,11 @@ CONFIG_BLK_DEV_IDE
   contained in Documentation/ide.txt. For detailed information about
   hard drives, consult the Disk-HOWTO and the Multi-Disk-HOWTO,
   available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   To fine-tune IDE drive/interface parameters for improved
   performance, look for the hdparm package at
-  ftp://sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/
+  ftp://metalab.unc.edu:/pub/Linux/kernel/patches/diskdrives/
 
   If you have one or more IDE drives, say Y here. If your system has
   no IDE drives, or if memory requirements are really tight, you could
@@ -264,7 +287,7 @@ CONFIG_BLK_DEV_HD_ONLY
   If you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
   instead of this one. For more detailed information, read the
   Disk-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   People with SCSI-only systems can say N here.
 
@@ -307,7 +330,7 @@ CONFIG_BLK_DEV_IDECD
   a newer protocol used by IDE CDROM and TAPE drives, similar to the
   SCSI protocol. Most new CDROM drives use ATAPI, including the
   NEC-260, Mitsumi FX400, Sony 55E, and just about all non-SCSI
-  double(2X), quad(4X), and six(6X) speed drives.
+  double(2X) or better speed drives.
 
   If you say Y here, the CDROM drive will be identified at boot time
   along with other IDE devices, as "hdb" or "hdc", or something
@@ -316,11 +339,11 @@ CONFIG_BLK_DEV_IDECD
   to say Y or M to "ISO 9660 CDROM filesystem support".
 
   Read the CDROM-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and the file
   Documentation/cdrom/ide-cd. Note that older versions of lilo (the
   Linux boot loader) cannot properly deal with IDE/ATAPI CDROMs, so
   install lilo-16 or higher, available from
-  ftp://sunsite.unc.edu/pub/Linux/system/Linux-boot/lilo.
+  ftp://metalab.unc.edu/pub/Linux/system/Linux-boot/lilo.
 
   If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -402,7 +425,7 @@ CONFIG_BLK_DEV_CMD640
   bootparam" or see the documentation of your boot loader about how to
   pass options to the kernel. The lilo procedure is also explained in
   the SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.)
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.)
 
   The CMD640 chip is also used on add-in cards by Acculogic, and on
   the "CSA-6400E PCI to IDE controller" that some people have. For
@@ -448,7 +471,7 @@ CONFIG_BLK_DEV_IDEDMA
   for these drives, but you can change that by saying Y to the
   following question "Use DMA by default when available". You can get
   the latest version of the hdparm utility via anonymous FTP from
-  ftp://sunsite.unc.edu/pub/Linux/system/hardware/.
+  ftp://metalab.unc.edu/pub/Linux/system/hardware/.
 
   Read the comments at the beginning of drivers/block/idedma.c and the
   file Documentation/ide.txt for more information. 
@@ -872,7 +895,7 @@ CONFIG_BLK_DEV_MD
 
   More information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If unsure, say N.
@@ -900,7 +923,7 @@ CONFIG_MD_STRIPED
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to compile this as a module ( = code which can be
@@ -922,7 +945,7 @@ CONFIG_MD_MIRRORING
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to use such a RAID-1 set, say Y. This code is also
@@ -945,7 +968,7 @@ CONFIG_MD_RAID5
 
   Information about Software RAID on Linux is contained in the
   Software-RAID mini-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. There you will also
   learn where to get the supporting user space utilities raidtools.
 
   If you want to use such a RAID-4/RAID-5 set, say Y. This code is
@@ -1044,7 +1067,7 @@ CONFIG_NET_ALIAS
   address they listen on (e.g. "multihosting" or "virtual domains" or
   "virtual hosting services" on the web server apache and the ftp
   server wuftpd -- read the Virtual-Services-HOWTO, available via FTP
-  (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO)
+  (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO)
   or for connecting to different logical networks through the same
   physical interface (most commonly an Ethernet networking card). See
   Documentation/networking/alias.txt for more info.
@@ -1150,7 +1173,7 @@ CONFIG_ALPHA_AVANTI
   http://www.azstarnet.com/~axplinux/ (to browse the WWW, you need to
   have access to a machine on the Internet that has a program like
   lynx or netscape) and also the Alpha-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. For this
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. For this
   question, it suffices to give a unique prefix of the option you want
   to choose. The choices:
   ** Avanti: This is for Mustang (AS200), M3 (AS250), Avanti (AS400)
@@ -1232,7 +1255,7 @@ CONFIG_SERIAL_MANY_PORTS
   standard COM 1/2/3/4 ports. This may happen if you have an AST
   FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available
   via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini), or other custom
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini), or other custom
   serial port hardware which acts similar to standard serial port
   hardware. If you only use the standard COM 1/2/3/4 ports, you can
   say N here to save some memory. You can also say Y if you have an
@@ -1285,7 +1308,7 @@ CONFIG_PCI
   your box. Other bus systems are ISA, EISA, Microchannel (MCA) or
   VESA. If you have PCI, say Y, otherwise N. The PCI-HOWTO, available
   via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, contains valuable
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, contains valuable
   information about which PCI hardware does work under Linux and which
   doesn't.
 
@@ -1348,8 +1371,7 @@ CONFIG_MCA
   MicroChannel Architecture is found in some IBM PS/2 machines and
   laptops. It is a bus system similar to PCI or ISA. See
   Documentation/mca.txt (and especially the web page given there)
-  before attempting to build an MCA bus kernel. Note that this is
-  still experimental code.
+  before attempting to build an MCA bus kernel.
 
 System V IPC
 CONFIG_SYSVIPC
@@ -1359,13 +1381,13 @@ CONFIG_SYSVIPC
   thing, and some programs won't run unless you say Y here. In
   particular, if you want to run the DOS emulator dosemu under Linux
   (read the DOSEMU-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), you'll need to say Y
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO), you'll need to say Y
   here.
   
   You can find documentation about IPC with "info ipc" and also in
   section 6.4 of the Linux Programmer's Guide, available via FTP
   (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide.
+  ftp://metalab.unc.edu/pub/Linux/docs/LDP/programmers-guide.
 
   Saying Y here enlarges your kernel by about 7 KB. Just say Y.
 
@@ -1410,7 +1432,7 @@ CONFIG_BINFMT_ELF
   want to say Y here.
 
   Information about ELF is contained in the ELF HOWTO available via
-  FTP (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  FTP (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you find that after upgrading from Linux kernel 1.2 and saying Y
   here, you still can't run any ELF binaries (they just crash), then
@@ -1455,7 +1477,7 @@ CONFIG_BINFMT_JAVA
 
   If you want to execute JAVA binaries, read the Java on Linux HOWTO,
   available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You will then need to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You will then need to
   install the run time system contained in the Java Developers Kit
   (JDK) as described in the HOWTO. This is completely independent of
   the Linux kernel and you do NOT need to say Y here for this to work.
@@ -1499,7 +1521,7 @@ CONFIG_BINFMT_MISC
   programs that need an interpreter to run like Java, Python or
   Emacs-Lisp. It's also useful if you often run DOS executables under
   the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO). Once you have
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO). Once you have
   registered such a binary class with the kernel, you can start one of
   those programs simply by typing in its name at a shell prompt; Linux
   will automatically feed it to the correct interpreter.
@@ -1553,24 +1575,6 @@ CONFIG_M386
   In rare cases, it can make sense to specify "Pentium" even if
   running on a 486: the kernel will be smaller but slower.
 
-  If you have a single processor machine, make sure that the line
-  "SMP=1" at the top of the toplevel kernel Makefile is commented out;
-  if you have a multi processor machine and want Linux to use all the
-  processors in parallel (Symmetric Multi Processing), make sure that
-  the line "SMP=1" is not commented out and read Documentation/smp and
-  Documentation/IO-APIC.txt and the SMP-FAQ on the WWW at
-  http://www.irisa.fr/prive/mentre/smp-faq/ (to browse the WWW, you
-  need to have access to a machine on the Internet that has a program
-  like lynx or netscape). People using multiprocessor machines should
-  also say Y to "Enhanced Real Time Clock Support", below.
-
-  If you want to compile a kernel that works on both single processor
-  and multi processor machines, it is possible to set SMP=1. The
-  "Advanced Power Management" code (see configuration option below)
-  will not work in that scenario, though. In addition, the kernel will
-  be slower on single processor machines, and other problems may
-  appear, so this is not recommended.
-
   If you don't know what to do, choose "386".
 
 VGA text console
@@ -1581,7 +1585,7 @@ CONFIG_VGA_CONSOLE
 
   The program SVGATextMode can be used to utilize SVGA video cards to
   their full potential in text mode. Download it via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/utils/console.
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/utils/console.
 
   Say Y.
 
@@ -1596,7 +1600,7 @@ CONFIG_VIDEO_SELECT
   "man bootparam" or see the documentation of your boot loader about
   how to pass options to the kernel. The lilo procedure is also
   explained in the SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Read
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Read
   Documentation/svga.txt for more information about the Video mode
   selection support. If unsure, say N.
 
@@ -2232,10 +2236,10 @@ CONFIG_IP_FIREWALL
   If you want to configure your Linux box as a packet filter firewall
   for a local TCP/IP based network, say Y here. You may want to read
   the FIREWALL-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Also, you will need the ipchains tool (available on the WWW at
-  http://www.adelaide.net.au/~rustcorp/) to allow selective blocking
+  http://www.rustcorp.com/linux/ipchains/) to allow selective blocking
   of Internet traffic based on type, origin and destination. 
   Note that the Linux firewall code has changed and the old program
   called ipfwadm won't work anymore.
@@ -2336,9 +2340,7 @@ CONFIG_NET_IPIP
 
   Saying Y to this option will produce two modules ( = code which can
   be inserted in and removed from the running kernel whenever you
-  want), one encapsulator called tunnel.o and one decapsulator called
-  ipip.o. You can read details in drivers/net/README.tunnel. Most
-  people won't need this and can say N.
+  want). Most people won't need this and can say N.
 
 IP: GRE tunnels over IP
 CONFIG_NET_IPGRE
@@ -2387,7 +2389,7 @@ CONFIG_IP_MASQUERADE
   Linux box to the Internet using SLiRP [SLiRP is a SLIP/PPP emulator
   that works if you have a regular dial up shell account on some UNIX
   computer; get it via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/ ].) 
+  ftp://metalab.unc.edu/pub/Linux/system/network/serial/ ].) 
 
   The IP masquerading code will only work if IP forwarding is enabled
   in your kernel; you can do this by saying Y to "/proc
@@ -2400,7 +2402,7 @@ CONFIG_IP_MASQUERADE
 
   Details on how to set things up are contained in the IP Masquerade
   mini-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini; there's also some
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini; there's also some
   information on the WWW at
   http://www.tor.shaw.wave.ca/~ambrose/kernel21.html. 
 
@@ -2427,7 +2429,7 @@ CONFIG_IP_MASQUERADE_ICMP
 IP: masquerading special modules support
 CONFIG_IP_MASQUERADE_MOD
   This provides support for special modules that can modify the
-  rewriting rules used when masquerading. Please not that this feature
+  rewriting rules used when masquerading. Please note that this feature
   adds a little overhead in the input packet processing chain.
 
   Examples of such modules are ipautofw (allowing the masquerading of
@@ -2437,7 +2439,7 @@ CONFIG_IP_MASQUERADE_MOD
 
   You will need the user space program "ipmasqadm" to use these
   additional modules; you can download it from
-  http://juanjox.home.ml.org/
+  http://juanjox.linuxhq.com/
 
   All this additional code is still under development and so is
   currently marked EXPERIMENTAL.
@@ -2452,7 +2454,7 @@ CONFIG_IP_MASQUERADE_IPAUTOFW
   ftp://ftp.netis.com/pub/members/rlynch/
 
   You will also need the ipmasqadm tool available from
-  http://juanjox.home.ml.org .
+  http://juanjox.linuxhq.com/ .
 
   The ipautofw code is still under development and so is currently
   marked EXPERIMENTAL. If you want to try it, say Y.
@@ -2483,7 +2485,7 @@ CONFIG_IP_MASQUERADE_IPPORTFW
   see ftp://ftp.compsoc.net/users/steve/ipportfw/linux21/
 
   You will need the user space program "ipmasqadm" which can be
-  downloaded from http://juanjox.home.ml.org/
+  downloaded from http://juanjox.linuxhq.com/
 
   The portfw code is still under development and so is currently
   marked EXPERIMENTAL. If you want to try it, say Y.
@@ -2494,12 +2496,12 @@ CONFIG_IP_MASQUERADE_IPPORTFW
   it as a module, say M here and read Documentation/modules.txt.
 
 IP: ipmarkfw masquerade support
-CONFIG_IP_MASQUERADE_IPMARKFW
-  This provides functionality equivalent to port forwarding, the
-  difference is that Mark Forwarding uses "firewalling mark" to select
-  which packets must forward (see ipchains(8), "-m" argument).
+CONFIG_IP_MASQUERADE_MFW
+  This provides functionality similar to port forwarding, the
+  difference is that Firewall Mark Forwarding uses "firewalling mark" 
+  to select which packets must forward (see ipchains(8), "-m" argument).
 
-  The markfw code is still under development and so is currently
+  The ip_masq_mfw code is still under development and so is currently
   marked EXPERIMENTAL. If you want to try it, say Y.
 
   This code is also available as a module ( = code which can be
@@ -2538,7 +2540,7 @@ CONFIG_IP_ALIAS
   need to have access to a machine on the Internet that has a program
   like lynx or netscape) and also in the Virtual-Hosting-HOWTO,
   available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Another scenario would be that there are two logical networks living
   on your local Ethernet and you want to access them both with the
@@ -2605,7 +2607,7 @@ CONFIG_INET_RARP
 
   If you actually want to use a diskless Sun 3 machine as an X
   terminal to Linux, say Y here and fetch Linux-Xkernel from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/boot.net/.
+  ftp://metalab.unc.edu/pub/Linux/system/network/boot.net/.
 
   Superior solutions to the problem of booting and configuring
   machines over a net connection are given by the protocol BOOTP and
@@ -2756,9 +2758,9 @@ CONFIG_IPX
   used for local networks of Windows machines. You need it if you want
   to access Novell NetWare file or print servers using the Linux
   Novell client ncpfs (available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/filesystems/) or from within
+  ftp://metalab.unc.edu/pub/Linux/system/filesystems/) or from within
   the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO). In order to do the
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO). In order to do the
   former, you'll also have to say Y to "NCP filesystem support",
   below.
 
@@ -2768,9 +2770,9 @@ CONFIG_IPX
 
   To turn your Linux box into a fully featured NetWare file server and
   IPX router, say Y here and fetch either lwared from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/daemons/ or mars_nwe
+  ftp://metalab.unc.edu/pub/Linux/system/network/daemons/ or mars_nwe
   from ftp://ftp.gwdg.de/pub/linux/misc/ncpfs. For more information,
-  read the IPX-HOWTO in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  read the IPX-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at http://www.eats.com/linux_mac_win.html (to
@@ -2793,7 +2795,7 @@ CONFIG_IPX_INTERN
   same address). The way this is done is to create a virtual internal
   "network" inside your box and to assign an IPX address to this
   network. Say Y here if you want to do this; read the IPX-HOWTO at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO for details.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO for details.
 
   The full internal IPX network enables you to allocate sockets on
   different virtual nodes of the internal network. This is done by
@@ -2823,7 +2825,7 @@ CONFIG_SPX
   space programs lwared or mars_nwe for the server side).
 
   Say Y here if you have use for SPX; read the IPX-HOWTO at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO for details.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO for details.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -2844,7 +2846,7 @@ CONFIG_ATALK
   slower LocalTalk is AppleTalk over a proprietary apple network using
   serial links. EtherTalk and LocalTalk are fully supported by Linux.
   The NET-2-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO contains valuable
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO contains valuable
   information as well.
 
   General information about how to connect Linux, Windows machines and
@@ -2928,7 +2930,7 @@ CONFIG_HAMRADIO
   (to browse the WWW, you need to have access to a machine on the
   Internet that has a program like lynx or netscape) and the HAM-HOWTO
   and the AX25-HOWTO, both available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that the answer to this question won't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -2952,7 +2954,7 @@ CONFIG_AX25
   Information about where to get supporting software for Linux amateur
   radio as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You might also want to
   check out the file Documentation/networking/ax25.txt in the kernel
   source. More information about digital amateur radio in general is
   on the WWW at http://www.tapr.org/tapr/html/pkthome.html. (To browse
@@ -2990,7 +2992,7 @@ CONFIG_NETROM
   A comprehensive listing of all the software for Linux amateur radio
   users as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You also might want to
   check out the file Documentation/networking/ax25.txt. More
   information about digital amateur radio in general is on the WWW at
   http://www.tapr.org/tapr/html/pkthome.html (to browse the WWW, you
@@ -3011,7 +3013,7 @@ CONFIG_ROSE
   A comprehensive listing of all the software for Linux amateur radio
   users as well as information about how to configure an AX.25 port is
   contained in the AX25-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You also might want to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You also might want to
   check out the file Documentation/networking/ax25.txt. More
   information about digital amateur radio in general is on the WWW at
   http://www.tapr.org/tapr/html/pkthome.html (to browse the WWW, you
@@ -3079,7 +3081,7 @@ CONFIG_DMASCC
   (http://www.paccomm.com/gracilis.html) boards. They are detected
   automatically. If you have one of these cards, say Y here and read
   the AX25-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/.
 
   This driver can operate multiple boards simultaneously. If you
   compile it as a module (by saying M instead of Y), it will be called
@@ -3105,7 +3107,7 @@ CONFIG_SCC
   in order to communicate with other computers. If you want to use
   this, read Documentation/networking/z8530drv.txt and the
   AX25-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Also make sure to say Y
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also make sure to say Y
   to "Amateur Radio AX.25 Level 2" support.
 
   If you want to compile this as a module ( = code which can be
@@ -3364,7 +3366,7 @@ CONFIG_BRIDGE
   probably contains several Ethernet devices, but the kernel is not
   able to recognize more than one at boot time without help; for
   details read the Ethernet-HOWTO, available via FTP (user: anonymous)
-  in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. The Bridging code is
+  in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. The Bridging code is
   still in test. If unsure, say N.
 
 Packet socket
@@ -3419,7 +3421,7 @@ CONFIG_SCSI
   port version of the 100 MB IOMEGA ZIP drive.
 
   Please read the SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. The
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. The
   SCSI-Programming-HOWTO contains information about how to add or
   remove an SCSI device from a running Linux machine without
   rebooting. 
@@ -3437,7 +3439,7 @@ CONFIG_BLK_DEV_SD
   If you want to use a SCSI hard disk or the SCSI or parallel port
   version of the IOMEGA ZIP drive under Linux, say Y and read the
   SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available via
-  FTP (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  FTP (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
   This is NOT for SCSI CDROMs.
 
   This driver is also available as a module ( = code which can be
@@ -3453,7 +3455,7 @@ SCSI tape support
 CONFIG_CHR_DEV_ST
   If you want to use a SCSI tape drive under Linux, say Y and read the
   SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and
   drivers/scsi/README.st in the kernel source. This is NOT for SCSI
   CDROMs.
 
@@ -3467,7 +3469,7 @@ SCSI CDROM support
 CONFIG_BLK_DEV_SR
   If you want to use a SCSI CDROM under Linux, say Y and read the
   SCSI-HOWTO and the CDROM-HOWTO from
-  ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. Also make sure to say Y
+  ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. Also make sure to say Y
   or M to "ISO 9660 CDROM filesystem support" later.
 
   This driver is also available as a module ( = code which can be
@@ -3491,11 +3493,11 @@ CONFIG_CHR_DEV_SG
   directly, so you need some additional software which knows how to
   talk to these devices using the SCSI protocol. For CD-writers, you
   would need the program cdwrite, available via FTP (user: anonymous)
-  from ftp://sunsite.unc.edu/pub/Linux/utils/disk-management; for
+  from ftp://metalab.unc.edu/pub/Linux/utils/disk-management; for
   other devices, it's possible that you'll have to write the driver
   software yourself, so have a look at the SCSI-HOWTO and at the
   SCSI-Programming-HOWTO, both available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -3558,7 +3560,7 @@ CONFIG_SCSI_AHA152X
   This is support for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
   SCSI host adapters. It is explained in section 3.3 of the
   SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You might also want to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You might also want to
   read the comments at the top of drivers/scsi/aha152x.c.
 
   This driver is also available as a module ( = code which can be
@@ -3570,7 +3572,7 @@ Adaptec AHA1542 support
 CONFIG_SCSI_AHA1542
   This is support for a SCSI host adapter. It is explained in section
   3.4 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that Trantor was
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that Trantor was
   recently purchased by Adaptec, and some former Trantor products are
   being sold under the Adaptec name. If it doesn't work out of the
   box, you may have to change some settings in drivers/scsi/aha1542.h.
@@ -3584,7 +3586,7 @@ Adaptec AHA1740 support
 CONFIG_SCSI_AHA1740
   This is support for a SCSI host adapter. It is explained in section
   3.5 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/aha1740.h.
 
@@ -3603,7 +3605,7 @@ CONFIG_SCSI_AIC7XXX
   found by checking the help file for each of the available
   configuration options. You also want to read
   drivers/scsi/README.aic7xxx and the SCSI-HOWTO, available via FTP
-  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
   Note that the AHA2920 SCSI host adapter is *not* supported by this
   driver; choose "Future Domain 16xx SCSI support" instead if you have
   one of those.
@@ -3680,7 +3682,7 @@ BusLogic SCSI support
 CONFIG_SCSI_BUSLOGIC
   This is support for BusLogic MultiMaster and FlashPoint SCSI Host
   Adapters. Consult the SCSI-HOWTO, available via anonymous FTP from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, and the files
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, and the files
   README.BusLogic and README.FlashPoint in drivers/scsi for more
   information. If this driver does not work correctly without
   modification, please contact the author, Leonard N. Zubkoff, by
@@ -3703,7 +3705,7 @@ DTC3180/3280 SCSI support
 CONFIG_SCSI_DTC3280
   This is support for DTC 3180/3280 SCSI Host Adapters. Please read
   the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and the file
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and the file
   drivers/scsi/README.dtc3x80. 
 
   This driver is also available as a module ( = code which can be
@@ -3711,15 +3713,18 @@ CONFIG_SCSI_DTC3280
   The module will be called dtc.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
-EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
+EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support
 CONFIG_SCSI_EATA_DMA
+  This driver is obsolete. You should normally be using the generic EATA
+  driver for this hardware.
+
   This is support for the EATA-DMA protocol compliant SCSI Host
   Adapters like the SmartCache III/IV, SmartRAID controller families
   and the DPT PM2011B and PM2012B controllers. Note that there is
   also another driver for the same hardware: "EATA ISA/EISA/PCI
   support". You should only say Y to one of them. Please read the
   SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3734,7 +3739,7 @@ CONFIG_SCSI_EATA_PIO
   doing so, since this driver only supports hard disks and lacks
   numerous features. You might want to have a look at the SCSI-HOWTO,
   available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -3748,7 +3753,7 @@ CONFIG_SCSI_U14_34F
   this hardware. If the driver doesn't work out of the box, you may
   have to change some settings in drivers/scsi/u14-34f.c. Read the
   SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that there is also
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that there is also
   another driver for the same hardware: "UltraStor SCSI support",
   below. You should say Y to both only if you want 24F support as
   well. 
@@ -3778,7 +3783,7 @@ CONFIG_SCSI_FUTURE_DOMAIN
   other adapters based on the Future Domain chipsets (Quantum
   ISA-200S, ISA-250MG; Adaptec AHA-2920; and at least one IBM board).
   It is explained in section 3.7 of the SCSI-HOWTO, available via FTP
-  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -3797,7 +3802,7 @@ CONFIG_SCSI_GENERIC_NCR5380
   This is the generic NCR family of SCSI controllers, not to be
   confused with the NCR 53c7 or 8xx controllers. It is explained in
   section 3.8 of the SCSI-HOWTO, available via FTP (user: anonymous)
-  at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work
+  at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work
   out of the box, you may have to change some settings in
   drivers/scsi/g_NCR5380.h.
 
@@ -3826,7 +3831,7 @@ CONFIG_SCSI_NCR53C7xx
   This is the 53c7 and 8xx NCR family of SCSI controllers, not to be
   confused with the NCR 5380 controllers. It is explained in section
   3.8 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/53c7,8xx.h.
 
@@ -4011,7 +4016,7 @@ CONFIG_SCSI_IBMMCA
   bootparam" or see the documentation of your boot loader about how to
   pass options to the kernel. The lilo procedure is also explained in
   the SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -4062,6 +4067,17 @@ CONFIG_IBMMCA_SCSI_DEV_RESET
   you know that one of your older devices needs it; N is the safe
   answer.
 
+NCR 53C9x MCA support
+CONFIG_SCSI_MCA_53C9X
+  Some Microchannel machines, notably the NCR 35xx line, use a SCSI
+  controller based on the NCR 53C94.  This driver will allow use of
+  the controller on the 3550, and very possibly others.   
+
+  If you want to compile this as a module (= code which can be inserted
+  and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt.  The module will be
+  called mca_53c9x.o.
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
   This is support for an ISA bus SCSI host adapter. You'll find more
@@ -4078,7 +4094,7 @@ PAS16 SCSI support
 CONFIG_SCSI_PAS16
   This is support for a SCSI host adapter. It is explained in section
   3.10 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/pas16.h.
   
@@ -4091,7 +4107,7 @@ PCI2000 support
 CONFIG_SCSI_PCI2000
   This is support for the PCI2000I EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
-  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called pci2000.o ( = code
   which can be inserted in and removed from the running kernel
@@ -4102,7 +4118,7 @@ PCI2220i support
 CONFIG_SCSI_PCI2220I
   This is support for the PCI2220i EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
-  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called pci2220i.o ( = code
   which can be inserted in and removed from the running kernel
@@ -4113,7 +4129,7 @@ PSI240i support
 CONFIG_SCSI_PSI240I
   This is support for the PSI240i EIDE interface card which acts as a
   SCSI host adapter. Please read the SCSI-HOWTO, available via FTP
-  (user: anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module called psi240i.o ( = code
   which can be inserted in and removed from the running kernel
@@ -4129,7 +4145,7 @@ CONFIG_SCSI_QLOGIC_FAS
   the Qlogic ISP driver though. Information about this driver is
   contained in drivers/scsi/README.qlogicfas. You should also read
   the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -4146,7 +4162,7 @@ CONFIG_SCSI_QLOGIC_ISP
 
   Please read the file drivers/scsi/README.qlogicisp. You should also
   read the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -4158,7 +4174,7 @@ CONFIG_SCSI_SEAGATE
   These are 8-bit SCSI controllers; the ST-01 is also supported by
   this driver. It is explained in section 3.9 of the SCSI-HOWTO,
   available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/seagate.h.
 
@@ -4171,7 +4187,7 @@ Trantor T128/T128F/T228 SCSI support
 CONFIG_SCSI_T128
   This is support for a SCSI host adapter. It is explained in section
   3.11 of the SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/t128.h. Note that Trantor was purchased by Adaptec, and
   some former Trantor products are being sold under the Adaptec name.
@@ -4186,7 +4202,7 @@ CONFIG_SCSI_ULTRASTOR
   This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
   adapter family. This driver is explained in section 3.12 of the
   SCSI-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If it doesn't work out
   of the box, you may have to change some settings in
   drivers/scsi/ultrastor.h.
   
@@ -4216,7 +4232,7 @@ CONFIG_SCSI_EATA
   to "PCI BIOS support", the addresses of all the PCI SCSI controllers
   reported by BIOS32 are probed as well. You want to read the start of
   drivers/scsi/eata.c and the SCSI-HOWTO, available via FTP (user:
-  anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that there is also another driver for the same hardware
   available: "EATA-DMA support". You should say Y to only one of them.
@@ -4252,7 +4268,7 @@ CONFIG_SCSI_NCR53C406A
   This is support for the NCR53c406a SCSI host adapter. For user
   configurable parameters, check out drivers/scsi/NCR53c406.c in the
   kernel source. Also read the SCSI-HOWTO, available via FTP (user:
-  anonymous) at ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -4296,7 +4312,7 @@ CONFIG_SCSI_AM53C974
   This is support for the AM53/79C974 SCSI host adapters. Please read
   drivers/scsi/README.AM53C974 for details. Also, the SCSI-HOWTO,
   available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, is for you.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, is for you.
 
   Note that there is another driver for AM53C974 based adapters:
   "Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support", above.
@@ -4324,7 +4340,7 @@ CONFIG_SCSI_PPA
   driver and how to use it you should read the file
   drivers/scsi/README.ppa. You should also read the SCSI-HOWTO, which
   is available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If you use this driver,
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If you use this driver,
   you will still be able to use the parallel port for other tasks,
   such as a printer; it is safe to compile both drivers into the
   kernel.
@@ -4441,7 +4457,7 @@ CONFIG_NETDEVICES
   line with a modem either via UUCP (UUCP is a protocol to forward
   mail and news between unix hosts over telephone lines; read the
   UUCP-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO) or dialing up a shell
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO) or dialing up a shell
   account or a BBS, even using term (term is a program which gives you
   almost full Internet connectivity if you have a regular dial up
   shell account on some Internet connected Unix computer. Read
@@ -4453,7 +4469,7 @@ CONFIG_NETDEVICES
   you want to use under Linux (make sure you know its name because you
   will be asked for it and read the Ethernet-HOWTO (especially if you
   plan to use more than one network card under Linux), available from
-  ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini) or if you want to
+  ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO/mini) or if you want to
   use SLIP (Serial Line Internet Protocol is the protocol used to send
   Internet traffic over telephone lines or null modem cables) or CSLIP
   (compressed SLIP) or PPP (Point to Point Protocol, a better and
@@ -4464,7 +4480,7 @@ CONFIG_NETDEVICES
 
   Make sure to read the NET-2-HOWTO. Eventually, you will have to read
   Olaf Kirch's excellent and free book "Network Administrator's
-  Guide", to be found in ftp://sunsite.unc.edu:/pub/Linux/docs/LDP. If
+  Guide", to be found in ftp://metalab.unc.edu:/pub/Linux/docs/LDP. If
   unsure, say Y.
 
 Dummy net driver support
@@ -4475,7 +4491,7 @@ CONFIG_DUMMY
   inactive SLIP address seem like a real address for local programs.
   If you use SLIP or PPP, you might want to say Y here. Read about it
   in the Network Administrator's Guide, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/LDP. Since this
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/LDP. Since this
   thing often comes in handy, the default is Y. It won't enlarge your
   kernel either. What a deal.
 
@@ -4500,11 +4516,11 @@ CONFIG_SLIP
   Normally, your access provider has to support SLIP in order for you
   to be able to use it, but there is now a SLIP emulator called SLiRP
   around (available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/ ) which
+  ftp://metalab.unc.edu/pub/Linux/system/network/serial/ ) which
   allows you to use SLIP over a regular dial up shell connection. If
   you plan to use SLiRP, make sure to say Y to CSLIP, below. The
   NET-2-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, explains how to
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, explains how to
   configure SLIP. Note that you don't need this option if you just
   want to run term (term is a program which gives you almost full
   Internet connectivity if you have a regular dial up shell account on
@@ -4528,10 +4544,10 @@ CONFIG_SLIP_COMPRESSED
   answer Y, just in case. You will still be able to use plain SLIP. If
   you plan to use SLiRP, the SLIP emulator (available via FTP (user:
   anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/) which allows
+  ftp://metalab.unc.edu/pub/Linux/system/network/serial/) which allows
   you to use SLIP over a regular dial up shell connection, you
   definitely want to say Y here. The NET-2-HOWTO, available via FTP
-  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO,
+  (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO,
   explains how to configure CSLIP. This won't enlarge your kernel.
 
 Keepalive and linefill
@@ -4559,7 +4575,7 @@ CONFIG_PPP
   program SLiRP can emulate a PPP line if you just have a regular dial
   up shell account on some UNIX computer; get it via FTP (user:
   anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/network/serial/). Note that
+  ftp://metalab.unc.edu/pub/Linux/system/network/serial/). Note that
   you don't need "PPP support" if you just want to run term (term is a
   program which gives you almost full Internet connectivity if you
   have a regular dial up shell account on some Internet connected UNIX
@@ -4570,7 +4586,7 @@ CONFIG_PPP
 
   To use PPP, you need an additional program called pppd as described
   in Documentation/networking/ppp.txt and in the PPP-HOWTO, available
-  from ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade
+  from ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. If you upgrade
   from an older kernel, you might need to upgrade pppd as well. The
   PPP option enlarges your kernel by about 16 KB.
 
@@ -4637,7 +4653,7 @@ CONFIG_WAVELAN
 
   If you want to use an ISA WaveLAN card under Linux, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some more specific
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Some more specific
   information is contained in Documentation/networking/wavelan.txt and
   in the source code drivers/net/wavelan.p.h.
 
@@ -4722,8 +4738,8 @@ CONFIG_PLIP
 
   If you want to use PLIP, say Y and read the PLIP mini-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini as well as the
-  NET-2-HOWTO in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini as well as the
+  NET-2-HOWTO in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that
   the PLIP protocol was changed and this PLIP driver won't work
   together with the PLIP support in Linux versions 1.0.x. This option
   enlarges your kernel by about 8 KB.
@@ -5078,6 +5094,48 @@ CONFIG_HOSTESS_SV11
   up to 256Kbits. It supports both PPP and Cisco HDLC
   At this point, the driver can only be compiled as a module.
 
+COSA/SRP sync serial boards support
+CONFIG_COSA
+  This is a driver for COSA and SRP synchronous serial boards.
+  These boards enable to connect synchronous serial devices (for
+  example base-band modems, or any other device with the X.21, V.24,
+  V.35 or V.36 interface) to your Linux box. The cards can work
+  as the character device, synchronous PPP network device, or the Cisco
+  HDLC network device.
+
+  To actually use the COSA or SRP board, you will need user-space
+  utilities for downloading the firmware to the cards and to set 
+  them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more
+  information about the cards (including the pointer to the user-space
+  utilities). You can also read the comment at the top of the
+  drivers/net/cosa.c for details about the cards and the driver itself.
+
+  The driver will be compiled as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called cosa.o. For general information about
+  modules read Documentation/modules.txt.
+
+COSA/SRP sync serial boards support
+CONFIG_COSA
+  This is a driver for COSA and SRP synchronous serial boards.
+  These boards enable to connect synchronous serial devices (for
+  example base-band modems, or any other device with the X.21, V.24,
+  V.35 or V.36 interface) to your Linux box. The cards can work
+  as the character device, synchronous PPP network device, or the Cisco
+  HDLC network device.
+
+  To actually use the COSA or SRP board, you will need user-space
+  utilities for downloading the firmware to the cards and to set 
+  them up. Look at the http://www.fi.muni.cz/~kas/cosa/ for more
+  information about the cards (including the pointer to the user-space
+  utilities). You can also read the comment at the top of the
+  drivers/net/cosa.c for details about the cards and the driver itself.
+
+  The driver will be compiled as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called cosa.o. For general information about
+  modules read Documentation/modules.txt.
+
 WAN Drivers
 CONFIG_WAN_DRIVERS
   Say Y to this option if your Linux box contains a WAN card and you
@@ -5160,7 +5218,7 @@ CONFIG_NET_ETHERNET
   If your Linux machine will be connected to an Ethernet and you have
   an Ethernet network interface card (NIC) installed in your computer,
   say Y here and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. You will
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. You will
   then also have to say Y to the driver for your particular NIC.
 
   Note that the answer to this question won't directly affect the
@@ -5187,7 +5245,7 @@ Western Digital/SMC cards
 CONFIG_NET_VENDOR_SMC
   If you have a network (Ethernet) card belonging to this class, say Y
   and read the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -5198,7 +5256,7 @@ WD80*3 support
 CONFIG_WD80x3
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5211,7 +5269,7 @@ CONFIG_ULTRAMCA
   If you have a network (Ethernet) card of this type and are running
   an MCA based system (PS/2), say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5223,7 +5281,7 @@ SMC Ultra support
 CONFIG_ULTRA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
   
   Important: There have been many reports that, with some motherboards
   mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
@@ -5242,7 +5300,7 @@ SMC Ultra32 EISA support
 CONFIG_ULTRA32
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5258,7 +5316,7 @@ CONFIG_SMC9194
   into the kernel, and read the file
   Documentation/networking/smc9.txt and the Ethernet-HOWTO, available
   via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you
@@ -5272,7 +5330,7 @@ CONFIG_NE2K_PCI
   with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
   support" below). If you have a PCI NE2000 network (Ethernet) card,
   say Y and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5285,7 +5343,7 @@ CONFIG_NET_VENDOR_RACAL
   If you have a network (Ethernet) card belonging to this class, such
   as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -5296,7 +5354,7 @@ NI5010 support
 CONFIG_NI5010
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this is still
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that this is still
   experimental code. 
 
   This driver is also available as a module ( = code which can be
@@ -5309,7 +5367,7 @@ NI5210 support
 CONFIG_NI52
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5321,7 +5379,7 @@ NI6510 support
 CONFIG_NI65
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5334,7 +5392,7 @@ CONFIG_RTL8139
   This is a driver for the Fast Ethernet PCI network cards based on
   the RTL8129 and RTL8139 chips. If you have one of those, say Y and
   read the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -5373,14 +5431,14 @@ AMD LANCE and PCnet (AT1500 and NE2100) support
 CONFIG_LANCE
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Some LinkSys cards are
   of this type.
 
 3COM cards
 CONFIG_NET_VENDOR_3COM
   If you have a network (Ethernet) card belonging to this class, say Y
   and read the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -5391,7 +5449,7 @@ CONFIG_NET_VENDOR_3COM
 CONFIG_EL1
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Also, consider buying a
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Also, consider buying a
   new card, since the 3c501 is slow, broken, and obsolete: you will
   have problems. Some people suggest to ping ("man ping") a nearby
   machine every minute ("man cron") when using this card.
@@ -5406,7 +5464,7 @@ CONFIG_EL1
 CONFIG_EL2
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5419,7 +5477,7 @@ CONFIG_ELPLUS
   Information about this network (Ethernet) card can be found in
   Documentation/networking/3c505.txt. If you have a card of this type,
   say Y and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -5431,7 +5489,7 @@ CONFIG_ELPLUS
 CONFIG_EL16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5443,7 +5501,7 @@ CONFIG_EL16
 CONFIG_ELMC
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5456,7 +5514,7 @@ CONFIG_EL3
   If you have a network (Ethernet) card belonging to the 3Com
   EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
   via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If your card is not working you may need to use the DOS
   setup disk to disable Plug & Play mode, and to select the default
@@ -5473,7 +5531,7 @@ CONFIG_VORTEX
   If you have a 3Com "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597)
   or "Boomerang" series (EtherLink XL 3c900 or 3c905) network
   (Ethernet) card, say Y and read the Ethernet-HOWTO, available via
-  FTP (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  FTP (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
   More specific information is in Documentation/networking/vortex.txt
   and in the comments at the beginning of drivers/net/3c59x.c.
 
@@ -5489,7 +5547,7 @@ CONFIG_NET_ISA
   of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
   Make sure you know the name of your card. Read the Ethernet-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. If unsure, say Y.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. If unsure, say Y.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -5508,7 +5566,7 @@ CONFIG_ARCNET
 
   You might also want to have a look at the Ethernet-HOWTO, available
   via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO (even though ARCnet is
   not really Ethernet).
 
   This driver is also available as a module ( = code which can be
@@ -5596,7 +5654,7 @@ Cabletron E21xx support
 CONFIG_E2100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5609,7 +5667,7 @@ CONFIG_CS89x0
   Support for CS89x0 chipset based Ethernet cards. If you have a
   network (Ethernet) card of this type, say Y and read the
   Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO as well as
   Documentation/networking/cs89x0.txt.
 
   If you want to compile this as a module ( = code which can be
@@ -5622,7 +5680,7 @@ DEPCA support
 CONFIG_DEPCA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO as well as
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO as well as
   drivers/net/depca.c.
 
   If you want to compile this as a module ( = code which can be
@@ -5637,7 +5695,7 @@ CONFIG_EWRK3
   cards. If this is for you, say Y and read
   Documentation/networking/ewrk3.txt in the kernel source as well as
   the Ethernet-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -5649,13 +5707,13 @@ SEEQ8005 support
 CONFIG_SEEQ8005
   This is a driver for the SEEQ 8005 network (Ethernet) card. If this
   is for you, read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
 AT1700/1720 support
 CONFIG_AT1700
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5668,7 +5726,7 @@ FMV-181/182/183/184 support
 CONFIG_FMV18X
   If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card,
   say Y and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you use an FMV-183 or FMV-184 and it is not working, you may need
   to disable Plug & Play mode of the card.
@@ -5684,7 +5742,7 @@ CONFIG_EEXPRESS_PRO
   If you have a network (Ethernet) card of this type, say Y. Note
   however that the EtherExpress PRO/100 Ethernet card has its own
   separate driver. Please read the Ethernet-HOWTO, available via FTP
-  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5696,7 +5754,7 @@ EtherExpress support
 CONFIG_EEXPRESS
   If you have an EtherExpress16 network (Ethernet) card, say Y and
   read the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that the Intel
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that the Intel
   EtherExpress16 card used to be regarded as a very poor choice
   because the driver was very unreliable. We now have a new driver
   that should do better.
@@ -5711,7 +5769,7 @@ HP PCLAN+ (27247B and 27252A) support
 CONFIG_HPLAN_PLUS
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5723,7 +5781,7 @@ HP PCLAN (27245 and other 27xxx series) support
 CONFIG_HPLAN
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5735,7 +5793,7 @@ HP 10/100VG PCLAN (ISA, EISA, PCI) support
 CONFIG_HP100
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -5747,7 +5805,7 @@ NE2000/NE1000 support
 CONFIG_NE2000
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Many Ethernet cards
   without a specific driver are compatible with NE2000. 
 
   If you have a PCI NE2000 card however, say N here and Y to "PCI
@@ -5766,13 +5824,13 @@ SK_G16 support
 CONFIG_SK_G16
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
 NE/2 (ne2000 MCA version) support
 CONFIG_NE2_MCA
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5785,7 +5843,7 @@ CONFIG_NET_EISA
   This is another class of network cards which attach directly to the
   bus. If you have one of those, say Y and read the Ethernet-HOWTO,
   available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -5797,7 +5855,7 @@ AMD PCnet32 (VLB and PCI) support
 CONFIG_PCNET32
   If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
   answer Y here and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5809,7 +5867,7 @@ Ansel Communications EISA 3200 support
 CONFIG_AC3200
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5821,7 +5879,7 @@ Mylex EISA LNE390A/LNE390B support
 CONFIG_LNE390
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5833,7 +5891,7 @@ Novell/Eagle/Microdyne NE3210 EISA support
 CONFIG_NE3210
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Note that this driver
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Note that this driver
   will NOT WORK for NE3200 cards as they are completely different.
 
   This driver is also available as a module ( = code which can be
@@ -5846,7 +5904,7 @@ Apricot Xen-II on board Ethernet
 CONFIG_APRICOT
   If you have a network (Ethernet) controller of this type, say Y and
   read the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -5860,7 +5918,7 @@ CONFIG_DE4X5
   These include the DE425, DE434, DE435, DE450 and DE500 models. If
   you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific
   information is contained in Documentation/networking/de4x5.txt.
 
   This driver is also available as a module ( = code which can be
@@ -5878,7 +5936,7 @@ CONFIG_DEC_ELCP
   (smc9332dst), you can also try the driver for "Generic DECchip"
   cards, above. However, most people with a network card of this type
   will say Y here.) Do read the Ethernet-HOWTO, available via FTP
-  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
   More specific information is contained in
   Documentation/networking/tulip.txt.
 
@@ -5894,7 +5952,7 @@ CONFIG_DGRS
   PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6
   models. If you have a network card of this type, say Y and read the
   Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. More specific
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. More specific
   information is contained in Documentation/networking/dgrs.txt.
 
   This driver is also available as a module ( = code which can be
@@ -5907,7 +5965,7 @@ EtherExpress PRO/100 support
 CONFIG_EEXPRESS_PRO100
   If you have an Intel EtherExpress PRO/100 PCI network (Ethernet)
   card, say Y and read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5919,7 +5977,7 @@ ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5932,7 +5990,7 @@ CONFIG_TLAN
   If you have a PCI Ethernet network card based on the ThunderLAN chip
   which is supported by this driver, say Y and read the
   Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Devices currently supported by this driver are Compaq Netelligent,
   Compaq NetFlex and Olicom cards. Please read the file
@@ -5961,7 +6019,7 @@ Racal-Interlan EISA ES3210 support
 CONFIG_ES3210
   If you have a network (Ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5974,7 +6032,7 @@ CONFIG_EPIC100
   If you have an SMC EtherPower II 9432 PCI Ethernet network card
   which is based on the SMC83c170, say Y and read the Ethernet-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -5993,14 +6051,14 @@ CONFIG_ZNET
   (Ethernet) card, and this is the Linux driver for it. Note that the
   IBM Thinkpad 300 is compatible with the Z-Note and is also supported
   by this driver. Read the Ethernet-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
 Pocket and portable adapters
 CONFIG_NET_POCKET
   Cute little network (Ethernet) devices which attach to the parallel
   port ("pocket adapters"), commonly used with laptops. If you have
   one of those, say Y and read the Ethernet-HOWTO, available via FTP
-  (user: anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  (user: anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to plug a network card into the PCMCIA slot of your
   laptop instead (PCMCIA is the standard for credit card size
@@ -6023,7 +6081,7 @@ CONFIG_ATP
   This is a network (Ethernet) device which attaches to your parallel
   port. Read drivers/net/atp.c as well as the Ethernet-HOWTO,
   available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
   If you intend to use this driver, you should have said N to the
   Parallel Printer support, because the two drivers don't like each
   other.
@@ -6033,7 +6091,7 @@ CONFIG_DE600
   This is a network (Ethernet) device which attaches to your parallel
   port. Read Documentation/networking/DLINK.txt as well as the
   Ethernet-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
   It is possible to have several devices share a single parallel port
   and it is safe to compile the corresponding drivers into the kernel.
 
@@ -6047,7 +6105,7 @@ CONFIG_DE620
   This is a network (Ethernet) device which attaches to your parallel
   port. Read Documentation/networking/DLINK.txt as well as the
   Ethernet-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO if you want to use this.
   It is possible to have several devices share a single parallel port
   and it is safe to compile the corresponding drivers into the kernel.
 
@@ -6065,7 +6123,7 @@ CONFIG_TR
   Ring card under Linux, say Y here and to the driver for your
   particular card below and read the Token-Ring mini-HOWTO, available
   via FTP (user:anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. Most people can say N
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. Most people can say N
   here.
 
 IBM Tropic chipset based adapter support
@@ -6073,7 +6131,7 @@ CONFIG_IBMTR
   This is support for all IBM Token Ring cards that don't use DMA. If
   you have such a beast, say Y and read the Token-Ring mini-HOWTO,
   available via FTP (user:anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Warning: this driver will almost definitely fail if more than one
   active Token Ring card is present. 
@@ -6091,7 +6149,7 @@ CONFIG_SKTR
 
   If you have such an adapter and would like to use it, say Y or M and
   read the Token-Ring mini-HOWTO, available via FTP (user: anonymous)
-  from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Also read the file linux/Documentation/networking/sktr.txt or check
   the Linux-SNA WWW site for the latest information at
@@ -6181,7 +6239,7 @@ CONFIG_ARM_ETHERH
   should say Y to this option if you wish to use it with Linux.
 
 EBSA-110 Ethernet interface
-CONFIG_AM79C961A
+CONFIG_ARM_AM79C961A
   If you wish to compile a kernel for the EBSA-110, then you should
   always answer Y to this.
 
@@ -6189,7 +6247,7 @@ Support CDROM drives that are not SCSI or IDE/ATAPI
 CONFIG_CD_NO_IDESCSI
   If you have a CDROM drive that is neither SCSI nor IDE/ATAPI, say Y
   here, otherwise N. Read the CDROM-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   Note that the answer to this question doesn't directly affect the
   kernel: saying N will just cause this configure script to skip all
@@ -6446,7 +6504,7 @@ CONFIG_QUOTA
   ext2 filesystem. You need additional software in order to use quota
   support; for details, read the Quota mini-HOWTO, available via FTP
   (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini. Probably the quota
   support is only useful for multi user systems. If unsure, say N.
 
 Minix fs support
@@ -6487,7 +6545,7 @@ CONFIG_EXT2_FS
   by about 41 kB.
 
   The Ext2fs-Undeletion mini-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini,
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini,
   gives information about how to retrieve deleted files on ext2fs
   filesystems.
 
@@ -6497,9 +6555,9 @@ CONFIG_EXT2_FS
   
   Ext2fs partitions can be read from within DOS using the ext2tool
   command line tool package (available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/filesystems/ext2) and from
+  ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2) and from
   within Windows NT using the ext2nt command line tool package from
-  ftp://sunsite.unc.edu/pub/Linux/utils/dos. Explore2fs is a graphical
+  ftp://metalab.unc.edu/pub/Linux/utils/dos. Explore2fs is a graphical
   explorer for ext2fs partitions which runs on Windows 95 and Windows
   NT and includes experimental write support; it is available from
   http://jnewbigin-pc.it.swin.edu.au/Linux/Explore2fs.htm.
@@ -6522,7 +6580,7 @@ CONFIG_ISO9660_FS
   listen to audio CDs and watch its LEDs, say Y (and read
   Documentation/filesystems/isofs.txt and the CDROM-HOWTO, available
   via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO), thereby enlarging your
   kernel by about 27 kB; otherwise say N.
 
   If you want to compile this as a module ( = code which can be
@@ -6583,8 +6641,8 @@ CONFIG_MSDOS_FS
   they are compressed; to access compressed MSDOS partitions under
   Linux, you can either use the DOS emulator DOSEMU, described in the
   DOSEMU-HOWTO, available via FTP (user: anonymous) at
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO, or try dmsdosfs in
-  ftp://sunsite.unc.edu/pub/Linux/system/filesystems/dosfs. If you
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO, or try dmsdosfs in
+  ftp://metalab.unc.edu/pub/Linux/system/filesystems/dosfs. If you
   intend to use dosemu with a non-compressed MSDOS partition, say Y
   here) and MSDOS floppies. This means that file access becomes
   transparent, i.e. the MSDOS files look and behave just like all
@@ -6683,7 +6741,7 @@ CONFIG_NFS_FS
   programs nfsd and mountd (but does not need to have NFS filesystem
   support enabled in its kernel). NFS is explained in the Network
   Administrator's Guide, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/LDP, on its man page: "man
+  ftp://metalab.unc.edu/pub/Linux/docs/LDP, on its man page: "man
   nfs", and in the NFS-HOWTO.
   
   A superior but less widely used alternative to NFS is provided by
@@ -6703,7 +6761,7 @@ CONFIG_NFS_FS
   cannot compile this driver as a module in this case. There are two
   packages designed for booting diskless machines over the net:
   netboot and etherboot, both available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/system/boot/ethernet/ .
+  ftp://metalab.unc.edu/pub/Linux/system/boot/ethernet/ .
 
   If you don't know what all this is about, say N.
 
@@ -6731,7 +6789,7 @@ CONFIG_NFSD
   You will need the support software from the linux-nfs package
   available at ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/.
   Please read the NFS-HOWTO, available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu:/pub/Linux/docs/HOWTO. 
+  ftp://metalab.unc.edu:/pub/Linux/docs/HOWTO. 
 
   The NFS server is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -6994,6 +7052,24 @@ CONFIG_DEVPTS_FS
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
+Unixware slices support (EXPERIMENTAL)
+CONFIG_UNIXWARE_DISKLABEL
+  Like some systems, Unixware uses, except DOS-like partition table,
+  its own slice table inside a partition (VTOC - Virtual Table of
+  Contents). Its format is incompatible with all other OSes. Saying Y
+  here allows you to read VTOC and further mount Unixware partitions
+  read-only from within Linux if you have also said Y to "UFS 
+  filesystem support" or "System V and Coherent filesystem support", 
+  above.
+
+  This is mainly used to carry data from a Unixware box to your
+  Linux box via a removable medium like magneto-optical, ZIP or
+  removable IDE drives. Note, however, that a good portable way to
+  transport files and directories between unixes (and even other
+  operating systems) is given by the tar program ("man tar" or
+  preferably "info tar"). If you don't know what all this is about,
+  say N.
+
 Macintosh partition map support
 CONFIG_MAC_PARTITION
   Say Y here if you want your Linux system to be able to read the
@@ -7011,13 +7087,13 @@ CONFIG_SMB_FS
   transport protocol, and not NetBEUI. For details, read
   Documentation/filesystems/smbfs.txt and the SMB-HOWTO, available via
   FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   Note: if you just want your box to act as an SMB *server* and make
   files and printing services available to Windows clients (which need
   to have a TCP/IP stack), you don't need to say Y here; you can use
   the program samba (available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/system/network/samba) for that.
+  ftp://metalab.unc.edu/pub/Linux/system/network/samba) for that.
 
   General information about how to connect Linux, Windows machines and
   Macs is on the WWW at http://www.eats.com/linux_mac_win.html (to
@@ -7067,7 +7143,7 @@ CONFIG_NCP_FS
   mount NetWare file server volumes and to access them just like any
   other Unix directory. For details, please read the file
   Documentation/filesystems/ncpfs.txt in the kernel source and the
-  IPX-HOWTO on ftp://sunsite.unc.edu:/pub/Linux/docs/howto.
+  IPX-HOWTO on ftp://metalab.unc.edu:/pub/Linux/docs/howto.
 
   You do not have to say Y here if you want your Linux box to act as a
   file *server* for Novell NetWare clients.
@@ -7489,7 +7565,7 @@ CONFIG_VT_CONSOLE
   loadlin) about how to pass options to the kernel at boot time. The
   lilo procedure is also explained in the SCSI-HOWTO, available via
   FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.)
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.)
 
   If unsure, say Y.
 
@@ -7553,7 +7629,7 @@ CONFIG_SERIAL_CONSOLE
   your boot loader (lilo or loadlin) about how to pass options to the
   kernel at boot time. The lilo procedure is also explained in the
   SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) 
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) 
 
   If you don't have a VGA card installed and you say Y here, the
   kernel will automatically use the first serial line, /dev/ttyS0, as
@@ -7739,7 +7815,7 @@ CONFIG_PRINTER
   box (as opposed to using a serial printer; if the connector at the
   printer has 9 or 25 holes ["female"], then it's serial), say Y. Also
   read the Printing-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   It is possible to share one parallel port among several devices
   (e.g. printer and ZIP drive) and it is safe to compile the
@@ -7754,7 +7830,7 @@ CONFIG_PRINTER
   of your boot loader (lilo or loadlin) about how to pass options to
   the kernel at boot time. The lilo procedure is also explained in the
   SCSI-HOWTO, available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.) The standard base
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.) The standard base
   addresses as well as the syntax of the "lp" command line option can
   be found in drivers/char/lp.c.
 
@@ -7774,7 +7850,7 @@ CONFIG_MOUSE
   Microsoft mouse (made by Logitech) that plugs into a COM port
   (rectangular with 9 or 25 pins). These people say N here. If you
   have something else, read the Busmouse-HOWTO, available via FTP
-  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO and
+  (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO and
   say Y here.
 
   If you have a laptop, you either have to check the documentation or
@@ -7792,7 +7868,7 @@ CONFIG_BUSMOUSE
   made by Logitech don't use the Logitech protocol anymore; for those,
   you don't need this option. You want to read the Busmouse-HOWTO,
   available via FTP (user: anonymous) in
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -7812,20 +7888,20 @@ CONFIG_PSMOUSE
 
   Although PS/2 mice are not technically bus mice, they are explained
   in detail in the Busmouse-HOWTO, available via FTP (user: anonymous)
-  in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. 
+  in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. 
 
   When using a PS/2 mouse, you can get problems if you want to use the
   mouse both on the Linux console and under X. Using the "-R" option
   of the Linux mouse managing program gpm (available from
-  ftp://sunsite.unc.edu:/pub/Linux/system/Daemons) solves this
-  problem, or you can get the "mconv" utility also from sunsite.
+  ftp://metalab.unc.edu:/pub/Linux/system/Daemons) solves this
+  problem, or you can get the "mconv" utility also from metalab.
 
 C&T 82C710 mouse port support (as on TI Travelmate)
 CONFIG_82C710_MOUSE
   This is a certain kind of PS/2 mouse used on the TI Travelmate. If
   you are unsure, try first to say N here and come back if the mouse
   doesn't work. Read the Busmouse-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
 PC110 digitizer pad support
 CONFIG_PC110_PAD
@@ -7845,7 +7921,7 @@ CONFIG_MS_BUSMOUSE
   These animals (also called Inport mice) are connected to an
   expansion board using a round connector with 9 pins. If this is what
   you have, say Y and read the Busmouse-HOWTO, available via FTP
-  (user: anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  (user: anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you are unsure, say N and read the HOWTO nevertheless: it will
   tell you what you have. Also be aware that several vendors talk
@@ -7862,7 +7938,7 @@ CONFIG_ATIXL_BUSMOUSE
   This is a rare type of busmouse that is connected to the back of an
   ATI video card. Note that most ATI mice are actually Microsoft
   busmice. Read the Busmouse-HOWTO, available via FTP (user:
-  anonymous) in ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO.
+  anonymous) in ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -8204,11 +8280,8 @@ CONFIG_MTRR
   set the MTRRs for the boot CPU and not the secondary CPUs. This can
   lead to all sorts of problems.
 
-  In general you should compile this into the kernel, rather than as a
-  loadable module, because the BIOS fix needs to be done early in the
-  boot sequence. If you compile this as a module, the BIOS fix will be
-  delayed until when you load the module. You do this at your own
-  risk.
+  You can safely say Y even if your machine doesn't have MTRRs, you'll
+  just add about 3k to your kernel.
 
   See Documentation/mtrr.txt for more information.
 
@@ -8234,7 +8307,7 @@ CONFIG_APM
 
   Supporting software is available; for more information, read the
   Battery Powered Linux mini-HOWTO, available via FTP (user:
-  anonymous) from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini.
+  anonymous) from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini.
 
   This driver does not spin down disk drives (see the hdparm(8)
   manpage ("man 8 hdparm") for that), and it doesn't turn off
@@ -8328,7 +8401,7 @@ CONFIG_APM_POWER_OFF
   is halted. You will need software (e.g., a suitable version of the
   halt(8) command ("man 8 halt")) to cause the computer to power down.
   Recent versions of the sysvinit package available from
-  ftp://sunsite.unc.edu/pub/Linux/system/daemons/init/ (user:
+  ftp://metalab.unc.edu/pub/Linux/system/daemons/init/ (user:
   anonymous) contain support for this ("halt -p" shuts down Linux and
   powers off the computer, if executed from runlevel 0). As with the
   other APM options, this option may not work reliably with some APM
@@ -8461,13 +8534,8 @@ CONFIG_RTC
   24 hour alarm. It reports status information via the file /proc/rtc
   and its behaviour is set by various ioctls on /dev/rtc.
 
-  People running SMP (multiprocessor) versions of Linux should say Y
-  here to read and set the RTC clock in a SMP compatible
-  fashion. (They should also read Documentation/smp and
-  Documentation/IO-APIC.txt and the SMP-FAQ on the WWW at
-  http://www.irisa.fr/prive/mentre/smp-faq/ (to browse the WWW, you
-  need to have access to a machine on the Internet that has a program
-  like lynx or netscape).)
+  If you enabled CONFIG_SMP, you should say Y here to read and set the
+  RTC clock in an SMP compatible fashion.
 
   If you think you have a use for such a device (such as periodic data
   sampling), then say Y here, and read Documentation/rtc.txt for
@@ -8491,7 +8559,11 @@ CONFIG_NVRAM
   and "NVRAM" on Ataris. /dev/nvram may be used to view settings
   there, or to change them (with some utility). It could also be used
   to frequently save a few bits of very important data that may not be
-  lost over power-off and for which writing to disk is too insecure.
+  lost over power-off and for which writing to disk is too insecure. Note
+  however that most NVRAM space in a PC belongs to the BIOS and you should
+  NEVER idly tamper with it. See Ralf Browns interrupt list for a guide to 
+  the use of CMOS bytes by your BIOS.
+
   On Atari machines, /dev/nvram is always configured and does not need
   to be selected.
 
@@ -8610,7 +8682,7 @@ CONFIG_SOUND
   about your sound card and its configuration down (I/O port,
   interrupt and DMA channel), because you will be asked for it. You
   want to read the Sound-HOWTO, available via FTP (user: anonymous)
-  from ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO. There is also some
+  from ftp://metalab.unc.edu/pub/Linux/docs/HOWTO. There is also some
   information in various README files in drivers/sound, esp. in
   Readme.cards which you should read first to find out whether your
   card is supported by Linux, and, if yes, which driver to use.
@@ -8645,6 +8717,14 @@ CONFIG_SOUND_SGALAXY
   cards from Aztech. It supports the Waverider Pro 32 - 3D and the
   Galaxy Washington 16.
 
+Support for AD1816(A) based cards (EXPERIMENTAL)
+CONFIG_SOUND_AD1816
+  Say M here if you have a soundcard based on the Analog Devices 
+  AD1816(A) chip.
+
+  NOTE: This driver is still EXPERIMENTAL. 
+        See Documentation/sound/AD1816 for further information.
+
 Yamaha OPL3-SA1 audio controller
 CONFIG_SOUND_OPL3SA1
   Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
@@ -8852,9 +8932,11 @@ CONFIG_SOUND_CS4232
   See Documentation/sound/CS4232 for more information on configuring
   this card.
 
-Support for Yamaha OPL3-SA[2,3,x] based (PnP) cards
+Support for Yamaha OPL3-SA2, SA3, and SAx based PnP cards
 CONFIG_SOUND_OPL3SA2
-  Say Y or M here if you have such a sound card.
+  Say Y or M if you have a card based on one of these Yamaha
+  sound chipsets. Read Documentation/sound/OPL3-SA2 for more
+  information on configuring these cards.
 
 Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers
 CONFIG_SOUND_MAUI
@@ -8975,16 +9057,16 @@ CONFIG_LOWLEVEL_SOUND
   affect the kernel; saying Y will simply cause this configure script
   to present you with more options. If unsure, say Y.
 
-ACI mixer (miroPCM12)
+ACI mixer (miroPCM12/PCM20)
 CONFIG_ACI_MIXER
   Audio Command Interface (ACI) driver. ACI is a protocol used to
   communicate with the microcontroller on some sound cards produced by
   miro, e.g. the miroSOUND PCM12 and PCM20. The main function of the
   ACI is to control the mixer and to get a product identification.
   This Voxware ACI driver currently only supports the ACI functions on
-  the miroSOUND PCM12 card. On the PCM20, ACI also controls the radio
-  tuner on this card, however this is not yet supported in this
-  software.
+  the miroSOUND PCM12 and PCM20 cards. On the PCM20, ACI also controls
+  the radio tuner. This is supported in the video4linux radio-miropcm20
+  driver.
 
 SB32/AWE support
 CONFIG_AWE32_SYNTH
@@ -8992,7 +9074,7 @@ CONFIG_AWE32_SYNTH
   similar sound card. See drivers/sound/lowlevel/README.awe,
   Documentation/sound/AWE32 and the Soundblaster-AWE mini-HOWTO,
   available via FTP (user: anonymous) from
-  ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/mini for more info.
+  ftp://metalab.unc.edu/pub/Linux/docs/HOWTO/mini for more info.
 
 Gallant's Audio Excel DSP 16 support (SC-6000 and SC-6600)
 CONFIG_AEDSP16
@@ -9013,17 +9095,11 @@ CONFIG_AEDSP16
   Documentation/sound/AudioExcelDSP16 to get more information about
   this driver and its configuration.
 
-SC-6600 based audio cards (new Audio Excel DSP 16)
-CONFIG_SC6600
-  The SC6600 is the new version of DSP mounted on the Audio Excel DSP
-  16 cards. Find in the manual the FCC ID of your audio card and
-  answer Y if you have an SC6600 DSP.
-
-Audio Excel DSP 16 (MSS emulation)
-CONFIG_AEDSP16_MSS
-  Answer Y if you want your audio card to emulate Microsoft Sound
-  System. You should then say Y to "Microsoft Sound System support"
-  and say N to "Audio Excel DSP 16 (SBPro emulation)".
+I/O base for Audio Excel DSP 16
+CONFIG_AEDSP16_BASE
+  This is the base I/O address of the Audio Excel DSP 16 card. It must
+  be 220 or 240. If you compiled aedsp16.o as a module you can specify
+  this parameter as 'io=0xNNN'.
 
 Audio Excel DSP 16 (SBPro emulation)
 CONFIG_AEDSP16_SBPRO
@@ -9032,6 +9108,68 @@ CONFIG_AEDSP16_SBPRO
   (SB16/32/64, ESS, Jazz16) support" and N to "Audio Excel DSP 16 (MSS
   emulation)".
 
+Audio Excel DSP 16 IRQ
+CONFIG_AEDSP16_SB_IRQ
+  This is the IRQ of the Audio Excel DSP 16 card. It must be 5, 7, 9,
+  10 or 11. If you compiled aedsp16.o as a module you can specify
+  this parameter as 'irq=NN'.
+
+Audio Excel DSP 16 DMA
+CONFIG_AEDSP16_SB_DMA
+  This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 or 3.
+  If you compiled aedsp16.o as a module you can specify this parameter
+  as 'dma=NN'.
+
+Audio Excel DSP 16 (MSS emulation)
+CONFIG_AEDSP16_MSS
+  Answer Y if you want your audio card to emulate Microsoft Sound
+  System. You should then say Y to "Microsoft Sound System support"
+  and say N to "Audio Excel DSP 16 (SBPro emulation)".
+
+Audio Excel DSP 16 IRQ
+CONFIG_AEDSP16_MSS_IRQ
+  This is the IRQ of the Audio Excel DSP 16 card. It must be 5, 7, 9,
+  10 or 11. If you compiled aedsp16.o as a module you can specify
+  this parameter as 'irq=NN'.
+
+Audio Excel DSP 16 DMA
+CONFIG_AEDSP16_MSS_DMA
+  This is the IRQ of the Audio Excel DSP 16 card. It must be 0, 1 or 3.
+  If you compiled aedsp16.o as a module you can specify this parameter
+  as 'dma=NN'.
+
+SC-6600 based audio cards (new Audio Excel DSP 16)
+CONFIG_SC6600
+  The SC6600 is the new version of DSP mounted on the Audio Excel DSP
+  16 cards. Find in the manual the FCC ID of your audio card and
+  answer Y if you have an SC6600 DSP.
+
+SC-6600 Joystick Interface
+CONFIG_SC6600_JOY
+  This option activate the Joystick interface of Audio Excel DSP 16 card.
+
+SC-6600 CDROM Interface
+CONFIG_SC6600_CDROM
+  This option activate the CDROM interface of Audio Excel DSP 16 card.
+  Required parameter can be: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for
+  no CDROM present.
+
+Audio Excel DSP 16 (MPU401 emulation)
+CONFIG_AEDSP16_MPU401
+  Answer Y if you want your audio card to emulate the MPU-401 midi
+  interface. You should then say Y to "MPU-401 support".
+  You have to hote that the I/O base for MPU-401 support of aedsp16 is
+  the same you have selected for "MPU-401 support". If you are using
+  this driver as a module you have to specify the MPU I/O base address
+  with the parameter 'mpu_base=0xNNN'.
+
+MPU401 IRQ for Audio Excel DSP 16
+CONFIG_AEDSP16_MPU_IRQ
+  This is the IRQ of the MPU-401 emulation of Audio Excel DSP 16 card.
+  It must be 5, 7, 9, 10 or 0 (to disable MPU-401 interface). If you
+  compiled aedsp16.o as a module you can specify this parameter as
+  'mpu_irq=NN'.
+
 Ensoniq ES1370 based PCI sound cards
 CONFIG_SOUND_ES1370
   Say Y or M if you have a PCI sound card utilizing the Ensoniq
@@ -9057,6 +9195,15 @@ CONFIG_SOUND_ES1371
   models are either ES1370 or ES1371 based. This driver differs
   slightly from OSS/Free, so PLEASE READ Documentation/sound/es1371.
 
+Gameport I/O-range selection
+CONFIG_SOUND_ES1371_GAMEPORT
+  Select the I/O-range of the gameport on a ES1371 based soundcard.
+  The card uses 8 ioports and the gameport is available at all eight
+  ioports. Legal hexadecimal values are 200, 208, 210 and 218.
+  The joystick driver will by default use 0x201. 
+  Leave the default 200 unless you have a joystick not attached
+  to your soundcard.
+
 S3 SonicVibes based PCI sound cards
 CONFIG_SOUND_SONICVIBES
   Say Y or M if you have a PCI sound card utilizing the S3
@@ -9489,6 +9636,13 @@ CONFIG_MAC
   Say N unless you're willing to code the remaining necessary support.
   ;)
 
+HP9000/300 support
+CONFIG_HP300
+  This option enables support for the HP9000/300 series of workstations.
+  Support for these machines is still very experimental.  If you plan to
+  try to use the kernel on such a machine say Y here.  Everybody else
+  says N.
+
 # CONFIG_APOLLO, etc. coming soon (?)
 
 68020 support
@@ -9932,6 +10086,21 @@ CONFIG_DMASOUND
   want). If you want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
+HP DCA serial support
+CONFIG_HPDCA
+  If you want to use the internal "DCA" serial ports on an HP300
+  machine, say Y here.
+
+HP on-board LANCE support
+CONFIG_HPLANCE
+  If you want to use the builtin "LANCE" Ethernet controller on an HP300
+  machine, say Y here.
+
+DIO bus support
+CONFIG_DIO
+  Say Y here to enable support for the "DIO" expansion bus used in HP300
+  machines. If you are using such a system you almost certainly want this.
+
 MSDOS partition support
 CONFIG_MSDOS_PARTITION
   This option enables support for using hard disks that were
@@ -10139,8 +10308,9 @@ CONFIG_RADIO_ZOLTRIX_PORT
 
 Miro PCM20 Radio
 CONFIG_RADIO_MIROPCM20
-  Choose Y here if you have one of these FM radio cards, and then fill
-  in the port address below.
+  Choose Y here if you have this FM radio card. You also need the
+  PCM12/PCM20 ACI mixer in additional low level sound drivers for this
+  to work.
 
   In order to control your radio card, you will need to use programs
   that are compatible with the Video for Linux API. Information on 
@@ -10154,6 +10324,28 @@ CONFIG_RADIO_MIROPCM20
   say M here and read Documentation/modules.txt. The module will be
   called radio-miropcm20.o
 
+GemTek Radio Card
+CONFIG_RADIO_GEMTEK
+  Choose Y here if you have this FM radio card, and then fill in the 
+  port address below.
+
+  In order to control your radio card, you will need to use programs
+  that are compatible with the Video for Linux API. Information on 
+  this API and pointers to "v4l" programs may be found on the WWW at
+  http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW,
+  you need to have access to a machine on the Internet that has a 
+  program like lynx or netscape.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called radio-gemtek.o.
+
+GemTek i/o port
+CONFIG_RADIO_GEMTEK_PORT
+  Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
+  0x34c, if you haven't changed the jumper setting on the card.
+
 BT848 Video For Linux
 CONFIG_VIDEO_BT848
   Support for BT848 based frame grabber/overlay boards. This includes
@@ -10216,6 +10408,19 @@ CONFIG_ARCH_ARC
   to set this option to, please consult any information supplied with
   your system.
 
+Include support for CATS boards
+CONFIG_CATS
+  Say Y here if you wish to include support for the extra hardware found
+  in Chalice CATS machines. The resulting kernel will still run on an 
+  EBSA-285 but will be slightly larger. If in doubt say N.
+
+Debug kernel errors
+CONFIG_DEBUG_ERRORS
+  This option controls verbose debugging information which can be printed
+  when the kernel detects an internal error.  Verbose debugging information
+  is useful when tracking down kernel problems, but it will be meaning less
+  for non-kernel hackers.  It's safe for everyone to say Y.
+
 Build Tools Selection
 CONFIG_BINUTILS_NEW
   Say Y here if and only if you're using GCC 2.8.1/EGCS with a
@@ -10228,6 +10433,261 @@ CONFIG_FRAME_POINTER
   it will give useful debugging/error results. If you don't debug the
   kernel, you can say N.
 
+Initial kernel command line
+CONFIG_CMDLINE
+  On some architectures (EBSA285, EBSA110 and Corel Netwinder), there is
+  currently no way for the boot loader to pass arguments to the kernel.
+  For these architectures, you should supply some command-line options
+  at build time by entering them here.  As a minimum, you should specify
+  the memory size and the root device (eg, mem=64M root=/dev/nfs)
+
+IrDA Protocols
+CONFIG_IRDA
+  Say Y here if you want to build support for the IrDA (TM)
+  protocols. The Infrared Data Associations (tm) specifies standards
+  for wireless infrared communication and is supported by most laptops
+  and PDA's If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
+
+  To use Linux support for the IrDA (tm) protocols, you will also need
+  some user-space utilities like the irmanager and probably irattach
+  as well. For more information, visit
+  http://www.cs.uit.no/~dagb/irda/
+
+IrDA Cache last LSAP
+CONFIG_IRDA_CACHE_LAST_LSAP
+  Say Y here if you want IrLMP to cache the last LSAP used. This makes
+  sense since most frames will be sent/received on the same connection.
+  Enabling this option will save a hash-lookup per frame.
+
+  If unsure, say Y.
+
+IrDA Fast RR's
+CONFIG_IRDA_FAST_RR
+  Say Y here is you want IrLAP to send fast RR (Receive Ready) frames
+  when acting as a primary station. This will make IrLAP send out a RR
+  frame immediately when receiving a frame if its own transmit queue is
+  currently empty. This will give a lot of speed improvement when
+  receiving much data since the secondary station will not have to
+  wait the max. turn around time before it is allowed to transmit the
+  next time. If the transmit queue of the secondary is also empty the
+  primary will back off waiting longer for sending out the RR frame
+  until the timeout reaches the normal value. Enabling this option
+  will make the IR-diode burn more power and thus reduce your battery
+  life.
+
+  If unsure, say N.
+
+IrDA Recycle RR's
+CONFIG_IRDA_RECYCLE_RR
+  In the normal life of the IrLAP protocol, it sends a lot of small RR
+  (Receive Ready) frames over the link (at least when it has nothing
+  else to do). Saying Y to this option will make IrLAP recycle these
+  frames thus avoiding many alloc_skb's and kfree_skb's. To do this it
+  will only buffer one of these frame which is enough for the normal
+  case.
+
+  If unsure, say Y.
+
+IrLAP Compression support
+CONFIG_IRDA_COMPRESSION
+  Compression is _not_ part of the IrDA(tm) protocol specification,
+  but its working great! Linux is the first to try out compresson
+  support at the IrLAP layer. This means that you will only benefit
+  from compression if you are running a Linux <-> Linux configuration
+
+IrLAP Deflate Compression Protocol
+CONFIG_IRDA_DEFLATE
+  Say Y here if you want to build support for the Deflate compression
+  protocol. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The deflate compression (GZIP) is exactly
+  the same as used by the PPP protocol. Enabling this option will
+  build a module called irda_deflate.o
+
+IrLAN Protocol 
+CONFIG_IRLAN
+  Say Y here if you want to build support for the IrLAN protocol. If
+  you want to compile it as a module, say M here and read
+  Documentation/modules.txt. IrLAN emulates an Ethernet and makes it
+  possible to put up an wireless LAN using infrared beams.
+
+IrLAN Client Protocol 
+CONFIG_IRLAN_CLIENT
+  Say Y here if you want to build support for the IrLAN client
+  protocol. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The IrLAN client protocol can be used to
+  talk with infrared access points like the HP NetbeamIR, or the ESI
+  JetEye NET. You can also connect to another Linux machine running
+  the IrLAN server protocol for ac-hoc networking!
+
+IrLAN Server Protocol 
+CONFIG_IRLAN_SERVER
+  Say Y here if you want to build support for infrared LAN access. If
+  you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The IrLAN server protocol makes it
+  possible to set up a wireless LAN with a machine running the IrLAN
+  client protocol. Notice that the IrLAN server protocol currently
+  only emulates an access point and does not implement the ad-hoc
+  specification of IrLAN, but this will not be noticeable for the
+  user.
+
+IrOBEX Protocol
+CONFIG_IROBEX
+  Say Y here if you want to build support for the IrOBEX protocol. If
+  you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The module does not actually implement
+  the IrOBEX protocol since that protocol lives in userspace, but it 
+  contains the necessary functions to interface the user-space stuff
+  with the kernel. So you will need to have the user-space library and
+  programs that can use this library installed as well to be able to
+  use the IrOBEX protocol. This module will hopefully be replaced by
+  IrDA sockets in the future.
+
+IrCOMM Protocol
+CONFIG_IRCOMM
+  Say Y here if you want to build support for the IrCOMM protocol. If
+  you want to compile it as a module, say M here and read
+  Documentation/modules.txt. IrCOMM implements serial port emulation,
+  and makes it possible to use all existing applications that
+  understands TTY's with an infrared link. Thus you should be able to
+  use application like PPP, minicom and others. Enabling this option
+  will create two modules called ircomm and ircomm_tty. For more
+  information go to http://www.pluto.dti.ne.jp/~thiguchi/irda/
+
+IrTTY IrDA Device Driver
+CONFIG_IRTTY_SIR
+  Say Y here if you want to build support for the IrTTY line
+  discipline. If you want to compile it as a module, say M here and
+  read Documentation/modules.txt. IrTTY makes it possible to use
+  Linux's own serial driver for all IrDA ports that are 16550
+  compatible. Most IrDA chips are 16550 compatible so you should
+  probably say Y to this option. Using IrTTY will however limit the
+  speed of the connection to 115200 bps (IrDA SIR mode)
+
+  If unsure, say Y.
+
+Winbond W83977AF IrDA Device Driver
+CONFIG_WINBOND_FIR
+  Say Y here if you want to build IrDA support for the Winbond W83977AF
+  super-io chipset. If you want to compile it as a module, say M here
+  and read Documentation/modules.txt. This driver should be used for
+  the IrDA chipset in the Corel NetWinder. The driver supports SIR,
+  MIR and FIR (4Mbps) speeds.
+
+NSC PC87108 IrDA Device Driver
+CONFIG_NSC_FIR
+  Say Y here if you want to build support for the NSC PC87108 IrDA
+  chipset. If you want to compile it as a module, say M here and
+  read Documentation/modules.txt. This drivers currently only supports
+  the ACTiSYS IR2000B ISA card and supports SIR, MIR and FIR (4Mbps)
+  speeds.
+
+ESI JetEye PC Dongle
+CONFIG_ESI_DONGLE
+  Say Y here if you want to build support for the Extended Systems
+  JetEye PC dongle. If you want to compile it as a module, say M here
+  and read Documentation/modules.txt. The ESI dongle attaches to the
+  normal 9-pin serial port connector, and can currently only be used
+  by IrTTY. To activate support for ESI dongles you will have to
+  insert "irattach -d esi" in the /etc/irda/drivers script.
+
+ACTiSYS IR-220L and IR220L+ dongle
+CONFIG_ACTISYS_DONGLE
+  Say Y here if you want to build support for the ACTiSYS
+  IR-220L and IR220L+ dongles. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. The ACTiSYS dongles
+  attaches to the normal 9-pin serial port connector, and can
+  currently only be used by IrTTY. To activate support for ACTiSYS
+  dongles you will have to insert "irattach -d actisys" or
+  "irattach -d actisys_plus" in the/etc/irda/drivers script.
+
+Tekram IrMate 210B dongle
+CONFIG_TEKRAM_DONGLE
+  Say Y here if you want to build support for the Tekram IrMate 210B 
+  dongle. If you want to compile it as a module, say M here
+  and read Documentation/modules.txt. The Tekram dongle attaches to
+  the normal 9-pin serial port connector, and can currently only be
+  used by IrTTY. To activate support for Tekram dongles you will have
+  to insert "irattach -d tekram" in the /etc/irda/drivers script.
+
+VME (Motorola and BVM) support
+CONFIG_VME
+  Say Y here if you want to build a kernel for a 680x0 based VME
+  board.  Boards currently supported include Motorola boards MVME162,
+  MVME166, MVME167, MVME172, and MVME177.  BVME4000 and BVME6000
+  boards from BVM Ltd are also supported.
+
+MVME162, 166 and 167 support
+CONFIG_MVME16x
+  Say Y to include support for Motorola VME boards.  This will build a
+  kernel which can run on MVME162, MVME166, MVME167, MVME172, and
+  MVME177 boards.  If you select this option you will have to select
+  the appropriate drivers for SCSI, Ethernet and serial ports later
+  on.
+
+BVME4000 and BVME6000 support
+CONFIG_BVME6000
+  Say Y to include support for VME boards from BVM Ltd.  This will
+  build a kernel which can run on BVME4000 and BVME6000 boards.  If
+  you select this option you will have to select the appropriate
+  drivers for SCSI, Ethernet and serial ports later on.
+
+Use write-through caching for 68060 supervisor accesses
+CONFIG_060_WRITETHROUGH
+  The 68060 generally uses copyback caching of recently accessed data.
+  Copyback caching means that memory writes will be held in an on-chip
+  cache and only written back to memory some time later.  Saying Y
+  here will force supervisor (kernel) accesses to use writethrough
+  caching.  Writethrough caching means that data is written to memory
+  straight away, so that cache and memory data always agree.
+  Writethrough caching is less efficient, but is needed for some
+  drivers on 68060 based systems where the 68060 bus snooping signal
+  is hardwired on.  The 53c710 SCSI driver is known to suffer from
+  this problem.
+
+NCR53C710 SCSI driver for MVME16x
+CONFIG_MVME16x_SCSI
+  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
+  SCSI controller chip.  Almost everyone using one of these boards
+  will want to say Y to this question.
+
+NCR53C710 SCSI driver for BVME6000
+CONFIG_BVME6000_SCSI
+  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
+  SCSI controller chip.  Almost everyone using one of these boards
+  will want to say Y to this question.
+
+MVME16x Ethernet support
+CONFIG_MVME16x_NET
+  This is the driver for the Ethernet interface on the Motorola
+  MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
+  driver for this chip in your kernel.   If you want to compile it as
+  a module, say M here and read Documentation/modules.txt.
+
+BVME6000 Ethernet support
+CONFIG_BVME6000_NET
+  This is the driver for the Ethernet interface on BVME4000 and
+  BVME6000 VME boards.  Say Y here to include the driver for this chip
+  in your kernel.   If you want to compile it as a module, say M here
+  and read Documentation/modules.txt.
+
+CD2401 support for MVME166/7 serial ports
+CONFIG_SERIAL167
+  This is the driver for the serial ports on the Motorola MVME166,
+  167, and 172 boards.  Everyone using one of these boards should say
+  Y here.
+
+SCC support for MVME162 serial ports
+CONFIG_MVME162_SCC
+  This is the driver for the serial ports on the Motorola MVME162 and
+  172 boards.  Everyone using one of these boards should say Y here.
+
+SCC support for BVME6000 serial ports
+CONFIG_BVME6000_SCC
+  This is the driver for the serial ports on the BVME4000 and BVME6000
+  boards from BVM Ltd.  Everyone using one of these boards should say
+  Y here.
+
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ, 
@@ -10237,7 +10697,7 @@ CONFIG_FRAME_POINTER
 #
 # This is used by Emacs' spell checker ispell.el:
 #
-# LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp sunsite
+# LocalWords:  CONFIG coprocessor DX Pentium SX lilo loadlin HOWTO ftp metalab
 # LocalWords:  unc edu docs emu README kB BLK DEV FD Thinkpad fd MFM RLL IDE gz
 # LocalWords:  cdrom diskless netboot nfs xzvf ATAPI MB ide pavia rubini pl pd
 # LocalWords:  HD CDROMs IDECD NEC MITSUMI filesystem XT XD PCI BIOS cezar ATEN
index bafcd31654aeecfeb5223dc182a8352302f68099..4f0c66b264a86ca56d94f4315595f127ed57b182 100644 (file)
@@ -94,9 +94,12 @@ L:   linux-net@vger.rutgers.edu
 S:     Maintained
 W:     http://rsphy1.anu.edu.au/~gpg109/ne2000.html
 
-AEDSP16 DRIVER
-P:     Riccardo Facchetti
-M:     fizban@tin.it
+AD1816 SOUND DRIVER
+P:     Thorsten Knabe
+M:     Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
+M:     Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de>
+W:     http://www.student.informatik.tu-darmstadt.de/~tek/projects/linux.html
+W:     http://www.tu-darmstadt.de/~tek01/projects/linux.html
 S:     Maintained
 
 ADVANSYS SCSI DRIVER
@@ -105,6 +108,11 @@ M: Bob Frey <bobf@advansys.com>
 W:     http://www.advansys.com/linux
 S:     Maintained
 
+AEDSP16 DRIVER
+P:     Riccardo Facchetti
+M:     fizban@tin.it
+S:     Maintained
+
 AHA152X SCSI DRIVER
 P:     Juergen E. Fischer
 M:     Juergen Fischer <fischer@et-inf.fho-emden.de>
@@ -167,14 +175,26 @@ P:        Axel Boldt
 M:     boldt@math.ucsb.edu
 S:     Maintained
 
+COSA/SRP SYNC SERIAL DRIVER
+P:     Jan "Yenya" Kasprzak
+M:     kas@fi.muni.cz
+W:     http://www.fi.muni.cz/~kas/cosa/
+S:     Maintained
+
+COSA/SRP SYNC SERIAL DRIVER
+P:     Jan "Yenya" Kasprzak
+M:     kas@fi.muni.cz
+W:     http://www.fi.muni.cz/~kas/cosa/
+S:     Maintained
+
 CREDITS FILE
 P:     John A. Martin
 M:     jam@acm.org
 S:     Maintained
 
 CYCLADES ASYNC MUX DRIVER
-P:     Marcio Saito
-M:     Marcio Saito <marcio@cyclades.com>
+P:     Ivan Passos
+M:     Ivan Passos <ivan@cyclades.com>
 W:     http://www.cyclades.com/
 S:     Supported
 
@@ -188,13 +208,15 @@ S:        Maintained
 
 DC390/AM53C974 SCSI driver
 P:     Kurt Garloff
-M:     K.Garloff@ping.de
-W:     ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/
+M:     kurt@garloff.de
+W:     http://www.garloff.de/kurt/linux/dc390/
 S:     Maintained
 
 DECnet NETWORK LAYER
 P:     Steven Whitehouse
 M:     SteveW@ACM.org
+W:     http://www.sucs.swan.ac.uk/~rohan/
+W:     http://www-sigproc.eng.cam.ac.uk/~sjw44/
 L:     netdev@roxanne.nuclecu.unam.mx
 S:     Maintained
 
@@ -350,7 +372,7 @@ S:  Maintained
 IP FIREWALL
 P:     Paul Russell
 M:     Paul.Russell@rustcorp.com.au
-W:     http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
+W:     http://www.rustcorp.com/linux/ipchains
 S:     Supported
 
 IPX/SPX NETWORK LAYER
@@ -359,6 +381,13 @@ M: Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
 L:     linux-net@vger.rutgers.edu
 S:     Maintained
 
+IRDA SUBSYSTEM
+P:      Dag Brattli
+M:      Dag Brattli <dagb@cs.uit.no>
+L:      linux-irda@list.uit.no
+W:      http://www.cs.uit.no/~dagb/irda/
+S:      Maintained
+
 ISDN SUBSYSTEM
 P:     Fritz Elfert
 M:     fritz@wuemaus.franken.de
@@ -448,6 +477,13 @@ M: rubini@ipvvis.unipv.it
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
+MTRR AND SIMILAR SUPPORT [i386]
+P:     Richard Gooch
+M:     rgooch@atnf.csiro.au
+L:     linux-kernel@vger.rutgers.edu
+W:     http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
+S:     Maintained
+
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
 M:     andrewtv@usa.net
@@ -457,7 +493,7 @@ NCP FILESYSTEM
 P:     Petr Vandrovec
 M:     vandrove@vc.cvut.cz
 P:     Volker Lendecke
-M:     lendecke@Math.Uni-Goettingen.de
+M:     vl@kki.org
 L:     linware@sh.cvut.cz
 S:     Maintained
 
@@ -502,6 +538,12 @@ M: emoenke@gwdg.de
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
+OPL3-SA2, SA3, and SAx DRIVER
+P:     Scott Murray
+M:     scottm@interlog.com
+L:     linux-sound@vger.rutgers.edu
+S:     Maintained
+
 PARALLEL PORT SUPPORT
 P:     Phil Blundell
 M:     Philip.Blundell@pobox.com
@@ -596,7 +638,7 @@ S:  Maintained
 
 SMB FILESYSTEM
 P:     Volker Lendecke
-M:     lendecke@Math.Uni-Goettingen.de
+M:     vl@kki.org
 L:     samba@listproc.anu.edu.au
 S:     Maintained
 
index 96666ced77517fddc4cc1fc83588c96001b049d9..cfd366eb59173d2f8a90692b32270cf957edf7a3 100644 (file)
@@ -42,6 +42,7 @@ CONFIG_ALPHA_GENERIC=y
 # CONFIG_ALPHA_SX164 is not set
 # CONFIG_ALPHA_SABLE is not set
 # CONFIG_ALPHA_TAKARA is not set
+# CONFIG_SMP is not set
 CONFIG_PCI=y
 CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
 # CONFIG_PCI_QUIRKS is not set
index 4323b569596b0c50d92f5231ffb1678335788a15..467a861d1478da1ed32cd3e7ac5b36c968f66d2c 100644 (file)
@@ -824,7 +824,7 @@ probe_irq_on(void)
         * Wait about 100ms for spurious interrupts to mask themselves
         * out again...
         */
-       for (delay = jiffies + HZ/10; delay > jiffies; )
+       for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
                barrier();
 
        /* Now filter out any obviously spurious interrupts.  */
index a2c702501a6c1a79d5d1bd527142833d9f5fc571..fc092a495eff0300f08e0e9bd83c95f55732543e 100644 (file)
@@ -215,7 +215,7 @@ static void ecard_irq_noexpmask(int intr_no, void *dev_id, struct pt_regs *regs)
                } else
                        lockup = 0;
 
-               if (!last || last + 500 < jiffies) {
+               if (!last || time_after(jiffies, last + 500)) {
                        last = jiffies;
                        printk(KERN_ERR "\nUnrecognised interrupt from backplane\n");
                }
index d88ca6ce99a3711452092c4454b0e7d533f5ef03..e3385696b076c1e640b86985289425466ed209ed 100644 (file)
@@ -123,7 +123,7 @@ static void irq_pci_err(int irq, void *dev_id, struct pt_regs *regs)
                err = "system";
                break;
        }
-       if (next_warn[idx] <= jiffies) {
+       if (time_after_eq(jiffies, next_warn[idx])) {
                next_warn[idx] = jiffies + 3 * HZ / 100;
                printk(KERN_ERR "PCI %s error detected\n", err);
        }
index 4c2063ae5e62c5754feb539ee98bdb59cdbdbabd..332e8940d707c7c199e9f7a4797ea2e17bbba305 100644 (file)
@@ -356,7 +356,7 @@ unsigned long probe_irq_on(void)
        /*
         * wait for spurious interrupts to mask themselves out again
         */
-       for (delay = jiffies + HZ/10; delay > jiffies; )
+       for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
                /* min 100ms delay */;
 
        /*
index 9a7bd3f5bd1713a0eefa48b2df799066d0abd2ce..f64a0da2fc24a7f8f98a36c8512e97b4728d5046 100644 (file)
@@ -17,9 +17,7 @@ choice 'Processor family' \
         Pentium/K5/5x86/6x86   CONFIG_M586     \
         PPro/K6/6x86MX         CONFIG_M686" Pentium
 bool 'Math emulation' CONFIG_MATH_EMULATION
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
-fi
+bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
 endmenu
 
@@ -38,10 +36,16 @@ comment 'General setup'
 bool 'Networking support' CONFIG_NET
 bool 'PCI support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
-  bool '   PCI BIOS support' CONFIG_PCI_BIOS
-  bool '   PCI direct access support' CONFIG_PCI_DIRECT
-  if [ "$CONFIG_PCI_BIOS" = "n" -a "$CONFIG_PCI_DIRECT" = "n" ]; then
-    define_bool CONFIG_PCI_BIOS "y"
+  unset CONFIG_PCI_BIOS CONFIG_PCI_DIRECT
+  choice 'PCI access mode' \
+       "BIOS           CONFIG_PCI_GOBIOS       \
+        Direct         CONFIG_PCI_GODIRECT     \
+        Any            CONFIG_PCI_GOANY"       Any
+  if [ -n "$CONFIG_PCI_GOBIOS" -o -n "$CONFIG_PCI_GOANY" ]; then
+    define_bool CONFIG_PCI_BIOS y
+  fi
+  if [ -n "$CONFIG_PCI_GODIRECT" -o -n "$CONFIG_PCI_GOANY" ]; then
+    define_bool CONFIG_PCI_DIRECT y
   fi
   bool '   PCI quirks' CONFIG_PCI_QUIRKS
   if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
index 3f6ebecd15506f9e1b46e2b1d38b4e38ffd37091..4187224cda509d84e356a7ea43f635e6ee296ee4 100644 (file)
@@ -15,6 +15,7 @@
 CONFIG_M586=y
 # CONFIG_M686 is not set
 # CONFIG_MATH_EMULATION is not set
+# CONFIG_MTRR is not set
 CONFIG_SMP=y
 
 #
@@ -29,6 +30,9 @@ CONFIG_MODULES=y
 #
 CONFIG_NET=y
 CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_QUIRKS=y
@@ -211,6 +215,7 @@ CONFIG_EEXPRESS_PRO100=y
 # CONFIG_NET_RADIO is not set
 # CONFIG_TR is not set
 # CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
 # CONFIG_WAN_DRIVERS is not set
 # CONFIG_LAPBETHER is not set
 # CONFIG_X25_ASY is not set
@@ -242,6 +247,10 @@ CONFIG_SERIAL=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 CONFIG_MOUSE=y
+
+#
+# Mice
+#
 # CONFIG_ATIXL_BUSMOUSE is not set
 # CONFIG_BUSMOUSE is not set
 # CONFIG_MS_BUSMOUSE is not set
@@ -250,9 +259,17 @@ CONFIG_82C710_MOUSE=y
 # CONFIG_PC110_PAD is not set
 # CONFIG_QIC02_TAPE is not set
 # CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
 # CONFIG_VIDEO_DEV is not set
-# CONFIG_NVRAM is not set
+
+#
+# Joystick support
+#
 # CONFIG_JOYSTICK is not set
 
 #
@@ -264,36 +281,44 @@ CONFIG_82C710_MOUSE=y
 # Filesystems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_SUN is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
 # CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MAC_PARTITION is not set
 # CONFIG_SMD_DISKLABEL is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_MAC_PARTITION is not set
 # CONFIG_NLS is not set
 
 #
index 324e8cec7d5bde7b0a4f24223e467911e4a7387d..fd330ac294baff2eed29a7d51da931fdeedfda11 100644 (file)
@@ -615,7 +615,8 @@ static void do_all_cpus (void (*handler) (struct set_mtrr_context *ctxt,
     smp_message_pass (MSG_ALL_BUT_SELF, MSG_MTRR_CHANGE, 0, 0);
     /*  Wait for it to be done  */
     timeout = jiffies + JIFFIE_TIMEOUT;
-    while ( (atomic_read (&undone_count) > 0) && (jiffies < timeout) )
+    while ( (atomic_read (&undone_count) > 0) &&
+           time_before(jiffies, timeout) )
        barrier ();
     if (atomic_read (&undone_count) > 0)
     {
index 1cafe87c6a19ead6e56734e382b45560d906a825..30f0dac3f4f58747635cfbcc1942a443752b74ba 100644 (file)
  *     ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
  * 1998-12-16    Andrea Arcangeli
  *     Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
- *     because was not accounting lost_ticks. I also removed some ugly
- *     not needed global cli() and where needed I used a disable_irq(0).
+ *     because was not accounting lost_ticks.
+ * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
+ *     Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
+ *     serialize accesses to xtime/lost_ticks).
  */
 
 /* What about the "updated NTP code" stuff in 2.0 time.c? It's not in
@@ -82,6 +84,8 @@ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
  */
 static unsigned long fast_gettimeoffset_quotient=0;
 
+extern rwlock_t xtime_lock;
+
 static unsigned long do_fast_gettimeoffset(void)
 {
        register unsigned long eax asm("ax");
@@ -237,12 +241,12 @@ void do_gettimeofday(struct timeval *tv)
        extern volatile unsigned long lost_ticks;
        unsigned long flags;
 
-       save_flags(flags); cli();
+       read_lock_irqsave(&xtime_lock, flags);
        *tv = xtime;
        tv->tv_usec += do_gettimeoffset();
        if (lost_ticks)
                tv->tv_usec += lost_ticks * (1000000/HZ);
-       restore_flags(flags);
+       read_unlock_irqrestore(&xtime_lock, flags);
        while (tv->tv_usec >= 1000000) {
                tv->tv_usec -= 1000000;
                tv->tv_sec++;
@@ -251,7 +255,7 @@ void do_gettimeofday(struct timeval *tv)
 
 void do_settimeofday(struct timeval *tv)
 {
-       cli();
+       write_lock_irq(&xtime_lock);
        /* This is revolting. We need to set the xtime.tv_usec
         * correctly. However, the value in this location is
         * is value at the last tick.
@@ -269,7 +273,7 @@ void do_settimeofday(struct timeval *tv)
        time_state = TIME_BAD;
        time_maxerror = MAXPHASE;
        time_esterror = MAXPHASE;
-       sti();
+       write_unlock_irq(&xtime_lock);
 }
 
 /*
@@ -344,7 +348,7 @@ static long last_rtc_update = 0;
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        do_timer(regs);
 /*
@@ -398,37 +402,56 @@ static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
 }
 
+static int use_tsc = 0;
+
 /*
  * This is the same as the above, except we _also_ save the current
  * Time Stamp Counter value at the time of the timer interrupt, so that
  * we later on can estimate the time of day more exactly.
  */
-static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        int count;
 
-       /* It is important that these two operations happen almost at the
-        * same time. We do the RDTSC stuff first, since it's faster. To
-         * avoid any inconsistencies, we need interrupts disabled locally.
-         */
-
        /*
-        * Interrupts are just disabled locally since the timer irq has the
-        * SA_INTERRUPT flag set. -arca
+        * Here we are in the timer irq handler. We just have irqs locally
+        * disabled but we don't know if the timer_bh is running on the other
+        * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+        * the irq version of write_lock because as just said we have irq
+        * locally disabled. -arca
         */
+       write_lock(&xtime_lock);
+
+       if (use_tsc)
+       {
+               /*
+                * It is important that these two operations happen almost at
+                * the same time. We do the RDTSC stuff first, since it's
+                * faster. To avoid any inconsistencies, we need interrupts
+                * disabled locally.
+                */
+
+               /*
+                * Interrupts are just disabled locally since the timer irq
+                * has the SA_INTERRUPT flag set. -arca
+                */
        
-       /* read Pentium cycle counter */
-       __asm__("rdtsc" : "=a" (last_tsc_low) : : "edx");
+               /* read Pentium cycle counter */
+               __asm__("rdtsc" : "=a" (last_tsc_low) : : "edx");
 
-       outb_p(0x00, 0x43);     /* latch the count ASAP */
+               outb_p(0x00, 0x43);     /* latch the count ASAP */
 
-       count = inb_p(0x40);    /* read the latched count */
-       count |= inb(0x40) << 8;
+               count = inb_p(0x40);    /* read the latched count */
+               count |= inb(0x40) << 8;
 
-       count = ((LATCH-1) - count) * TICK_SIZE;
-       delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+               count = ((LATCH-1) - count) * TICK_SIZE;
+               delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+       }
  
-       timer_interrupt(irq, NULL, regs);
+       do_timer_interrupt(irq, NULL, regs);
+
+       write_unlock(&xtime_lock);
+
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -601,7 +624,7 @@ __initfunc(void time_init(void))
        if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
                do_gettimeoffset = do_fast_gettimeoffset;
                do_get_fast_time = do_gettimeofday;
-               irq0.handler = pentium_timer_interrupt;
+               use_tsc = 1;
                fast_gettimeoffset_quotient = calibrate_tsc();
                
                /* report CPU clock rate in Hz.
index 6e9a954230087c3dcc3450634884ae3ceaac8eae..71b47d78858427b95576bfc2c5e5ddb65d2c03ad 100644 (file)
@@ -499,15 +499,18 @@ __initfunc(void trap_init_f00f_bug(void))
 }
 
 #define _set_gate(gate_addr,type,dpl,addr) \
-__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
-       "movw %2,%%dx\n\t" \
+do { \
+  int __d0, __d1; \
+  __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
+       "movw %4,%%dx\n\t" \
        "movl %%eax,%0\n\t" \
        "movl %%edx,%1" \
        :"=m" (*((long *) (gate_addr))), \
-        "=m" (*(1+(long *) (gate_addr))) \
+        "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
        :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
-        "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \
-       :"ax","dx")
+        "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
+} while (0)
+
 
 /*
  * This needs to use 'idt_table' rather than 'idt', and
index 6490984b16fcbc050867519f3af6ad9101694190..c2cb3e5a6b9d97dc96d1d0f71a49440c771c3262 100644 (file)
@@ -6,6 +6,7 @@
        $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
 
 L_TARGET = lib.a
-L_OBJS  = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o
+L_OBJS  = checksum.o old-checksum.o semaphore.o delay.o \
+       usercopy.o getuser.o putuser.o
 
 include $(TOPDIR)/Rules.make
diff --git a/arch/i386/lib/checksum.S b/arch/i386/lib/checksum.S
new file mode 100644 (file)
index 0000000..f721cb8
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * INET                An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             IP/TCP/UDP checksumming routines
+ *
+ * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
+ *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
+ *             Tom May, <ftom@netcom.com>
+ *              Pentium Pro/II routines:
+ *              Alexander Kjeldaas <astor@guardian.no>
+ *              Finn Arne Gangstad <finnag@guardian.no>
+ *             Lots of code moved from tcp.c and ip.c; see those files
+ *             for more names.
+ *
+ * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
+ *                          handling.
+ *             Andi Kleen,  add zeroing on error
+ *                   converted to pure assembler
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/errno.h>
+                               
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+
+/*     
+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+ */
+               
+.text
+.align 4
+.globl csum_partial                                                            
+               
+#if CPU!=686
+
+         /*            
+          * Experiments with Ethernet and SLIP connections show that buff
+          * is aligned on either a 2-byte or 4-byte boundary.  We get at
+          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
+          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
+          * alignment for the unrolled loop.
+          */           
+csum_partial:  
+       pushl %esi
+       pushl %ebx
+       movl 20(%esp),%eax      # Function arg: unsigned int sum
+       movl 16(%esp),%ecx      # Function arg: int len
+       movl 12(%esp),%esi      # Function arg: unsigned char *buff
+       testl $2, %esi          # Check alignment.
+       jz 2f                   # Jump if alignment is ok.
+       subl $2, %ecx           # Alignment uses up two bytes.
+       jae 1f                  # Jump if we had at least two bytes.
+       addl $2, %ecx           # ecx was < 2.  Deal with it.
+       jmp 4f
+1:     movw (%esi), %bx
+       addl $2, %esi
+       addw %bx, %ax
+       adcl $0, %eax
+2:
+       movl %ecx, %edx
+       shrl $5, %ecx
+       jz 2f
+       testl %esi, %esi
+1:     movl (%esi), %ebx
+       adcl %ebx, %eax
+       movl 4(%esi), %ebx
+       adcl %ebx, %eax
+       movl 8(%esi), %ebx
+       adcl %ebx, %eax
+       movl 12(%esi), %ebx
+       adcl %ebx, %eax
+       movl 16(%esi), %ebx
+       adcl %ebx, %eax
+       movl 20(%esi), %ebx
+       adcl %ebx, %eax
+       movl 24(%esi), %ebx
+       adcl %ebx, %eax
+       movl 28(%esi), %ebx
+       adcl %ebx, %eax
+       lea 32(%esi), %esi
+       dec %ecx
+       jne 1b
+       adcl $0, %eax
+2:     movl %edx, %ecx
+       andl $0x1c, %edx
+       je 4f
+       shrl $2, %edx           # This clears CF
+3:     adcl (%esi), %eax
+       lea 4(%esi), %esi
+       dec %edx
+       jne 3b
+       adcl $0, %eax
+4:     andl $3, %ecx
+       jz 7f
+       cmpl $2, %ecx
+       jb 5f
+       movw (%esi),%cx
+       leal 2(%esi),%esi
+       je 6f
+       shll $16,%ecx
+5:     movb (%esi),%cl
+6:     addl %ecx,%eax
+       adcl $0, %eax 
+7:     
+       popl %ebx
+       popl %esi
+       ret
+
+#else /* CPU==686 */
+
+csum_partial:
+       movl 12(%esp),%eax      # Function arg: unsigned int sum
+       movl 8(%esp),%ecx       # Function arg: int len
+       movl 4(%esp),%esi       # Function arg: const unsigned char *buf
+
+       testl $2, %esi         
+       jnz 30f                 
+10:
+       movl %ecx, %edx
+       movl %ecx, %ebx
+       andl $0x7c, %ebx
+       shrl $7, %ecx
+       addl %ebx,%esi
+       shrl $2, %ebx  
+       negl %ebx
+       lea 45f(%ebx,%ebx,2), %ebx
+       testl %esi, %esi
+       jmp *%ebx
+
+       # Handle 2-byte-aligned regions
+20:    addw (%esi), %ax
+       lea 2(%esi), %esi
+       adcl $0, %eax
+       jmp 10b
+
+30:    subl $2, %ecx          
+       ja 20b                 
+       je 32f
+       movzbl (%esi),%ebx      # csumming 1 byte, 2-aligned
+       addl %ebx, %eax
+       adcl $0, %eax
+       jmp 80f
+32:
+       addw (%esi), %ax        # csumming 2 bytes, 2-aligned
+       adcl $0, %eax
+       jmp 80f
+
+40: 
+       addl -128(%esi), %eax
+       adcl -124(%esi), %eax
+       adcl -120(%esi), %eax
+       adcl -116(%esi), %eax   
+       adcl -112(%esi), %eax   
+       adcl -108(%esi), %eax
+       adcl -104(%esi), %eax
+       adcl -100(%esi), %eax
+       adcl -96(%esi), %eax
+       adcl -92(%esi), %eax
+       adcl -88(%esi), %eax
+       adcl -84(%esi), %eax
+       adcl -80(%esi), %eax
+       adcl -76(%esi), %eax
+       adcl -72(%esi), %eax
+       adcl -68(%esi), %eax
+       adcl -64(%esi), %eax     
+       adcl -60(%esi), %eax     
+       adcl -56(%esi), %eax     
+       adcl -52(%esi), %eax   
+       adcl -48(%esi), %eax   
+       adcl -44(%esi), %eax
+       adcl -40(%esi), %eax
+       adcl -36(%esi), %eax
+       adcl -32(%esi), %eax
+       adcl -28(%esi), %eax
+       adcl -24(%esi), %eax
+       adcl -20(%esi), %eax
+       adcl -16(%esi), %eax
+       adcl -12(%esi), %eax
+       adcl -8(%esi), %eax
+       adcl -4(%esi), %eax
+45:
+       lea 128(%esi), %esi
+       adcl $0, %eax
+       dec %ecx
+       jge 40b
+       movl %edx, %ecx
+50:    andl $3, %ecx
+       jz 80f
+
+       # Handle the last 1-3 bytes without jumping
+       notl %ecx               # 1->2, 2->1, 3->0, higher bits are masked
+       movl $0xffffff,%ebx     # by the shll and shrl instructions
+       shll $3,%ecx
+       shrl %cl,%ebx
+       andl -128(%esi),%ebx    # esi is 4-aligned so should be ok
+       addl %ebx,%eax
+       adcl $0,%eax
+80: 
+       ret
+                               
+#endif /* CPU==686 */ 
+
+/*
+unsigned int csum_partial_copy_generic (const char *src, char *dst,
+                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
+ */ 
+
+/*
+ * Copy from ds while checksumming, otherwise like csum_partial
+ *
+ * The macros SRC and DST specify the type of access for the instruction.
+ * thus we can call a custom exception handler for all access types.
+ *
+ * FIXME: could someone double-check whether I haven't mixed up some SRC and
+ *       DST definitions? It's damn hard to trigger all cases.  I hope I got
+ *       them all but there's no guarantee.
+ */
+
+#define SRC(y...)                      \
+       9999: y;                        \
+       .section __ex_table, "a";       \
+       .long 9999b, 6001f      ;       \
+       .previous
+
+#define DST(y...)                      \
+       9999: y;                        \
+       .section __ex_table, "a";       \
+       .long 9999b, 6002f      ;       \
+       .previous
+
+.align 4
+.globl csum_partial_copy_generic
+                               
+#if CPU!=686
+
+#define ARGBASE 16             
+#define FP             12
+               
+csum_partial_copy_generic:
+       subl  $4,%esp   
+       pushl %edi
+       pushl %esi
+       pushl %ebx
+       movl ARGBASE+16(%esp),%eax      # sum
+       movl ARGBASE+12(%esp),%ecx      # len
+       movl ARGBASE+4(%esp),%esi       # src
+       movl ARGBASE+8(%esp),%edi       # dst
+
+       testl $2, %edi                  # Check alignment. 
+       jz 2f                           # Jump if alignment is ok.
+       subl $2, %ecx                   # Alignment uses up two bytes.
+       jae 1f                          # Jump if we had at least two bytes.
+       addl $2, %ecx                   # ecx was < 2.  Deal with it.
+       jmp 4f
+SRC(1: movw (%esi), %bx        )
+       addl $2, %esi
+DST(   movw %bx, (%edi)        )
+       addl $2, %edi
+       addw %bx, %ax   
+       adcl $0, %eax
+2:
+       movl %ecx, FP(%esp)
+       shrl $5, %ecx
+       jz 2f
+       testl %esi, %esi
+SRC(1: movl (%esi), %ebx       )
+SRC(   movl 4(%esi), %edx      )
+       adcl %ebx, %eax
+DST(   movl %ebx, (%edi)       )
+       adcl %edx, %eax
+DST(   movl %edx, 4(%edi)      )
+
+SRC(   movl 8(%esi), %ebx      )
+SRC(   movl 12(%esi), %edx     )
+       adcl %ebx, %eax
+DST(   movl %ebx, 8(%edi)      )
+       adcl %edx, %eax
+DST(   movl %edx, 12(%edi)     )
+
+SRC(   movl 16(%esi), %ebx     )
+SRC(   movl 20(%esi), %edx     )
+       adcl %ebx, %eax
+DST(   movl %ebx, 16(%edi)     )
+       adcl %edx, %eax
+DST(   movl %edx, 20(%edi)     )
+
+SRC(   movl 24(%esi), %ebx     )
+SRC(   movl 28(%esi), %edx     )
+       adcl %ebx, %eax
+DST(   movl %ebx, 24(%edi)     )
+       adcl %edx, %eax
+DST(   movl %edx, 28(%edi)     )
+
+SRC(   lea 32(%esi), %esi      )
+DST(   lea 32(%edi), %edi      )
+       dec %ecx
+       jne 1b
+       adcl $0, %eax
+2:     movl FP(%esp), %edx
+       movl %edx, %ecx
+       andl $0x1c, %edx
+       je 4f
+       shrl $2, %edx                   # This clears CF
+SRC(3: movl (%esi), %ebx       )
+       adcl %ebx, %eax
+DST(   movl %ebx, (%edi)       )
+SRC(   lea 4(%esi), %esi       )
+DST(   lea 4(%edi), %edi       )
+       dec %edx
+       jne 3b
+       adcl $0, %eax
+4:     andl $3, %ecx
+       jz 7f
+       cmpl $2, %ecx
+       jb 5f
+SRC(   movw (%esi), %cx        )
+SRC(   leal 2(%esi), %esi      )
+DST(   movw %cx, (%edi)        )
+DST(   leal 2(%edi), %edi      )
+       je 6f
+       shll $16,%ecx
+SRC(5: movb (%esi), %cl        )
+DST(   movb %cl, (%edi)        )
+6:     addl %ecx, %eax
+       adcl $0, %eax
+7:
+5000:
+
+# Exception handler:
+.section .fixup, "ax"                                                  
+
+6000:
+
+       movl $-EFAULT, (%ebx)
+
+       # zero the complete destination - computing the rest
+       # is too much work 
+       movl ARGBASE+8(%esp), %edi      # dst
+       movl ARGBASE+12(%esp), %ecx     # len
+       xorl %eax,%eax
+       rep ; stosb
+
+       jmp 5000b
+
+6001:
+       movl ARGBASE+20(%esp), %ebx     # src_err_ptr
+       jmp 6000b
+
+6002:
+       movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
+       jmp 6000b
+
+.previous
+
+       popl %ebx
+       popl %esi
+       popl %edi
+       popl %ecx                       # equivalent to addl $4,%esp
+       ret     
+
+#else
+
+/* Version for PentiumII/PPro */
+
+#define ROUND1(x) \
+       SRC(movl x(%esi), %ebx  )       ;       \
+       addl %ebx, %eax\n               ;       \
+       DST(movl %ebx, x(%edi)  )       ; 
+
+#define ROUND(x) \
+       SRC(movl x(%esi), %ebx  )       ;       \
+       adcl %ebx, %eax                 ;       \
+       DST(movl %ebx, x(%edi)  )       ;
+
+#define ARGBASE 12
+               
+csum_partial_copy_generic:
+       pushl %ebx
+       pushl %edi
+       pushl %esi
+       movl ARGBASE+4(%esp),%esi       #src
+       movl ARGBASE+8(%esp),%edi       #dst    
+       movl ARGBASE+12(%esp),%ecx      #len
+       movl ARGBASE+16(%esp),%eax      #sum
+       movl %ecx, %edx  
+       movl %ecx, %ebx  
+       shrl $6, %ecx     
+       andl $0x3c, %ebx  
+       negl %ebx
+       subl %ebx, %esi  
+       subl %ebx, %edi  
+       lea 3f(%ebx,%ebx), %ebx
+       testl %esi, %esi 
+       jmp *%ebx         
+1:     addl $64,%esi
+       addl $64,%edi 
+       ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)    
+       ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)    
+       ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)    
+       ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)     
+3:     adcl $0,%eax
+       dec %ecx
+       jge 1b
+4:      andl $3, %edx
+       jz 7f
+       cmpl $2, %edx
+       jb 5f
+SRC(   movw (%esi), %dx         )
+       leal 2(%esi), %esi
+DST(   movw %dx, (%edi)         )
+       leal 2(%edi), %edi
+       je 6f
+       shll $16,%edx
+5:
+SRC(   movb (%esi), %dl         )
+DST(   movb %dl, (%edi)         )
+6:     addl %edx, %eax
+       adcl $0, %eax
+7:
+.section .fixup, "ax"
+6000:  movl $-EFAULT, (%ebx)
+       # zero the complete destination (computing the rest is too much work)
+       movl ARGBASE+8(%esp),%edi       # dst
+       movl ARGBASE+12(%esp),%ecx      # len
+       xorl %eax,%eax
+       rep; stosb
+       jmp 7b
+6001:  movl ARGBASE+20(%esp), %ebx     # src_err_ptr
+       jmp 6000b       
+6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
+       jmp 6000b
+.previous                              
+
+       popl %esi
+       popl %edi
+       popl %ebx
+       ret
+                               
+#undef ROUND
+#undef ROUND1          
+               
+#endif /* CPU==i686 */ 
diff --git a/arch/i386/lib/checksum.c b/arch/i386/lib/checksum.c
deleted file mode 100644 (file)
index 51a9219..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * INET                An implementation of the TCP/IP protocol suite for the LINUX
- *             operating system.  INET is implemented using the  BSD Socket
- *             interface as the means of communication with the user level.
- *
- *             IP/TCP/UDP checksumming routines
- *
- * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
- *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *             Tom May, <ftom@netcom.com>
- *              Pentium Pro/II routines:
- *              Alexander Kjeldaas <astor@guardian.no>
- *              Finn Arne Gangstad <finnag@guardian.no>
- *             Lots of code moved from tcp.c and ip.c; see those files
- *             for more names.
- *
- * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
- *                          handling.
- *             Andi Kleen,  add zeroing on error, fix constraints.
- *
- * To fix:
- *             Convert to pure asm, because this file is too hard
- *             for gcc's register allocator and it is not clear if the
- *             contraints are correct.
- *
- *             This program is free software; you can redistribute it and/or
- *             modify it under the terms of the GNU General Public License
- *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
- */
-
-#include <net/checksum.h>
-
-/*
- * computes a partial checksum, e.g. for TCP/UDP fragments
- */
-
-#if CPU!=686
-
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) {
-         /*
-          * Experiments with Ethernet and SLIP connections show that buff
-          * is aligned on either a 2-byte or 4-byte boundary.  We get at
-          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
-          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
-          * alignment for the unrolled loop.
-          */
-       __asm__("
-           testl $2, %%esi             # Check alignment.
-           jz 2f                       # Jump if alignment is ok.
-           subl $2, %%ecx              # Alignment uses up two bytes.
-           jae 1f                      # Jump if we had at least two bytes.
-           addl $2, %%ecx              # ecx was < 2.  Deal with it.
-           jmp 4f
-1:         movw (%%esi), %%bx
-           addl $2, %%esi
-           addw %%bx, %%ax
-           adcl $0, %%eax
-2:
-           movl %%ecx, %%edx
-           shrl $5, %%ecx
-           jz 2f
-           testl %%esi, %%esi
-1:         movl (%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 4(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 8(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 12(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 16(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 20(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 24(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           movl 28(%%esi), %%ebx
-           adcl %%ebx, %%eax
-           lea 32(%%esi), %%esi
-           dec %%ecx
-           jne 1b
-           adcl $0, %%eax
-2:         movl %%edx, %%ecx
-           andl $0x1c, %%edx
-           je 4f
-           shrl $2, %%edx      # This clears CF
-3:         adcl (%%esi), %%eax
-           lea 4(%%esi), %%esi
-           dec %%edx
-           jne 3b
-           adcl $0, %%eax
-4:         andl $3, %%ecx
-           jz 7f
-           cmpl $2, %%ecx
-           jb 5f
-           movw (%%esi),%%cx
-           leal 2(%%esi),%%esi
-           je 6f
-           shll $16,%%ecx
-5:         movb (%%esi),%%cl
-6:         addl %%ecx,%%eax
-           adcl $0, %%eax 
-7:         "
-       : "=a"(sum)
-       : "0"(sum), "c"(len), "S"(buff)
-       : "bx", "dx", "si", "cx", "memory");
-       return(sum);
-}
-
-#else  /* 686 */
-
-unsigned int csum_partial(const unsigned char * buf, int len, unsigned int sum) {
-         __asm__ ("
-            testl $2, %%esi         
-            jnz 30f                 
-10:
-            movl %%ecx, %%edx
-            movl %%ecx, %%ebx
-            andl $0x7c, %%ebx
-            shrl $7, %%ecx
-            addl %%ebx,%%esi
-            shrl $2, %%ebx  
-            negl %%ebx
-            lea 45f(%%ebx,%%ebx,2), %%ebx
-            testl %%esi, %%esi
-            jmp *%%ebx
-
-            # Handle 2-byte-aligned regions
-20:         addw (%%esi), %%ax
-            lea 2(%%esi), %%esi
-            adcl $0, %%eax
-            jmp 10b
-
-30:         subl $2, %%ecx          
-            ja 20b                 
-            je 32f
-            movzbl (%%esi),%%ebx # csumming 1 byte, 2-aligned
-            addl %%ebx, %%eax
-            adcl $0, %%eax
-            jmp 80f
-32:
-            addw (%%esi), %%ax # csumming 2 bytes, 2-aligned
-            adcl $0, %%eax
-            jmp 80f
-
-40: 
-           addl -128(%%esi), %%eax
-            adcl -124(%%esi), %%eax
-            adcl -120(%%esi), %%eax
-            adcl -116(%%esi), %%eax   
-           adcl -112(%%esi), %%eax   
-            adcl -108(%%esi), %%eax
-            adcl -104(%%esi), %%eax
-            adcl -100(%%esi), %%eax
-            adcl -96(%%esi), %%eax
-            adcl -92(%%esi), %%eax
-            adcl -88(%%esi), %%eax
-            adcl -84(%%esi), %%eax
-            adcl -80(%%esi), %%eax
-            adcl -76(%%esi), %%eax
-            adcl -72(%%esi), %%eax
-            adcl -68(%%esi), %%eax
-           adcl -64(%%esi), %%eax     
-            adcl -60(%%esi), %%eax     
-            adcl -56(%%esi), %%eax     
-            adcl -52(%%esi), %%eax   
-            adcl -48(%%esi), %%eax   
-            adcl -44(%%esi), %%eax
-            adcl -40(%%esi), %%eax
-            adcl -36(%%esi), %%eax
-            adcl -32(%%esi), %%eax
-            adcl -28(%%esi), %%eax
-            adcl -24(%%esi), %%eax
-            adcl -20(%%esi), %%eax
-            adcl -16(%%esi), %%eax
-            adcl -12(%%esi), %%eax
-            adcl -8(%%esi), %%eax
-            adcl -4(%%esi), %%eax
-45:
-            lea 128(%%esi), %%esi
-            adcl $0, %%eax
-            dec %%ecx
-            jge 40b
-            movl %%edx, %%ecx
-50:         andl $3, %%ecx
-            jz 80f
-
-            # Handle the last 1-3 bytes without jumping
-            notl %%ecx            # 1->2, 2->1, 3->0, higher bits are masked
-           movl $0xffffff,%%ebx  # by the shll and shrl instructions
-           shll $3,%%ecx
-           shrl %%cl,%%ebx
-           andl -128(%%esi),%%ebx # esi is 4-aligned so should be ok
-           addl %%ebx,%%eax
-           adcl $0,%%eax
-80:          "
-        : "=a"(sum)
-        : "0"(sum), "c"(len), "S"(buf)
-        : "bx", "dx", "cx", "si", "memory");
-        return(sum);
-}
-
-#endif
-
-/*
- * Copy from ds while checksumming, otherwise like csum_partial
- *
- * The macros SRC and DST specify the type of access for the instruction.
- * thus we can call a custom exception handler for all access types.
- *
- * FIXME: could someone double-check whether I haven't mixed up some SRC and
- *       DST definitions? It's damn hard to trigger all cases.  I hope I got
- *       them all but there's no guarantee.
- */
-
-#define SRC(y...)                      \
-"      9999: "#y";                     \n \
-       .section __ex_table, \"a\";     \n \
-       .long 9999b, 6001f              \n \
-       .previous\n"
-
-#define DST(y...)                      \
-"      9999: "#y";                     \n \
-       .section __ex_table, \"a\";     \n \
-       .long 9999b, 6002f              \n \
-       .previous\n"
-
-#if CPU!=686
-
-unsigned int csum_partial_copy_generic (const char *src, char *dst,
-                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
-{
-    __u32 tmp_var;
-
-    __asm__ __volatile__ ( "
-               movl  %6,%%edi
-               testl $2, %%edi         # Check alignment. 
-               jz 2f                   # Jump if alignment is ok.
-               subl $2, %%ecx          # Alignment uses up two bytes.
-               jae 1f                  # Jump if we had at least two bytes.
-               addl $2, %%ecx          # ecx was < 2.  Deal with it.
-               jmp 4f
-"SRC(  1:      movw (%%esi), %%bx                              )"
-               addl $2, %%esi
-"DST(          movw %%bx, (%%edi)                              )"
-               addl $2, %%edi
-               addw %%bx, %%ax 
-               adcl $0, %%eax
-       2:
-               movl %%ecx, %8
-               shrl $5, %%ecx
-               jz 2f
-               testl %%esi, %%esi
-"SRC(  1:      movl (%%esi), %%ebx                             )"
-"SRC(          movl 4(%%esi), %%edx                            )"
-               adcl %%ebx, %%eax
-"DST(          movl %%ebx, (%%edi)                             )"
-               adcl %%edx, %%eax
-"DST(          movl %%edx, 4(%%edi)                            )"
-
-"SRC(          movl 8(%%esi), %%ebx                            )"
-"SRC(          movl 12(%%esi), %%edx                           )"
-               adcl %%ebx, %%eax
-"DST(          movl %%ebx, 8(%%edi)                            )"
-               adcl %%edx, %%eax
-"DST(          movl %%edx, 12(%%edi)                           )"
-
-"SRC(          movl 16(%%esi), %%ebx                           )"
-"SRC(          movl 20(%%esi), %%edx                           )"
-               adcl %%ebx, %%eax
-"DST(          movl %%ebx, 16(%%edi)                           )"
-               adcl %%edx, %%eax
-"DST(          movl %%edx, 20(%%edi)                           )"
-
-"SRC(          movl 24(%%esi), %%ebx                           )"
-"SRC(          movl 28(%%esi), %%edx                           )"
-               adcl %%ebx, %%eax
-"DST(          movl %%ebx, 24(%%edi)                           )"
-               adcl %%edx, %%eax
-"DST(          movl %%edx, 28(%%edi)                           )"
-
-"SRC(          lea 32(%%esi), %%esi                            )"
-"DST(          lea 32(%%edi), %%edi                            )"
-               dec %%ecx
-               jne 1b
-               adcl $0, %%eax
-       2:      movl %8, %%edx
-               movl %%edx, %%ecx
-               andl $0x1c, %%edx
-               je 4f
-               shrl $2, %%edx          # This clears CF
-"SRC(  3:      movl (%%esi), %%ebx                             )"
-               adcl %%ebx, %%eax
-"DST(          movl %%ebx, (%%edi)                             )"
-"SRC(          lea 4(%%esi), %%esi                             )"
-"DST(          lea 4(%%edi), %%edi                             )"
-               dec %%edx
-               jne 3b
-               adcl $0, %%eax
-       4:      andl $3, %%ecx
-               jz 7f
-               cmpl $2, %%ecx
-               jb 5f
-"SRC(          movw (%%esi), %%cx                              )"
-"SRC(          leal 2(%%esi), %%esi                            )"
-"DST(          movw %%cx, (%%edi)                              )"
-"DST(          leal 2(%%edi), %%edi                            )"
-               je 6f
-               shll $16,%%ecx
-"SRC(  5:      movb (%%esi), %%cl                              )"
-"DST(          movb %%cl, (%%edi)                              )"
-       6:      addl %%ecx, %%eax
-               adcl $0, %%eax
-       7:
-
-5000:
-
-# Exception handler:
-################################################
-                                               #
-.section .fixup, \"ax\"                                #
-                                               #
-6000:                                          #
-                                               #
-       movl    %7, (%%ebx)                     #
-                                               #
-# zero the complete destination - computing the rest
-# is too much work 
-       movl    %6, %%edi
-       movl    %9, %%ecx
-       xorl    %%eax,%%eax
-       rep ; stosb
-                                               #
-       jmp     5000b                           #
-                                               #
-6001:                                          #
-       movl    %1, %%ebx                       #
-       jmp     6000b                           #
-                                               #
-6002:                                          #
-       movl    %2, %%ebx                       #
-       jmp     6000b                           #
-                                               #
-.previous                                      #
-                                               #
-################################################
-
-"
-       : "=a" (sum)
-       : "m" (src_err_ptr), "m" (dst_err_ptr),
-         "0" (sum), "c" (len), "S" (src), "m" (dst),
-               "i" (-EFAULT), "m"(tmp_var),
-               "m" (len)
-       : "bx", "dx", "si", "di", "cx", "memory" );
-
-    return(sum);
-}
-
-#else /* CPU == 686 */
-
-#define ROUND1(x) \
-        SRC(movl x(%%esi), %%ebx         ) \
-        "addl %%ebx, %%eax\n" \
-        DST(movl %%ebx, x(%%edi)         )
-
-#define ROUND(x) \
-        SRC(movl x(%%esi), %%ebx         ) \
-        "adcl %%ebx, %%eax\n" \
-        DST(movl %%ebx, x(%%edi)         )
-
-unsigned int csum_partial_copy_generic (const char *src, char *dst,
-                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
-{
-       __asm__ __volatile__ ("
-       movl %4,%%ecx
-        movl %%ecx, %%edx  
-        movl %%ecx, %%ebx  
-        shrl $6, %%ecx     
-        andl $0x3c, %%ebx  
-        negl %%ebx
-        subl %%ebx, %%esi  
-        subl %%ebx, %%edi  
-        lea 3f(%%ebx,%%ebx), %%ebx
-        testl %%esi, %%esi 
-        jmp *%%ebx         
-1:      addl $64,%%esi
-        addl $64,%%edi\n" 
-ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)
-ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)
-ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)
-ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)
-"3:     adcl $0,%%eax
-        dec %%ecx
-        jge 1b
-4:      andl $3, %%edx
-        jz 7f
-        cmpl $2, %%edx
-        jb 5f
-  " SRC(movw (%%esi), %%dx         )"
-        leal 2(%%esi), %%esi
-  " DST(movw %%dx, (%%edi)         )"
-        leal 2(%%edi), %%edi
-        je 6f
-        shll $16,%%edx
-5:" SRC(movb (%%esi), %%dl         )"
-  " DST(movb %%dl, (%%edi)         )"
-6:      addl %%edx, %%eax
-        adcl $0, %%eax
-7:
-.section .fixup, \"ax\"
-6000:  movl    %7, (%%ebx)
-# zero the complete destination (computing the rest is too much work)
-       movl    %8,%%edi
-       movl    %4,%%ecx
-       xorl    %%eax,%%eax
-       rep ; stosb
-       jmp     7b
-6001:  movl    %1, %%ebx       
-       jmp     6000b   
-6002:  movl    %2, %%ebx
-       jmp     6000b
-.previous
-        "
-       : "=a"(sum)
-        : "m"(src_err_ptr), "m"(dst_err_ptr), 
-         "0"(sum), "m"(len), "S"(src), "D" (dst),
-         "i" (-EFAULT),
-         "m" (dst)
-        : "bx", "cx", "si", "di", "dx", "memory" );
-       return(sum);
-}
-
-#undef ROUND
-#undef ROUND1
-
-#endif
-
-
-#undef SRC
-#undef DST
-
-/*
- * FIXME: old compatibility stuff, will be removed soon.
- */
-
-unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum)
-{
-       int src_err=0, dst_err=0;
-
-       sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err);
-
-       if (src_err || dst_err)
-               printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n");
-
-       return sum;
-}
-
-
index ae8aec6360f961e80f3d7223c2fa04ce74fb1b8e..6918451a6b024b026e4c4519be268b8537b4f395 100644 (file)
 
 void __delay(unsigned long loops)
 {
+       int d0;
        __asm__ __volatile__(
                "\tjmp 1f\n"
                ".align 16\n"
                "1:\tjmp 2f\n"
                ".align 16\n"
                "2:\tdecl %0\n\tjns 2b"
-               :/* no outputs */
-               :"a" (loops)
-               :"ax");
+               :"=&a" (d0)
+               :"0" (loops));
 }
 
 inline void __const_udelay(unsigned long xloops)
 {
+       int d0;
        __asm__("mull %0"
-               :"=d" (xloops)
-               :"a" (xloops),"0" (current_cpu_data.loops_per_sec)
-               :"ax");
+               :"=d" (xloops), "=&a" (d0)
+               :"1" (xloops),"0" (current_cpu_data.loops_per_sec));
         __delay(xloops);
 }
 
diff --git a/arch/i386/lib/old-checksum.c b/arch/i386/lib/old-checksum.c
new file mode 100644 (file)
index 0000000..ae3a380
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * FIXME: old compatibility stuff, will be removed soon.
+ */
+
+#include <net/checksum.h>
+
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum)
+{
+       int src_err=0, dst_err=0;
+
+       sum = csum_partial_copy_generic ( src, dst, len, sum, &src_err, &dst_err);
+
+       if (src_err || dst_err)
+               printk("old csum_partial_copy_fromuser(), tell mingo to convert me.\n");
+
+       return sum;
+}
+
+
index d5b052c20f3cab7e460faeed2a1e7321ceb281be..f43be511f34a67848ac4a9544d30e2d12def883b 100644 (file)
@@ -29,6 +29,8 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n)
  */
 
 #define __do_strncpy_from_user(dst,src,count,res)                         \
+do {                                                                      \
+       int __d0, __d1, __d2;                                              \
        __asm__ __volatile__(                                              \
                "       testl %1,%1\n"                                     \
                "       jz 2f\n"                                           \
@@ -41,16 +43,18 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n)
                "1:     subl %1,%0\n"                                      \
                "2:\n"                                                     \
                ".section .fixup,\"ax\"\n"                                 \
-               "3:     movl %2,%0\n"                                      \
+               "3:     movl %5,%0\n"                                      \
                "       jmp 2b\n"                                          \
                ".previous\n"                                              \
                ".section __ex_table,\"a\"\n"                              \
                "       .align 4\n"                                        \
                "       .long 0b,3b\n"                                     \
                ".previous"                                                \
-               : "=d"(res), "=c"(count)                                   \
-               : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \
-               : "si", "di", "ax", "memory")
+               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
+                 "=&D" (__d2)                                             \
+               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
+               : "memory");                                               \
+} while (0)
 
 long
 __strncpy_from_user(char *dst, const char *src, long count)
@@ -74,14 +78,16 @@ strncpy_from_user(char *dst, const char *src, long count)
  * Zero Userspace
  */
 
-#define __do_clear_user(addr,size)                                             \
-       __asm__ __volatile__(                                           \
+#define __do_clear_user(addr,size)                                     \
+do {                                                                   \
+       int __d0;                                                       \
+       __asm__ __volatile__(                                           \
                "0:     rep; stosl\n"                                   \
-               "       movl %1,%0\n"                                   \
+               "       movl %2,%0\n"                                   \
                "1:     rep; stosb\n"                                   \
                "2:\n"                                                  \
                ".section .fixup,\"ax\"\n"                              \
-               "3:     lea 0(%1,%0,4),%0\n"                            \
+               "3:     lea 0(%2,%0,4),%0\n"                            \
                "       jmp 2b\n"                                       \
                ".previous\n"                                           \
                ".section __ex_table,\"a\"\n"                           \
@@ -89,9 +95,9 @@ strncpy_from_user(char *dst, const char *src, long count)
                "       .long 0b,3b\n"                                  \
                "       .long 1b,2b\n"                                  \
                ".previous"                                             \
-               : "=&c"(size)                                           \
-               : "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0)       \
-               : "di")
+               : "=&c"(size), "=&D" (__d0)                             \
+               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
+} while (0)
 
 unsigned long
 clear_user(void *to, unsigned long n)
index 693072b1a5d54c50c2f31ecfeabc2f18dabdfaee..6697a991117bb425b6bc3d38dff050ca8c88d253 100644 (file)
@@ -119,24 +119,28 @@ int do_check_pgt_cache(int low, int high)
 pte_t * __bad_pagetable(void)
 {
        extern char empty_bad_page_table[PAGE_SIZE];
-
-       __asm__ __volatile__("cld ; rep ; stosl":
-               :"a" (pte_val(BAD_PAGE)),
-                "D" ((long) empty_bad_page_table),
-                "c" (PAGE_SIZE/4)
-               :"di","cx");
+       int d0, d1;
+
+       __asm__ __volatile__("cld ; rep ; stosl"
+                            : "=&D" (d0), "=&c" (d1)
+                            : "a" (pte_val(BAD_PAGE)),
+                            "0" ((long) empty_bad_page_table),
+                            "1" (PAGE_SIZE/4)
+                            : "memory");
        return (pte_t *) empty_bad_page_table;
 }
 
 pte_t __bad_page(void)
 {
        extern char empty_bad_page[PAGE_SIZE];
-
-       __asm__ __volatile__("cld ; rep ; stosl":
-               :"a" (0),
-                "D" ((long) empty_bad_page),
-                "c" (PAGE_SIZE/4)
-               :"di","cx");
+       int d0, d1;
+
+       __asm__ __volatile__("cld ; rep ; stosl"
+                            : "=&D" (d0), "=&c" (d1)
+                            : "a" (0),
+                            "0" ((long) empty_bad_page),
+                            "1" (PAGE_SIZE/4)
+                            : "memory");
        return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
 }
 
@@ -298,7 +302,8 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
                 * NOTE! There are Linux loaders that will corrupt the EBDA
                 * area, and as such this kind of SMP config may be less
                 * trustworthy, simply because the SMP table may have been
-                * stomped on during early boot.
+                * stomped on during early boot. These loaders are buggy and
+                * should be fixed.
                 */
                address = *(unsigned short *)phys_to_virt(0x40E);
                address<<=4;
index b91d7f81efdabe8901a3b2edf1213600ba03bc62..b20e92d2f2a672b8c4a298e07b88f0e90392296d 100644 (file)
@@ -287,7 +287,7 @@ unsigned long probe_irq_on (void)
        }
 
        /* wait for spurious interrupts to mask themselves out again */
-       for (delay = jiffies + HZ/10; delay > jiffies; )
+       for (delay = jiffies + HZ/10; time_before(jiffies, delay); )
                /* about 100ms delay */;
 
        /* now filter out any obviously spurious interrupts */
index fdbd0c79693f816c854ff3cdef2ebb3637991b39..94901245fcfe02aa337f6a46f81c765761b7301a 100644 (file)
@@ -1692,7 +1692,7 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout)
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
-               if (timeout && ((orig_jiffies + timeout) < jiffies))
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
                bdp = info->tx_cur;
        } while (bdp->cbd_sc & BD_SC_READY);
index 1e9499a9c4c3da011ea1eabbba860741361f76a5..c9f900cfed0d7e30be7add51b4d91da02398de49 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_PMAC=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 CONFIG_MACH_SPECIFIC=y
 
 #
index dcaf4b2d54ac8498a90397ab3251e8c63da7dd1b..9141b2d908f5fbf85095d26de1aae35ef9bf8825 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_CHRP=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 CONFIG_MACH_SPECIFIC=y
 
 #
index 4a5ea33d918c24002069a364f3a60ef499cd2146..6cc14e80b76253dfd98be859c6c965b17825ce58 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_6xx=y
 CONFIG_ALL_PPC=y
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 
 #
 # General setup
index 59223a45c46298f1d11011e9924440e712418ab1..0378a8e4b97c08abfeed7ebd98c295b58f605711 100644 (file)
@@ -22,6 +22,9 @@ choice 'Machine Type' \
 if [ "$CONFIG_ALL_PPC" != "y" ];then
   define_bool CONFIG_MACH_SPECIFIC y
 fi
+
+bool 'Symmetric multi-processing support' CONFIG_SMP
+
 endmenu
 
 if [ "$CONFIG_MBX" = "y" ];then
index ae1303bb481341402a58e810ef41997c3a629da6..b0c9ad966f43a59294165cb2ef9ffb7e4b744a48 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_PMAC=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 CONFIG_MACH_SPECIFIC=y
 
 #
index 0914879f5607dd499478284bb07cefe18ddbba0c..d047c2086d63cdd81dae2596b6a34159f73eb2e1 100644 (file)
@@ -42,7 +42,7 @@ endif
 endif
 endif
 
-ifdef SMP
+ifdef CONFIG_SMP
 O_OBJS += smp.o
 endif
 
index 4cc49de17f37bab348d3b7cf87a80b6760641e69..8ca9a3cd54666da6937af628910d2a05671e08df 100644 (file)
@@ -8,7 +8,7 @@
 O_TARGET = lib.o
 O_OBJS  = checksum.o string.o strcase.o
 
-ifdef SMP
+ifdef CONFIG_SMP
 O_OBJS += locks.o
 endif
 
index 4882740c5d9856911bc22cf44c0a9ede5c6ae91e..54035b866044fb12bb299e325b674529f9d3c684 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_8xx=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 CONFIG_MBX=y
+CONFIG_SMP=n
 CONFIG_MACH_SPECIFIC=y
 CONFIG_SERIAL_CONSOLE=y
 
index ae1303bb481341402a58e810ef41997c3a629da6..b0c9ad966f43a59294165cb2ef9ffb7e4b744a48 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_PMAC=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 CONFIG_MACH_SPECIFIC=y
 
 #
index 41db35a4a4a9bf7f265a32b904115790ef69cc5e..14b4ea4a0ffc77141250974d4f638eff0d783789 100644 (file)
@@ -14,6 +14,7 @@ CONFIG_PREP=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
 # CONFIG_MBX is not set
+# CONFIG_SMP is not set
 CONFIG_MACH_SPECIFIC=y
 
 #
index abb51426e40242da218ed947d148d437a39c17f1..079c9f4c0db6b22edcd5db53b30cca70edbae755 100644 (file)
@@ -393,7 +393,7 @@ void ap_nfs_hook(unsigned long server)
     unsigned end = jiffies + 20*HZ;
     /* we are booting from another cell */
     printk("waiting for the master cell\n");
-    while (jiffies < end) ;
+    while (time_before(jiffies, end)) ;
     printk("continuing\n");
   }
 }
index a92320305539e4dec464c090960a754076fb5210..9597bd51aeb1cd0b74b2e3cfc85ea809e52bd3f1 100644 (file)
@@ -1090,7 +1090,7 @@ static void finish_fdc_done(int dummy)
        NeedSeek = 0;
 
        if ((timer_active & (1 << FLOPPY_TIMER)) &&
-           timer_table[FLOPPY_TIMER].expires < jiffies + 5)
+           time_after(jiffies + 5, timer_table[FLOPPY_TIMER].expires)) 
                /* If the check for a disk change is done too early after this
                 * last seek command, the WP bit still reads wrong :-((
                 */
@@ -1424,7 +1424,7 @@ static int fd_test_drive_present(int drive)
        FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_RESTORE | FDC1772CMDADD_H | FDC1772STEP_6);
 
        /*printk("fd_test_drive_present: Going into timeout loop\n"); */
-       for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; jiffies < timeout;) {
+       for (ok = 0, timeout = jiffies + 2 * HZ + HZ / 2; time_before(jiffies, timeout);) {
                /*  What does this piece of atariism do? - query for an interrupt? */
                /*  if (!(mfp.par_dt_reg & 0x20))
                   break; */
index f57cb7ffef6a6a6c7f234b861b5f65ddfbb95807..1d2283f3d9b1a9dc4a468c0792446b7acc4dd2f4 100644 (file)
@@ -519,7 +519,7 @@ ether1_init_for_open (struct device *dev)
        /* 586 should now unset iscp.busy */
        i = jiffies + HZ/2;
        while (ether1_inw (dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) {
-               if (jiffies > i) {
+               if (time_after(jiffies, i)) {
                        printk (KERN_WARNING "%s: can't initialise 82586: iscp is busy\n", dev->name);
                        return 1;
                }
@@ -529,7 +529,7 @@ ether1_init_for_open (struct device *dev)
        i += HZ/10;
        while (((status = ether1_inw (dev, CFG_ADDR, cfg_t, cfg_status, DISABLEIRQS))
                        & STAT_COMPLETE) == 0) {
-               if (jiffies > i)
+               if (time_after(jiffies, i))
                        break;
        }
 
@@ -546,7 +546,7 @@ ether1_init_for_open (struct device *dev)
        i += HZ/10;
        while (((status = ether1_inw (dev, SA_ADDR, sa_t, sa_status, DISABLEIRQS))
                        & STAT_COMPLETE) == 0) {
-               if (jiffies > i)
+               if (time_after(jiffies, i))
                        break;
        }
 
@@ -563,7 +563,7 @@ ether1_init_for_open (struct device *dev)
        i += HZ/10;
        while (((status = ether1_inw (dev, MC_ADDR, mc_t, mc_status, DISABLEIRQS))
                        & STAT_COMPLETE) == 0) {
-               if (jiffies > i)
+               if (time_after(jiffies, i))
                        break;
        }
 
@@ -580,7 +580,7 @@ ether1_init_for_open (struct device *dev)
        i += HZ;
        while (((status = ether1_inw (dev, TDR_ADDR, tdr_t, tdr_status, DISABLEIRQS))
                        & STAT_COMPLETE) == 0) {
-               if (jiffies > i)
+               if (time_after(jiffies, i))
                        break;
        }
 
index 56aafd46784cd15648449ecf062286677ee6421d..50ec36436b7a2785d6c66e79579a2da7d28979b0 100644 (file)
@@ -323,7 +323,7 @@ acornscsi_csdelay (unsigned int cs)
     save_flags (flags);
     sti ();
 
-    while (jiffies < target_jiffies) barrier();
+    while (time_before(jiffies, target_jiffies)) barrier();
 
     restore_flags (flags);
 }
index b6ffe08d9ea01e0d7c47e833fbaae594e85b902c..6cd638242847ae18179cdc76e8fa6a67f462f899 100644 (file)
@@ -2049,7 +2049,7 @@ int fas216_init(struct Scsi_Host *instance)
        save_flags(flags);
        sti();
 
-       while (jiffies < target_jiffies) barrier();
+       while (time_before(jiffies, target_jiffies)) barrier();
 
        restore_flags(flags);
 
index b853a3216b93727bdd1aa95a3c3ec54cf3cdf37d..d6cf122160d6b0a2c1d94876885cfc255db1bdb0 100644 (file)
@@ -92,7 +92,7 @@ int ddv_restart_cpu(void)
                return(-1);
        }
        for (timeout=jiffies + 10; 
-            (jiffies < timeout) || (OPT_IO(PBUF0) == 0);
+            time_before(jiffies, timeout) || (OPT_IO(PBUF0) == 0);
             ) /* wait */ ;
        if (OPT_IO(PBUF0) == 0) {
                printk("WARNING: option kernel didn't startup\n");
index 7fb8430ee77a15b1ffaa1131930c56ec7f946b79..6eb8cfa163351d7fb4db9cbdb006aeaf1c15d526 100644 (file)
@@ -317,11 +317,50 @@ solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
 #endif
 
 #ifdef CONFIG_BSD_DISKLABEL
+static void check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p)
+{
+       struct hd_struct *lin_p;
+               /* check relative position of partitions.  */
+       for (lin_p = hd->part + 1; lin_p - hd->part < current_minor; lin_p++) {
+                       /* no relationship -> try again */
+               if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset 
+                       || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
+                       continue;       
+                       /* equal -> no need to add */
+               if (lin_p->start_sect == bsd_p->p_offset && 
+                       lin_p->nr_sects == bsd_p->p_size) 
+                       return;
+                       /* bsd living within dos partition */
+               if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect 
+                       + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) {
+#ifdef DEBUG_BSD_DISKLABEL
+                       printk("w: %d %ld+%ld,%d+%d", 
+                               lin_p - hd->part, 
+                               lin_p->start_sect, lin_p->nr_sects, 
+                               bsd_p->p_offset, bsd_p->p_size);
+#endif
+                       break;
+               }
+        /* ouch: bsd and linux overlap. Don't even try for that partition */
+#ifdef DEBUG_BSD_DISKLABEL
+               printk("???: %d %ld+%ld,%d+%d",
+                       lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects,
+                       bsd_p->p_offset, bsd_p->p_size);
+#endif
+               printk("???");
+               return;
+       } /* if the bsd partition is not currently known to linux, we end
+          * up here 
+          */
+       add_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size);
+       current_minor++;
+}
 /* 
  * Create devices for BSD partitions listed in a disklabel, under a
  * dos-like partition. See extended_partition() for more information.
  */
-static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
+static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev, 
+   int max_partitions)
 {
        struct buffer_head *bh;
        struct bsd_disklabel *l;
@@ -337,19 +376,56 @@ static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
                return;
        }
 
-       p = &l->d_partitions[0];
-       while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
+       if (l->d_npartitions < max_partitions)
+               max_partitions = l->d_npartitions;
+       for (p = l->d_partitions; p - l->d_partitions <  max_partitions; p++) {
                if ((current_minor & mask) >= (4 + hd->max_p))
                        break;
 
-               if (p->p_fstype != BSD_FS_UNUSED) {
-                       add_partition(hd, current_minor, p->p_offset, p->p_size);
+               if (p->p_fstype != BSD_FS_UNUSED) 
+                       check_and_add_bsd_partition(hd, p);
+       }
+       brelse(bh);
+
+}
+#endif
+
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+/*
+ * Create devices for Unixware partitions listed in a disklabel, under a
+ * dos-like partition. See extended_partition() for more information.
+ */
+static void unixware_partition(struct gendisk *hd, kdev_t dev)
+{
+       struct buffer_head *bh;
+       struct unixware_disklabel *l;
+       struct unixware_slice *p;
+       int mask = (1 << hd->minor_shift) - 1;
+
+       if (!(bh = bread(dev, 14, get_ptable_blocksize(dev))))
+               return;
+       bh->b_state = 0;
+       l = (struct unixware_disklabel *) (bh->b_data+512);
+       if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
+           le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
+               brelse(bh);
+               return;
+       }
+       printk(" <unixware:");
+       p = &l->vtoc.v_slice[1];
+       /* I omit the 0th slice as it is the same as whole disk. */
+       while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
+               if ((current_minor & mask) == 0)
+                       break;
+
+               if (p->s_label != UNIXWARE_FS_UNUSED) {
+                       add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
                        current_minor++;
                }
                p++;
        }
        brelse(bh);
-
+       printk(" >");
 }
 #endif
 
@@ -360,6 +436,11 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
        struct partition *p;
        unsigned char *data;
        int mask = (1 << hd->minor_shift) - 1;
+#ifdef CONFIG_BSD_DISKLABEL
+       /* no bsd disklabel as a default */
+       kdev_t bsd_kdev = 0;
+       int bsd_maxpart;
+#endif
 #ifdef CONFIG_BLK_DEV_IDE
        int tested_for_xlate = 0;
 
@@ -476,12 +557,25 @@ check_table:
                                hd->part[minor].nr_sects = 2;
                }
 #ifdef CONFIG_BSD_DISKLABEL
+                       /* tag first disklabel for late recognition */
                if (SYS_IND(p) == BSD_PARTITION) {
-                       printk(" <");
-                       bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
-                       printk(" >");
+                       printk("!");
+                       if (!bsd_kdev) {
+                               bsd_kdev = MKDEV(hd->major, minor);
+                               bsd_maxpart = BSD_MAXPARTITIONS;
+                       }
+               } else if (SYS_IND(p) == OPENBSD_PARTITION) {
+                       printk("!");
+                       if (!bsd_kdev) {
+                               bsd_kdev = MKDEV(hd->major, minor);
+                               bsd_maxpart = OPENBSD_MAXPARTITIONS;
+                       }
                }
 #endif
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+               if (SYS_IND(p) == UNIXWARE_PARTITION)
+                       unixware_partition(hd, MKDEV(hd->major, minor));
+#endif
 #ifdef CONFIG_SOLARIS_X86_PARTITION
 
                /* james@bpgc.com: Solaris has a nasty indicator: 0x82
@@ -495,6 +589,13 @@ check_table:
                }
 #endif
        }
+#ifdef CONFIG_BSD_DISKLABEL
+       if (bsd_kdev) {
+               printk(" <");
+               bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart);
+               printk(" >");
+       }
+#endif
        /*
         *  Check for old-style Disk Manager partition table
         */
index 2231f56937b1f5ee00204b0696e2ccf209160ca1..ebd77992f025aafc6589e49c1df07ce53d9eaffe 100644 (file)
@@ -1,4 +1,3 @@
-#define VERBOSE_IDE_CD_ERRORS  1
 /*
  * linux/drivers/block/ide-cd.c
  * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
@@ -28,7 +27,6 @@
  *   This will allow us to get automagically notified when the media changes
  *   on ATAPI drives (something the stock ATAPI spec is lacking).  Looks
  *   very cool.  I discovered its existance the other day at work...
- * -Fix ide_cdrom_reset so that it works (it does nothing right now)
  * -Query the drive to find what features are available before trying to
  *   use them (like trying to close the tray in drives that can't).
  * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
@@ -36,9 +34,6 @@
  * -Handle older drives that can't report their speed. (i.e. check if they
  *   support a version of ATAPI where they can report their speed before
  *   checking their speed and believing what they return).
- * -It seems we do not always honor it when Uniform gets a request to change 
- *   the cdi->options.  We should _always_ check the options before doing stuff.
- *   This must be fixed.
  *
  *
  * ----------------------------------
  *                         Jens Axboe <axboe@image.dk>
  *                         Chris Zwilling <chris@cloudnet.com>
  *
+ * 4.51  Dec 23, 1998  -- Jens Axboe <axboe@image.dk>
+ *                      - ide_cdrom_reset enabled since the ide subsystem
+ *                         handles resets fine now. <axboe@image.dk>
+ *                      - Transfer size fix for Samsung CD-ROMs, thanks to
+ *                        "Ville Hallik" <ville.hallik@mail.ee>.
+ *                      - other minor stuff.
+ *
  *************************************************************************/
 
-#define IDECD_VERSION "4.50"
+#define IDECD_VERSION "4.51"
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -456,7 +458,7 @@ static void cdrom_queue_request_sense (ide_drive_t *drive,
        len *= 4;
 
        pc->c[0] = REQUEST_SENSE;
-       pc->c[4] = len;
+       pc->c[4] = (unsigned char) len;
        pc->buffer = (char *)reqbuf;
        pc->buflen = len;
        pc->sense_data = (struct atapi_request_sense *)failed_command;
@@ -856,7 +858,12 @@ static void cdrom_read_intr (ide_drive_t *drive)
        if ((len % SECTOR_SIZE) != 0) {
                printk ("%s: cdrom_read_intr: Bad transfer size %d\n",
                        drive->name, len);
-               printk ("  This drive is not supported by this version of the driver\n");
+               if (CDROM_CONFIG_FLAGS (drive)->limit_nframes)
+                       printk ("  This drive is not supported by this version of the driver\n");
+               else {
+                       printk ("  Trying to limit transfer sizes\n");
+                       CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
+               }
                cdrom_end_request (0, drive);
                return;
        }
@@ -992,7 +999,6 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
 {
        struct packet_command pc;
        struct request *rq = HWGROUP(drive)->rq;
-
        int nsect, sector, nframes, frame, nskip;
 
        /* Number of sectors to transfer. */
@@ -1029,8 +1035,10 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
        nframes = (nsect + SECTORS_PER_FRAME-1) / SECTORS_PER_FRAME;
        frame = sector / SECTORS_PER_FRAME;
 
-       /* Largest number of frames was can transfer at once is 64k-1. */
-       nframes = MIN (nframes, 65535);
+       /* Largest number of frames was can transfer at once is 64k-1. For
+          some drives we need to limit this even more. */
+       nframes = MIN (nframes, (CDROM_CONFIG_FLAGS (drive)->limit_nframes) ?
+               (65534 / CD_FRAMESIZE) : 65535);
 
        /* Set up the command */
        memset (&pc.c, 0, sizeof (pc.c));
@@ -1328,7 +1336,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
                        struct atapi_request_sense *reqbuf = pc->sense_data;
 
                        if (reqbuf->sense_key == UNIT_ATTENTION)
-                               ;
+                               cdrom_saw_media_change (drive);
                        else if (reqbuf->sense_key == NOT_READY &&
                                 reqbuf->asc == 4) {
                                /* The drive is in the process of loading
@@ -2477,19 +2485,12 @@ static
 int ide_cdrom_reset (struct cdrom_device_info *cdi)
 {
 
-/* This doesn't work reliably yet, and so it is currently just a stub. */
-
-#if 0 
        ide_drive_t *drive = (ide_drive_t*) cdi->handle;
        struct request req;
+
        ide_init_drive_cmd (&req);
        req.cmd = RESET_DRIVE_COMMAND;
        return ide_do_drive_cmd (drive, &req, ide_wait);
-#endif
-
-/* For now, just return 0, as if things had worked...  */
-       return 0;
-
 
 }
 
@@ -2916,10 +2917,10 @@ static void ide_cdrom_add_settings(ide_drive_t *drive)
        int major = HWIF(drive)->major;
        int minor = drive->select.b.unit << PARTN_BITS;
 
-       ide_add_setting(drive,  "breada_readahead",     SETTING_RW,                                     BLKRAGET,               BLKRASET,               TYPE_INT,       0,      255,                            1,      2,      &read_ahead[major],             NULL);
-       ide_add_setting(drive,  "file_readahead",       SETTING_RW,                                     BLKFRAGET,              BLKFRASET,              TYPE_INTA,      0,      INT_MAX,                        1,      1024,   &max_readahead[major][minor],   NULL);
-       ide_add_setting(drive,  "max_kb_per_request",   SETTING_RW,                                     BLKSECTGET,             BLKSECTSET,             TYPE_INTA,      1,      255,                            1,      2,      &max_sectors[major][minor],     NULL);
-       ide_add_setting(drive,  "dsc_overlap",          SETTING_RW,                                     -1,                     -1,                     TYPE_BYTE,      0,      1,                              1,      1,      &drive->dsc_overlap,            NULL);
+       ide_add_setting(drive,  "breada_readahead",     SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL);
+       ide_add_setting(drive,  "file_readahead",       SETTING_RW, BLKFRAGET, BLKFRASET, TYPE_INTA, 0, INT_MAX, 1, 1024, &max_readahead[major][minor], NULL);
+       ide_add_setting(drive,  "max_kb_per_request",   SETTING_RW, BLKSECTGET, BLKSECTSET, TYPE_INTA, 1, 255, 1, 2, &max_sectors[major][minor], NULL);
+       ide_add_setting(drive,  "dsc_overlap",          SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
 }
 
 static
@@ -2959,6 +2960,13 @@ int ide_cdrom_setup (ide_drive_t *drive)
        CDROM_CONFIG_FLAGS (drive)->cd_rw = 0;
        CDROM_CONFIG_FLAGS (drive)->no_eject = 1;
        CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 0;
+       
+       /* limit transfer size per interrupt. currently only one Samsung
+          drive needs this. */
+       CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
+       if (drive->id != NULL)
+               if (strcmp (drive->id->model, "SAMSUNG CD-ROM SCR-2432") == 0)
+                       CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
 
 #if ! STANDARD_ATAPI
        /* by default Sanyo 3 CD changer support is turned off and
index e72777fddd92673edfadef63b1698f8d1728695e..93d31c0432f8b4c3ff1922460063cff826400507 100644 (file)
@@ -14,7 +14,7 @@
    memory, though. */
 
 #ifndef VERBOSE_IDE_CD_ERRORS
-#define VERBOSE_IDE_CD_ERRORS 0
+#define VERBOSE_IDE_CD_ERRORS 1
 #endif
 
 
@@ -130,6 +130,9 @@ struct ide_cd_config_flags {
        __u8 cd_rw            : 1; /* Drive can write to CD-R/W media . */
        __u8 supp_disc_present: 1; /* Changer can report exact contents
                                      of slots. */
+       __u8 limit_nframes    : 1; /* Drive does not provide data in
+                                     multiples of SECTOR_SIZE when more
+                                     than one interrupt is needed. */
        __u8 seeking          : 1; /* Seeking in progress */
        __u8 reserved         : 6;
        byte max_speed;            /* Max speed of the drive */
index e5d48249d1661e27b99145014eeff4a1e78d24ee..30c862f11ed312b5ba8a7ec7ef991ae4ed3048b3 100644 (file)
@@ -633,6 +633,9 @@ static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
        }
        if (error)
                floppy->failed_pc = NULL;
+       /* Why does this happen? */
+       if (!rq)
+               return;
        if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {
                ide_end_request (uptodate, hwgroup);
                return;
index bcaa402216e55e01b816ca821838be72b2fe3930..f82f3553ab76499f6402fbd9906b6244d9b22610 100644 (file)
@@ -291,7 +291,7 @@ static int do_probe (ide_drive_t *drive, byte cmd)
                        delay_50ms();
                        OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
                        timeout = jiffies;
-                       while ((GET_STAT() & BUSY_STAT) && jiffies < timeout + WAIT_WORSTCASE)
+                       while ((GET_STAT() & BUSY_STAT) && time_before(jiffies, timeout + WAIT_WORSTCASE))
                                delay_50ms();
                        rc = try_to_identify(drive, cmd);
                }
index 3d26017566d4e30dc5fbcfdfee275ce302010c2e..3ef4f81c38f790b7351bba2d368a06fa011245f0 100644 (file)
@@ -649,86 +649,6 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
        return;
 }
 
-void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buf)
-{
-       int i, j;
-       int buffersize;
-       int max_req;
-       unsigned long rsector;
-       kdev_t rdev;
-       struct request * req[8];
-       unsigned int major = MAJOR(dev);
-       struct semaphore sem = MUTEX_LOCKED;
-
-       if (major >= MAX_BLKDEV || !(blk_dev[major].request_fn)) {
-               printk(KERN_NOTICE "ll_rw_swap_file: trying to swap to"
-                                   " nonexistent block-device\n");
-               return;
-       }
-       max_req = NR_REQUEST;
-       switch (rw) {
-               case READ:
-                       break;
-               case WRITE:
-                       max_req = (NR_REQUEST * 2) / 3;
-                       if (is_read_only(dev)) {
-                               printk(KERN_NOTICE
-                                       "Can't swap to read-only device %s\n",
-                                       kdevname(dev));
-                               return;
-                       }
-                       break;
-               default:
-                       panic("ll_rw_swap: bad block dev cmd, must be R/W");
-       }
-       buffersize = PAGE_SIZE / nb;
-
-       if ((major == LOOP_MAJOR) || (major == NBD_MAJOR))
-            max_req >>= 1;
-       for (j=0, i=0; i<nb;)
-       {
-               for (; j < 8 && i < nb; j++, i++, buf += buffersize)
-               {
-                       rdev = dev;
-                       rsector = b[i] * (buffersize >> 9);
-#ifdef CONFIG_BLK_DEV_MD
-                       if (major==MD_MAJOR &&
-                           md_map (MINOR(dev), &rdev,
-                                   &rsector, buffersize >> 9)) {
-                               printk (KERN_ERR
-                                        "Bad md_map in ll_rw_swap_file\n");
-                               return;
-                       }
-#endif
-                       
-                       if (j == 0) {
-                               req[j] = get_request_wait(max_req, rdev);
-                       } else {
-                               unsigned long flags;
-                               spin_lock_irqsave(&io_request_lock,flags);
-                               req[j] = get_request(max_req, rdev);
-                               spin_unlock_irqrestore(&io_request_lock,flags);
-                               if (req[j] == NULL)
-                                       break;
-                       }
-                       req[j]->cmd = rw;
-                       req[j]->errors = 0;
-                       req[j]->sector = rsector;
-                       req[j]->nr_sectors = buffersize >> 9;
-                       req[j]->current_nr_sectors = buffersize >> 9;
-                       req[j]->buffer = buf;
-                       req[j]->sem = &sem;
-                       req[j]->bh = NULL;
-                       req[j]->next = NULL;
-                       add_request(MAJOR(rdev)+blk_dev,req[j]);
-               }
-               run_task_queue(&tq_disk);
-               while (j > 0) {
-                       j--;
-                       down(&sem);
-               }
-       }
-}
 #ifdef CONFIG_STRAM_SWAP
 extern int stram_device_init( void );
 #endif
index 1563a2afc1855b71f2d3784f9f7c094c66bf413d..89c83db655cfc67408f941c151da2f9607d6cc37 100644 (file)
@@ -367,21 +367,21 @@ static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
        PG.status = 0;
 
        j = 0;
-       while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
+       while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(time_before(jiffies,tmo))) {
                if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
                else pg_sleep(1);
        }
 
-       if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
+       if ((r&(STAT_ERR&stop))||time_after_eq(jiffies, tmo)) {
           s = RR(0,7);
           e = RR(0,1);
           p = RR(0,2);
           if (verbose > 1)
             printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
-                  PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
+                  PG.name,msg,s,e,p,time_after_eq(jiffies, tmo)?" timeout":"");
 
 
-          if (jiffies>=tmo) e |= 0x100;
+          if (time_after_eq(jiffies, tmo)) e |= 0x100;
           PG.status = (e >> 4) & 0xff;
           return -1;
        }
index 13924396cf926f501addb6777a880ebf76588bcb..3992f3c3018b13c428be610d9e416d41c02e662f 100644 (file)
@@ -47,7 +47,7 @@ static int ps_timer_active = 0;
 static int ps_tq_active = 0;
 static int ps_nice = 0;
 
-static spinlock_t ps_spinlock = SPIN_LOCK_UNLOCKED;
+static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;
 
 static struct timer_list ps_timer = {0,0,0,0,ps_timer_int};
 static struct tq_struct ps_tq = {0,0,ps_tq_int,NULL};
index 85ed482b87e9c390965a020645a8b3d4229506dc..7d063f0641615089d3a7f67969dbac16b758c031 100644 (file)
   Thanks to Grant R. Guenther <grant@torque.net> for spotting this bug.
   -- Made a few things more pedanticly correct.
 
- 2.50  Oct 19, 1998 - Jens Axboe <axboe@image.dk>
+2.50 Oct 19, 1998 - Jens Axboe <axboe@image.dk>
   -- New maintainers! Erik was too busy to continue the work on the driver,
   so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
   will do their best to follow in his footsteps
+  
+  2.51 Dec 20, 1998 - Jens Axboe <axboe@image.dk>
+  -- Check if drive is capable of doing what we ask before blindly changing
+  cdi->options in various ioctl.
+  -- Added version to proc entry.
 
 -------------------------------------------------------------------------*/
 
-#define REVISION "Revision: 2.50"
-#define VERSION "Id: cdrom.c 2.50 1998/10/19"
+#define REVISION "Revision: 2.51"
+#define VERSION "Id: cdrom.c 2.51 1998/12/20"
 
 /* I use an error-log mask to give fine grain control over the type of
    messages dumped to the system logs.  The available masks include: */
@@ -211,6 +216,8 @@ int register_cdrom(struct cdrom_device_info *cdi)
         struct cdrom_device_ops *cdo = cdi->ops;
         int *change_capability = (int *)&cdo->capability; /* hack */
 
+       cdinfo(CD_OPEN, "entering register_cdrom\n"); 
+
        if (major < 0 || major >= MAX_BLKDEV)
                return -1;
        if (cdo->open == NULL || cdo->release == NULL)
@@ -236,9 +243,10 @@ int register_cdrom(struct cdrom_device_info *cdi)
        cdi->mc_flags = 0;
        cdo->n_minors = 0;
         cdi->options = CDO_USE_FFLAGS;
-       if (autoclose==1)
+       
+       if (autoclose==1 && cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)
                cdi->options |= (int) CDO_AUTO_CLOSE;
-       if (autoeject==1)
+       if (autoeject==1 && cdo->capability & ~cdi->mask & CDC_OPEN_TRAY)
                cdi->options |= (int) CDO_AUTO_EJECT;
        if (lockdoor==1)
                cdi->options |= (int) CDO_LOCK;
@@ -257,6 +265,8 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
        struct cdrom_device_info *cdi, *prev;
        int major = MAJOR (unreg->dev);
 
+       cdinfo(CD_OPEN, "entering unregister_cdrom\n"); 
+
        if (major < 0 || major >= MAX_BLKDEV)
                return -1;
 
@@ -713,6 +723,8 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
        case CDROMEJECT_SW:
                cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); 
+               if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
+                       return -ENOSYS;
                cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
                if (arg)
                        cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
@@ -733,6 +745,8 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
 
        case CDROM_SET_OPTIONS:
                cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); 
+               if (cdo->capability & arg & ~cdi->mask)
+                       return -ENOSYS;
                cdi->options |= (int) arg;
                return cdi->options;
 
@@ -984,7 +998,7 @@ int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp,
         int retv,pos;
        struct cdrom_device_info *cdi;
 
-        pos = sprintf(cdrom_drive_info, "CD-ROM information\n");
+       pos = sprintf(cdrom_drive_info, "CD-ROM information, " VERSION "\n");
        
        pos += sprintf(cdrom_drive_info+pos, "\ndrive name:\t");
        for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next)
index 6fb352f15564f1fa3af589cfd02e99ad9c21a09e..d3933e72d39e9b8138d5902022e30a3871aa110d 100644 (file)
@@ -56,12 +56,15 @@ fi
 
 bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
 if [ "$CONFIG_MOUSE" = "y" ]; then
+       mainmenu_option next_comment
+       comment 'Mice'
        tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
        tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
        tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
        bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
        tristate 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
        tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD
+       endmenu
 fi
 
 tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE
@@ -72,12 +75,14 @@ if [ "$CONFIG_QIC02_TAPE" != "n" ]; then
   else
     comment '   Setting runtime QIC-02 configuration is done with qic02conf'
     comment '   from the tpqic02-support package.  It is available at'
-    comment '   sunsite.unc.edu or ftp://titus.cfw.com/pub/Linux/util/'
+    comment '   metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/'
   fi
 fi
 
 bool 'Watchdog Timer Support'  CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
+  mainmenu_option next_comment
+  comment 'Watchdog Cards'
   bool '   Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
   tristate '   WDT Watchdog timer' CONFIG_WDT
   if [ "$CONFIG_WDT" != "n" ]; then
@@ -89,12 +94,19 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
   tristate '   Software Watchdog' CONFIG_SOFT_WATCHDOG
   tristate '   Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
   tristate '   Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
+  endmenu
 fi
+
+
+tristate '/dev/nvram support' CONFIG_NVRAM
 bool 'Enhanced Real Time Clock Support' CONFIG_RTC
 if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then
   bool 'Tadpole ANA H8 Support'  CONFIG_H8
 fi
 
+mainmenu_option next_comment
+comment 'Video For Linux'
+
 tristate 'Video For Linux' CONFIG_VIDEO_DEV
 if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
   dep_tristate 'AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
@@ -110,6 +122,10 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
     hex '  Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
   fi
   dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
+  dep_tristate 'GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
+  if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
+    hex '  GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
+  fi
   if [ "$CONFIG_PCI" != "n" ]; then
     dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
   fi
@@ -128,11 +144,18 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
     hex '  ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
   fi
 fi
-tristate '/dev/nvram support' CONFIG_NVRAM
+
+endmenu
+
+mainmenu_option next_comment
+comment 'Joystick support'
+
 tristate 'Joystick support' CONFIG_JOYSTICK
 if [ "$CONFIG_JOYSTICK" != "n" ]; then
   source drivers/char/joystick/Config.in
 fi
+endmenu
+
 mainmenu_option next_comment
 comment 'Ftape, the floppy tape device driver'
 tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE
index ad7e1f9986e8f6868f45d6678f7893618b7607df..b38c4e5f14baddcc2da20abd02c9a2a7f978426c 100644 (file)
@@ -380,6 +380,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_RADIO_GEMTEK),y)
+L_OBJS += radio-gemtek.o
+else
+  ifeq ($(CONFIG_RADIO_GEMTEK),m)
+  M_OBJS += radio-gemtek.o
+  endif
+endif                                             
+
 ifeq ($(CONFIG_QIC02_TAPE),y)
 L_OBJS += tpqic02.o
 else
index 1ccf11bc5bbe6e7283502975e24fabf5ca269a32..58ce881b30e56e824220edf4e3d0a94552fd7744 100644 (file)
@@ -152,12 +152,12 @@ static int ISILoad_ioctl(struct inode *inode, struct file *filp,
                                                                
                        inw(base+0x8);
                        
-                       for(i=jiffies+HZ/100;i>jiffies;);
+                       for(i=jiffies+HZ/100;time_before(jiffies, i););
                                
                        outw(0,base+0x8); /* Reset */
                        
                        for(j=1;j<=3;j++) {
-                               for(i=jiffies+HZ;i>jiffies;);
+                               for(i=jiffies+HZ;time_before(jiffies, i););
                                printk(".");
                        }       
                        signature=(inw(base+0x4)) & 0xff;       
diff --git a/drivers/char/radio-gemtek.c b/drivers/char/radio-gemtek.c
new file mode 100644 (file)
index 0000000..1bfe30e
--- /dev/null
@@ -0,0 +1,310 @@
+/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi>
+ *
+ * GemTek hasn't released any specs on the card, so the protocol had to
+ * be reverse engineered with dosemu.
+ *
+ * Besides the protocol changes, this is mostly a copy of:
+ *
+ *    RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
+ * 
+ *    Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
+ *    Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ *    Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
+ *
+ * TODO: Allow for more than one of these foolish entities :-)
+ *
+ */
+
+#include <linux/module.h>      /* Modules                      */
+#include <linux/init.h>                /* Initdata                     */
+#include <linux/ioport.h>      /* check_region, request_region */
+#include <linux/delay.h>       /* udelay                       */
+#include <asm/io.h>            /* outb, outb_p                 */
+#include <asm/uaccess.h>       /* copy to/from user            */
+#include <linux/videodev.h>    /* kernel radio structs         */
+#include <linux/config.h>      /* CONFIG_RADIO_GEMTEK_PORT     */
+
+#ifndef CONFIG_RADIO_GEMTEK_PORT
+#define CONFIG_RADIO_GEMTEK_PORT -1
+#endif
+
+static int io = CONFIG_RADIO_GEMTEK_PORT; 
+static int users = 0;
+
+struct gemtek_device
+{
+       int port;
+       unsigned long curfreq;
+       int muted;
+};
+
+
+/* local things */
+
+/* the correct way to mute the gemtek may be to write the last written
+ * frequency || 0x10, but just writing 0x10 once seems to do it as well
+ */
+static void gemtek_mute(struct gemtek_device *dev)
+{
+        if(dev->muted)
+               return;
+       outb(0x10, io);
+       dev->muted = 1;
+}
+
+static void gemtek_unmute(struct gemtek_device *dev)
+{
+       if(dev->muted == 0)
+               return;
+       outb(0x20, io);
+       dev->muted = 0;
+}
+
+static void zero(void)
+{
+       outb_p(0x04, io);
+       udelay(5);
+       outb_p(0x05, io);
+       udelay(5);
+}
+
+static void one(void)
+{
+       outb_p(0x06, io);
+       udelay(5);
+       outb_p(0x07, io);
+       udelay(5);
+}
+
+static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+{
+       int i;
+
+/*        freq = 78.25*((float)freq/16000.0 + 10.52); */
+
+       freq /= 16;
+       freq += 10520;
+       freq *= 7825;
+       freq /= 100000;
+
+       /* 2 start bits */
+       outb_p(0x03, io);
+       udelay(5);
+       outb_p(0x07, io);
+       udelay(5);
+
+        /* 28 frequency bits (lsb first) */
+       for (i = 0; i < 14; i++)
+               if (freq & (1 << i))
+                       one();
+               else
+                       zero();
+        /* 36 unknown bits */
+       for (i = 0; i < 11; i++)
+               zero();
+       one();
+       for (i = 0; i < 4; i++)
+               zero();
+       one();
+       zero();
+
+       /* 2 end bits */
+       outb_p(0x03, io);
+       udelay(5);
+       outb_p(0x07, io);
+       udelay(5);
+
+       return 0;
+}
+
+int gemtek_getsigstr(struct gemtek_device *dev)
+{
+       inb(io);
+       udelay(5);
+       if (inb(io) & 8)                /* bit set = no signal present */
+               return 0;
+       return 1;               /* signal present */
+}
+
+static int gemtek_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       struct gemtek_device *rt=dev->priv;
+
+       switch(cmd)
+       {
+               case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type=VID_TYPE_TUNER;
+                       v.channels=1;
+                       v.audios=1;
+                       /* No we don't do pictures */
+                       v.maxwidth=0;
+                       v.maxheight=0;
+                       v.minwidth=0;
+                       v.minheight=0;
+                       strcpy(v.name, "GemTek");
+                       if(copy_to_user(arg,&v,sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg,sizeof(v))!=0) 
+                               return -EFAULT;
+                       if(v.tuner)     /* Only 1 tuner */ 
+                               return -EINVAL;
+                       v.rangelow=87*16000;
+                       v.rangehigh=108*16000;
+                       v.flags=VIDEO_TUNER_LOW;
+                       v.mode=VIDEO_MODE_AUTO;
+                       v.signal=0xFFFF*gemtek_getsigstr(rt);
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if(v.tuner!=0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+               case VIDIOCGFREQ:
+                       if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
+                               return -EFAULT;
+                       return 0;
+               case VIDIOCSFREQ:
+                       if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
+                               return -EFAULT;
+               /* needs to be called twice in order for getsigstr to work */
+                       gemtek_setfreq(rt, rt->curfreq);
+                       gemtek_setfreq(rt, rt->curfreq);
+                       return 0;
+               case VIDIOCGAUDIO:
+               {       
+                       struct video_audio v;
+                       memset(&v,0, sizeof(v));
+                       v.flags|=VIDEO_AUDIO_MUTABLE;
+                       v.volume=1;
+                       v.step=65535;
+                       strcpy(v.name, "Radio");
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
+               case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if(copy_from_user(&v, arg, sizeof(v))) 
+                               return -EFAULT; 
+                       if(v.audio) 
+                               return -EINVAL;
+
+                       if(v.flags&VIDEO_AUDIO_MUTE) 
+                               gemtek_mute(rt);
+                       else
+                               gemtek_unmute(rt);
+
+                       return 0;
+               }
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+static int gemtek_open(struct video_device *dev, int flags)
+{
+       if(users)
+               return -EBUSY;
+       users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void gemtek_close(struct video_device *dev)
+{
+       users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct gemtek_device gemtek_unit;
+
+static struct video_device gemtek_radio=
+{
+       "GemTek radio",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_GEMTEK,
+       gemtek_open,
+       gemtek_close,
+       NULL,   /* Can't read  (no capture ability) */
+       NULL,   /* Can't write */
+       NULL,   /* Can't poll */
+       gemtek_ioctl,
+       NULL,
+       NULL
+};
+
+__initfunc(int gemtek_init(struct video_init *v))
+{
+       if (check_region(io, 4)) 
+       {
+               printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
+               return -EBUSY;
+       }
+
+       gemtek_radio.priv=&gemtek_unit;
+       
+       if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO)==-1)
+               return -EINVAL;
+               
+       request_region(io, 4, "gemtek");
+       printk(KERN_INFO "GemTek Radio Card driver.\n");
+
+       /* mute card - prevents noisy bootups */
+       outb(0x10, io);
+       udelay(5);
+       gemtek_unit.muted = 1;
+
+       /* this is _maybe_ unnecessary */
+       outb(0x01, io);
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Jonas Munsin");
+MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c)");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+       if(io==-1)
+       {
+               printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c\n");
+               return -EINVAL;
+       }
+       return gemtek_init(NULL);
+}
+
+void cleanup_module(void)
+{
+       video_unregister_device(&gemtek_radio);
+       release_region(io,4);
+}
+
+#endif
+
+/*
+  Local variables:
+  compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
+  End:
+*/
index f4101d133d71057a033a90e82369f261d326bafd..af9d7848d251c2a0c62adc9659871d00e1bacfaf 100644 (file)
@@ -2369,7 +2369,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
-               if (timeout && ((orig_jiffies + timeout) < jiffies))
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
        }
        current->state = TASK_RUNNING;
index 4878d877efc7d5dd7bbe2db23b57a3395ea2504e..30e0260b783be239631e9f7f7c158233f46bbb3a 100644 (file)
@@ -571,7 +571,7 @@ static int wait_for_ready(time_t timeout)
        timeout -= spin_t;
        spin_t += jiffies;
 
-       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (jiffies<spin_t))
+       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t))
                schedule();             /* don't waste all the CPU time */
        if ((stat & QIC02_STAT_READY) == 0)
                return TE_OK;
@@ -586,7 +586,7 @@ static int wait_for_ready(time_t timeout)
        TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
 
                /* not ready and no exception && timeout not expired yet */
-       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (jiffies<spin_t)) {
+       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t)) {
                /* be `nice` to other processes on long operations... */
                current->state = TASK_INTERRUPTIBLE;
                /* nap 0.30 sec between checks, */
index def6e70391f13b77438028c5f7019344248b9210..36f9b3855e5d80472f5b7d1ebe6d92f2bf7245c9 100644 (file)
@@ -68,6 +68,9 @@ extern int fmi_init(struct video_init *);
 #ifdef CONFIG_RADIO_MIROPCM20
 extern int pcm20_init(struct video_init *);
 #endif
+#ifdef CONFIG_RADIO_GEMTEK
+extern int gemtek_init(struct video_init *);
+#endif
 #ifdef CONFIG_VIDEO_PMS
 extern int init_pms_cards(struct video_init *);
 #endif
@@ -103,6 +106,9 @@ static struct video_init video_init_list[]={
 #endif
 #ifdef CONFIG_RADIO_MIROPCM20
        {"PCM20", pcm20_init}, 
+#endif 
+#ifdef CONFIG_RADIO_GEMTEK
+       {"GemTek", gemtek_init}, 
 #endif 
        {"end", NULL}
 };
index 1c4c0b80671ed3f2c372a250b7fecd698834aea8..db6fe1453fe8d3165b53df28d7cd91d344ef1342 100644 (file)
@@ -173,7 +173,7 @@ static inline int B1_rx_full(unsigned short base)
 static inline unsigned char B1_get_byte(unsigned short base)
 {
        unsigned long i = jiffies + 5 * HZ;     /* maximum wait time 5 sec */
-       while (!B1_rx_full(base) && i > jiffies);
+       while (!B1_rx_full(base) && time_before(jiffies, i));
        if (B1_rx_full(base))
                return inb(base + B1_READ);
        printk(KERN_CRIT "b1lli: rx not full after 5 second\n");
@@ -477,7 +477,7 @@ int B1_loaded(unsigned short base)
 
        if (loaddebug)
                printk(KERN_DEBUG "b1capi: loaded: wait 1 ..\n");
-       for (i = jiffies + 10 * HZ; i > jiffies;) {
+       for (i = jiffies + 10 * HZ; time_before(jiffies, i);) {
                if (B1_tx_empty(base))
                        break;
        }
@@ -487,7 +487,7 @@ int B1_loaded(unsigned short base)
        }
        B1_put_byte(base, SEND_POLL);
        printk(KERN_DEBUG "b1capi: loaded: wait 2 ..\n");
-       for (i = jiffies + 10 * HZ; i > jiffies;) {
+       for (i = jiffies + 10 * HZ; time_before(jiffies, i);) {
                if (B1_rx_full(base)) {
                        if ((ans = B1_get_byte(base)) == RECEIVE_POLL) {
                                if (loaddebug)
index 6924e3f9e5475d7132d6c615d7f27dfb5c7dbe4a..bcd305058ca99521a5902da9098b72c85f7dbab5 100644 (file)
@@ -62,7 +62,7 @@
 #include "hisax.h"
 
 #ifdef MODULE
-#define MOD_USE_COUNT ((&__this_module)->usecount)
+#define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif                         /* MODULE */
 
 const char *lli_revision = "$Revision: 2.13 $";
@@ -2055,7 +2055,7 @@ HiSax_command(isdn_ctrl * ic)
                        if (csta->channel[0].debug & 0x400) {
                                jiftime(tmp, jiffies);
                                i = strlen(tmp);
-                               sprintf(tmp + i, "   LOCK modcnt %lx\n", MOD_USE_COUNT);
+                               sprintf(tmp + i, "   LOCK modcnt %d\n", MOD_USE_COUNT);
                                HiSax_putstatus(csta, tmp);
                        }
 #endif                         /* MODULE */
@@ -2066,7 +2066,7 @@ HiSax_command(isdn_ctrl * ic)
                        if (csta->channel[0].debug & 0x400) {
                                jiftime(tmp, jiffies);
                                i = strlen(tmp);
-                               sprintf(tmp + i, " UNLOCK modcnt %lx\n", MOD_USE_COUNT);
+                               sprintf(tmp + i, " UNLOCK modcnt %d\n", MOD_USE_COUNT);
                                HiSax_putstatus(csta, tmp);
                        }
 #endif                         /* MODULE */
@@ -2128,7 +2128,8 @@ HiSax_command(isdn_ctrl * ic)
                                        break;
 #ifdef MODULE
                                case (55):
-                                       MOD_USE_COUNT = 0;
+                                       while ( MOD_USE_COUNT > 0)
+                                           MOD_DEC_USE_COUNT;
                                        HiSax_mod_inc_use_count();
                                        break;
 #endif                         /* MODULE */
index 5af8ad871d455c27833457653321bdffdc730036..84f88cd75aea8e46c39cc0e5409c97ad335897e3 100644 (file)
@@ -1328,7 +1328,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
-               if (timeout && ((orig_jiffies + timeout) < jiffies))
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
        }
        current->state = TASK_RUNNING;
index b1bb32a28df05e0ab3c788b6688ad8c0f8de241e..3b027da3f903edb871952c4baf6a8439ab91eddc 100644 (file)
@@ -894,7 +894,7 @@ int powerbook_sleep(void)
                pmu_enable_backlight(0);
 
        /* Give the disks a little time to actually finish writing */
-       for (wait = jiffies + (HZ/4); jiffies < wait; )
+       for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
                mb();
 
        /* Disable all interrupts except pmu */
index 13bf1028a5a2d67b18d6fa02b915ff5660c1175d..37843e6df594f00d8506a43d9083bf092e6e07d1 100644 (file)
@@ -539,7 +539,7 @@ __initfunc(int elmc_probe(struct device *dev))
        }
        dev->mem_end = dev->mem_start + size;   /* set mem_end showed by 'ifconfig' */
 
-       ((struct priv *) (dev->priv))->base = phys_to_virt(dev->mem_start + size - 0x01000000);
+       ((struct priv *) (dev->priv))->base = (unsigned long)phys_to_virt(dev->mem_start + size - 0x01000000);
        alloc586(dev);
 
        elmc_id_reset586();     /* make sure it doesn't generate spurious ints */
index 4f865b68c15b3726adce59a3e00934ad51abc972..aaec2728eef2c61582a1f0e5059f333f5bb44e34 100644 (file)
@@ -224,6 +224,10 @@ fi
 #
 dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m
 #
+# The COSA/SRP driver has not been tested as non-modular yet.
+#
+dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m
+#
 if [ "$CONFIG_WAN_ROUTER" != "n" ]; then
   bool 'WAN drivers' CONFIG_WAN_DRIVERS
   if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then
index b52fea887a774fea0573f6e84a62ab855a35888a..2ecc6c85b70816cc5a8cef33ba2324f0f23c8e7c 100644 (file)
@@ -886,7 +886,7 @@ static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
                if (len + 40 > size) {
                        return -1;
                }
-               len += sprintf(buf + len, "IRQ %x.  ", dev->irq);
+               len += sprintf(buf + len, "IRQ %d.  ", dev->irq);
        }
 
        if (dev->master) {
index f445a14b2efc8e0037989ac63c2e921adb07ff0a..0121a03e7f40fa890cf26ecb5b2a9bf23c4d9389 100644 (file)
@@ -337,8 +337,8 @@ static int wait_for(unsigned short set, unsigned short clr,
        * responds real good. The first while loop guesses an expire
        * time accounting for possible wraparound of jiffies.
        */
-      while (extime <= jiffies) extime = jiffies + 1;
-      while ( (jiffies < extime)
+      while (time_after_eq(jiffies, extime) extime = jiffies + 1;
+      while ( (time_before(jiffies, extime))
               && (((pins & set) != set) || ((pins & clr) != 0)) ) {
             pins = get_pins(minor);
       }
index 3f0924525477365750da043a290f49ec4c8820dd..1ea3177264028947f2ba35cdb2eb17551af640e8 100644 (file)
@@ -1676,7 +1676,7 @@ static void sab82532_wait_until_sent(struct tty_struct *tty, int timeout)
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
-               if (timeout && (orig_jiffies + timeout) < jiffies)
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
        }
        current->state = TASK_RUNNING;
index b05acc3143e7099b19cb1dcb69cbb24da673267d..b4ab6693f0dc7f7bb8f7bc2af0e05601c6c174d4 100644 (file)
@@ -1818,7 +1818,7 @@ su_wait_until_sent(struct tty_struct *tty, int timeout)
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
-               if (timeout && ((orig_jiffies + timeout) < jiffies))
+               if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
        }
        current->state = TASK_RUNNING;
index b11cd4df2e2fc84fa629f02b1f0b6f4690375caa..99ae1e5a71fff62c30345b3c271d0b20cfbef5f3 100644 (file)
@@ -17,6 +17,7 @@ The tmscsim driver supports PCI SCSI Host Adapters based on the AM53C974
 chip. AM53C974 based SCSI adapters include: 
  Tekram DC390, DC390T
  Dawicontrol 2974
+ QLogic Fast! PCI Basic
  some on-board adapters
 (This is most probably not a complete list)
 
@@ -44,7 +45,8 @@ The numbering scheme isn't consistent. The first versions went from 1.00 to
 1.12, then 1.20a to 1.20t. Finally I decided to use the ncr53c8xx scheme. So
 the next revisions will be 2.0a to 2.0X (stable), 2.1a to 2.1X (experimental),
 2.2a to 2.2X (stable, again) etc. (X = anything between a and z.) If I send
-fixes to people for testing, those will have a digit appended, e.g. 2.0a1.
+fixes to people for testing, I create intermediate versions with a digit 
+appended, e.g. 2.0c3.
 
 
 2. Installation
@@ -55,32 +57,36 @@ driver. Of course you have to choose to compile SCSI support and DC390(T)
 support into your kernel or as module when configuring your kernel for
 compiling.
 
-If you got an older kernel with an old version of this driver included, you
-should copy the files (dc390.h, tmscsim.h, tmscsim.c, scsiiom.c and
-README.tmscsim) from this directory to linux/drivers/scsi. You have to
-recompile your kernel/module of course.
+ If you got an old kernel (pre 2.1.127, pre 2.0.37p1) with an old version of
+ this driver: Get dc390-21125-20b.diff.gz or dc390-2036p21-20b1.diff.gz from
+ my website and apply the patch. 
 
-You should apply the three patches included in dc390-20-kernel.diff
-(Applying them: cd /usr/src; patch -p0 <~/dc390-20-kernel.diff)
-The patches are against 2.1.103, so you might have to manually resolve
-rejections when applying to another kernel version.
+ If you want to do it manually, you should copy the files (dc390.h,
+ tmscsim.h, tmscsim.c, scsiiom.c and README.tmscsim) from this directory to
+ linux/drivers/scsi. You have to recompile your kernel/module of course.
 
-The patches will update the kernel startup code to allow boot parameters to
-be passed to the driver, update the Documentation and finally offer you the
-possibility to omit the non-DC390 parts of the driver.
-(By selecting "Omit support for non DC390" you basically disable the
-emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes
-of memory.)
+ You should apply the three patches included in dc390-120-kernel.diff
+ (Applying them: cd /usr/src; patch -p0 <~/dc390-120-kernel.diff)
+ The patches are against 2.1.125, so you might have to manually resolve
+ rejections when applying to another kernel version.
+
+ The patches will update the kernel startup code to allow boot parameters to
+ be passed to the driver, update the Documentation and finally offer you the
+ possibility to omit the non-DC390 parts of the driver.
+ (By selecting "Omit support for non DC390" you basically disable the
+ emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes
+ of memory.)
 
 If you got a very old kernel without the tmscsim driver (pre 2.0.31)
 I recommend upgrading your kernel. However, if you don't want to, please
 contact me to get the appropriate patches.
 
-Testing a SCSI driver is always a delicate thing to do. The 2.0 driver has
+
+Upgrading a SCSI driver is always a delicate thing to do. The 2.0 driver has
 proven stable on many systems, but it's still a good idea to take some
 precautions. In an ideal world you would have a full backup of your disks.
 The world isn't ideal and most people don't have full backups (me neither).
-So take at least the following two measures:
+So take at least the following measures:
 * make your kernel remount the FS read-only on detecting an error:
   tune2fs -e remount-ro /dev/sd??
 * have copies of your SCSI disk's partition tables on some safe location:
@@ -103,18 +109,19 @@ SA_SHIRQ | SA_INTERRUPT.
 3.Features
 ----------
 - SCSI
- * Tagged queueing
+ * Tagged command queueing
  * Sync speed up to 10 MHz
  * Disconnection
  * Multiple LUNs
 
 - General / Linux interface
- * Support for up to 4 adapters.
+ * Support for up to 4 AM53C974 adapters.
  * DC390 EEPROM usage or boot/module params
  * Information via cat /proc/scsi/tmscsim/?
  * Dynamically configurable by writing to /proc/scsi/tmscsim/?
  * Dynamic allocation of resources
- * SMP support: Adapter specific locks (Linux 2.1.x)
+ * SMP support: Locking on io_request lock (Linux 2.1/2.2) or adapter 
+    specific locks (Linux 2.3)
  * Uniform source code for Linux-2.x.y
  * Support for dyn. addition/removal of devices via add/remove-single-device
    (Try: echo "scsi add-single-device H C I L" >/proc/scsi/scsi 
@@ -336,9 +343,7 @@ to further improve its usability:
 
 Further investigation on these problems:
 
-* TagQ and Disconnection (Resel: SRB Tag Seleection)
-* Problems with IRQ sharing (IO-APIC on SMP Systems) (??)
-* Driver crashes with readcdda (xcdroast)
+* Driver hangs with sync readcdda (xcdroast) (most probably VIA PCI error)
 
 Known problems:
 
@@ -362,12 +367,9 @@ Known problems:
   Richard Waltham <dormouse@farsrobt.demon.co.uk> or Doug Ledford
   <dledford@dialnet.net>, if you want to help further debugging it.
 * 2.0.35: CD changers (e.g. NAKAMICHI MBR-7.{0,2}) have problems because
-  the mid-level code doesn't handle BLIST_SINGLELUN correctly. Apply
-  the patch 2035-scsi-singlelun.diff. Thanks to Chiaki Ishikawa.
-  I was told that this fix will be in 2.0.36, so you don't need it for
-  2.0.36. 
-[The patch file is contained in the dc390-XXX.tar.gz files which can be found
-on the ftp server. See below.]
+  the mid-level code doesn't handle BLIST_SINGLELUN correctly. There used
+  to be a patch included here to fix this, but I was told that it is fixed
+  in 2.0.36.
 
 
 7. Bug reports, debugging and updates
@@ -379,7 +381,7 @@ If you find something, which you believe to be a bug, please report it to me.
 Please append the output of /proc/scsi/scsi, /proc/scsi/tmscsim/? and
 maybe the DC390 log messages to the report. 
 
-Bug reports should be send to me (Kurt Garloff <K.Garloff@ping.de>) as well
+Bug reports should be send to me (Kurt Garloff <dc390@garloff.de>) as well
 as to the linux-scsi list (<linux-scsi@vger.rutgers.edu>), as sometimes bugs
 are caused by the SCSI mid-level code.
 
@@ -391,7 +393,10 @@ AM53C974, the logging might produce log output again, and you might end
 having your box spending most of its time doing the logging.
 
 The latest version of the driver can be found at:
-ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/
+ http://www.garloff.de/kurt/linux/dc390/
+and
+ ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/
+(The latter might shut down some day.)
 
 
 8. Acknowledgements
@@ -408,6 +413,6 @@ doing this during early revisions).
 
 
 -------------------------------------------------------------------------
-Written by Kurt Garloff <K.Garloff@ping.de> 1998/06/11
-Last updated 1998/10/15, driver revision 2.0b
-$Id: README.tmscsim,v 2.4 1998/10/24 08:45:02 garloff Exp $
+Written by Kurt Garloff <kurt@garloff.de> 1998/06/11
+Last updated 1998/12/25, driver revision 2.0d
+$Id: README.tmscsim,v 2.9 1998/12/25 18:04:20 garloff Exp $
index 10fae9bbd77b09610a42c2914a9c65e003e9ac72..c5c7337390155ec9a3497ca1a3179f03ab49b157 100644 (file)
@@ -5785,8 +5785,8 @@ advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
         }
         scp->result = HOST_BYTE(DID_ERROR);
         ret = SCSI_RESET_ERROR;
-    } else if (jiffies >= boardp->last_reset &&
-               jiffies < (boardp->last_reset + (10 * HZ))) {
+    } else if (time_after_eq(jiffies, boardp->last_reset) &&
+               time_before(jiffies, boardp->last_reset + (10 * HZ))) {
         /*
          * Don't allow a reset to be attempted within 10 seconds
          * of the last reset.
index b3a30ebe072403eb4393a2def713c9f25fadf98b..719df770a06036c69a852cb43faa4ae6ea6f443c 100644 (file)
@@ -4,7 +4,7 @@
  *     Description: Device Driver for Tekram DC-390(T) PCI SCSI       *
  *                  Bus Master Host Adapter                           *
  ***********************************************************************/
-/* $Id: dc390.h,v 2.3 1998/10/24 08:45:02 garloff Exp $ */
+/* $Id: dc390.h,v 2.12 1998/12/25 17:33:27 garloff Exp $ */
 
 #include <linux/version.h>
 
@@ -16,7 +16,7 @@
 #define DC390_H
 
 #define DC390_BANNER "Tekram DC390/AM53C974"
-#define DC390_VERSION "2.0b 1998/10/24"
+#define DC390_VERSION "2.0d 1998/12/25"
 
 #if defined(HOSTS_C) || defined(MODULE)
 
index d8c0c9e0d1cbd8b1e0f5e35325f0b1f2b6be4088..ec1f6edc8569eed2e41713cbbdca9815e175fd6e 100644 (file)
@@ -495,7 +495,7 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
 #else
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
-       memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
+       memcpy(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
 #endif
        start+=128;
        blocks--;
@@ -516,7 +516,7 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
 #else
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
-       memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
+       memcpy(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
 #endif
        start+=128;
        blocks--;
@@ -603,7 +603,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
 #else
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
-       memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
+       memcpy(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
 #endif
        start+=128;
        blocks--;
@@ -623,7 +623,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
 #else
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
-       memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
+       memcpy(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
 #endif
        start+=128;
        blocks--;
index 18a86415561a8ce846d881454347c46ae435472b..9cf73a89441d7d1d3b150d9652bdaea0b81f0a89 100644 (file)
@@ -268,7 +268,7 @@ static ulong act_ints=0, act_ios=0, act_stats=0, act_rq=0;
 #endif
 
 #define PTR2USHORT(a)   (ushort)(ulong)(a)
-#define JIFFYWAIT(a)    {ulong gdtjf;gdtjf=jiffies+(a);while(gdtjf>jiffies);}
+#define JIFFYWAIT(a)    {ulong gdtjf;gdtjf=jiffies+(a);while(time_before(jiffies,gdtjf));}
 #define GDTOFFSOF(a,b)  (size_t)&(((a*)0)->b)   
 #define INDEX_OK(i,t)   ((i)<sizeof(t)/sizeof((t)[0]))
 
index 56c268bea52f98b5d6cca69ad983c73d8a7ce63c..a28c388e8317aede22652b6b84a6ffe33e151ec3 100644 (file)
@@ -234,7 +234,7 @@ static void tul_do_pause(unsigned amount)
         */
        spin_lock_irq(&io_request_lock);
 #else
-       while (jiffies < the_time);
+       while (time_before(jiffies, the_time));
 #endif
 }
 
index fd6374cc969631353616a5bae1f1ceed9b71602e..ed3942efde4cda22cf92852c06526a5850f3fc01 100644 (file)
@@ -1182,14 +1182,14 @@ STATIC  int scsi_check_sense (Scsi_Cmnd * SCpnt)
       }
 
     if (SCpnt->sense_buffer[2] & 0xe0)
-       return FAILED;
+       return SUCCESS;
 
     switch (SCpnt->sense_buffer[2] & 0xf)
     {
     case NO_SENSE:
        return SUCCESS;
     case RECOVERED_ERROR:
-       return SOFT_ERROR;
+       return /* SOFT_ERROR */ SUCCESS;
 
     case ABORTED_COMMAND:
        return NEEDS_RETRY;
@@ -1212,18 +1212,17 @@ STATIC  int scsi_check_sense (Scsi_Cmnd * SCpnt)
     case COPY_ABORTED:
     case VOLUME_OVERFLOW:
     case MISCOMPARE:
+        return SUCCESS;
 
     case MEDIUM_ERROR:
-       return FAILED;
+       return NEEDS_RETRY;
 
     case ILLEGAL_REQUEST:
-       return SUCCESS;
-
     case BLANK_CHECK:
     case DATA_PROTECT:
     case HARDWARE_ERROR:
     default:
-       return FAILED;
+       return SUCCESS;
     }
 }
 
index e09e7dc3b01d8f9708c42c4f760632aef31a4660..4b7d4af49362eb10a14783b650c9ee43987e5e7e 100644 (file)
@@ -4,7 +4,7 @@
  *     Description: Device Driver for Tekram DC-390 (T) PCI SCSI      *
  *                  Bus Master Host Adapter                           *
  ***********************************************************************/
-/* $Id: scsiiom.c,v 2.3 1998/10/24 09:10:28 garloff Exp $ */
+/* $Id: scsiiom.c,v 2.15 1998/12/25 17:33:27 garloff Exp $ */
 
 UCHAR
 dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
@@ -36,7 +36,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            DC390_write8 (ScsiFifo, bval);
            bval1 = SEL_W_ATN;
            pSRB->SRBState = SRB_START_;
-           DEBUG1(printk ("DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
+           DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
            if( pDCB->SyncMode & SYNC_ENABLE )
                {
                if( !(pDCB->IdentifyMsg & 7) ||         /* LUN == 0 || Cmd != INQUIRY */
@@ -53,21 +53,21 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            if(pDCB->SyncMode & EN_TAG_QUEUEING)
            {
                DC390_write8 (ScsiFifo, MSG_SIMPLE_QTAG);
-                   DEBUG1(printk ("DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN3, pDCB->TagMask);)
+               DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN3, pDCB->TagMask);)
                bval = 0; wlval = 1;
                while (wlval & pDCB->TagMask)
                  { bval++; wlval <<= 1; };
                pDCB->TagMask |= wlval;
                DC390_write8 (ScsiFifo, bval);
                pSRB->TagNumber = bval;
-               DEBUG1(printk ("DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
+               DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
                bval1 = SEL_W_ATN3;
                pSRB->SRBState = SRB_START_;
            }
            else        /* No TagQ */
            {
                bval1 = SEL_W_ATN;
-                   DEBUG1(printk ("DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
+               DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
                pSRB->SRBState = SRB_START_;
            }
        }
@@ -82,7 +82,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            bval &= 0xBF;       /* No DisConn */
            DC390_write8 (ScsiFifo, bval);
            bval1 = SEL_W_ATN;
-           DEBUG1(printk ("DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
+           DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
            pSRB->SRBState = SRB_START_;
              /* ??? */
            if( pDCB->SyncMode & SYNC_ENABLE )
@@ -101,13 +101,13 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            if(pDCB->SyncMode & EN_TAG_QUEUEING)
            {
                pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG;
-               DEBUG1(printk ("DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);)
+               DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);)
                bval = 0; wlval = 1;
                while (wlval & pDCB->TagMask)
                  { bval++; wlval <<= 1; };
                pDCB->TagMask |= wlval;
                pSRB->TagNumber = bval;
-               DEBUG1(printk ("DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
+               DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
                pSRB->MsgOutBuf[1] = bval;
                pSRB->MsgCnt = 2;
                bval1 = SEL_W_ATN_STOP;
@@ -119,7 +119,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
                pSRB->MsgCnt = 1;
                pSRB->SRBState = SRB_START_;
                bval1 = SEL_W_ATN_STOP;
-               DEBUG1(printk ("DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
+               DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
            };
        }
     }
@@ -134,7 +134,7 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
            DC390_write8 (ScsiFifo, bval);
            DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
            DC390_write8 (ScsiFifo, bval);
-           DEBUG1(printk ("DC390: AutoReqSense !\n");)
+           DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n");)
          }
        else    /* write cmnd to bus */ 
          {
@@ -150,16 +150,16 @@ dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
     {
        pSRB->SRBState = SRB_READY;
        pDCB->TagMask &= ~( 1 << pSRB->TagNumber );
-       DEBUG0(printk ("DC390: Interrupt during StartSCSI!\n");)
+       DEBUG0(printk (KERN_WARNING "DC390: Interrupt during StartSCSI!\n");)
        return 1;
     }
     else
     {
        pSRB->ScsiPhase = SCSI_NOP1;
        DEBUG0(if (pACB->pActiveDCB)    \
-                   printk ("DC390: ActiveDCB != 0\n");)
+                   printk (KERN_WARNING "DC390: ActiveDCB != 0\n");)
        DEBUG0(if (pDCB->pActiveSRB)    \
-                   printk ("DC390: ActiveSRB != 0\n");)
+                   printk (KERN_WARNING "DC390: ActiveSRB != 0\n");)
        pACB->pActiveDCB = pDCB;
        pDCB->pActiveSRB = pSRB;
        //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
@@ -183,12 +183,10 @@ dc390_dma_intr (PACB pACB)
   DEBUG0(PDEVSET1;)
   DEBUG0(PCI_READ_CONFIG_WORD (PDEV, PCI_STATUS, &pstate);)
   DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\
-       { printk("DC390: PCI state = %04x!\n", pstate); \
+       { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
          PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));};)
 
-  dstate = DC390_read8 (DMA_Status);
-  DC390_write8 (DMA_Status, dstate);   /* clear */
-  //DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */
+  dstate = DC390_read8 (DMA_Status); 
 
   if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
   else pSRB  = pACB->pActiveDCB->pActiveSRB;
@@ -207,12 +205,11 @@ dc390_dma_intr (PACB pACB)
              {
                DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n");)
                dstate = DC390_read8 (DMA_Status);
-               DC390_write8 (DMA_Status, dstate);      /* clear */
                residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
                  DC390_read8 (CtcReg_High) << 16;
                residual += DC390_read8 (Current_Fifo) & 0x1f;
              } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
-           if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr));
+           if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
            /* residual =  ... */
          }
        else
@@ -231,6 +228,7 @@ dc390_dma_intr (PACB pACB)
        
        DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
     }
+  dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
   return dstate;
 };
 #endif
@@ -245,14 +243,16 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
     UCHAR  phase, i;
     void   (*stateV)( PACB, PSRB, PUCHAR );
     UCHAR  istate, istatus;
+#if DMA_INT
     UCHAR  dstatus;
+#endif
     DC390_AFLAGS DC390_IFLAGS DC390_DFLAGS
 
     pACB = dc390_pACB_start;
 
     if (pACB == 0)
     {
-       printk(KERN_ERR "DC390: Interrupt on uninitialized adapter!\n");
+       printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n");
        return;
     }
     DC390_LOCK_DRV;
@@ -275,8 +275,8 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
 
     DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus);)
 
-    if( pACB == (PACB )-1) { DC390_UNLOCK_DRV; return; };
-   
+    if( !pACB ) { DC390_UNLOCK_DRV; return; };
+
 #if DMA_INT
     DC390_LOCK_IO;
     DC390_LOCK_ACB;
@@ -284,15 +284,17 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
     DC390_UNLOCK_ACB;
     DC390_UNLOCK_IO;
 
-    DEBUG1(printk ("dstatus=%02x,", dstatus);)
+    DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus);)
     if (! (dstatus & SCSI_INTERRUPT))
       {
-       DEBUG0(printk ("DC390 Int w/o SCSI actions (only DMA?)\n");)
+       DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");)
        DC390_UNLOCK_DRV;
        return;
       };
 #else
-    dstatus = DC390_read8 (DMA_Status);
+    //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
+    //dstatus = DC390_read8 (DMA_Status);
+    //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
 #endif
 
     DC390_LOCK_IO;
@@ -302,14 +304,15 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
     istate = DC390_read8 (Intern_State);
     istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
 
-    DEBUG1(printk ("Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);)
-    dc390_laststatus = dstatus<<24 | sstatus<<16 | istate<<8 | istatus;
+    DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);)
+    dc390_laststatus &= ~0x00ffffff;
+    dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
 
     if (sstatus & ILLEGAL_OP_ERR)
-       {
-              printk ("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus);
-              dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
-       };
+    {
+       printk ("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus);
+       dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
+    };
        
     if(istatus &  DISCONNECTED)
     {
@@ -323,18 +326,6 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
        goto unlock;
     }
 
-    if(istatus &  INVALID_CMD)
-    {
-       dc390_InvalidCmd( pACB );
-       goto unlock;
-    }
-
-    if(istatus &  SCSI_RESET)
-    {
-       dc390_ScsiRstDetect( pACB );
-       goto unlock;
-    }
-
     if( istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
     {
        pDCB = pACB->pActiveDCB;
@@ -345,7 +336,7 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
        };
        pSRB = pDCB->pActiveSRB;
        if( pDCB->DCBFlag & ABORT_DEV_ )
-               dc390_EnableMsgOut( pACB, pSRB );
+         dc390_EnableMsgOut_Abort (pACB, pSRB);
 
        phase = pSRB->ScsiPhase;
        DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);)
@@ -357,7 +348,21 @@ DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
        DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);)
        stateV = (void *) dc390_phase1[phase];
        ( *stateV )( pACB, pSRB, &sstatus );
+       goto unlock;
     }
+
+    if(istatus &  INVALID_CMD)
+    {
+       dc390_InvalidCmd( pACB );
+       goto unlock;
+    }
+
+    if(istatus &  SCSI_RESET)
+    {
+       dc390_ScsiRstDetect( pACB );
+       goto unlock;
+    }
+
  unlock:
     DC390_LOCK_DRV_NI;
     DC390_UNLOCK_ACB;
@@ -380,6 +385,7 @@ dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
     UCHAR   sstatus;
     PSGL    psgl;
     ULONG   ResidCnt, xferCnt;
+    UCHAR   dstate = 0;
 
     sstatus = *psstatus;
 
@@ -391,10 +397,9 @@ dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
        if( sstatus & COUNT_2_ZERO )
        {
            int ctr = 5000000; /* only try for about a tenth of a second */
-           while( --ctr && !(DC390_read8 (DMA_Status) & DMA_XFER_DONE) && pSRB->SGToBeXferLen )
-               DC390_write8 (DMA_Status,  DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT);     /* clear */
-           if (!ctr) printk (KERN_CRIT "DC390: DataOut_0: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr));
-           DC390_write8 (DMA_Status,  DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT); /* clear */
+           while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
+           if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
+           dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
            pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
            pSRB->SGIndex++;
            if( pSRB->SGIndex < pSRB->SGcount )
@@ -443,15 +448,14 @@ dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
        {
            int ctr = 5000000; /* only try for about a tenth of a second */
            int dstate = 0;
-           while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen )
-               DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT);      /* clear */
-           if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA aborted unfinished: %06x bytes remain!\n", DC390_read32 (DMA_Wk_ByteCntr));
+           while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
+           if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
            if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
+           dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
            DEBUG1(ResidCnt = ((ULONG) DC390_read8 (CtcReg_High) << 16) \
                + ((ULONG) DC390_read8 (CtcReg_Mid) << 8)               \
                + ((ULONG) DC390_read8 (CtcReg_Low));)
-           DEBUG1(printk ("Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);)
-           DC390_write8 (DMA_Status, DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT);  /* clear */
+           DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);)
 
            DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
 
@@ -474,7 +478,7 @@ dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
            bval = DC390_read8 (Current_Fifo);
            while( bval & 0x1f )
            {
-               DEBUG1(printk ("Check for residuals,");)
+               DEBUG1(printk (KERN_DEBUG "Check for residuals,");)
                if( (bval & 0x1f) == 1 )
                {
                    for(i=0; i < 0x100; i++)
@@ -494,17 +498,18 @@ dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
            }
 din_1:
            DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
-           for (i=0; i<0x8000; i++)
+           for (i = 0xa000; i; i--)
            {
                bval = DC390_read8 (DMA_Status);
-               DC390_write8 (DMA_Status, BLAST_COMPLETE | DMA_XFER_DONE | DMA_XFER_ABORT | DMA_XFER_ERROR | PCI_MS_ABORT);     /* clear */
                if (bval & BLAST_COMPLETE)
                    break;
            }
-           if (i == 0x8000) printk (KERN_CRIT "DC390: DMA Blast aborted unfinished!!\n");
+           /* It seems a DMA Blast abort isn't that bad ... */
+           if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
            //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
+           dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
 
-           DEBUG1(printk ("Blast: Read %i times DMA_Status %02x", i, bval);)
+           DEBUG1(printk (KERN_DEBUG "Blast: Read %li times DMA_Status %02x", 0xa000-i, bval);)
            ResidCnt = (ULONG) DC390_read8 (CtcReg_High);
            ResidCnt <<= 8;
            ResidCnt |= (ULONG) DC390_read8 (CtcReg_Mid);
@@ -525,7 +530,7 @@ din_1:
                pSRB->TotalXferredLen++;
                pSRB->SGToBeXferLen--;
            }
-           DEBUG1(printk ("Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
+           DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
                           pSRB->TotalXferredLen, pSRB->SGToBeXferLen);)
 
        }
@@ -558,164 +563,278 @@ dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 }
 
-void
-dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+
+static void __inline__
+dc390_reprog (PACB pACB, PDCB pDCB)
 {
-    UCHAR  bval;
-    USHORT wval, wval1;
-    PDCB   pDCB;
-    PSRB   psrb;
+  DC390_write8 (Sync_Period, pDCB->SyncPeriod);
+  DC390_write8 (Sync_Offset, pDCB->SyncOffset);
+  DC390_write8 (CtrlReg3, pDCB->CtrlR3);
+  DC390_write8 (CtrlReg4, pDCB->CtrlR4);
+  dc390_SetXferRate (pACB, pDCB);
+};
 
-    pDCB = pACB->pActiveDCB;
 
-    bval = DC390_read8 (ScsiFifo);
-    if( !(pSRB->SRBState & SRB_MSGIN_MULTI) )
+#ifdef DC390_DEBUG0
+static void
+dc390_printMsg (UCHAR *MsgBuf, UCHAR len)
+{
+  int i;
+  printk (" %02x", MsgBuf[0]);
+  for (i = 1; i < len; i++)
+    printk (" %02x", MsgBuf[i]);
+  printk ("\n");
+};
+#endif
+
+#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
+
+/* reject_msg */
+static void __inline__
+dc390_MsgIn_reject (PACB pACB, PSRB pSRB)
+{
+  pSRB->MsgOutBuf[0] = MSG_REJECT_;
+  pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+  DEBUG0 (printk (KERN_INFO "DC390: Reject message\n");)
+}
+
+/* abort command */
+static void __inline__
+dc390_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB )
+{
+    pSRB->MsgOutBuf[0] = MSG_ABORT; 
+    pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+    pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
+}
+
+static PSRB
+dc390_MsgIn_QTag (PACB pACB, PDCB pDCB, UCHAR tag)
+{
+  PSRB lastSRB = pDCB->pGoingLast;
+  PSRB pSRB = pDCB->pGoingSRB;
+
+  if (pSRB)
     {
-       if(bval == MSG_DISCONNECT)
-       {
-           pSRB->SRBState = SRB_DISCONNECT;
-       }
-       else if( bval == MSG_SAVE_PTR )
-           goto  min6;
-       else if( (bval == MSG_EXTENDED) || ((bval >= MSG_SIMPLE_QTAG) &&
-                                           (bval <= MSG_ORDER_QTAG)) )
+      for( ;pSRB ; )
        {
-           pSRB->SRBState |= SRB_MSGIN_MULTI;
-           pSRB->MsgInBuf[0] = bval;
-           pSRB->MsgCnt = 1;
-           pSRB->pMsgPtr = &(pSRB->MsgInBuf[1]);
+         if (pSRB->TagNumber == tag) break;
+         if (pSRB == lastSRB) goto mingx0;
+         pSRB = pSRB->pNextSRB;
        }
-       else if(bval == MSG_REJECT_)
+
+      if( pDCB->DCBFlag & ABORT_DEV_ )
        {
-           DC390_write8 (ScsiCmd, RESET_ATN_CMD);
-           pDCB->NegoPeriod = 50;
-           if( pSRB->SRBState & DO_SYNC_NEGO)
-               goto  set_async;
+         pSRB->SRBState = SRB_ABORT_SENT;
+         dc390_EnableMsgOut_Abort( pACB, pSRB );
        }
-       else if( bval == MSG_RESTORE_PTR)
-           goto  min6;
-       else
-           goto  min6;
+
+      if( !(pSRB->SRBState & SRB_DISCONNECT) )
+       goto  mingx0;
+
+      pDCB->pActiveSRB = pSRB;
+      pSRB->SRBState = SRB_DATA_XFER;
     }
-    else
-    {  /* minx: */
+  else
+    {
+    mingx0:
+      pSRB = pACB->pTmpSRB;
+      pSRB->SRBState = SRB_UNEXPECT_RESEL;
+      pDCB->pActiveSRB = pSRB;
+      pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
+      pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+    }
+  return pSRB;
+}
 
-       *pSRB->pMsgPtr = bval;
-       pSRB->MsgCnt++;
-       pSRB->pMsgPtr++;
-       if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) &&
-           (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) )
-       {
-           if( pSRB->MsgCnt == 2)
-           {
-               pSRB->SRBState = 0;
-               bval = pSRB->MsgInBuf[1];
-               pSRB = pDCB->pGoingSRB;
-               psrb = pDCB->pGoingLast;
-               if( pSRB )
-               {
-                   for( ;pSRB ; )
-                   {
-                       if(pSRB->TagNumber != bval)
-                       {
-                           if( pSRB == psrb )
-                               goto  mingx0;
-                           pSRB = pSRB->pNextSRB;
-                       }
-                       else
-                           break;
-                   }
-                   if( pDCB->DCBFlag & ABORT_DEV_ )
-                   {
-                       pSRB->SRBState = SRB_ABORT_SENT;
-                       dc390_EnableMsgOut( pACB, pSRB );
-                   }
-                   if( !(pSRB->SRBState & SRB_DISCONNECT) )
-                       goto  mingx0;
-                   pDCB->pActiveSRB = pSRB;
-                   pSRB->SRBState = SRB_DATA_XFER;
-               }
-               else
-               {
-mingx0:
-                   pSRB = pACB->pTmpSRB;
-                   pSRB->SRBState = SRB_UNEXPECT_RESEL;
-                   pDCB->pActiveSRB = pSRB;
-                   pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
-                   dc390_EnableMsgOut2( pACB, pSRB );
-               }
-           }
+
+/* set async transfer mode */
+static void 
+dc390_MsgIn_set_async (PACB pACB, PSRB pSRB)
+{
+  PDCB pDCB = pSRB->pSRBDCB;
+  if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
+    printk ("DC390: Target %i initiates Non-Sync?\n", pDCB->UnitSCSIID);
+  pSRB->SRBState &= ~DO_SYNC_NEGO;
+  pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
+  pDCB->SyncPeriod = 0;
+  pDCB->SyncOffset = 0;
+  //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
+  pDCB->CtrlR3 = FAST_CLK;     /* fast clock / normal scsi */
+  pDCB->CtrlR4 &= 0x3f;
+  pDCB->CtrlR4 |= pACB->glitch_cfg;    /* glitch eater */
+  dc390_reprog (pACB, pDCB);
+}
+
+/* set sync transfer mode */
+static void
+dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
+{
+  UCHAR bval;
+  USHORT wval, wval1;
+  PDCB pDCB = pSRB->pSRBDCB;
+  UCHAR oldsyncperiod = pDCB->SyncPeriod;
+  UCHAR oldsyncoffset = pDCB->SyncOffset;
+  
+  if (!(pSRB->SRBState & DO_SYNC_NEGO))
+    {
+      printk ("DC390: Target %i initiates Sync: %ins %i ... answer ...\n", 
+             pDCB->UnitSCSIID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
+
+      /* reject */
+      //dc390_MsgIn_reject (pACB, pSRB);
+      //return dc390_MsgIn_set_async (pACB, pSRB);
+
+      /* Reply with corrected SDTR Message */
+      if (pSRB->MsgInBuf[4] > 15)
+       { 
+         printk ("DC390: Lower Sync Offset to 15\n");
+         pSRB->MsgInBuf[4] = 15;
        }
-       else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) )
-       {       /* Note: This will fail for target initiated SDTR ? */
-           pSRB->SRBState &= ~(SRB_MSGIN_MULTI);
-           if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != EXTENDED_SDTR) )
-           {   /* reject_msg: */
-               pSRB->MsgCnt = 1;
-               pSRB->MsgInBuf[0] = MSG_REJECT_;
-               DC390_write8 (ScsiCmd, SET_ATN_CMD);
-           }
-           else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) )
-           {
-set_async:
-               pDCB = pSRB->pSRBDCB;
-               if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
-                       printk ("DC390: Target (%i,%i) initiates Non-Sync?\n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
-               pSRB->SRBState &= ~DO_SYNC_NEGO;
-               pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
-               pDCB->SyncPeriod = 0;
-               pDCB->SyncOffset = 0;
-               pDCB->CtrlR3 = FAST_CLK;        /* fast clock / normal scsi */
-               pDCB->CtrlR4 &= 0x3f;
-               pDCB->CtrlR4 |= pACB->glitch_cfg;       /* glitch eater */
-               goto re_prog;
-           }
+      if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
+       {
+         printk ("DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
+         pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
+       };
+      memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
+      pSRB->MsgCnt = 5;
+      DC390_ENABLE_MSGOUT;
+    };
+
+  pSRB->SRBState &= ~DO_SYNC_NEGO;
+  pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
+  pDCB->SyncOffset &= 0x0f0;
+  pDCB->SyncOffset |= pSRB->MsgInBuf[4];
+  pDCB->NegoPeriod = pSRB->MsgInBuf[3];
+
+  wval = (USHORT) pSRB->MsgInBuf[3];
+  wval = wval << 2; wval -= 3; wval1 = wval / 25;      /* compute speed */
+  if( (wval1 * 25) != wval) wval1++;
+  bval = FAST_CLK+FAST_SCSI;   /* fast clock / fast scsi */
+
+  pDCB->CtrlR4 &= 0x3f;                /* Glitch eater: 12ns less than normal */
+  if (pACB->glitch_cfg != NS_TO_GLITCH(0))
+    pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
+  else
+    pDCB->CtrlR4 |= NS_TO_GLITCH(0);
+  if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
+
+  if (wval1 >= 8)
+    {
+      wval1--; /* Timing computation differs by 1 from FAST_SCSI */
+      bval = FAST_CLK;         /* fast clock / normal scsi */
+      pDCB->CtrlR4 |= pACB->glitch_cfg;        /* glitch eater */
+    }
+
+  pDCB->CtrlR3 = bval;
+  pDCB->SyncPeriod = (UCHAR)wval1;
+  
+  if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->UnitSCSILUN == 0)
+    {
+      if (! (bval & FAST_SCSI)) wval1++;
+      printk ("DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->UnitSCSIID, 
+             40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
+    }
+  
+  dc390_reprog (pACB, pDCB);
+};
+
+
+/* According to the docs, the AM53C974 reads the message and 
+ * generates a Succesful Operation IRQ before asserting ACK for
+ * the last byte (how does it know whether it's the last ?) */
+/* The old code handled it in another way, indicating, that on
+ * every message byte an IRQ is generated and every byte has to
+ * be manually ACKed. Hmmm ?  (KG, 98/11/28) */
+/* The old implementation was correct. Sigh! */
+
+/* Check if the message is complete */
+static UCHAR __inline__
+dc390_MsgIn_complete (UCHAR *msgbuf, ULONG len)
+{ 
+  if (*msgbuf == MSG_EXTENDED)
+    {
+      if (len < 2) return 0;
+      if (len < msgbuf[1] + 2) return 0;
+    }
+  else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
+    if (len < 2) return 0;
+  return 1;
+}
+
+
+
+/* read and eval received messages */
+void
+dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
+    PDCB   pDCB = pACB->pActiveDCB;
+
+    /* Read the msg */
+
+    pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
+    //pSRB->SRBState = 0;
+
+    /* Msg complete ? */
+    if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
+      {
+       DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen);)
+       /* Now eval the msg */
+       switch (pSRB->MsgInBuf[0]) 
+         {
+         case MSG_DISCONNECT: 
+           pSRB->SRBState = SRB_DISCONNECT; break;
+           
+         case MSG_SIMPLE_QTAG:
+         case MSG_HEAD_QTAG:
+         case MSG_ORDER_QTAG:
+           pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
+           break;
+           
+         case MSG_REJECT_: 
+           DC390_write8 (ScsiCmd, RESET_ATN_CMD);
+           pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
+           if( pSRB->SRBState & DO_SYNC_NEGO)
+             dc390_MsgIn_set_async (pACB, pSRB);
+           break;
+           
+         case MSG_EXTENDED:
+           /* reject every extended msg but SDTR */
+           if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
+             dc390_MsgIn_reject (pACB, pSRB);
            else
-           {   /* set_sync: */
-
-               pDCB = pSRB->pSRBDCB;
-               if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
-                       printk ("DC390: Target (%i,%i) initiates Sync: %ins %i ?\n", 
-                               pDCB->UnitSCSIID, pDCB->UnitSCSILUN, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
-               pSRB->SRBState &= ~DO_SYNC_NEGO;
-               pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
-               pDCB->SyncOffset &= 0x0f0;
-               pDCB->SyncOffset |= pSRB->MsgInBuf[4];
-               pDCB->NegoPeriod = pSRB->MsgInBuf[3];
-               wval = (USHORT) pSRB->MsgInBuf[3];
-               wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */
-               if( (wval1 * 25) != wval)
-                   wval1++;
-               bval = FAST_CLK+FAST_SCSI;      /* fast clock / fast scsi */
-               pDCB->CtrlR4 &= 0x3f;           /* Glitch eater: 12ns less than normal */
-               if (pACB->glitch_cfg != NS_TO_GLITCH(0))
-                       pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
+             {
+               if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
+                 dc390_MsgIn_set_async (pACB, pSRB);
                else
-                       pDCB->CtrlR4 |= NS_TO_GLITCH(0);
-               if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
-               if (wval1 >= 8)
-               {
-                   wval1--;    /* Timing computation differs by 1 from FAST_SCSI */
-                   bval = FAST_CLK;            /* fast clock / normal scsi */
-                   pDCB->CtrlR4 |= pACB->glitch_cfg;   /* glitch eater */
-               }
-               pDCB->CtrlR3 = bval;
-               pDCB->SyncPeriod = (UCHAR)wval1;
-re_prog:
-               DC390_write8 (Sync_Period, pDCB->SyncPeriod);
-               DC390_write8 (Sync_Offset, pDCB->SyncOffset);
-               DC390_write8 (CtrlReg3, pDCB->CtrlR3);
-               DC390_write8 (CtrlReg4, pDCB->CtrlR4);
-               dc390_SetXferRate (pACB, pDCB);
-           }
-       }
-    }
-min6:
+                 dc390_MsgIn_set_sync (pACB, pSRB);
+             };
+           
+           // nothing has to be done
+         case MSG_COMPLETE: break;
+           
+           // SAVE POINTER my be ignored as we have the PSRB associated with the
+           // scsi command. Thanks, Gerard, for pointing it out.
+         case MSG_SAVE_PTR: break;
+           // The device might want to restart transfer with a RESTORE
+         case MSG_RESTORE_PTR: 
+           printk ("DC390: RESTORE POINTER message received ... reject\n");
+           // fall through
+
+           // reject unknown messages
+         default: dc390_MsgIn_reject (pACB, pSRB);
+         }
+       
+       /* Clear counter and MsgIn state */
+       pSRB->SRBState &= ~SRB_MSGIN;
+       pACB->MsgLen = 0;
+      };
+
     *psstatus = SCSI_NOP0;
     DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
 }
 
+
 void
 dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
 {
@@ -730,10 +849,10 @@ dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
            psgl = pSRB->pSegmentList;
            pSRB->SGBusAddr = virt_to_bus( psgl->address );
            pSRB->SGToBeXferLen = (ULONG) psgl->length;
-           DEBUG1(printk (" DC390: Next SG segment.");)
+           DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.");)
        }
        lval = pSRB->SGToBeXferLen;
-       DEBUG1(printk (" DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);)
+       DEBUG1(printk (KERN_DEBUG " DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);)
        DC390_write8 (CtcReg_Low, (UCHAR) lval);
        lval >>= 8;
        DC390_write8 (CtcReg_Mid, (UCHAR) lval);
@@ -749,21 +868,22 @@ dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
        DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
 
        DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
-       //DEBUG1(printk ("DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
+       //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
+       //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
+       //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
     }
     else    /* xfer pad */
     {
-       UCHAR bval = 0;
        if( pSRB->SGcount )
        {
            pSRB->AdaptStatus = H_OVER_UNDER_RUN;
            pSRB->SRBStatus |= OVER_RUN;
-           DEBUG0(printk (" DC390: Overrun -");)
+           DEBUG0(printk (KERN_WARNING " DC390: Overrun -");)
        }
-       DEBUG0(printk (" Clear transfer pad \n");)
-       DC390_write8 (CtcReg_Low, bval);
-       DC390_write8 (CtcReg_Mid, bval);
-       DC390_write8 (CtcReg_High, bval);
+       DEBUG0(printk (KERN_WARNING " Clear transfer pad \n");)
+       DC390_write8 (CtcReg_Low, 0);
+       DC390_write8 (CtcReg_Mid, 0);
+       DC390_write8 (CtcReg_High, 0);
 
        pSRB->SRBState |= SRB_XFERPAD;
        DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
@@ -1017,7 +1137,7 @@ disc1:
            dc390_SRBdone( pACB, pDCB, pSRB);
        }
     }
-    return;
+    pACB->MsgLen = 0;
 }
 
 
@@ -1032,7 +1152,7 @@ dc390_Reselect( PACB pACB )
     DEBUG0(printk(KERN_INFO "RSEL,");)
     pDCB = pACB->pActiveDCB;
     if( pDCB )
-    {  /* Arbitration lost but Reselection win */
+    {  /* Arbitration lost but Reselection won */
        DEBUG0(printk ("(ActiveDCB != 0)");)
        pSRB = pDCB->pActiveSRB;
        if( !( pACB->scan_devices ) )
@@ -1075,23 +1195,23 @@ dc390_Reselect( PACB pACB )
            printk (KERN_ERR "DC390: Reselect without outstanding cmnd (ID %02x, LUN %02x)\n",
                    wval & 0xff, (wval & 0xff00) >> 8);
            pDCB->pActiveSRB = pSRB;
-           dc390_EnableMsgOut( pACB, pSRB );
+           dc390_EnableMsgOut_Abort ( pACB, pSRB );
        }
        else
        {
            if( pDCB->DCBFlag & ABORT_DEV_ )
            {
                pSRB->SRBState = SRB_ABORT_SENT;
-               printk (KERN_NOTICE "DC390: Reselect: Abort (ID %02x, LUN %02x)\n",
+               printk (KERN_INFO "DC390: Reselect: Abort (ID %02x, LUN %02x)\n",
                        wval & 0xff, (wval & 0xff00) >> 8);
-               dc390_EnableMsgOut( pACB, pSRB );
+               dc390_EnableMsgOut_Abort( pACB, pSRB );
            }
            else
                pSRB->SRBState = SRB_DATA_XFER;
        }
     }
 
-    DEBUG1(printk ("Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);)
+    DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);)
     pSRB->ScsiPhase = SCSI_NOP0;
     DC390_write8 (Scsi_Dest_ID, pDCB->UnitSCSIID);
     DC390_write8 (Sync_Period, pDCB->SyncPeriod);
@@ -1244,7 +1364,7 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
            else
                pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |
                                SCSI_STAT_CHECKCOND;
-           REMOVABLEDEBUG(printk("Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->CmdBlock[0],\
+           REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->CmdBlock[0],\
                (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
            goto ckc_e;
        }
@@ -1260,7 +1380,7 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
            {
                pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) 
                            | SCSI_STAT_CHECKCOND;
-               REMOVABLEDEBUG(printk("Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->CmdBlock[0],\
+               REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->CmdBlock[0],\
                       (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
                goto ckc_e;
            }
@@ -1299,7 +1419,7 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
                    swlval += ptr2->length;
                    ptr2++;
                }
-               REMOVABLEDEBUG(printk("XferredLen=%08x,NotXferLen=%08x\n",\
+               REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\
                        (UINT) pSRB->TotalXferredLen, (UINT) swlval);)
            }
            dc390_RequestSense( pACB, pDCB, pSRB );
@@ -1587,22 +1707,6 @@ dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
 }
 
 
-static void __inline__
-dc390_EnableMsgOut2( PACB pACB, PSRB pSRB )
-{
-    pSRB->MsgCnt = 1;
-    DC390_write8 (ScsiCmd, SET_ATN_CMD);
-}
-
-
-static void __inline__
-dc390_EnableMsgOut( PACB pACB, PSRB pSRB )
-{
-    pSRB->MsgOutBuf[0] = MSG_ABORT;
-    dc390_EnableMsgOut2( pACB, pSRB );
-    pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
-}
-
 
 static void __inline__
 dc390_InvalidCmd( PACB pACB )
index 8ec3dbc0696a474a3deea816744f3d7269b41005..8ffabde7ecc2e294f312ac467cabeb2aa9c8a7f8 100644 (file)
@@ -11,7 +11,7 @@
   Copyright 1992 - 1998 Kai Makisara
                 email Kai.Makisara@metla.fi
 
-  Last modified: Sun Sep  6 09:34:49 1998 by root@home
+  Last modified: Thu Dec  3 20:27:46 1998 by makisara@home
   Some small formal changes - aeb, 950809
 */
 
@@ -707,7 +707,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
       STp->density = 0;        /* Clear the erroneous "residue" */
       STp->write_prot = 0;
       STp->block_size = 0;
-      STp->ps[0].drv_file = STp->ps[0].drv_block = 0;
+      STp->ps[0].drv_file = STp->ps[0].drv_block = (-1);
       STp->partition = STp->new_partition = 0;
       STp->door_locked = ST_UNLOCKED;
       STp->in_use = 1;
@@ -785,6 +785,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
          !enlarge_buffer(STp->buffer, STp->block_size, STp->restr_dma)) {
        printk(KERN_NOTICE "st%d: Blocksize %d too large for buffer.\n", dev,
               STp->block_size);
+       scsi_release_command(SCpnt);
        (STp->buffer)->in_use = 0;
        STp->buffer = NULL;
        if (scsi_tapes[dev].device->host->hostt->module)
@@ -3414,8 +3415,8 @@ static int st_attach(Scsi_Device * SDp){
      STps->eof = ST_NOEOF;
      STps->at_sm = 0;
      STps->last_block_valid = FALSE;
-     STps->drv_block = 0;
-     STps->drv_file = 0;
+     STps->drv_block = (-1);
+     STps->drv_file = (-1);
    }
 
    tpnt->current_mode = 0;
index cafd9280c407d0d4291e9d5efdd0fc042dfc4079..af47e706c70e76864b04d9a4fcebaf2be03de211 100644 (file)
@@ -5,9 +5,11 @@
  *                  Bus Master Host Adapter                           *
  * (C)Copyright 1995-1996 Tekram Technology Co., Ltd.                 *
  ***********************************************************************/
-/* $Id: tmscsim.c,v 2.4 1998/10/24 08:50:47 garloff Exp $              */
+/* (C) Copyright: put under GNU GPL in 10/96                           *
+*************************************************************************/
+/* $Id: tmscsim.c,v 2.16 1998/12/25 17:54:44 garloff Exp $             */
 /*     Enhancements and bugfixes by                                    *
- *     Kurt Garloff <K.Garloff@ping.de>                                *
+ *     Kurt Garloff <kurt@garloff.de>                                  *
  ***********************************************************************/
 /*     HISTORY:                                                        *
  *                                                                     *
  *                             bios_param() now respects part. table.  *
  *     2.0b  98/10/24  KG      Docu fixes. Timeout Msg in DMA Blast.   *
  *                             Disallow illegal idx in INQUIRY/REMOVE  *
+ *     2.0c  98/11/19  KG      Cleaned up detect/init for SMP boxes,   *
+ *                             Write Erase DMA (1.20t) caused problems *
+ *     2.0d  98/12/25  KG      Christmas release ;-) Message handling  *
+ *                             competely reworked. Handle target ini-  *
+ *                             tiated SDTR correctly.                  *
  ***********************************************************************/
 
 /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
 # if USE_SPINLOCKS == 3 /* both */
 
 #  if defined (__SMP__) || DEBUG_SPINLOCKS > 0
-#   define DC390_LOCK_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
+#   define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
 #  else
-#   define DC390_LOCK_INIT
+#   define DC390_LOCKA_INIT
 #  endif
    spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED;
 
 #  define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
 #  define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
 #  define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
-//#  define DC390_LOCK_INIT spin_lock_init (&(pACB->lock))
+//#  define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
 
 # else
 
 #  if USE_SPINLOCKS == 2 /* adapter specific locks */
 
 #   if defined (__SMP__) || DEBUG_SPINLOCKS > 0
-#    define DC390_LOCK_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
+#    define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
 #   else
-#    define DC390_LOCK_INIT
+#    define DC390_LOCKA_INIT
 #   endif
     spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED;
 #   define DC390_AFLAGS unsigned long aflags;
 #   define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
 #   define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
 #   define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
-//#   define DC390_LOCK_INIT spin_lock_init (&(pACB->lock))
+//#   define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
 
 #  else /* USE_SPINLOCKS == 1: global lock io_request_lock */
 
 #   define DC390_UNLOCK_ACB /* DC390_UNLOCK_IO */
 #   define DC390_LOCK_ACB_NI /* spin_lock (&(pACB->lock)) */
 #   define DC390_UNLOCK_ACB_NI /* spin_unlock (&(pACB->lock)) */
-#   define DC390_LOCK_INIT /* DC390_LOCK_INIT */
+#   define DC390_LOCKA_INIT /* DC390_LOCKA_INIT */
 
 #  endif /* 2 */
 # endif /* 3 */
 # define DC390_UNLOCK_ACB restore_flags (aflags)
 # define DC390_LOCK_ACB_NI
 # define DC390_UNLOCK_ACB_NI
-# define DC390_LOCK_INIT
+# define DC390_LOCKA_INIT
 #endif /* def */
 
 
@@ -365,9 +372,8 @@ void dc390_DoingSRB_Done( PACB pACB );
 static void dc390_ScsiRstDetect( PACB pACB );
 static void dc390_ResetSCSIBus( PACB pACB );
 static void __inline__ dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
-static void __inline__ dc390_EnableMsgOut2( PACB pACB, PSRB pSRB );
-static void __inline__ dc390_EnableMsgOut( PACB pACB, PSRB pSRB );
 static void __inline__ dc390_InvalidCmd( PACB pACB );
+static void __inline__ dc390_EnableMsgOut_Abort (PACB, PSRB);
 static void dc390_remove_dev (PACB pACB, PDCB pDCB);
 void do_DC390_Interrupt( int, void *, struct pt_regs *);
 
@@ -481,9 +487,190 @@ struct proc_dir_entry     DC390_proc_scsi_tmscsim ={
        S_IFDIR | S_IRUGO | S_IXUGO, 2
        };
 
+
 /***********************************************************************
+ * Functions for access to DC390 EEPROM
+ * and some to emulate it
  *
- *
+ **********************************************************************/
+
+
+static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval )
+{
+    UCHAR bval;
+
+    bval = 0;
+    if(mode == ENABLE_CE)
+       *regval = 0xc0;
+    else
+       *regval = 0x80;
+    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
+    if(mode == DISABLE_CE)
+        PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
+    udelay(160);
+}
+
+#ifndef CONFIG_SCSI_DC390T_NOGENSUPP
+static void __init dc390_EEpromDefaults (UCHAR index)
+{
+    PUCHAR ptr;
+    UCHAR  id;
+    ptr = (PUCHAR) dc390_eepromBuf[index];
+    
+    /* Adapter Settings */
+    ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */
+    ptr[EE_MODE2] = (UCHAR)tmscsim[3];
+    ptr[EE_DELAY] = 0; /* ?? */
+    ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Comds */
+    
+    /* Device Settings */
+    for (id = 0; id < MAX_SCSI_ID; id++)
+    {
+      ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */
+      ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */
+    };
+    dc390_adapname = "AM53C974";
+}
+
+static void __init dc390_checkparams (void)
+{
+       PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x\n", tmscsim[0],\
+                     tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4]);)
+       if (tmscsim[0] < 0 || tmscsim[0] > 7) /* modules-2.0.0 passes -1 as string */
+       {
+               tmscsim[0] = 7; tmscsim[1] = 4; 
+               tmscsim[2] = 9; tmscsim[3] = 15;
+               tmscsim[4] = 2;
+               printk (KERN_INFO "DC390: Using safe settings.\n");
+       }
+       else
+       {
+               /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */
+               if (tmscsim[1] < 0 || tmscsim[1] > 7) tmscsim[1] = 4;
+               if (tmscsim[4] < 0 || tmscsim[4] > 5) tmscsim[4] = 4;
+       };
+};
+/* Override defaults on cmdline:
+ * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped)
+ */
+void __init dc390_setup (char *str, int *ints)
+{
+       int i;
+       for (i = 0; i < ints[0]; i++)
+               tmscsim[i] = ints[i+1];
+       if (ints[0] > 5)
+               printk (KERN_NOTICE "DC390: ignore extra params!\n");
+       /* dc390_checkparams (); */
+};
+#endif /* CONFIG_SCSI_DC390T_NOGENSUPP */
+
+
+static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry )
+{
+    UCHAR bval;
+
+    bval = 0;
+    if(Carry)
+    {
+       bval = 0x40;
+       *regval = 0x80;
+       PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
+    }
+    udelay(160);
+    bval |= 0x80;
+    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
+    udelay(160);
+    bval = 0;
+    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
+    udelay(160);
+}
+
+
+static UCHAR __init dc390_EEpromInDO( PDEVDECL )
+{
+    UCHAR bval;
+
+    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80);
+    udelay(160);
+    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40);
+    udelay(160);
+    PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval);
+    if(bval == 0x22)
+       return(1);
+    else
+       return(0);
+}
+
+
+static USHORT __init dc390_EEpromGetData1( PDEVDECL )
+{
+    UCHAR i;
+    UCHAR carryFlag;
+    USHORT wval;
+
+    wval = 0;
+    for(i=0; i<16; i++)
+    {
+       wval <<= 1;
+       carryFlag = dc390_EEpromInDO(PDEV);
+       wval |= carryFlag;
+    }
+    return(wval);
+}
+
+
+static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd )
+{
+    UCHAR i,j;
+    UCHAR carryFlag;
+
+    carryFlag = 1;
+    j = 0x80;
+    for(i=0; i<9; i++)
+    {
+       dc390_EEpromOutDI(PDEV,regval,carryFlag);
+       carryFlag = (EEpromCmd & j) ? 1 : 0;
+       j >>= 1;
+    }
+}
+
+
+static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr)
+{
+    UCHAR   regval,cmd;
+    UCHAR   i;
+
+    cmd = EEPROM_READ;
+    for(i=0; i<0x40; i++)
+    {
+       dc390_EnDisableCE(ENABLE_CE, PDEV, &regval);
+       dc390_Prepare(PDEV, &regval, cmd++);
+       *ptr++ = dc390_EEpromGetData1(PDEV);
+       dc390_EnDisableCE(DISABLE_CE, PDEV, &regval);
+    }
+}
+
+
+static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index )
+{
+    UCHAR  i;
+    char  EEbuf[128];
+    USHORT wval, *ptr = (PUSHORT)EEbuf;
+
+    dc390_ReadEEprom( PDEV, ptr );
+    memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);
+    memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], 
+           &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);
+    wval = 0;
+    for(i=0; i<0x40; i++, ptr++)
+       wval += *ptr;
+    return (wval == 0x1234 ? 0 : 1);
+}
+
+
+/***********************************************************************
+ * Functions for the management of the internal structures 
+ * (DCBs, SRBs, Queueing)
  *
  **********************************************************************/
 static PDCB __inline__ dc390_findDCB ( PACB pACB, Scsi_Cmnd *cmd)
@@ -494,7 +681,7 @@ static PDCB __inline__ dc390_findDCB ( PACB pACB, Scsi_Cmnd *cmd)
        pDCB = pDCB->pNextDCB;
        if (pDCB == pACB->pLinkDCB)
          {
-            printk (KERN_ERR "DC390: DCB not found (DCB=%08x, DCBmap[%2x]=%2x)\n",
+            printk (KERN_WARNING "DC390: DCB not found (DCB=%08x, DCBmap[%2x]=%2x)\n",
                     (int)pDCB, cmd->target, pACB->DCBmap[cmd->target]);
             return 0;
          }
@@ -578,7 +765,7 @@ static void dc390_RewaitSRB( PDCB pDCB, PSRB pSRB )
     UCHAR  bval;
 
     pDCB->GoingSRBCnt--; pDCB->pDCBACB->SelLost++;
-    DEBUG0(printk("DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB, pSRB, pSRB->pcmd->pid);)
+    DEBUG0(printk(KERN_INFO "DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB, pSRB, pSRB->pcmd->pid);)
     psrb1 = pDCB->pGoingSRB;
     if( pSRB == psrb1 )
     {
@@ -678,6 +865,13 @@ static __inline__ void dc390_SRBwaiting( PDCB pDCB, PSRB pSRB)
 }
 
 
+/***********************************************************************
+ * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB)
+ *
+ * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB)
+ *
+ ***********************************************************************/
+
 static void dc390_SendSRB( PACB pACB, PSRB pSRB )
 {
     PDCB   pDCB;
@@ -720,6 +914,14 @@ SND_EXIT:
     return;
 }
 
+/***********************************************************************
+ * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, PDCB pDCB, 
+ *                                      PSRB pSRB)
+ *
+ * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd
+ *
+ ***********************************************************************/
+
 static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB)
 {
     pSRB->pSRBDCB = pDCB;
@@ -790,7 +992,7 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
 
 
     DEBUG0(/*  if(pACB->scan_devices) */       \
-       printk(KERN_DEBUG "DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\
+       printk(KERN_INFO "DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\
                cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);)
 
     DC390_LOCK_ACB;
@@ -1056,15 +1258,17 @@ void dc390_dumpinfo (PACB pACB, PDCB pDCB, PSRB pSRB)
     printk ("   %02x   %02x   %02x   %02x   %02x   %02x\n",
            DC390_read8(INT_Status), DC390_read8(Current_Fifo), DC390_read8(CtrlReg1),
            DC390_read8(CtrlReg2), DC390_read8(CtrlReg3), DC390_read8(CtrlReg4));
+    DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
     printk ("DC390: Register dump: DMA engine:\n");
     printk ("DC390: Cmd   STrCnt    SBusA    WrkBC    WrkAC Stat SBusCtrl\n");
     printk ("DC390:  %02x %08x %08x %08x %08x   %02x %08x\n",
            DC390_read8(DMA_Cmd), DC390_read32(DMA_XferCnt), DC390_read32(DMA_XferAddr),
            DC390_read32(DMA_Wk_ByteCntr), DC390_read32(DMA_Wk_AddrCntr),
            DC390_read8(DMA_Status), DC390_read32(DMA_ScsiBusCtrl));
+    DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
     PDEVSET1; PCI_READ_CONFIG_WORD(PDEV, PCI_STATUS, &pstat);
     printk ("DC390: Register dump: PCI Status: %04x\n", pstat);
-    printk ("DC390: Please report driver trouble to K.Garloff@ping.de\n");
+    printk ("DC390: In case of driver trouble read linux/drivers/scsi/README.tmscsim\n");
 };
 
 
@@ -1076,6 +1280,8 @@ void dc390_dumpinfo (PACB pACB, PDCB pDCB, PSRB pSRB)
  * Inputs : cmd - command to abort
  *
  * Returns : 0 on success, -1 on failure.
+ *
+ * Status: Buggy !
  ***********************************************************************/
 
 int DC390_abort (Scsi_Cmnd *cmd)
@@ -1347,13 +1553,13 @@ int DC390_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)
 
 
 /***********************************************************************
- * Function : static void dc390_initDCB
+ * Function : static void dc390_initDCB()
  *
  * Purpose :  initialize the internal structures for a given DCB
  *
  * Inputs : cmd - pointer to this scsi cmd request block structure
- *
  ***********************************************************************/
+
 void dc390_initDCB( PACB pACB, PDCB *ppDCB, PSCSICMD cmd )
 {
     PEEprom    prom;
@@ -1412,11 +1618,11 @@ void dc390_initDCB( PACB pACB, PDCB *ppDCB, PSCSICMD cmd )
 }
 
 /***********************************************************************
- * Function : static void dc390_updateDCB
+ * Function : static void dc390_updateDCB()
  *
  * Purpose :  Set the configuration dependent DCB parameters
- *
  ***********************************************************************/
+
 void dc390_updateDCB (PACB pACB, PDCB pDCB)
 {
   pDCB->IdentifyMsg = IDENTIFY (pDCB->DevMode & EN_DISCONNECT_, pDCB->UnitSCSILUN);
@@ -1441,11 +1647,11 @@ void dc390_updateDCB (PACB pACB, PDCB pDCB)
 
 
 /***********************************************************************
- * Function : static void dc390_updateDCBs
+ * Function : static void dc390_updateDCBs ()
  *
  * Purpose :  Set the configuration dependent DCB params for all DCBs
- *
  ***********************************************************************/
+
 static void dc390_updateDCBs (PACB pACB)
 {
   int i;
@@ -1459,13 +1665,13 @@ static void dc390_updateDCBs (PACB pACB)
   
 
 /***********************************************************************
- * Function : static void dc390_initSRB
+ * Function : static void dc390_initSRB()
  *
  * Purpose :  initialize the internal structures for a given SRB
  *
  * Inputs : psrb - pointer to this scsi request block structure
- *
  ***********************************************************************/
+
 static void __inline__ dc390_initSRB( PSRB psrb )
 {
   /* psrb->PhysSRB = virt_to_phys( psrb ); */
@@ -1489,13 +1695,14 @@ void dc390_linkSRB( PACB pACB )
 
 
 /***********************************************************************
- * Function : static void dc390_initACB
+ * Function : static void dc390_initACB ()
  *
  * Purpose :  initialize the internal structures for a given SCSI host
  *
  * Inputs : psh - pointer to this host adapter's structure
- *
+ *         io_port, Irq, index: Resources and adapter index
  ***********************************************************************/
+
 void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
 {
     PACB    pACB;
@@ -1510,14 +1717,14 @@ void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
     psh->irq = Irq;
 
     pACB = (PACB) psh->hostdata;
-    DC390_LOCK_INIT;
+    DC390_LOCKA_INIT;
     DC390_LOCK_ACB;
 
     pACB->pScsiHost = psh;
     pACB->IOPortBase = (USHORT) io_port;
     pACB->IRQLevel = Irq;
 
-    DEBUG0(printk (KERN_DEBUG "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n",       \
+    DEBUG0(printk (KERN_INFO "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n",        \
            index, psh->this_id, (int)io_port, Irq);)
    
     psh->max_id = 8;
@@ -1541,6 +1748,8 @@ void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
     pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
     pACB->ACBFlag = 0;
     pACB->scan_devices = 1;
+    pACB->MsgLen = 0;
+    pACB->Ignore_IRQ = 0;
     pACB->Gmode2 = dc390_eepromBuf[index][EE_MODE2];
     dc390_linkSRB( pACB );
     pACB->pTmpSRB = &pACB->TmpSRB;
@@ -1554,33 +1763,44 @@ void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
 
 
 /***********************************************************************
- * Function : static int dc390_initAdapter
+ * Function : static int dc390_initAdapter ()
  *
  * Purpose :  initialize the SCSI chip ctrl registers
  *
  * Inputs : psh - pointer to this host adapter's structure
+ *         io_port, Irq, index: Resources
  *
+ * Outputs: 0 on success, -1 on error
  ***********************************************************************/
+
 int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
 {
-    PACB   pACB, pacb;
+    PACB   pACB, pACB2;
     UCHAR  used_irq = 0, dstate;
     int    i;
+    
+    pACB = (PACB) psh->hostdata;
+    
+    for ( pACB2 = dc390_pACB_start; pACB2 ; )
+      {
+       if( pACB2->IRQLevel == Irq )
+         {
+           used_irq = 1;
+           break;
+         }
+       else
+         pACB2 = pACB2->pNextACB;
+      }
 
-    pacb = dc390_pACB_start;
-    if( pacb != NULL )
-    {
-       for ( ; (pacb != (PACB) -1) ; )
+    if (check_region (io_port, psh->n_io_port))
        {
-           if( pacb->IRQLevel == Irq )
-           {
-               used_irq = 1;
-               break;
-           }
-           else
-               pacb = pacb->pNextACB;
+           printk(KERN_ERR "DC390: register IO ports error!\n");
+           return( -1 );
        }
-    }
+    else
+       request_region (io_port, psh->n_io_port, "tmscsim");
+
+    DC390_read8_ (INT_Status, io_port);                /* Reset Pending INT */
 
     if( !used_irq )
     {
@@ -1591,18 +1811,22 @@ int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
            }
     }
 
-    if (check_region (io_port, psh->n_io_port))
-       {
-           printk(KERN_ERR "DC390: register IO ports error!\n");
-           return( -1 );
-       }
+    if( !dc390_pACB_start )
+      {
+       pACB2 = NULL;
+       dc390_pACB_start = pACB;
+       dc390_pACB_current = pACB;
+       pACB->pNextACB = NULL;
+      }
     else
-       request_region (io_port, psh->n_io_port, "tmscsim");
-   
-    pACB = (PACB) psh->hostdata;
-    /* pACB->IOPortBase = (USHORT) io_port; */
+      {
+       pACB2 = dc390_pACB_current;
+       dc390_pACB_current->pNextACB = pACB;
+       dc390_pACB_current = pACB;
+       pACB->pNextACB = NULL;
+      };
 
-    DC390_write8_ (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id, io_port);     /* Disable SCSI bus reset interrupt */
+    DC390_write8 (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id);       /* Disable SCSI bus reset interrupt */
 
     if (pACB->Gmode2 & RST_SCSI_BUS)
     {
@@ -1612,6 +1836,7 @@ int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
                udelay(1000);
     };
     pACB->ACBFlag = 0;
+    DC390_read8 (INT_Status);                          /* Reset Pending INT */
     
     DC390_write8 (Scsi_TimeOut, SEL_TIMEOUT);          /* 250ms selection timeout */
     DC390_write8 (Clk_Factor, CLK_FREQ_40MHZ);         /* Conversion factor = 0 , 40MHz clock */
@@ -1622,7 +1847,7 @@ int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
                (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ? NEGATE_REQACKDATA : 0);  /* Negation */
     DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
-    DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
+    DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
     dstate = DC390_read8 (DMA_Status);
     DC390_write8 (DMA_Status, dstate); /* clear */
 
@@ -1630,194 +1855,24 @@ int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
 }
 
 
-static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval )
-{
-    UCHAR bval;
-
-    bval = 0;
-    if(mode == ENABLE_CE)
-       *regval = 0xc0;
-    else
-       *regval = 0x80;
-    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
-    if(mode == DISABLE_CE)
-        PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
-    udelay(160);
-}
-
-#ifndef CONFIG_SCSI_DC390T_NOGENSUPP
-static void __init dc390_EEpromDefaults (UCHAR index)
-{
-    PUCHAR ptr;
-    UCHAR  id;
-    ptr = (PUCHAR) dc390_eepromBuf[index];
-    
-    /* Adapter Settings */
-    ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */
-    ptr[EE_MODE2] = (UCHAR)tmscsim[3];
-    ptr[EE_DELAY] = 0; /* ?? */
-    ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Comds */
-    
-    /* Device Settings */
-    for (id = 0; id < MAX_SCSI_ID; id++)
-    {
-      ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */
-      ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */
-    };
-    dc390_adapname = "AM53C974";
-}
-
-static void __init dc390_checkparams (void)
-{
-       PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x\n", tmscsim[0],\
-                     tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4]);)
-       if (tmscsim[0] < 0 || tmscsim[0] > 7) /* modules-2.0.0 passes -1 as string */
-       {
-               tmscsim[0] = 7; tmscsim[1] = 4; 
-               tmscsim[2] = 9; tmscsim[3] = 15;
-               tmscsim[4] = 2;
-               printk (KERN_INFO "DC390: Using safe settings.\n");
-       }
-       else
-       {
-               /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */
-               if (tmscsim[1] < 0 || tmscsim[1] > 7) tmscsim[1] = 4;
-               if (tmscsim[4] < 0 || tmscsim[4] > 5) tmscsim[4] = 4;
-       };
-};
-/* Override defaults on cmdline:
- * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped)
- */
-void __init dc390_setup (char *str, int *ints)
-{
-       int i;
-       for (i = 0; i < ints[0]; i++)
-               tmscsim[i] = ints[i+1];
-       if (ints[0] > 5)
-               printk (KERN_NOTICE "DC390: ignore extra params!\n");
-       /* dc390_checkparams (); */
-};
-#endif /* CONFIG_SCSI_DC390T_NOGENSUPP */
-
-
-static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry )
-{
-    UCHAR bval;
-
-    bval = 0;
-    if(Carry)
-    {
-       bval = 0x40;
-       *regval = 0x80;
-       PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
-    }
-    udelay(160);
-    bval |= 0x80;
-    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
-    udelay(160);
-    bval = 0;
-    PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
-    udelay(160);
-}
-
-
-static UCHAR __init dc390_EEpromInDO( PDEVDECL )
-{
-    UCHAR bval;
-
-    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80);
-    udelay(160);
-    PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40);
-    udelay(160);
-    PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval);
-    if(bval == 0x22)
-       return(1);
-    else
-       return(0);
-}
-
-
-static USHORT __init dc390_EEpromGetData1( PDEVDECL )
-{
-    UCHAR i;
-    UCHAR carryFlag;
-    USHORT wval;
-
-    wval = 0;
-    for(i=0; i<16; i++)
-    {
-       wval <<= 1;
-       carryFlag = dc390_EEpromInDO(PDEV);
-       wval |= carryFlag;
-    }
-    return(wval);
-}
-
-
-static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd )
-{
-    UCHAR i,j;
-    UCHAR carryFlag;
-
-    carryFlag = 1;
-    j = 0x80;
-    for(i=0; i<9; i++)
-    {
-       dc390_EEpromOutDI(PDEV,regval,carryFlag);
-       carryFlag = (EEpromCmd & j) ? 1 : 0;
-       j >>= 1;
-    }
-}
-
-
-static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr)
-{
-    UCHAR   regval,cmd;
-    UCHAR   i;
-
-    cmd = EEPROM_READ;
-    for(i=0; i<0x40; i++)
-    {
-       dc390_EnDisableCE(ENABLE_CE, PDEV, &regval);
-       dc390_Prepare(PDEV, &regval, cmd++);
-       *ptr++ = dc390_EEpromGetData1(PDEV);
-       dc390_EnDisableCE(DISABLE_CE, PDEV, &regval);
-    }
-}
-
-
-static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index )
-{
-    UCHAR  i;
-    char  EEbuf[128];
-    USHORT wval, *ptr = (PUSHORT)EEbuf;
-
-    dc390_ReadEEprom( PDEV, ptr );
-    memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);
-    memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], 
-           &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);
-    wval = 0;
-    for(i=0; i<0x40; i++, ptr++)
-       wval += *ptr;
-    return (wval == 0x1234 ? 0 : 1);
-}
-
-
 /***********************************************************************
- * Function : static int DC390_init (struct Scsi_Host *host)
+ * Function : static int DC390_init (struct Scsi_Host *host, ...)
  *
  * Purpose :  initialize the internal structures for a given SCSI host
  *
- * Inputs : host - pointer to this host adapter's structure/
+ * Inputs : host - pointer to this host adapter's structure
+ *         io_port - IO ports mapped to this adapter
+ *         Irq - IRQ assigned to this adpater
+ *         PDEVDECL - PCI access handle
+ *         index - Adapter index
  *
- * Preconditions : when this function is called, the chip_type
- *     field of the pACB structure MUST have been set.
+ * Outputs: 0 on success, -1 on error
  *
  * Note: written in capitals, because the locking is only done here,
  *     not in DC390_detect, called from outside 
  ***********************************************************************/
 
-static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, int index)
+static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, UCHAR index)
 {
     PSH   psh;
     PACB  pACB;
@@ -1846,7 +1901,7 @@ static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, int
     if( !psh ) return( -1 );
        
     pACB = (PACB) psh->hostdata;
-    DC390_LOCK_INIT;
+    DC390_LOCKA_INIT;
     DC390_LOCK_ACB;
 
 #if 0
@@ -1862,37 +1917,21 @@ static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, int
     }
 #endif
 
-    DEBUG0(printk("DC390: pSH = %8x,", (UINT) psh);)
-    DEBUG0(printk("DC390: Index %02i,", index);)
+    DEBUG0(printk(KERN_INFO "DC390: pSH = %8x,", (UINT) psh);)
+    DEBUG0(printk(" Index %02i,", index);)
 
     dc390_initACB( psh, io_port, Irq, index );
+    pACB = (PACB) psh->hostdata;
+        
     PDEVSET;
 
-    DC390_read8_ (INT_Status, io_port);                /* Reset Pending INT */
-
     if( !dc390_initAdapter( psh, io_port, Irq, index ) )
     {
-       pACB = (PACB) psh->hostdata;
-       if( !dc390_pACB_start )
-       {
-           dc390_pACB_start = pACB;
-           dc390_pACB_current = pACB;
-           pACB->pNextACB = (PACB) -1;
-       }
-       else
-       {
-           dc390_pACB_current->pNextACB = pACB;
-           dc390_pACB_current = pACB;
-           pACB->pNextACB = (PACB)  -1;
-       }
-        
-       DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
+       DEBUG0(printk("\nDC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
                (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array);)
        DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
                sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) );)
 
-       DC390_read8_ (INT_Status, io_port);             /* Reset Pending INT */
-
        DC390_UNLOCK_ACB;
         return (0);
     }
@@ -1960,7 +1999,6 @@ int __init DC390_detect (Scsi_Host_Template *psht)
     PDEVDECL0;
     UCHAR   irq;
     UINT    io_port;
-    UCHAR   adaptCnt = 0;      /* Number of boards detected */
     DC390_IFLAGS DC390_DFLAGS
 
     DC390_LOCK_DRV;
@@ -1972,29 +2010,36 @@ int __init DC390_detect (Scsi_Host_Template *psht)
        {
            DC390_LOCK_IO;              /* Remove this when going to new eh */
            PCI_GET_IO_AND_IRQ;
-           DEBUG0(printk(KERN_DEBUG "DC390(%i): IO_PORT=%04x,IRQ=%x\n", adaptCnt, (UINT) io_port, irq);)
+           DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq);)
 
-           if( !DC390_init(psht, io_port, irq, PDEV, adaptCnt))
+           if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
            {
                PCI_SET_MASTER;
                dc390_set_pci_cfg (PDEV);
-               adaptCnt++;
+               dc390_adapterCnt++;
            };
            DC390_UNLOCK_IO;            /* Remove when going to new eh */
        }
     else
        printk (KERN_ERR "DC390: No PCI BIOS found!\n");
    
-    if (adaptCnt)
+    if (dc390_adapterCnt)
        psht->proc_dir = &DC390_proc_scsi_tmscsim;
 
-    printk(KERN_INFO "DC390: %i adapters found\n", adaptCnt);
-    dc390_adapterCnt = adaptCnt;
+    printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
     DC390_UNLOCK_DRV;
-    return( adaptCnt );
+    return( dc390_adapterCnt );
 }
 
 
+/***********************************************************************
+ * Functions: dc390_inquiry(), dc390_inquiry_done()
+ *
+ * Purpose: When changing speed etc., we have to issue an INQUIRY
+ *         command to make sure, we agree upon the nego parameters
+ *         with the device
+ ***********************************************************************/
+
 static void dc390_inquiry_done (Scsi_Cmnd* cmd)
 {
    printk (KERN_INFO "DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n",
@@ -2211,7 +2256,7 @@ int dc390_set_info (char *buffer, int length, PACB pACB)
       /* NegoPeriod */
       if (*pos != '-')
        {
-         SCANF (pos, p0, dum, 76, 800); 
+         SCANF (pos, p0, dum, 72, 800); 
          pDCB->NegoPeriod = dum >> 2;
          if (pDCB->NegoPeriod != olddevmode) needs_inquiry++;
          if (!pos) goto ok;
@@ -2367,8 +2412,6 @@ int dc390_set_info (char *buffer, int length, PACB pACB)
  *
  ********************************************************************/
 
-/* KG: proc_info taken from driver aha152x.c */
-
 #undef SPRINTF
 #define SPRINTF(args...) pos += sprintf(pos, ## args)
 
@@ -2529,14 +2572,14 @@ int DC390_release(struct Scsi_Host *host)
     if (host->irq != IRQ_NONE)
     {
        for (irq_count = 0, pACB = dc390_pACB_start; 
-            pACB && pACB != (PACB)-1; pACB = pACB->pNextACB)
+            pACB; pACB = pACB->pNextACB)
        {
            if ( pACB->IRQLevel == host->irq )
                ++irq_count;
        }
        if (irq_count == 1)
         {
-           DEBUG0(printk(KERN_DEBUG "DC390: Free IRQ %i\n",host->irq);)
+           DEBUG0(printk(KERN_INFO "DC390: Free IRQ %i\n",host->irq);)
            free_irq(host->irq,NULL);
         }
     }
index 6cee55837786d471d0408fd02425568e8b468c8f..acc6526fdfec37b679342683d421fd81847c2530 100644 (file)
@@ -3,7 +3,7 @@
 ;*                 TEKRAM DC-390(T) PCI SCSI Bus Master Host Adapter  *
 ;*                 Device Driver                                      *
 ;***********************************************************************/
-/* $Id: tmscsim.h,v 2.1 1998/10/14 10:31:48 garloff Exp $ */
+/* $Id: tmscsim.h,v 2.4 1998/12/25 17:33:27 garloff Exp $ */
 
 #ifndef _TMSCSIM_H
 #define _TMSCSIM_H
@@ -95,15 +95,13 @@ UCHAR               MsgOutBuf[6];
 /* 0x48: */
 SGL            Segmentx;       /* make a one entry of S/G list table */
 
-PUCHAR         pMsgPtr;
-
 UCHAR          ScsiCmdLen;
 UCHAR          ScsiPhase;
 
 UCHAR          AdaptStatus;
 UCHAR          TargetStatus;
 
-/* 0x5c: */
+/* 0x58: */
 UCHAR          MsgCnt;
 UCHAR          EndMessage;
 UCHAR          RetryCnt;
@@ -115,7 +113,7 @@ UCHAR               SGIndex;
 UCHAR          SRBStatus;
   //UCHAR              IORBFlag;       /*;81h-Reset, 2-retry */
 
-/* 0x64: */
+/* 0x60: */
 };
 
 
@@ -218,14 +216,16 @@ spinlock_t        lock;
 UCHAR          sel_timeout;
 UCHAR          glitch_cfg;
 
-UCHAR          reserved[2];    /* alignment */
+UCHAR          MsgLen;
+UCHAR          Ignore_IRQ;     /* Not used */
 
 PDEVDECL1;                     /* Pointer to PCI cfg. space */
-/* 0x44/0x40: */
+/* 0x40/0x3c: */
 ULONG          Cmds;
 ULONG          CmdInQ;
 ULONG          CmdOutOfSRB;
 ULONG          SelLost;
+
        
 /* 0x50/0x4c: */       
 DC390_SRB      TmpSRB;
index dc8beb9610c3b9de7f43ef862fcdab006c9a45b5..53cf0ba76655e7ed320ffc000d185eb82fb10d09 100644 (file)
@@ -131,7 +131,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       int 'PSS MIDI IRQ 3, 4, 5, 7, 9, 10, 11, 12' CONFIG_PSS_MPU_IRQ 9
       bool '  Have DSPxxx.LD firmware file' CONFIG_PSS_HAVE_BOOT
       if [ "$CONFIG_PSS_HAVE_BOOT" = "y" ]; then
-         string '  Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE
+         string '  Full pathname of DSPxxx.LD firmware file' CONFIG_PSS_BOOT_FILE /etc/sound/dsp001.ld
       fi
   fi
   if [ "$CONFIG_SOUND_PSS" = "y" -o "$CONFIG_SOUND_PSS" = "m" ]; then
@@ -168,7 +168,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       int 'TRIX SB DMA 1 or 3' CONFIG_TRIX_SB_DMA 1
       bool '  Have TRXPRO.HEX firmware file' CONFIG_TRIX_HAVE_BOOT
       if [ "$CONFIG_TRIX_HAVE_BOOT" = "y" ]; then
-       string '  Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE
+       string '  Full pathname of TRXPRO.HEX firmware file' CONFIG_TRIX_BOOT_FILE /etc/sound/trxpro.hex
       fi
   fi
   
@@ -185,7 +185,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       int 'MAD16 MIDI IRQ 5, 7, 9 or 10' CONFIG_MAD16_MPU_IRQ 9
   fi
   
-  dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS
+  dep_tristate 'Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m
   if [ "$CONFIG_SOUND_WAVEFRONT" = "y" ]; then
       hex 'I/O base for WaveFront 210, 230, 260, 290, 300, 320, 338 or 330' CONFIG_WAVEFRONT_BASE 330
       int 'WaveFront IRQ 5, 9, 12 or 15' CONFIG_WAVEFRONT_IRQ 9
@@ -218,7 +218,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
       int 'Maui IRQ 5, 9, 12 or 15' CONFIG_MAUI_IRQ 9
       bool '  Have OSWF.MOT firmware file' CONFIG_MAUI_HAVE_BOOT
       if [ "$CONFIG_MAUI_HAVE_BOOT" = "y" ]; then
-       string '  Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE
+       string '  Full pathname of OSWF.MOT firmware file' CONFIG_MAUI_BOOT_FILE /etc/sound/oswf.mot
       fi
   fi
 
index af172bac2137ebe74d9eafc9872ff8447a6ea9c7..240e0dd68a11b290b68756abd0cb155a6afc2fd3 100644 (file)
@@ -71,6 +71,7 @@ typedef struct
 #define MD_4232                5
 #define MD_C930                6
 #define MD_IWAVE       7
+#define MD_4235         8 /* Crystal Audio CS4235 */
 
        /* Mixer parameters */
        int             recmask;
@@ -111,7 +112,7 @@ static int timer_installed = -1;
 
 #endif
 
-static int ad_format_mask[8 /*devc->model */ ] =
+static int ad_format_mask[9 /*devc->model */ ] =
 {
        0,
        AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
@@ -120,7 +121,8 @@ static int ad_format_mask[8 /*devc->model */ ] =
        AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,       /* AD1845 */
        AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
        AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
-       AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM
+       AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_S16_BE | AFMT_IMA_ADPCM,
+       AFMT_U8 | AFMT_S16_LE /* CS4235 */
 };
 
 static ad1848_info adev_info[MAX_AUDIO_DEV];
@@ -1594,103 +1596,107 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
                        ad_write(devc, 25, ~tmp1);      /* Invert all bits */
                        if ((ad_read(devc, 25) & 0xe7) == (tmp1 & 0xe7))
                        {
-                               int id, full_id;
+                               int id;
 
                                /*
                                 *      It's at least CS4231
                                 */
                                
-                               devc->chip_name = "CS4231";
-                               devc->model = MD_4231;
-
                                /*
                                 * It could be an AD1845 or CS4231A as well.
                                 * CS4231 and AD1845 report the same revision info in I25
                                 * while the CS4231A reports different.
                                 */
 
-                               id = ad_read(devc, 25) & 0xe7;
-                               full_id = ad_read(devc, 25);
-                               if (id == 0x80) /* Device busy??? */
-                                       id = ad_read(devc, 25) & 0xe7;
-                               if (id == 0x80) /* Device still busy??? */
-                                       id = ad_read(devc, 25) & 0xe7;
+                               id = ad_read(devc, 25);
+                               if ((id & 0xe7) == 0x80)        /* Device busy??? */
+                                       id = ad_read(devc, 25);
+                               if ((id & 0xe7) == 0x80)        /* Device still busy??? */
+                                       id = ad_read(devc, 25);
                                DDB(printk("ad1848_detect() - step J (%02x/%02x)\n", id, ad_read(devc, 25)));
 
-                               switch (id)
+                                if ((id & 0xe7) == 0x80) {
+                                       /* 
+                                        * It must be a CS4231 or AD1845. The register I23 of
+                                        * CS4231 is undefined and it appears to be read only.
+                                        * AD1845 uses I23 for setting sample rate. Assume
+                                        * the chip is AD1845 if I23 is changeable.
+                                        */
+
+                                       unsigned char   tmp = ad_read(devc, 23);
+                                       ad_write(devc, 23, ~tmp);
+
+                                       if (interwave)
+                                       {
+                                               devc->model = MD_IWAVE;
+                                               devc->chip_name = "IWave";
+                                       }
+                                       else if (ad_read(devc, 23) != tmp)      /* AD1845 ? */
+                                       {
+                                               devc->chip_name = "AD1845";
+                                               devc->model = MD_1845;
+                                       }
+                                       else if (cs4248_flag)
+                                       {
+                                               if (ad_flags)
+                                                         *ad_flags |= AD_F_CS4248;
+                                               devc->chip_name = "CS4248";
+                                               devc->model = MD_1848;
+                                               ad_write(devc, 12, ad_read(devc, 12) & ~0x40);  /* Mode2 off */
+                                       }
+                                       ad_write(devc, 23, tmp);        /* Restore */
+                               }
+                               else
                                {
-
-                                       case 0xa0:
-                                               devc->chip_name = "CS4231A";
-                                               devc->model = MD_4231A;
+                                       switch (id & 0x1f) {
+                                       case 3: /* CS4236/CS4235 */
+                                               {
+                                                       int xid;
+                                                       ad_write(devc, 12, ad_read(devc, 12) | 0x60); /* switch to mode 3 */
+                                                       ad_write(devc, 23, 0x9c); /* select extended register 25 */
+                                                       xid = inb(io_Indexed_Data(devc));
+                                                       ad_write(devc, 12, ad_read(devc, 12) & ~0x60); /* back to mode 0 */
+                                                       if ((xid & 0x1f) == 0x1d) {
+                                                               devc->chip_name = "CS4235";
+                                                               devc->model = MD_4235;
+                                                       } else {
+                                                               devc->chip_name = "CS4236";
+                                                               devc->model = MD_4232;
+                                                       }
+                                               }
                                                break;
 
-                                       case 0xa2:
+                                       case 2: /* CS4232/CS4232A */
                                                devc->chip_name = "CS4232";
                                                devc->model = MD_4232;
                                                break;
-
-                                       case 0xb2:
-                                               devc->chip_name = "CS4232A";
-                                               devc->model = MD_4232;
-                                               break;
-
-                                       case 0x03:
-                                       case 0x83:
-                                               devc->chip_name = "CS4236";
-                                               devc->model = MD_4232;
-                                               break;
-
-                                       case 0x41:
-                                               devc->chip_name = "CS4236B";
-                                               devc->model = MD_4232;
-                                               break;
-
-                                       case 0x80:
+                               
+                                       case 0:
+                                               if ((id & 0xe0) == 0xa0)
                                                {
-                                                       /* 
-                                                        * It must be a CS4231 or AD1845. The register I23 of
-                                                        * CS4231 is undefined and it appears to be read only.
-                                                        * AD1845 uses I23 for setting sample rate. Assume
-                                                        * the chip is AD1845 if I23 is changeable.
-                                                        */
-
-                                                       unsigned char   tmp = ad_read(devc, 23);
-                                                       ad_write(devc, 23, ~tmp);
-
-                                                       if (interwave)
-                                                       {
-                                                               devc->model = MD_IWAVE;
-                                                               devc->chip_name = "IWave";
-                                                       }
-                                                       else if (ad_read(devc, 23) != tmp)      /* AD1845 ? */
-                                                       {
-                                                               devc->chip_name = "AD1845";
-                                                               devc->model = MD_1845;
-                                                       }
-                                                       else if (cs4248_flag)
-                                                       {
-                                                               if (ad_flags)
-                                                                         *ad_flags |= AD_F_CS4248;
-                                                               devc->chip_name = "CS4248";
-                                                               devc->model = MD_1848;
-                                                               ad_write(devc, 12, ad_read(devc, 12) & ~0x40);  /* Mode2 off */
-                                                       }
-                                                       ad_write(devc, 23, tmp);        /* Restore */
+                                                       devc->chip_name = "CS4231A";
+                                                       devc->model = MD_4231A;
+                                               }
+                                               else
+                                               {
+                                                       devc->chip_name = "CS4321";
+                                                       devc->model = MD_4231;
                                                }
                                                break;
 
-                                       default:        /* Assume CS4231 or OPTi 82C930 */
+                                       default: /* maybe */
                                                DDB(printk("ad1848: I25 = %02x/%02x\n", ad_read(devc, 25), ad_read(devc, 25) & 0xe7));
-                                               if (optiC930)
-                                               {
-                                                       devc->chip_name = "82C930";
-                                                       devc->model = MD_C930;
-                                               }
+                                                if (optiC930)
+                                                {
+                                                        devc->chip_name = "82C930";
+                                                        devc->model = MD_C930;
+                                                }
                                                else
                                                {
+                                                       devc->chip_name = "CS4231";
                                                        devc->model = MD_4231;
                                                }
+                                       }
                                }
                        }
                        ad_write(devc, 25, tmp1);       /* Restore bits */
index 4d529bcaf5e16056ce3c20bd21a24efba1ec4a4a..11feddcccb0bc3bd9c425c35d4cc28bfa267bbcb 100644 (file)
@@ -369,9 +369,6 @@ int init_module(void)
        cfg.dma = dma;
        cfg.dma2 = dma2;
 
-       if (probe_cs4232(&cfg) == 0)
-               return -ENODEV;
-
        mpu_cfg.io_base = -1;
        mpu_cfg.irq = -1;
 
@@ -381,6 +378,9 @@ int init_module(void)
                probe_cs4232_mpu(&mpu_cfg); /* Bug always returns 0 not OK -- AC */
        }
 
+       if (probe_cs4232(&cfg) == 0)
+               return -ENODEV;
+
        attach_cs4232(&cfg);
 
        if (mpuio != -1 && mpuirq != -1) {
index 7471afcc3010f42e8636c4f759f6ed30d3600876..b202c38f04037c26d41c92c95448e315c7d68dfb 100644 (file)
@@ -80,6 +80,7 @@
  *    08.10.98   0.14  Joystick support fixed
  *                    -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
  *    10.12.98   0.15  Fix drain_dac trying to wait on not yet initialized DMA
+ *    16.12.98   0.16  Don't wake up app until there are fragsize bytes to read/write
  *
  * some important things missing in Ensoniq documentation:
  *
@@ -603,17 +604,14 @@ static void es1370_update_ptr(struct es1370_state *s)
                diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT);
                s->dma_adc.total_bytes += diff;
                s->dma_adc.count += diff;
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                               wake_up(&s->dma_adc.wait);
-               } else {
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
+                       wake_up(&s->dma_adc.wait);
+               if (!s->dma_adc.mapped) {
                        if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
                                s->ctrl &= ~CTRL_ADC_EN;
                                outl(s->ctrl, s->io+ES1370_REG_CONTROL);
                                s->dma_adc.error++;
                        }
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
                }
        }
        /* update DAC1 pointer */
@@ -635,7 +633,7 @@ static void es1370_update_ptr(struct es1370_state *s)
                                              s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
                                s->dma_dac1.endcleared = 1;
                        }
-                       if (s->dma_dac1.count < (signed)s->dma_dac1.dmasize)
+                       if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
                                wake_up(&s->dma_dac1.wait);
                }
        }
@@ -658,7 +656,7 @@ static void es1370_update_ptr(struct es1370_state *s)
                                              s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
                                s->dma_dac2.endcleared = 1;
                        }
-                       if (s->dma_dac2.count < (signed)s->dma_dac2.dmasize)
+                       if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
                                wake_up(&s->dma_dac2.wait);
                }
        }
@@ -1186,20 +1184,15 @@ static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wai
        spin_lock_irqsave(&s->lock, flags);
        es1370_update_ptr(s);
        if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+                       mask |= POLLIN | POLLRDNORM;
        }
        if (file->f_mode & FMODE_WRITE) {
                if (s->dma_dac2.mapped) {
                        if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
                                mask |= POLLOUT | POLLWRNORM;
                } else {
-                       if ((signed)s->dma_dac2.dmasize > s->dma_dac2.count)
+                       if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
                                mask |= POLLOUT | POLLWRNORM;
                }
        }
@@ -1704,7 +1697,7 @@ static unsigned int es1370_poll_dac(struct file *file, struct poll_table_struct
                if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
                        mask |= POLLOUT | POLLWRNORM;
        } else {
-               if ((signed)s->dma_dac1.dmasize > s->dma_dac1.count)
+               if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
                        mask |= POLLOUT | POLLWRNORM;
        }
        spin_unlock_irqrestore(&s->lock, flags);
@@ -2277,7 +2270,7 @@ __initfunc(int init_es1370(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "es1370: version v0.15 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "es1370: version v0.16 time " __TIME__ " " __DATE__ "\n");
        while (index < NR_DEVICE && 
               (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) {
                if (pcidev->base_address[0] == 0 || 
index 3a4ceb8c9ca6e23526c1056e27cbd1ccde3654e1..e759ae81903375d2d765ae82d78a458a62ad1ef1 100644 (file)
@@ -50,6 +50,8 @@
  *    27.10.98   0.5   Fix joystick support
  *                     -- Oliver Neukum (c188@org.chemie.uni-muenchen.de)
  *    10.12.98   0.6   Fix drain_dac trying to wait on not yet initialized DMA
+ *    23.12.98   0.7   Fix a few f_file & FMODE_ bugs
+ *                     Don't wake up app until there are fragsize bytes to read/write
  *
  */
 
@@ -837,17 +839,14 @@ static void es1371_update_ptr(struct es1371_state *s)
                diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT);
                s->dma_adc.total_bytes += diff;
                s->dma_adc.count += diff;
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= s->dma_adc.fragsize) 
-                               wake_up(&s->dma_adc.wait);
-               } else {
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
+                       wake_up(&s->dma_adc.wait);
+               if (!s->dma_adc.mapped) {
                        if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
                                s->ctrl &= ~CTRL_ADC_EN;
                                outl(s->ctrl, s->io+ES1371_REG_CONTROL);
                                s->dma_adc.error++;
                        }
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
                }
        }
        /* update DAC1 pointer */
@@ -869,7 +868,7 @@ static void es1371_update_ptr(struct es1371_state *s)
                                              s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
                                s->dma_dac1.endcleared = 1;
                        }
-                       if (s->dma_dac1.count < (signed)s->dma_dac1.dmasize)
+                       if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
                                wake_up(&s->dma_dac1.wait);
                }
        }
@@ -892,7 +891,7 @@ static void es1371_update_ptr(struct es1371_state *s)
                                              s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
                                s->dma_dac2.endcleared = 1;
                        }
-                       if (s->dma_dac2.count < (signed)s->dma_dac2.dmasize)
+                       if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
                                wake_up(&s->dma_dac2.wait);
                }
        }
@@ -1625,27 +1624,22 @@ static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wai
        unsigned int mask = 0;
 
        VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
+       if (file->f_mode & FMODE_WRITE)
                poll_wait(file, &s->dma_dac2.wait, wait);
-       if (file->f_flags & FMODE_READ)
+       if (file->f_mode & FMODE_READ)
                poll_wait(file, &s->dma_adc.wait, wait);
        spin_lock_irqsave(&s->lock, flags);
        es1371_update_ptr(s);
-       if (file->f_flags & FMODE_READ) {
-               if (s->dma_adc.mapped) {
+       if (file->f_mode & FMODE_READ) {
                        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
                                mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
        }
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                if (s->dma_dac2.mapped) {
                        if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
                                mask |= POLLOUT | POLLWRNORM;
                } else {
-                       if ((signed)s->dma_dac2.dmasize > s->dma_dac2.count)
+                       if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
                                mask |= POLLOUT | POLLWRNORM;
                }
        }
@@ -2046,11 +2040,11 @@ static int es1371_release(struct inode *inode, struct file *file)
        if (file->f_mode & FMODE_WRITE)
                drain_dac2(s, file->f_flags & O_NONBLOCK);
        down(&s->open_sem);
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                stop_dac2(s);
                dealloc_dmabuf(&s->dma_dac2);
        }
-       if (file->f_flags & FMODE_READ) {
+       if (file->f_mode & FMODE_READ) {
                stop_adc(s);
                dealloc_dmabuf(&s->dma_adc);
        }
@@ -2150,7 +2144,7 @@ static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct
                if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
                        mask |= POLLOUT | POLLWRNORM;
        } else {
-               if ((signed)s->dma_dac1.dmasize > s->dma_dac1.count)
+               if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
                        mask |= POLLOUT | POLLWRNORM;
        }
        spin_unlock_irqrestore(&s->lock, flags);
@@ -2540,16 +2534,16 @@ static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct
        unsigned int mask = 0;
 
        VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
+       if (file->f_mode & FMODE_WRITE)
                poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
+       if (file->f_mode & FMODE_READ)
                poll_wait(file, &s->midi.iwait, wait);
        spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
+       if (file->f_mode & FMODE_READ) {
                if (s->midi.icnt > 0)
                        mask |= POLLIN | POLLRDNORM;
        }
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                if (s->midi.ocnt < MIDIOUTBUF)
                        mask |= POLLOUT | POLLWRNORM;
        }
@@ -2716,7 +2710,7 @@ __initfunc(int init_es1371(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "es1371: version v0.6 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "es1371: version v0.7 time " __TIME__ " " __DATE__ "\n");
        while (index < NR_DEVICE && 
               (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) {
                if (pcidev->base_address[0] == 0 || 
index 36928af081c8d8aecffc4786b4e0514ef9219cd7..09a9f7249621838c714e58f36e318b6c93bc904d 100644 (file)
@@ -6,6 +6,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then
     dep_tristate 'Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_AEDSP16 $CONFIG_SOUND_OSS
     if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
        hex '  I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
+        hex 'I/O base for MPU401 Check from manual of the card' CONFIG_MPU_BASE 330
     fi
 
     if [ "$CONFIG_AEDSP16" = "y" -o "$CONFIG_AEDSP16" = "m" ]; then
@@ -23,9 +24,9 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then
                bool 'Audio Excel DSP 16 (SBPro emulation)' CONFIG_AEDSP16_SBPRO
                if [ "$CONFIG_AEDSP16_SBPRO" = "y" ]; then
                    comment 'Audio Excel DSP 16 [Sound Blaster Pro]'
-                   hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE
-                   int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ
-                   int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA
+                   hex 'I/O base for Audio Excel DSP 16 220, 240' CONFIG_AEDSP16_BASE $CONFIG_SB_BASE 220
+                   int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_SB_IRQ $CONFIG_SB_IRQ 5
+                   int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_SB_DMA $CONFIG_SB_DMA 0
                fi
            fi
        fi
@@ -36,8 +37,8 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND" = "m" ]; then
                if [ "$CONFIG_AEDSP16_MSS" = "y" ]; then
                    comment 'Audio Excel DSP 16 [Microsoft Sound System]'
                    hex 'I/O base for Audio Excel DSP 16 220 or 240' CONFIG_AEDSP16_BASE 220
-                   int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ
-                   int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA
+                   int 'Audio Excel DSP 16 IRQ 5, 7, 9, 10, 11' CONFIG_AEDSP16_MSS_IRQ $CONFIG_MSS_IRQ 5
+                   int 'Audio Excel DSP 16 DMA 0, 1 or 3' CONFIG_AEDSP16_MSS_DMA $CONFIG_MSS_DMA 1
                fi
            fi
        fi
index 8be3b91a92d54bdeec537aed8897de45c85b49f5..3414387488423fd4445d1715dd6df9ebc751192d 100644 (file)
@@ -260,6 +260,7 @@ void unload_opl3sa_wss(struct address_info *hw_config)
                      hw_config->dma,
                      dma2,
                      0);
+       sound_unload_audiodev(hw_config->slots[0]);
 }
 
 void unload_opl3sa_mpu(struct address_info *hw_config)
index dc864646e14ce68830756513eb7253c0e164c11c..16fcba273d3a21c025aec604b4649ea6e31099bb 100644 (file)
@@ -48,6 +48,7 @@
 #define MDL_ES1868MIDI 14      /* MIDI port of ESS1868 */
 #define MDL_AEDSP      15      /* Audio Excel DSP 16 */
 
+#define SUBMDL_ES18XX  0x10    /* Introduced a subtype ESS 18XX (Rolf) */
 #define SUBMDL_ALS007  42      /* ALS-007 differs from SB16 only in mixer */
                                /* register assignment */
 /*
index bb8063ab5efa027dbb123231f58eb691be1f62eb..b05d7eb2d915d01e8115660e1277fe72ebc2e938 100644 (file)
@@ -13,6 +13,8 @@
 /*
  * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
  *                       for full duplex support ( only sb16 by now )
+ * Rolf Fokkens:        Added (BETA?) support for ES18XX chips.
+ *                      Which means: you can adjust the recording levels.
  */
 #include <linux/config.h>
 #include <linux/delay.h>
@@ -484,6 +486,24 @@ static void relocate_ess1688(sb_devc * devc)
 #endif
 }
 
+/*
+ * ESS technology describes a detection scheme in their docs. It involves
+ * fiddling with the bits in certain mixer registers. ess_probe is supposed
+ * to help.
+ */
+static int ess_probe (sb_devc * devc, int reg, int xorval)
+{
+       int  val1, val2, val3;
+
+       val1 = sb_getmixer (devc, reg);
+       val2 = val1 ^ xorval;
+       sb_setmixer (devc, reg, val2);
+       val3 = sb_getmixer (devc, reg); 
+       sb_setmixer (devc, reg, val1);
+
+       return (val2 == val3);
+}
+
 static int ess_init(sb_devc * devc, struct address_info *hw_config)
 {
        unsigned char cfg, irq_bits = 0, dma_bits = 0;
@@ -522,12 +542,30 @@ static int ess_init(sb_devc * devc, struct address_info *hw_config)
                devc->model = MDL_SBPRO;
                return 1;
        }
-       else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
+
+       /*
+        * This the detection heuristic of ESS technology, though somewhat
+        * changed to actually make it work :-)
+        * This is the most BETA part of the software: Will it work?
+        */
+       devc->model = MDL_ESS;
+       devc->submodel = ess_minor & 0x0f;
+
+       if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
        {
                char *chip = "ES688";
 
-               if ((ess_minor & 0x0f) >= 8)
-                       chip = "ES1688";
+               if ((ess_minor & 0x0f) >= 8) {
+                       if (  !ess_probe (devc, 0x64, (1 << 3))
+                           && ess_probe (devc, 0x70, 0x7f)) {
+                               chip = "ES18XX";
+                               devc->submodel = SUBMDL_ES18XX;
+                       } else {
+                               chip = "ES1688";
+                       };
+               } else {
+                       chip = "ES688";
+               };
 
                sprintf(name,"ESS %s AudioDrive (rev %d)",
                        chip, ess_minor & 0x0f);
@@ -535,8 +573,6 @@ static int ess_init(sb_devc * devc, struct address_info *hw_config)
        else
                strcpy(name, "Jazz16");
 
-       devc->model = MDL_ESS;
-       devc->submodel = ess_minor & 0x0f;
        hw_config->name = name;
        sb_dsp_reset(devc);     /* Turn on extended mode */
 
@@ -998,19 +1034,28 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu)
 
 /*
  *     Mixer access routines
+ *
+ *     ES18XX modifications: some mixer registers reside in the
+ *     range above 0xa0. These must be accessed in another way.
  */
 
 void sb_setmixer(sb_devc * devc, unsigned int port, unsigned int value)
 {
        unsigned long flags;
 
+       /* MDB(printk("ESS: write port %x: %x\n", port, value)); */
+
        save_flags(flags);
        cli();
-       outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
-
-       udelay(20);
-       outb(((unsigned char) (value & 0xff)), MIXER_DATA);
-       udelay(20);
+       if (devc->model == MDL_ESS && port >= 0xa0 && port <= 0xbf) {
+               ess_write (devc, port, value);
+       } else {
+               outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
+
+               udelay(20);
+               outb(((unsigned char) (value & 0xff)), MIXER_DATA);
+               udelay(20);
+       };
        restore_flags(flags);
 }
 
index aaab4907d3c3083beaf6d2cff8aafb62aa5d0cf4..a96c4e3921180320abb3722b8b7ef2a9779f53ab 100644 (file)
  *
  *
  * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
+ * Rolf Fokkens    : ES18XX recording level support
+ */
+
+/*
+ * About ES18XX support:
+ *
+ * The standard ES688 support doesn't take care of the ES18XX recording
+ * levels very well. Whenever a device is selected (recmask) for recording
+ * it's recording level is loud, and it cannot be changed.
+ *
+ * The ES18XX has separate registers to controll the recording levels. The
+ * ES18XX specific software makes these level the same as their corresponding
+ * playback levels, unless recmask says they aren't recorded. In tha latter
+ * case the recording volumens are 0.
+ *
+ * Now recording levels of inputs can be controlled, by changing the playback
+ * levels.
+ * Futhermore several devices can be recorded together (which is not possible
+ * with the ES688.
  */
 
 #include <linux/config.h>
@@ -78,22 +97,62 @@ void smw_mixer_init(sb_devc * devc)
        sb_mixer_reset(devc);
 }
 
-static int smw_mixer_set(sb_devc * devc, int dev, int value)
+static int common_mixer_set(sb_devc * devc, int dev, int left, int right)
 {
-       int left = value & 0x000000ff;
-       int right = (value & 0x0000ff00) >> 8;
-       int reg, val;
+       int regoffs;
+       unsigned char val;
 
-       if (left > 100)
-               left = 100;
-       if (right > 100)
-               right = 100;
+       regoffs = (*devc->iomap)[dev][LEFT_CHN].regno;
 
-       if (dev > 31)
+       if (regoffs == 0)
                return -EINVAL;
 
-       if (!(devc->supported_devices & (1 << dev)))    /* Not supported */
-               return -EINVAL;
+       val = sb_getmixer(devc, regoffs);
+       change_bits(devc, &val, dev, LEFT_CHN, left);
+
+       devc->levels[dev] = left | (left << 8);
+
+       if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs)    /*
+                                                                * Change register
+                                                                */
+       {
+               sb_setmixer(devc, regoffs, val);        /*
+                                                        * Save the old one
+                                                        */
+               regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno;
+
+               if (regoffs == 0)
+                       return left | (left << 8);      /*
+                                                        * Just left channel present
+                                                        */
+
+               val = sb_getmixer(devc, regoffs);       /*
+                                                        * Read the new one
+                                                        */
+       }
+       change_bits(devc, &val, dev, RIGHT_CHN, right);
+
+       sb_setmixer(devc, regoffs, val);
+
+       devc->levels[dev] = left | (right << 8);
+       return left | (right << 8);
+}
+
+/*
+ * Changing input levels at ES18XX means having to take care of recording
+ * levels of recorded inputs too!
+ */
+static int es18XX_mixer_set(sb_devc * devc, int dev, int left, int right)
+{
+       if (devc->recmask & (1 << dev)) {
+               common_mixer_set(devc, dev + ES18XX_MIXER_RECDIFF, left, right);
+       }
+       return common_mixer_set(devc, dev, left, right);
+}
+
+static int smw_mixer_set(sb_devc * devc, int dev, int left, int right)
+{
+       int reg, val;
 
        switch (dev)
        {
@@ -134,12 +193,6 @@ static int sb_mixer_set(sb_devc * devc, int dev, int value)
        int left = value & 0x000000ff;
        int right = (value & 0x0000ff00) >> 8;
 
-       int regoffs;
-       unsigned char   val;
-
-       if (devc->model == MDL_SMW)
-               return smw_mixer_set(devc, dev, value);
-
        if (left > 100)
                left = 100;
        if (right > 100)
@@ -153,47 +206,60 @@ static int sb_mixer_set(sb_devc * devc, int dev, int value)
                                                         */
                return -EINVAL;
 
-       regoffs = (*devc->iomap)[dev][LEFT_CHN].regno;
-
-       if (regoffs == 0)
-               return -EINVAL;
-
-       val = sb_getmixer(devc, regoffs);
-       change_bits(devc, &val, dev, LEFT_CHN, left);
-
-       devc->levels[dev] = left | (left << 8);
-
-       if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs)    /*
-                                                                * Change register
-                                                                */
-       {
-               sb_setmixer(devc, regoffs, val);        /*
-                                                        * Save the old one
-                                                        */
-               regoffs = (*devc->iomap)[dev][RIGHT_CHN].regno;
-
-               if (regoffs == 0)
-                       return left | (left << 8);      /*
-                                                        * Just left channel present
-                                                        */
-
-               val = sb_getmixer(devc, regoffs);       /*
-                                                        * Read the new one
-                                                        */
+       /* Differentiate dependong on the chipsets */
+       switch (devc->model) {
+       case MDL_SMW:
+               return smw_mixer_set(devc, dev, left, right);
+               break;
+       case MDL_ESS:
+               if (devc->submodel == SUBMDL_ES18XX) {
+                       return es18XX_mixer_set(devc, dev, left, right);
+               }
+               break;
        }
-       change_bits(devc, &val, dev, RIGHT_CHN, right);
-
-       sb_setmixer(devc, regoffs, val);
 
-       devc->levels[dev] = left | (right << 8);
-       return left | (right << 8);
+       return common_mixer_set(devc, dev, left, right);
 }
 
+/*
+ * set_recsrc doesn't apply to ES18XX
+ */
 static void set_recsrc(sb_devc * devc, int src)
 {
        sb_setmixer(devc, RECORD_SRC, (sb_getmixer(devc, RECORD_SRC) & ~7) | (src & 0x7));
 }
 
+/*
+ * Changing the recmask on a ES18XX means:
+ * (1) Find the differences
+ * (2) For "turned-on"  inputs: make the recording level the playback level
+ * (3) For "turned-off" inputs: make the recording level zero
+ */
+static int es18XX_set_recmask(sb_devc * devc, int mask)
+{
+       int i, i_mask, cur_mask, diff_mask;
+       int value, left, right;
+
+       cur_mask  = devc->recmask;
+       diff_mask = (cur_mask ^ mask);
+
+       for (i = 0; i < 32; i++) {
+               i_mask = (1 << i);
+               if (diff_mask & i_mask) {
+                       if (mask & i_mask) {    /* Turn it on (2) */
+                               value = devc->levels[i];
+                               left  = value & 0x000000ff;
+                               right = (value & 0x0000ff00) >> 8;
+                       } else {                /* Turn it off (3) */
+                               left  = 0;
+                               right = 0;
+                       }
+                       common_mixer_set(devc, i + ES18XX_MIXER_RECDIFF, left, right);
+               }
+       }
+       return mask;
+}
+
 static int set_recmask(sb_devc * devc, int mask)
 {
        int devmask, i;
@@ -203,8 +269,12 @@ static int set_recmask(sb_devc * devc, int mask)
 
        switch (devc->model)
        {
+               case MDL_ESS:   /* ES18XX needs a separate approach */
+                       if (devc->submodel == SUBMDL_ES18XX) {
+                               devmask = es18XX_set_recmask(devc, devmask);
+                               break;
+                       };
                case MDL_SBPRO:
-               case MDL_ESS:
                case MDL_JAZZ:
                case MDL_SMW:
 
@@ -423,7 +493,7 @@ static struct mixer_operations als007_mixer_operations =
 static void sb_mixer_reset(sb_devc * devc)
 {
        char name[32];
-       int i;
+       int i, regval;
        extern int sm_games;
 
        sprintf(name, "SB_%d", devc->sbmixnum);
@@ -435,6 +505,24 @@ static void sb_mixer_reset(sb_devc * devc)
 
        for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
                sb_mixer_set(devc, i, devc->levels[i]);
+
+       /*
+        * Separate actions for ES18XX:
+        * Change registers 7a and 1c to make the record mixer the input for
+        *
+        * Then call set_recmask twice to do extra ES18XX initializations
+        */
+       if (devc->model == MDL_ESS && devc->submodel == SUBMDL_ES18XX) {
+               regval = sb_getmixer(devc, 0x7a);
+               regval = (regval & 0xe7) | 0x08;
+               sb_setmixer(devc, 0x7a, regval);
+               regval = sb_getmixer(devc, 0x1c);
+               regval = (regval & 0xf8) | 0x07;
+               sb_setmixer(devc, 0x1c, regval);
+
+               set_recmask(devc, ES18XX_RECORDING_DEVICES);
+               set_recmask(devc, 0);
+       }
        set_recmask(devc, SOUND_MASK_MIC);
 }
 
@@ -464,9 +552,26 @@ int sb_mixer_init(sb_devc * devc)
 
                case MDL_ESS:
                        devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
-                       devc->supported_devices = ES688_MIXER_DEVICES;
-                       devc->supported_rec_devices = ES688_RECORDING_DEVICES;
-                       devc->iomap = &es688_mix;
+
+                       /*
+                        * Take care of ES18XX specifics...
+                        */
+                       switch (devc->submodel) {
+                       case SUBMDL_ES18XX:
+                               devc->supported_devices
+                                       = ES18XX_MIXER_DEVICES;
+                               devc->supported_rec_devices
+                                       = ES18XX_RECORDING_DEVICES;
+                               devc->iomap = &es18XX_mix;
+                               break;
+                       default:
+                               devc->supported_devices
+                                       = ES688_MIXER_DEVICES;
+                               devc->supported_rec_devices
+                                       = ES688_RECORDING_DEVICES;
+                               devc->iomap = &es688_mix;
+                       }
+
                        break;
 
                case MDL_SMW:
index 7f61e6e0c7d94c02d61ba4a20b0c30d060c31cab..2785567e5bebe6ccfec896ce22af8643e1d31bf2 100644 (file)
  * Modified:
  *     Hunyue Yau      Jan 6 1994
  *     Added defines for the Sound Galaxy NX Pro mixer.
- * 
+ *
+ *     Rolf Fokkens    Dec 20 1998
+ *     Added (BETA?) support for ES18XX chips.
+ *     Which means: you can adjust the recording levels.
+ *
  */
 #include <linux/config.h>
 #include "legacy.h"
 #define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
 #define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER)
 
+#define ES18XX_RECORDING_DEVICES       (ES688_RECORDING_DEVICES | SOUND_MASK_LINE2 \
+                                        |SOUND_MASK_SYNTH)
+#define ES18XX_MIXER_DEVICES (ES688_MIXER_DEVICES)
+
 #define SB16_MIXER_DEVICES             (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
                                         SOUND_MASK_CD | \
                                         SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
 #define LEFT_CHN       0
 #define RIGHT_CHN      1
 
+/*
+ * Mixer registers of ES18XX
+ *
+ * These register specifically take care of recording levels. To make the
+ * mapping from playback devices to recording devices every recording
+ * devices = playback device + ES18XX_MIXER_RECDIFF
+ */
+#define ES18XX_MIXER_RECBASE   (SOUND_MIXER_LINE3 + 1)
+#define ES18XX_MIXER_RECDIFF   (ES18XX_MIXER_RECBASE - SOUND_MIXER_SYNTH)
+
+#define ES18XX_MIXER_RECSYNTH  (SOUND_MIXER_SYNTH      + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECPCM    (SOUND_MIXER_PCM        + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECSPEAKER        (SOUND_MIXER_SPEAKER    + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECLINE   (SOUND_MIXER_LINE       + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECMIC    (SOUND_MIXER_MIC        + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECCD     (SOUND_MIXER_CD         + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECIMIX   (SOUND_MIXER_IMIX       + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM     + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECRECLEV (SOUND_MIXER_RECLEV     + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECIGAIN  (SOUND_MIXER_IGAIN      + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECOGAIN  (SOUND_MIXER_OGAIN      + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECLINE1  (SOUND_MIXER_LINE1      + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECLINE2  (SOUND_MIXER_LINE2      + ES18XX_MIXER_RECDIFF)
+#define ES18XX_MIXER_RECLINE3  (SOUND_MIXER_LINE3      + ES18XX_MIXER_RECDIFF)
+
 /*
  * Mixer registers of ALS007
  */
@@ -154,6 +187,48 @@ MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
 MIX_ENT(SOUND_MIXER_LINE3,     0x00, 0, 0, 0x00, 0, 0)
 };
 
+/*
+ * The ES18XX specifics.
+ * Note that de master volume unlike ES688 is now controlled by two 
+ * 6 bit registers.
+ * Also Note that the recording levels (ES18XX_MIXER_REC...) have own 
+ * entries as if they were playback devices. They are used internally only!
+ */
+static mixer_tab es18XX_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME,    0x60, 5, 6, 0x62, 5, 6),
+MIX_ENT(SOUND_MIXER_BASS,       0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE,     0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH,      0x36, 7, 4, 0x36, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM,        0x14, 7, 4, 0x14, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER,    0x3c, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE,       0x3e, 7, 4, 0x3e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC,        0x1a, 7, 4, 0x1a, 3, 4),
+MIX_ENT(SOUND_MIXER_CD,         0x38, 7, 4, 0x38, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX,       0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM,     0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV,     0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_IGAIN,      0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN,      0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE1,      0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE2,      0x3a, 7, 4, 0x3a, 3, 4),
+MIX_ENT(SOUND_MIXER_LINE3,      0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
+MIX_ENT(ES18XX_MIXER_RECPCM,   0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECSPEAKER,0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECLINE,  0x6e, 7, 4, 0x6e, 3, 4),
+MIX_ENT(ES18XX_MIXER_RECMIC,   0x68, 7, 4, 0x68, 3, 4),
+MIX_ENT(ES18XX_MIXER_RECCD,    0x6a, 7, 4, 0x6a, 3, 4),
+
+MIX_ENT(ES18XX_MIXER_RECIMIX,  0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECALTPCM,        0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECRECLEV,        0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES18XX_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
+MIX_ENT(ES18XX_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
+};
+
 #ifdef __SGNXPRO__
 #if 0
 static mixer_tab sgnxpro_mix = {       /* not used anywhere */
index ac9714ff5617d415de99f2b57b0c64fe81f9ac5e..2fa95f748b355d9df16aaaa24a527ea9e08e16ad 100644 (file)
@@ -49,7 +49,7 @@ void softsynth_resample_loop(short *buf, int loops)
 #endif
                                /* Interpolation (resolution of 512 steps) */
                                {
-                                       int fract = v->ptr & 0x1f     /* 9 bits */
+                                       int fract = v->ptr & 0x1ff;     /* 9 bits */
 
                                        /* This method works with less arithmetic operations */
                                        register int v1 = v->wave[ix];
index 20d273eeaa50b0689ca0c925110ab0188c0a9d0a..84b0bf978a67e45b656d19d9424627d8ee33b9db 100644 (file)
@@ -48,6 +48,7 @@
  *                     "OSS documented" and "OSS actual" behaviour
  *    31.08.98   0.7   Fix realplayer problems - dac.count issues
  *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA
+ *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs
  *
  */
 
@@ -764,17 +765,14 @@ static void sv_update_ptr(struct sv_state *s)
                s->dma_adc.hwptr = hwptr;
                s->dma_adc.total_bytes += diff;
                s->dma_adc.count += diff;
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                               wake_up(&s->dma_adc.wait);
-               } else {
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
+                       wake_up(&s->dma_adc.wait);
+               if (!s->dma_adc.mapped) {
                        if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
                                s->enable &= ~SV_CENABLE_RE;
                                wrindir(s, SV_CIENABLE, s->enable);
                                s->dma_adc.error++;
                        }
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
                }
        }
        /* update DAC pointer */
@@ -797,7 +795,7 @@ static void sv_update_ptr(struct sv_state *s)
                                clear_advance(s);
                                s->dma_dac.endcleared = 1;
                        }
-                       if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
+                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
                                wake_up(&s->dma_dac.wait);
                }
        }
@@ -1382,27 +1380,22 @@ static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait)
        unsigned int mask = 0;
 
        VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
+       if (file->f_mode & FMODE_WRITE)
                poll_wait(file, &s->dma_dac.wait, wait);
-       if (file->f_flags & FMODE_READ)
+       if (file->f_mode & FMODE_READ)
                poll_wait(file, &s->dma_adc.wait, wait);
        spin_lock_irqsave(&s->lock, flags);
        sv_update_ptr(s);
-       if (file->f_flags & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
+       if (file->f_mode & FMODE_READ) {
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+                       mask |= POLLIN | POLLRDNORM;
        }
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                if (s->dma_dac.mapped) {
                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
                                mask |= POLLOUT | POLLWRNORM;
                } else {
-                       if ((signed)s->dma_dac.dmasize > s->dma_dac.count)
+                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
                                mask |= POLLOUT | POLLWRNORM;
                }
        }
@@ -1786,11 +1779,11 @@ static int sv_release(struct inode *inode, struct file *file)
        if (file->f_mode & FMODE_WRITE)
                drain_dac(s, file->f_flags & O_NONBLOCK);
        down(&s->open_sem);
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                stop_dac(s);
                dealloc_dmabuf(&s->dma_dac);
        }
-       if (file->f_flags & FMODE_READ) {
+       if (file->f_mode & FMODE_READ) {
                stop_adc(s);
                dealloc_dmabuf(&s->dma_adc);
        }
@@ -1923,16 +1916,16 @@ static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wa
        unsigned int mask = 0;
 
        VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
+       if (file->f_mode & FMODE_WRITE)
                poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
+       if (file->f_mode & FMODE_READ)
                poll_wait(file, &s->midi.iwait, wait);
        spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
+       if (file->f_mode & FMODE_READ) {
                if (s->midi.icnt > 0)
                        mask |= POLLIN | POLLRDNORM;
        }
-       if (file->f_flags & FMODE_WRITE) {
+       if (file->f_mode & FMODE_WRITE) {
                if (s->midi.ocnt < MIDIOUTBUF)
                        mask |= POLLOUT | POLLWRNORM;
        }
@@ -2278,7 +2271,7 @@ __initfunc(int init_sonicvibes(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "sv: version v0.8 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "sv: version v0.9 time " __TIME__ " " __DATE__ "\n");
 #if 0
        if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
index 97113a838b719fc44d73a247e4626602f3eb1ad8..1a6b79c769d4e567ee38d546859b223719608817 100644 (file)
@@ -26,6 +26,7 @@
 #ifdef CONFIG_TRIX
 
 #ifdef INCLUDE_TRIX_BOOT
+#include <linux/init.h>
 #include "trix_boot.h"
 #else
 static unsigned char *trix_boot = NULL;
index a88af3709716cb428d3f5ba3e8382e725b14a637..4b29613e58c602eaa067b71e55e14bed2fcbc3b6 100644 (file)
@@ -5,23 +5,53 @@ mainmenu_option next_comment
 comment 'Filesystems'
 
 bool    'Quota support' CONFIG_QUOTA
+tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
 
-tristate 'Minix fs support' CONFIG_MINIX_FS
-tristate 'Second extended fs support' CONFIG_EXT2_FS
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS
+fi
+tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS
+tristate 'Apple Macintosh filesystem support (experimental)' CONFIG_HFS_FS
+# msdos filesystems
+tristate 'DOS FAT fs support' CONFIG_FAT_FS
+dep_tristate '  MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
+dep_tristate '  UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
+dep_tristate '  VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
 
 tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS
 if [ "$CONFIG_ISO9660_FS" != "n" ]; then
   bool 'Microsoft Joliet CDROM extensions' CONFIG_JOLIET
 fi
 
-# msdos filesystems
-tristate 'DOS FAT fs support' CONFIG_FAT_FS
-dep_tristate 'MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
-dep_tristate 'UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
-dep_tristate 'VFAT (Windows-95) fs support' CONFIG_VFAT_FS $CONFIG_FAT_FS
-
+tristate 'Minix fs support' CONFIG_MINIX_FS
+tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS
+if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  bool '   NTFS read-write support (experimental)' CONFIG_NTFS_RW
+fi
+tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
 bool '/proc filesystem support' CONFIG_PROC_FS
+if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
+  tristate '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS
+fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS
+  if [ "$CONFIG_QNX4FS_FS" != "n" ]; then
+    bool '   QNXFS read-write support (FOR TESTING ONLY)' CONFIG_QNX4FS_RW
+  fi    
+fi
+tristate 'ROM filesystem support' CONFIG_ROMFS_FS
+tristate 'Second extended fs support' CONFIG_EXT2_FS
+tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
+tristate 'UFS filesystem support' CONFIG_UFS_FS
+
+
+
+mainmenu_option next_comment
+comment 'Network File Systems'
+
 if [ "$CONFIG_INET" = "y" ]; then
+  tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS
   tristate 'NFS filesystem support' CONFIG_NFS_FS
   if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then
     bool '   Root file system on NFS' CONFIG_ROOT_NFS
@@ -42,7 +72,6 @@ if [ "$CONFIG_INET" = "y" ]; then
       define_bool CONFIG_LOCKD n
     fi
   fi
-  tristate 'Coda filesystem support (advanced network fs)' CONFIG_CODA_FS
   tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS
   if [ "$CONFIG_SMB_FS" != "n" ]; then
     bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95
@@ -54,34 +83,23 @@ if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
     source fs/ncpfs/Config.in
   fi
 fi
-tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
 
-tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS
-if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  bool '   NTFS read-write support (experimental)' CONFIG_NTFS_RW
-fi
+endmenu
 
-tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
-tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS
-tristate 'Apple Macintosh filesystem support (experimental)' CONFIG_HFS_FS
-tristate 'ROM filesystem support' CONFIG_ROMFS_FS
-tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
 if [ "$CONFIG_AFFS_FS" != "n" ]; then
   define_bool CONFIG_AMIGA_PARTITION y
 fi
-tristate 'UFS filesystem support' CONFIG_UFS_FS
+
+mainmenu_option next_comment
+comment 'Partition Types'
+
 bool 'BSD disklabel (BSD partition tables) support' CONFIG_BSD_DISKLABEL
+bool 'Macintosh partition map support' CONFIG_MAC_PARTITION
 bool 'SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL
 bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
-if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
-  tristate '/dev/pts filesystem for Unix98 PTYs' CONFIG_DEVPTS_FS
-fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-  tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS
-  tristate 'QNX filesystem support (EXPERIMENTAL)' CONFIG_QNX4FS_FS
-  if [ "$CONFIG_QNX4FS_FS" != "n" ]; then
-    bool '   QNXFS read-write support (FOR TESTING ONLY)' CONFIG_QNX4FS_RW
-  fi    
+  bool 'Unixware slices support (EXPERIMENTAL)' CONFIG_UNIXWARE_DISKLABEL
 fi
-bool 'Macintosh partition map support' CONFIG_MAC_PARTITION
+endmenu
+
 endmenu
index 8acea3b64ab45a6dd6551ddc7dea2e56aab4874d..f1b44f1020f9ec5559611f86c29926933ce68838 100644 (file)
@@ -15,6 +15,7 @@
  *  1997-08-09 removed extension stripping, locking cleanup
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -451,7 +452,9 @@ static int proc_write_status(struct file *file, const char *buffer,
  */
 static void entry_proc_cleanup(struct binfmt_entry *e)
 {
+#ifdef CONFIG_PROC_FS
        remove_proc_entry(e->proc_name, bm_dir);
+#endif
 }
 
 /*
@@ -459,6 +462,7 @@ static void entry_proc_cleanup(struct binfmt_entry *e)
  */
 static int entry_proc_setup(struct binfmt_entry *e)
 {
+#ifdef CONFIG_PROC_FS
        if (!(e->proc_dir = create_proc_entry(e->proc_name,
                                S_IFREG | S_IRUGO | S_IWUSR, bm_dir)))
                return -ENOMEM;
@@ -466,7 +470,7 @@ static int entry_proc_setup(struct binfmt_entry *e)
        e->proc_dir->data = (void *) (e->id);
        e->proc_dir->read_proc = proc_read_status;
        e->proc_dir->write_proc = proc_write_status;
-
+#endif
        return 0;
 }
 
@@ -490,8 +494,9 @@ static void bm_modcount(struct inode *inode, int fill)
 
 int __init init_misc_binfmt(void)
 {
-       struct proc_dir_entry *status = NULL, *reg;
        int error = -ENOMEM;
+#ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *status = NULL, *reg;
 
        bm_dir = create_proc_entry("sys/fs/binfmt_misc", S_IFDIR, NULL);
        if (!bm_dir)
@@ -511,6 +516,7 @@ int __init init_misc_binfmt(void)
        if (!reg)
                goto cleanup_status;
        reg->write_proc = proc_write_register;
+#endif /* CONFIG_PROC_FS */
 
        error = register_binfmt(&misc_format);
 out:
index a013b35420948e4d858c5fdfe0d38ef95b5ea25b..db2ecc42d76780bcabf58a19222cf5ce12219fa4 100644 (file)
@@ -1836,7 +1836,8 @@ asmlinkage int sync_old_buffers(void)
                                 if (buffer_locked(bh) || !buffer_dirty(bh))
                                          continue;
                                 ndirty++;
-                                if(bh->b_flushtime > jiffies) continue;
+                                if(time_before(jiffies, bh->b_flushtime))
+                                       continue;
                                 nwritten++;
                                 next->b_count++;
                                 bh->b_count++;
index db5cca48be7698f946b85cf9e1b6f000f1be2622..2ff69850a1b562b60a2753029a940974f164985d 100644 (file)
@@ -210,11 +210,11 @@ int check_disk_change(kdev_t dev)
                return 0;
 
        printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
-               kdevname(dev));
+               bdevname(dev));
 
        sb = get_super(dev);
        if (sb && invalidate_inodes(sb))
-               printk("VFS: busy inodes on changed media..\n");
+               printk("VFS: busy inodes on changed media.\n");
 
        invalidate_buffers(dev);
 
@@ -338,8 +338,7 @@ struct inode_operations chrdev_inode_operations = {
 };
 
 /*
- * Print device name (in decimal, hexadecimal or symbolic) -
- * at present hexadecimal only.
+ * Print device name (in decimal, hexadecimal or symbolic)
  * Note: returns pointer to static data!
  */
 char * kdevname(kdev_t dev)
@@ -348,3 +347,26 @@ char * kdevname(kdev_t dev)
        sprintf(buffer, "%02x:%02x", MAJOR(dev), MINOR(dev));
        return buffer;
 }
+
+char * bdevname(kdev_t dev)
+{
+       static char buffer[32];
+       const char * name = blkdevs[MAJOR(dev)].name;
+
+       if (!name)
+               name = "unknown-block";
+
+       sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev));
+       return buffer;
+}
+
+char * cdevname(kdev_t dev)
+{
+       static char buffer[32];
+       const char * name = chrdevs[MAJOR(dev)].name;
+
+       if (!name)
+               name = "unknown-char";
+       sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev));
+       return buffer;
+}
index 52e36caea5767eb32bdd5b2e7389224cbc0e2f87..0ff5f187f76b95217d682a82c6bb1fb6109727be 100644 (file)
@@ -375,6 +375,12 @@ ssize_t fat_file_write(
                *ppos = inode->i_size;
        if (count == 0)
                return 0;
+       if (*ppos + count > 0x7FFFFFFFLL) {
+               count = 0x7FFFFFFFLL-*ppos;
+               if (!count)
+                       return -EFBIG;
+       }
+
        error = carry = 0;
        for (start = buf; count || carry; count -= size) {
                while (!(sector = fat_smap(inode,*ppos >> SECTOR_BITS)))
index 200b6049bc303aba42da3cf0c0ec23f4e234f5d6..cbc33634aa4eb3be93377aff77fc45294efe9995 100644 (file)
@@ -20,7 +20,7 @@ int max_files = NR_FILE;/* tunable */
 /* Free list management, if you are here you must have f_count == 0 */
 static struct file * free_filps = NULL;
 
-void insert_file_free(struct file *file)
+static void insert_file_free(struct file *file)
 {
        if((file->f_next = free_filps) != NULL)
                free_filps->f_pprev = &file->f_next;
@@ -40,6 +40,15 @@ static inline void put_inuse(struct file *file)
        file->f_pprev = &inuse_filps;
 }
 
+/* It does not matter which list it is on. */
+static inline void remove_filp(struct file *file)
+{
+       if(file->f_next)
+               file->f_next->f_pprev = file->f_pprev;
+       *file->f_pprev = file->f_next;
+}
+
+
 void __init file_table_init(void)
 {
        filp_cache = kmem_cache_create("filp", sizeof(struct file),
@@ -116,3 +125,25 @@ int init_private_file(struct file *filp, struct dentry *dentry, int mode)
        else
                return 0;
 }
+
+void fput(struct file *file)
+{
+       int count = file->f_count-1;
+
+       if (!count) {
+               locks_remove_flock(file);
+               __fput(file);
+               file->f_count = 0;
+               remove_filp(file);
+               insert_file_free(file);
+       } else
+               file->f_count = count;
+}
+
+void put_filp(struct file *file)
+{
+       if(--file->f_count == 0) {
+               remove_filp(file);
+               insert_file_free(file);
+       }
+}
index 0bd14f24cc08a24493d997b06e0f9a1cb182b9a4..c0b077f474cdc3a74a2e62329f1b6b5b7aca6230 100644 (file)
@@ -1,3 +1,24 @@
+1998-12-20  a sun  <asun@hecate.darksunrising.blah>
+
+       * bdelete.c (del_root): assign bthLNode and bthFNode only if the
+       root node becomes a leaf node. Disk First Aid no longer
+       complains. Norton Utilities, of course, has decided that it
+       doesn't like the root node number. bleah. i think that it might be
+       due to Norton Utilities not expecting the root node to have moved.
+
+1998-12-16  a sun  <asun@hecate.darksunrising.blah>
+
+       * sysdep.c (hfs_revalidate_dentry): fix inode dates when there's a
+       timezone change.
+
+1998-12-15  root  <root@hecate.darksunrising.blah>
+
+       * extent.c (new_extent): expand block size variables to handle
+       u32. 
+
+       * mdb.c (hfs_mdb_get): AlBlkSiz shouldn't be capped at 65535. we
+       should be able to handle much larger volumes now.
+
 1998-11-21  a sun  <asun@hecate.darksunrising.blah>
 
        * hfs_sysdep.h, hfs_fs.h: added hfs_from_utc/to_utc to deal with
index 0e47c273791f4eacd3208bb149d15856f8d5e563..c968c74b70505d53141a6e726eec50d04b279c56 100644 (file)
@@ -135,11 +135,16 @@ static int del_root(struct hfs_bnode_ref *root)
 
                tree->bthRoot = child.bn->node;
                tree->root = child.bn;
+
+               /* re-assign bthFNode and bthLNode if the new root is
+                   a leaf node. */
+               if (child.bn->ndType == ndLeafNode) {
+                       tree->bthFNode = node;
+                       tree->bthLNode = node;
+               }
                hfs_bnode_relse(&child);
 
                tree->bthRoot = node;
-               tree->bthFNode = node;
-               tree->bthLNode = node;
                --tree->bthDepth;
                tree->dirt = 1;
                if (!tree->bthDepth) {
index 1fc749f344eb1583a0341b7c3dcba0fe1cf12dc1..3c92e7defa54fb7b582101a3c749dfa68be58c64 100644 (file)
@@ -354,7 +354,7 @@ static void delete_extent(struct hfs_fork *fork, struct hfs_extent *ext)
  *   hfs_u16 ablock: the number of allocation blocks in 'fork'.
  *   hfs_u16 start: first allocation block to add to 'fork'.
  *   hfs_u16 len: the number of allocation blocks to add to 'fork'.
- *   hfs_u16 ablksz: number of sectors in an allocation block.
+ *   hfs_u32 ablksz: number of sectors in an allocation block.
  * Output Variable(s):
  *   NONE
  * Returns:
@@ -471,7 +471,7 @@ static void shrink_fork(struct hfs_fork *fork, int ablocks)
        struct hfs_mdb *mdb = fork->entry->mdb;
        struct hfs_extent *ext;
        int i, error, next, count;
-       hfs_u16 ablksz = mdb->alloc_blksz;
+       hfs_u32 ablksz = mdb->alloc_blksz;
 
        next =  (fork->psize / ablksz) - 1;
        ext = find_ext(fork, next);
@@ -530,7 +530,7 @@ static void grow_fork(struct hfs_fork *fork, int ablocks)
        struct hfs_extent *ext;
        int i, start, err;
        hfs_u16 need, len=0;
-       hfs_u16 ablksz = mdb->alloc_blksz;
+       hfs_u32 ablksz = mdb->alloc_blksz;
        hfs_u32 blocks, clumpablks;
 
        blocks = fork->psize;
@@ -681,8 +681,7 @@ int hfs_ext_compare(const struct hfs_ext_key *key1,
 void hfs_extent_adj(struct hfs_fork *fork)
 {
        if (fork) {
-               hfs_u32 blks, ablocks;
-               hfs_u16 ablksz;
+               hfs_u32 blks, ablocks, ablksz;
 
                if (fork->lsize > HFS_FORK_MAX) {
                        fork->lsize = HFS_FORK_MAX;
index 06138ab2de5807b7df1a099ddd934031072521db..824e02be5e63de6e05a15c097ef79e86ace6cfc1 100644 (file)
@@ -252,7 +252,7 @@ struct hfs_mdb {
        hfs_u16                 free_ablocks;   /* The number of unused
                                                   allocation blocks
                                                   in the filesystem */
-       hfs_u16                 alloc_blksz;    /* The number of
+       hfs_u32                 alloc_blksz;    /* The number of
                                                   512-byte blocks per
                                                   "allocation block" */
        hfs_u16                 attrib;         /* Attribute word */
index 4d997baa87f0193dde60c010ce468ee271993925..d960b3da017af25f92d29e7de4527e5dc10ade7d 100644 (file)
@@ -260,6 +260,7 @@ struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,
                memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info));
                HFS_I(inode)->magic = HFS_INO_MAGIC;
                HFS_I(inode)->entry = entry;
+               HFS_I(inode)->tz_secondswest = hfs_to_utc(0);
 
                hsb->s_ifill(inode, type);
                if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&
index c7267373199b46e341350c19329f7d58e7ead000..61070b1d7504032c937dec61106f46e65f2285d4 100644 (file)
@@ -118,7 +118,7 @@ struct hfs_mdb *hfs_mdb_get(hfs_sysmdb sys_mdb, int readonly,
        mdb->buf = buf;
        
        bs = hfs_get_hl(raw->drAlBlkSiz);
-       if (!bs || bs > HFS_USHRT_MAX || (bs & (HFS_SECTOR_SIZE-1))) {
+       if (!bs || (bs & (HFS_SECTOR_SIZE-1))) {
                hfs_warn("hfs_fs: bad allocation block size %d != 512\n", bs);
                hfs_buffer_put(buf);
                HFS_DELETE(mdb);
index c1fb812de06936eb50496df52f58277059f069ca..0524808f7af86a2e6280d18cbb2fbc96199604d5 100644 (file)
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
 
+static int hfs_revalidate_dentry(struct dentry *);
 static int hfs_hash_dentry(struct dentry *, struct qstr *);
 static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static void hfs_dentry_iput(struct dentry *, struct inode *);
 struct dentry_operations hfs_dentry_operations =
 {
-       NULL,                   /* d_validate(struct dentry *) */
+       hfs_revalidate_dentry,  /* d_revalidate(struct dentry *) */
        hfs_hash_dentry,        /* d_hash */
        hfs_compare_dentry,     /* d_compare */
        NULL,                   /* d_delete(struct dentry *) */
@@ -87,3 +88,19 @@ static void hfs_dentry_iput(struct dentry *dentry, struct inode *inode)
        entry->sys_entry[HFS_ITYPE_TO_INT(HFS_ITYPE(inode->i_ino))] = NULL;
        iput(inode);
 }
+
+static int hfs_revalidate_dentry(struct dentry *dentry)
+{
+       struct inode *inode = dentry->d_inode;
+       int diff;
+
+       /* fix up inode on a timezone change */
+       if (inode && 
+           (diff = (hfs_to_utc(0) - HFS_I(inode)->tz_secondswest))) {
+               inode->i_ctime += diff;
+               inode->i_atime += diff;
+               inode->i_mtime += diff;
+               HFS_I(inode)->tz_secondswest += diff;
+       }
+       return 1;
+}
index 027c230a8423d06d68cd310d8930b65899a93b5d..d4ab7fcc1b2c5a8f1ce6d1a85200e0d33ee2fe52 100644 (file)
@@ -92,7 +92,7 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
        /* Lock hash table */
        down(&nlm_host_sema);
 
-       if (next_gc < jiffies)
+       if (time_after(jiffies, next_gc))
                nlm_gc_hosts();
 
        for (hp = &nlm_hosts[hash]; (host = *hp); hp = &host->h_next) {
@@ -173,7 +173,7 @@ nlm_bind_host(struct nlm_host *host)
        /* If we've already created an RPC client, check whether
         * RPC rebind is required */
        if ((clnt = host->h_rpcclnt) != NULL) {
-               if (host->h_nextrebind < jiffies) {
+               if (time_after(jiffies, host->h_nextrebind)) {
                        clnt->cl_port = 0;
                        host->h_nextrebind = jiffies + NLM_HOST_REBIND;
                        dprintk("lockd: next rebind in %ld jiffies\n",
@@ -219,7 +219,7 @@ void
 nlm_rebind_host(struct nlm_host *host)
 {
        dprintk("lockd: rebind host %s\n", host->h_name);
-       if (host->h_rpcclnt && host->h_nextrebind < jiffies) {
+       if (host->h_rpcclnt && time_after(jiffies, host->h_nextrebind)) {
                host->h_rpcclnt->cl_port = 0;
                host->h_nextrebind = jiffies + NLM_HOST_REBIND;
        }
@@ -298,7 +298,7 @@ nlm_gc_hosts(void)
                q = &nlm_hosts[i];
                while ((host = *q) != NULL) {
                        if (host->h_count || host->h_inuse
-                        || host->h_expires >= jiffies) {
+                        || time_before_eq(jiffies, host->h_expires)) {
                                q = &host->h_next;
                                continue;
                        }
index 49cb39c4d46cd4e982ebbb9d0cab5a3d314fcfd7..2eac8d0253170af4a52f5e96153497b0d1d8f3d1 100644 (file)
@@ -136,7 +136,7 @@ lockd(struct svc_rqst *rqstp)
                 */
                if (!nlmsvc_grace_period) {
                        timeout = nlmsvc_retry_blocked();
-               } else if (nlmsvc_grace_period < jiffies)
+               } else if (time_after(jiffies, nlmsvc_grace_period))
                        nlmsvc_grace_period = 0;
 
                /*
index 022206bbb1b085cd219968f4dfac984bbaae177f..38982227dc872ac50e160c8d73ad2655528de670 100644 (file)
@@ -154,10 +154,10 @@ static inline struct file_lock *locks_alloc_lock(struct file_lock *fl)
 static inline void locks_free_lock(struct file_lock *fl)
 {
        if (waitqueue_active(&fl->fl_wait))
-               panic("Aarggh: attempting to free lock with active wait queue - shoot Andy");
+               panic("Attempting to free lock with active wait queue");
 
        if (fl->fl_nextblock != NULL || fl->fl_prevblock != NULL)
-               panic("Aarggh: attempting to free lock with active block list - shoot Andy");
+               panic("Attempting to free lock with active block list");
                
        kfree(fl);
        return;
index 7f0908387100526e291bbe33e485a0b1ef0e843d..2063c54c044ffe387a484e595bfaaf5597d3baec 100644 (file)
  * [10-Sep-98 Alan Modra] Another symlink change.
  */
 
-static inline char * get_page(void)
-{
-       char * res;
-       res = (char*)__get_free_page(GFP_KERNEL);
-       return res;
-}
-
-inline void putname(char * name)
-{
-       free_page((unsigned long) name); 
-}
-
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
@@ -139,7 +127,7 @@ char * getname(const char * filename)
        char *tmp, *result;
 
        result = ERR_PTR(-ENOMEM);
-       tmp = get_page();
+       tmp = __getname();
        if (tmp)  {
                int retval = do_getname(filename, tmp);
 
index 99488fca14505870ba35fd9a8e368b4eb1c75f89..4a0459cdf19e1386f0f25dc250f7f30e2aa2b668 100644 (file)
@@ -382,7 +382,12 @@ out_free_server:
 out_no_server:
        printk(KERN_ERR "ncp_read_super: could not alloc ncp_server\n");
 out_unlock:
-       put_filp(ncp_filp);
+       /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
+        * 
+        * The previously used put_filp(ncp_filp); was bogous, since
+        * it doesn't proper unlocking.
+        */
+       fput(ncp_filp);
        unlock_super(sb);
        goto out;
 
index fd3a72e2c6f3a5a4d861b74e7a15dd2917832d29..329605a12057016f825400fd77cd8328346c1b47 100644 (file)
@@ -571,11 +571,6 @@ show_dentry(&inode->i_dentry);
                        error = 0;
                }
        }
-#ifdef NFS_PARANOIA
-if (error)
-printk("nfs_lookup: %s/%s failed, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, error);
-#endif
 out:
        return error;
 }
index 8c3d91f64e8cd528431b69c454efbe8d6b4030f4..a8bf3a3a59c1dba2de3fd9b08e6008bfb2ad4c9c 100644 (file)
@@ -1001,7 +1001,7 @@ out:
         * Perform any needed housekeeping ...
         * N.B. move this into one of the daemons ...
         */
-       if (jiffies >= nfsd_next_expire) {
+       if (time_after_eq(jiffies, nfsd_next_expire)) {
                expire_old(NFSD_FILE_CACHE,  5*HZ);
                expire_old(NFSD_DIR_CACHE , 60*HZ);
                nfsd_next_expire = jiffies + 5*HZ;
index 05d8f9ea435031d8859d6c44ca0dc66bf3b2ef0f..e6564f15e6fdac299ec4c570e44a2e3de721352e 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -6,14 +6,11 @@
 
 #include <linux/mm.h>
 #include <linux/utime.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <linux/quotaops.h>
 
 #include <asm/uaccess.h>
-#include <asm/bitops.h>
 
 asmlinkage int sys_statfs(const char * path, struct statfs * buf)
 {
@@ -671,18 +668,6 @@ out:
        return ERR_PTR(error);
 }
 
-/* should probably go into sys_open() */
-static int do_open(const char * filename, int flags, int mode, int fd)
-{
-       struct file * f;
-
-       f = filp_open(filename, flags, mode);
-       if (IS_ERR(f))
-               return PTR_ERR(f);
-       fd_install(fd, f);
-       return 0;
-}
-
 /*
  * Find an empty file descriptor entry, and mark it busy.
  */
@@ -727,24 +712,25 @@ asmlinkage int sys_open(const char * filename, int flags, int mode)
        char * tmp;
        int fd, error;
 
-       lock_kernel();
-       fd = get_unused_fd();
-       if (fd < 0)
-               goto out;
-
        tmp = getname(filename);
-       error = PTR_ERR(tmp);
-       if (IS_ERR(tmp))
-               goto out_fail;
-       error = do_open(tmp, flags, mode, fd);
-       putname(tmp);
-       if (error)
-               goto out_fail;
+       fd = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
+               lock_kernel();
+               fd = get_unused_fd();
+               if (fd >= 0) {
+                       struct file * f = filp_open(tmp, flags, mode);
+                       error = PTR_ERR(f);
+                       if (IS_ERR(f))
+                               goto out_error;
+                       fd_install(fd, f);
+               }
 out:
-       unlock_kernel();
+               unlock_kernel();
+               putname(tmp);
+       }
        return fd;
 
-out_fail:
+out_error:
        put_unused_fd(fd);
        fd = error;
        goto out;
index 00fa17ed6514ded60c1391291e0e3d5c45185fdf..7b9bf0bf759393d09479411abad843d2b6ac87ef 100644 (file)
@@ -215,7 +215,8 @@ static ssize_t do_readv_writev(int type, struct file *file,
                tot_len += iov[i].iov_len;
 
        inode = file->f_dentry->d_inode;
-       ret = locks_verify_area((type == VERIFY_READ
+       /* VERIFY_WRITE actually means a read, as we write to user space */
+       ret = locks_verify_area((type == VERIFY_WRITE
                                 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
                                inode, file, file->f_pos, tot_len);
        if (ret) goto out;
index e850b7f82b4f0955adbafca1f7187497b3ecc71b..1a278911ab55e2a65597a2dc151475d3473ce7bd 100644 (file)
@@ -260,7 +260,7 @@ smb_revalidate_inode(struct dentry *dentry)
        /*
         * Check whether we've recently refreshed the inode.
         */
-       if (jiffies < inode->u.smbfs_i.oldmtime + HZ/10)
+       if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10))
        {
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n",
index 17d50c777690e34780bbb673faa7e278751f1a28..035ffa4e2a9469a764076afa2988deae322f15c6 100644 (file)
@@ -4,6 +4,12 @@
 #include <linux/config.h>
 #include <linux/types.h>
 
+/*
+ *     This file gets pulled in by asm/io.h from user space. We don't
+ *     want most of this escaping.
+ */
+#ifdef __KERNEL__
 
 /* The following structure vectors all of the I/O and IRQ manipulation
    from the generic kernel to the hardware specific backend.  */
@@ -122,4 +128,5 @@ extern int alpha_use_srm_setup;
 #endif
 #endif /* GENERIC */
 
+#endif
 #endif /* __ALPHA_MACHVEC_H */
index 47432c051ab7d6f1f1b5d805aaa0c81b88eba504..639d7b4201903ddb360de9b11287d16b0c01ee24 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/processor.h>     /* For TASK_SIZE */
 #include <asm/mmu_context.h>
 #include <asm/machvec.h>
+#include <asm/spinlock.h>      /* For the task lock */
 
 
 /* Caches aren't brain-dead on the Alpha. */
index b47281a3b90e8a47656d7296ce50264b7f1f18db..66aed19eba88a90323638d3e7bb7f8447ebdfb8f 100644 (file)
@@ -27,7 +27,7 @@ static inline void clear_active_bhs(unsigned long x)
 extern inline void init_bh(int nr, void (*routine)(void))
 {
        bh_base[nr] = routine;
-       bh_mask_count[nr] = 0;
+       atomic_set(&bh_mask_count[nr], 0);
        bh_mask |= 1 << nr;
 }
 
@@ -116,12 +116,12 @@ extern inline void end_bh_atomic(void)
 extern inline void disable_bh(int nr)
 {
        bh_mask &= ~(1 << nr);
-       bh_mask_count[nr]++;
+       atomic_inc(&bh_mask_count[nr]);
 }
 
 extern inline void enable_bh(int nr)
 {
-       if (!--bh_mask_count[nr])
+       if (atomic_dec_and_test(&bh_mask_count[nr]))
                bh_mask |= 1 << nr;
 }
 
index 63837b1953cad893cbc226e306131c8a6a86f287..28baf0b7ad61423c82ad2e5f452ed1969939dc26 100644 (file)
@@ -88,12 +88,12 @@ typedef struct {
 } spinlock_t;
 
 #if DEBUG_SPINLOCK
-#define SPIN_LOCK_UNLOCKED {0, 1, 0, 0, 0, 0}
+#define SPIN_LOCK_UNLOCKED (spinlock_t) {0, 1, 0, 0, 0, 0}
 #define spin_lock_init(x)                                              \
        ((x)->lock = 0, (x)->target_ipl = 0, (x)->debug_state = 1,      \
         (x)->previous = 0, (x)->task = 0)
 #else
-#define SPIN_LOCK_UNLOCKED     { 0 }
+#define SPIN_LOCK_UNLOCKED     (spinlock_t) { 0 }
 #define spin_lock_init(x)      ((x)->lock = 0)
 #endif
 
@@ -163,7 +163,7 @@ static inline void spin_lock(spinlock_t * lock)
 
 typedef struct { volatile int write_lock:1, read_counter:31; } rwlock_t;
 
-#define RW_LOCK_UNLOCKED { 0, 0 }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
 
 #if DEBUG_RWLOCK
 extern void write_lock(rwlock_t * lock);
index 00dd9dcc847e166750560f9fa2dccf85f087301f..09f25dc78d1a8e7aecaabccb89ed81849c1e645c 100644 (file)
@@ -127,6 +127,7 @@ extern __inline__ int __test_bit(int nr, volatile void * addr)
  */
 extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
 {
+       int d0, d1, d2;
        int res;
 
        if (!size)
@@ -142,9 +143,8 @@ extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
                "1:\tsubl %%ebx,%%edi\n\t"
                "shll $3,%%edi\n\t"
                "addl %%edi,%%edx"
-               :"=d" (res)
-               :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
-               :"ax", "cx", "di");
+               :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+               :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
        return res;
 }
 
index 8ec5f9c8d71f20c7e1457ad7e35546cdadf1f2b5..addaea876b28ed711fa789b7695a5d366bd1b71f 100644 (file)
@@ -14,7 +14,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
 
 /*
  * the same as csum_partial, but copies from src while it
@@ -24,8 +24,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
  * better 64-bit) boundary
  */
 
-unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
-                                       int *src_err_ptr, int *dst_err_ptr);
+asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+                                                  int *src_err_ptr, int *dst_err_ptr);
 
 /*
  *     Note: when you get a NULL pointer exception here this means someone
index 6413683c20cc48065f39a8e6cc1bfb9ad91d722f..0a794e306c1e6aeead8a40223b8f9f36b38e2fdf 100644 (file)
@@ -59,10 +59,14 @@ typedef struct {
 
 #undef __FD_ZERO
 #define __FD_ZERO(fdsetp) \
-               __asm__ __volatile__("cld ; rep ; stosl" \
-                       :"=m" (*(__kernel_fd_set *) (fdsetp)) \
-                       :"a" (0), "c" (__FDSET_LONGS), \
-                       "D" ((__kernel_fd_set *) (fdsetp)) :"cx","di")
+do { \
+       int __d0, __d1; \
+       __asm__ __volatile__("cld ; rep ; stosl" \
+                       :"=m" (*(__kernel_fd_set *) (fdsetp)), \
+                         "=&c" (__d0), "=&D" (__d1) \
+                       :"a" (0), "1" (__FDSET_LONGS), \
+                       "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \
+} while (0)
 
 #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
 
index 3bb933e4277a03abcdc35995dbb91b8614939b39..73c9cf9271f5fea466a2813bf177f5df84aec5a5 100644 (file)
@@ -51,7 +51,7 @@ extern __inline__ void unlock_kernel(void)
 {
        __asm__ __volatile__(
                "decl %1\n\t"
-               "jns 9f\n"
+               "jns 9f\n\t"
                spin_unlock_string
                "\n9:"
                :"=m" (__dummy_lock(&kernel_flag)),
index 65012f648da4682fde8c61ff64ca7916f2516e03..9e01b26174d45fa92e98ef86c60f43cc4b273cac 100644 (file)
@@ -35,30 +35,30 @@ extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *n
                      "a" (prev), "d" (next));                          \
 } while (0)
 
-#define _set_base(addr,base) \
-__asm__("movw %%dx,%0\n\t" \
+#define _set_base(addr,base) do { unsigned long __pr; \
+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
        "rorl $16,%%edx\n\t" \
-       "movb %%dl,%1\n\t" \
-       "movb %%dh,%2" \
-       : /* no output */ \
+       "movb %%dl,%2\n\t" \
+       "movb %%dh,%3" \
+       :"=&d" (__pr) \
        :"m" (*((addr)+2)), \
         "m" (*((addr)+4)), \
         "m" (*((addr)+7)), \
-        "d" (base) \
-       :"dx")
+         "0" (base) \
+        ); } while(0)
 
-#define _set_limit(addr,limit) \
-__asm__("movw %%dx,%0\n\t" \
+#define _set_limit(addr,limit) do { unsigned long __lr; \
+__asm__ __volatile__ ("movw %%dx,%1\n\t" \
        "rorl $16,%%edx\n\t" \
-       "movb %1,%%dh\n\t" \
+       "movb %2,%%dh\n\t" \
        "andb $0xf0,%%dh\n\t" \
        "orb %%dh,%%dl\n\t" \
-       "movb %%dl,%1" \
-       : /* no output */ \
+       "movb %%dl,%2" \
+       :"=&d" (__lr) \
        :"m" (*(addr)), \
         "m" (*((addr)+6)), \
-        "d" (limit) \
-       :"dx")
+        "0" (limit) \
+        ); } while(0)
 
 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
index dcc56f31c1665f06fc047e91b45e00954500d017..5cfa0512fe09e3ad1d953ccd0809fbebba849c8c 100644 (file)
@@ -250,13 +250,15 @@ do {                                                                      \
 
 /* Generic arbitrary sized copy.  */
 #define __copy_user(to,from,size)                                      \
+do {                                                                   \
+       int __d0, __d1;                                                 \
        __asm__ __volatile__(                                           \
                "0:     rep; movsl\n"                                   \
-               "       movl %1,%0\n"                                   \
+               "       movl %3,%0\n"                                   \
                "1:     rep; movsb\n"                                   \
                "2:\n"                                                  \
                ".section .fixup,\"ax\"\n"                              \
-               "3:     lea 0(%1,%0,4),%0\n"                            \
+               "3:     lea 0(%3,%0,4),%0\n"                            \
                "       jmp 2b\n"                                       \
                ".previous\n"                                           \
                ".section __ex_table,\"a\"\n"                           \
@@ -264,18 +266,21 @@ do {                                                                      \
                "       .long 0b,3b\n"                                  \
                "       .long 1b,2b\n"                                  \
                ".previous"                                             \
-               : "=&c"(size)                                           \
-               : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from)      \
-               : "di", "si", "memory")
+               : "=&c"(size), "=&D" (__d0), "=&S" (__d1)               \
+               : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)      \
+               : "memory");                                            \
+} while (0)
 
 #define __copy_user_zeroing(to,from,size)                              \
+do {                                                                   \
+       int __d0, __d1;                                                 \
        __asm__ __volatile__(                                           \
                "0:     rep; movsl\n"                                   \
-               "       movl %1,%0\n"                                   \
+               "       movl %3,%0\n"                                   \
                "1:     rep; movsb\n"                                   \
                "2:\n"                                                  \
                ".section .fixup,\"ax\"\n"                              \
-               "3:     lea 0(%1,%0,4),%0\n"                            \
+               "3:     lea 0(%3,%0,4),%0\n"                            \
                "4:     pushl %0\n"                                     \
                "       pushl %%eax\n"                                  \
                "       xorl %%eax,%%eax\n"                             \
@@ -289,9 +294,10 @@ do {                                                                       \
                "       .long 0b,3b\n"                                  \
                "       .long 1b,4b\n"                                  \
                ".previous"                                             \
-               : "=&c"(size)                                           \
-               : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from)      \
-               : "di", "si", "memory");
+               : "=&c"(size), "=&D" (__d0), "=&S" (__d1)               \
+               : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)      \
+               : "memory");                                            \
+} while (0)
 
 /* We let the __ versions of copy_from/to_user inline, because they're often
  * used in fast paths and have only a small space overhead.
@@ -314,6 +320,7 @@ __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 /* Optimize just a little bit when we know the size of the move. */
 #define __constant_copy_user(to, from, size)                   \
 do {                                                           \
+       int __d0, __d1;                                         \
        switch (size & 3) {                                     \
        default:                                                \
                __asm__ __volatile__(                           \
@@ -327,9 +334,9 @@ do {                                                                \
                        "       .align 4\n"                     \
                        "       .long 0b,2b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 1:                                                 \
                __asm__ __volatile__(                           \
@@ -346,9 +353,9 @@ do {                                                                \
                        "       .long 0b,3b\n"                  \
                        "       .long 1b,4b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 2:                                                 \
                __asm__ __volatile__(                           \
@@ -365,9 +372,9 @@ do {                                                                \
                        "       .long 0b,3b\n"                  \
                        "       .long 1b,4b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 3:                                                 \
                __asm__ __volatile__(                           \
@@ -387,9 +394,9 @@ do {                                                                \
                        "       .long 1b,5b\n"                  \
                        "       .long 2b,6b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        }                                                       \
 } while (0)
@@ -397,6 +404,7 @@ do {                                                                \
 /* Optimize just a little bit when we know the size of the move. */
 #define __constant_copy_user_zeroing(to, from, size)           \
 do {                                                           \
+       int __d0, __d1;                                         \
        switch (size & 3) {                                     \
        default:                                                \
                __asm__ __volatile__(                           \
@@ -416,9 +424,9 @@ do {                                                                \
                        "       .align 4\n"                     \
                        "       .long 0b,2b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 1:                                                 \
                __asm__ __volatile__(                           \
@@ -448,9 +456,9 @@ do {                                                                \
                        "       .long 0b,3b\n"                  \
                        "       .long 1b,4b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 2:                                                 \
                __asm__ __volatile__(                           \
@@ -480,9 +488,9 @@ do {                                                                \
                        "       .long 0b,3b\n"                  \
                        "       .long 1b,4b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        case 3:                                                 \
                __asm__ __volatile__(                           \
@@ -522,9 +530,9 @@ do {                                                                \
                        "       .long 1b,5b\n"                  \
                        "       .long 2b,6b\n"                  \
                        ".previous"                             \
-                       : "=c"(size)                            \
-                       : "S"(from), "D"(to), "0"(size/4)       \
-                       : "di", "si", "memory");                \
+                       : "=c"(size), "=&S" (__d0), "=&D" (__d1)\
+                       : "1"(from), "2"(to), "0"(size/4)       \
+                       : "memory");                            \
                break;                                          \
        }                                                       \
 } while (0)
index 739b225803268409dcb160356b4fb13ae8eb1e9b..e2064f07d2b4b81f5b2f19543d2c6bf6778591eb 100644 (file)
@@ -12,7 +12,7 @@ extern unsigned int local_bh_count[NR_CPUS];
 extern inline void init_bh(int nr, void (*routine)(void))
 {
        bh_base[nr] = routine;
-       bh_mask_count[nr] = 0;
+       atomic_set(&bh_mask_count[nr], 0);
        bh_mask |= 1 << nr;
 }
 
@@ -96,13 +96,13 @@ extern inline void end_bh_atomic(void)
 extern inline void disable_bh(int nr)
 {
        bh_mask &= ~(1 << nr);
-       bh_mask_count[nr]++;
+       atomic_inc(&bh_mask_count[nr]);
        synchronize_bh();
 }
 
 extern inline void enable_bh(int nr)
 {
-       if (!--bh_mask_count[nr])
+       if (atomic_dec_and_test(&bh_mask_count[nr]))
                bh_mask |= 1 << nr;
 }
 
index 5641129d7efb6813e1e70ba3ac42ff07a0067da5..e9d209791d10e34a8d064c2795dcf4ab9295f0a2 100644 (file)
@@ -10,7 +10,7 @@
 
 #define ATPORT_FIRST   1
 #define ATPORT_RESERVED        128
-#define ATPORT_LAST    255
+#define ATPORT_LAST    254 /* 254 is only legal on localtalk */ 
 #define ATADDR_ANYNET  (__u16)0
 #define ATADDR_ANYNODE (__u8)0
 #define ATADDR_ANYPORT  (__u8)0
index 0884fad2ffe2b7762e629fe9d70598285a6b555d..8fd72b507ecf0bdc8221878f242459556fbf7ef5 100644 (file)
@@ -6,7 +6,6 @@
 #define __LINUX_FILE_H
 
 extern void __fput(struct file *);
-extern void insert_file_free(struct file *file);
 
 /*
  * Check whether the specified task has the fd open. Since the task
@@ -50,34 +49,23 @@ extern inline void fd_install(unsigned int fd, struct file *file)
        current->files->fd[fd] = file;
 }
 
-/* It does not matter which list it is on. */
-extern inline void remove_filp(struct file *file)
-{
-       if(file->f_next)
-               file->f_next->f_pprev = file->f_pprev;
-       *file->f_pprev = file->f_next;
-}
-
-extern inline void fput(struct file *file)
-{
-       int count = file->f_count-1;
-
-       if (!count) {
-               locks_remove_flock(file);
-               __fput(file);
-               file->f_count = 0;
-               remove_filp(file);
-               insert_file_free(file);
-       } else
-               file->f_count = count;
-}
-
-extern inline void put_filp(struct file *file)
-{
-       if(--file->f_count == 0) {
-               remove_filp(file);
-               insert_file_free(file);
-       }
-}
+/*
+ * 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: 
+ * 
+ * Since those functions where calling other functions, it was compleatly 
+ * bogous to make them all "extern inline".
+ *
+ * The removal of this pseudo optimization saved me scandaleous:
+ *
+ *             3756 (i386 arch) 
+ *
+ * precious bytes from my kernel, even without counting all the code compiled
+ * as module!
+ *
+ * I suspect there are many other similiar "optimizations" across the
+ * kernel...
+ */
+extern void fput(struct file *file); 
+extern void put_filp(struct file *file);
 
 #endif
index 0139168ca8096e730c15cc7239cb9a3be3b70d5c..9a1684a0e269dda343325d435ce53dcfc6d250bd 100644 (file)
@@ -466,7 +466,7 @@ struct file_lock {
        } fl_u;
 };
 
-extern struct file_lock                *file_lock_table;
+extern struct file_lock                        *file_lock_table;
 
 #include <linux/fcntl.h>
 
@@ -692,7 +692,8 @@ extern int close_fp(struct file *, fl_owner_t id);
 extern struct file *filp_open(const char *, int, int);
 
 extern char * getname(const char * filename);
-extern void putname(char * name);
+#define __getname()    ((char *) __get_free_page(GFP_KERNEL))
+#define putname(name)  free_page((unsigned long)(name))
 
 extern void kill_fasync(struct fasync_struct *fa, int sig);
 extern int register_blkdev(unsigned int, const char *, struct file_operations *);
@@ -702,11 +703,16 @@ extern int blkdev_release (struct inode * inode);
 extern struct file_operations def_blk_fops;
 extern struct inode_operations blkdev_inode_operations;
 
+/* fs/devices.c */
 extern int register_chrdev(unsigned int, const char *, struct file_operations *);
 extern int unregister_chrdev(unsigned int major, const char * name);
 extern int chrdev_open(struct inode * inode, struct file * filp);
 extern struct file_operations def_chr_fops;
 extern struct inode_operations chrdev_inode_operations;
+extern char * bdevname(kdev_t dev);
+extern char * cdevname(kdev_t dev);
+extern char * kdevname(kdev_t dev);
+
 
 extern void init_fifo(struct inode * inode);
 extern struct inode_operations fifo_inode_operations;
@@ -815,8 +821,6 @@ extern struct buffer_head * get_hash_table(kdev_t, int, int);
 extern struct buffer_head * getblk(kdev_t, int, int);
 extern struct buffer_head * find_buffer(kdev_t dev, int block, int size);
 extern void ll_rw_block(int, int, struct buffer_head * bh[]);
-extern void ll_rw_page(int, kdev_t, unsigned long, char *);
-extern void ll_rw_swap_file(int, kdev_t, unsigned int *, int, char *);
 extern int is_read_only(kdev_t);
 extern void __brelse(struct buffer_head *);
 extern inline void brelse(struct buffer_head *buf)
index fe89b7e7a99e58ab70522319e06d25d810a56413..96469a0bdb63ffe3e1b34ba33d1fd28c3bcdb87f 100644 (file)
@@ -108,12 +108,19 @@ struct solaris_x86_vtoc {
 #ifdef CONFIG_BSD_DISKLABEL
 /*
  * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il>
+ * updated by Marc Espie <Marc.Espie@openbsd.org>
  */
 
-#define BSD_PARTITION          0xa5    /* Partition ID */
+#define FREEBSD_PARTITION      0xa5    /* FreeBSD Partition ID */
+#define OPENBSD_PARTITION      0xa6    /* OpenBSD Partition ID */
+#define NETBSD_PARTITION       0xa9    /* NetBSD Partition ID */
+#define BSDI_PARTITION         0xb7    /* BSDI Partition ID */
+
+/* check against BSD src/sys/sys/disklabel.h for consistency */
 
 #define BSD_DISKMAGIC  (0x82564557UL)  /* The disk magic number */
 #define BSD_MAXPARTITIONS      8
+#define OPENBSD_MAXPARTITIONS  16
 #define BSD_FS_UNUSED          0       /* disklabel unused partition entry ID */
 struct bsd_disklabel {
        __u32   d_magic;                /* the magic number */
@@ -160,6 +167,62 @@ struct bsd_disklabel {
 
 #endif /* CONFIG_BSD_DISKLABEL */
 
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+/*
+ * Unixware slices support by Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl>
+ * and Krzysztof G. Baranowski <kgb@knm.org.pl>
+ */
+
+#define UNIXWARE_PARTITION     0x63            /* Partition ID, same as */
+                                               /* GNU_HURD and SCO Unix */
+#define UNIXWARE_DISKMAGIC     (0xCA5E600DUL)  /* The disk magic number */
+#define UNIXWARE_DISKMAGIC2    (0x600DDEEEUL)  /* The slice table magic nr */
+#define UNIXWARE_NUMSLICE      16
+#define UNIXWARE_FS_UNUSED     0               /* Unused slice entry ID */
+
+struct unixware_slice {
+       __u16   s_label;        /* label */
+       __u16   s_flags;        /* permission flags */
+       __u32   start_sect;     /* starting sector */
+       __u32   nr_sects;       /* number of sectors in slice */
+};
+
+struct unixware_disklabel {
+       __u32   d_type;                 /* drive type */
+       __u32   d_magic;                /* the magic number */
+       __u32   d_version;              /* version number */
+       char    d_serial[12];           /* serial number of the device */
+       __u32   d_ncylinders;           /* # of data cylinders per device */
+       __u32   d_ntracks;              /* # of tracks per cylinder */
+       __u32   d_nsectors;             /* # of data sectors per track */
+       __u32   d_secsize;              /* # of bytes per sector */
+       __u32   d_part_start;           /* # of first sector of this partition */
+       __u32   d_unknown1[12];         /* ? */
+       __u32   d_alt_tbl;              /* byte offset of alternate table */
+       __u32   d_alt_len;              /* byte length of alternate table */
+       __u32   d_phys_cyl;             /* # of physical cylinders per device */
+       __u32   d_phys_trk;             /* # of physical tracks per cylinder */
+       __u32   d_phys_sec;             /* # of physical sectors per track */
+       __u32   d_phys_bytes;           /* # of physical bytes per sector */
+       __u32   d_unknown2;             /* ? */
+       __u32   d_unknown3;             /* ? */
+       __u32   d_pad[8];               /* pad */
+
+       struct unixware_vtoc {
+               __u32   v_magic;                /* the magic number */
+               __u32   v_version;              /* version number */
+               char    v_name[8];              /* volume name */
+               __u16   v_nslices;              /* # of slices */
+               __u16   v_unknown1;             /* ? */
+               __u32   v_reserved[10];         /* reserved */
+               struct unixware_slice
+                       v_slice[UNIXWARE_NUMSLICE];     /* slice headers */
+       } vtoc;
+
+};  /* 408 */
+
+#endif /* CONFIG_UNIXWARE_DISKLABEL */
+
 extern struct gendisk *gendisk_head;   /* linked list of disks */
 
 /*
index 45389688274164c98d5ebaefcbaedc8cc2666171..03585a08644af50608bf08e069546ce4f366a346 100644 (file)
@@ -33,6 +33,9 @@ struct hfs_inode_info {
        const struct hfs_hdr_layout     *default_layout;
        struct hfs_hdr_layout           *layout;
 
+       /* to deal with localtime ugliness */
+       int                             tz_secondswest;
+
         /* for dentry cleanup */
         void (*d_drop_op)(struct dentry *, const ino_t);
 };
index 9349f0f4970ab9698c2b56228c5c2f77d7c20799..851ff4cef5eeef7662165926ff34a3e082cef159 100644 (file)
@@ -21,6 +21,11 @@ struct ipc_perm
 #define IPC_EXCL   00002000   /* fail if key exists */
 #define IPC_NOWAIT 00004000   /* return error on wait */
 
+/* these fields are used by the DIPC package so the kernel as standard
+   should avoid using them if possible */
+   
+#define IPC_DIPC 00010000  /* make it distributed */
+#define IPC_OWN  00020000  /* this machine is the DIPC owner */
 
 /* 
  * Control commands used with semctl, msgctl and shmctl 
index c6846779b7adb70b2b874b2f1fa8b69550cc7467..8b9d6bb127ae0f470f39cbdc621fb58947738b12 100644 (file)
@@ -76,6 +76,7 @@ struct ipx_route_def
 #define SIOCAIPXITFCRT         (SIOCPROTOPRIVATE)
 #define SIOCAIPXPRISLT         (SIOCPROTOPRIVATE+1)
 #define SIOCIPXCFGDATA         (SIOCPROTOPRIVATE+2)
+#define SIOCIPXNCPCONN         (SIOCPROTOPRIVATE+3)
 
 #ifdef __KERNEL__
 #include <linux/skbuff.h>
index ad3d10baf6cb2fade74b16cb2f29da52fc0eca99..94cce874f6189b25267463333514452eec6d7c73 100644 (file)
@@ -20,6 +20,7 @@
 # endif
 #endif /* __GENKSYMS__ */
 
+#include <asm/atomic.h>
 
 /* Don't need to bring in all of uaccess.h just for this decl.  */
 struct exception_table_entry;
@@ -54,7 +55,12 @@ struct module
        const char *name;
        unsigned long size;
 
-       long usecount;
+       union
+       {
+               atomic_t usecount;
+               long pad;
+       } uc;                           /* Needs to keep its size - so says rth */
+
        unsigned long flags;            /* AUTOCLEAN et al */
 
        unsigned nsyms;
@@ -80,10 +86,10 @@ struct module
 
 struct module_info
 {
-  unsigned long addr;
-  unsigned long size;
-  unsigned long flags;
-          long usecount;
+       unsigned long addr;
+       unsigned long size;
+       unsigned long flags;
+       long usecount;
 };
 
 /* Bits of module.flags.  */
@@ -114,17 +120,17 @@ struct module_info
 
 /* Backwards compatibility definition.  */
 
-#define GET_USE_COUNT(module)  ((module)->usecount)
+#define GET_USE_COUNT(module)  (atomic_read(&(module)->uc.usecount))
 
 /* Poke the use count of a module.  */
 
 #define __MOD_INC_USE_COUNT(mod)                                       \
-       ((mod)->usecount++, (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
+       (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
 #define __MOD_DEC_USE_COUNT(mod)                                       \
-       ((mod)->usecount--, (mod)->flags |= MOD_VISITED)
+       (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
 #define __MOD_IN_USE(mod)                                              \
        (mod_member_present((mod), can_unload) && (mod)->can_unload     \
-        ? (mod)->can_unload() : (mod)->usecount)
+        ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount))
 
 /* Indirect stringification.  */
 
index 4985eef157f0e669c550ec3eb33e72e48533f003..4497eeedbe705ff52d6072f699d73852c9107660 100644 (file)
@@ -35,9 +35,11 @@ struct vfat_unicode {
 struct msdos_sb_info {
        unsigned short cluster_size; /* sectors/cluster */
        unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
-       unsigned short fat_start,fat_length; /* FAT start & length (sec.) */
-       unsigned short dir_start,dir_entries; /* root dir start & entries */
-       unsigned short data_start;   /* first data sector */
+       unsigned short fat_start;
+       unsigned long fat_length;    /* FAT start & length (sec.) */
+       unsigned long dir_start;
+       unsigned short dir_entries;  /* root dir start & entries */
+       unsigned long data_start;    /* first data sector */
        unsigned long clusters;      /* number of clusters */
        unsigned long root_cluster;  /* first cluster of the root directory */
        unsigned long fsinfo_offset; /* FAT32 fsinfo offset from start of disk */
index a5b3134bfaf607c013681e6e5c268085f14901ae..3fb2a48f682229481347ec292238b68e0a73ac48 100644 (file)
@@ -92,6 +92,7 @@ struct sem_queue {
        struct semid_ds *       sma;     /* semaphore array for operations */
        struct sembuf *         sops;    /* array of pending operations */
        int                     nsops;   /* number of operations */
+       int                     alter;   /* operation will alter semaphore */
 };
 
 /* Each task has a list of undo requests. They are executed automatically
index 9257ca698e6863325e3ea55680b0a2975a96f21f..4b7a5ca699dc06135add58928b6b744b93113c64 100644 (file)
@@ -87,6 +87,7 @@ extern int try_to_free_pages(unsigned int gfp_mask, int count);
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, unsigned long, char *, int);
 extern void rw_swap_page_nocache(int, unsigned long, char *);
+extern void rw_swap_page_nolock(int, unsigned long, char *, int);
 extern void swap_after_unlock_page (unsigned long entry);
 
 /* linux/mm/page_alloc.c */
index ce043b96cf68cd53e670cc8d0dc446b28a2ef596..bbf9d8351f21cfb5afef42ef69ad8a3ec9a9562c 100644 (file)
@@ -261,6 +261,8 @@ struct video_unit
 #define VID_HARDWARE_PERMEDIA2 14      /* Reserved for Permedia2 */
 #define VID_HARDWARE_RIVA128   15      /* Reserved for RIVA 128 */
 #define VID_HARDWARE_PLANB     16      /* PowerMac motherboard video-in */
+#define VID_HARDWARE_BROADWAY  17      /* Broadway project */
+#define VID_HARDWARE_GEMTEK    18
 
 /*
  *     Initialiser list
index a9cc39260216e606c9e8d3ff20e21b3d11a5e150..03e4b7fea831ebf608350b0eb3cdda4048d0951c 100644 (file)
@@ -128,6 +128,11 @@ struct ipx_opt {
        unsigned char           node[IPX_NODE_LEN];
 #endif
        unsigned short          type;
+/* 
+ * To handle special ncp connection-handling sockets for mars_nwe,
+ * the connection number must be stored in the socket.
+ */
+       unsigned short          ipx_ncp_conn;
 };
 #endif
 
index 5502b23811336a3911d9cbabbe319b43782c60e5..4fe4eb7eb9ec2b3c7a4c1d7d0ac590d5e4722b4a 100644 (file)
@@ -441,6 +441,7 @@ static __inline__ void *mymemset(void *s, size_t count)
 
 static __inline__ void fast_memmove(void *d, const void *s, size_t count)
 {
+  int d0, d1, d2, d3;
     if (d < s) {
 __asm__ __volatile__ (
        "cld\n\t"
@@ -452,9 +453,9 @@ __asm__ __volatile__ (
        "movsw\n"
        "2:\trep\n\t"
        "movsl"
-       : /* no output */
-       :"c"(count),"D"((long)d),"S"((long)s)
-       :"cx","di","si","memory");
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+       :"0"(count),"1"((long)d),"2"((long)s)
+       :"memory");
     } else {
 __asm__ __volatile__ (
        "std\n\t"
@@ -475,9 +476,9 @@ __asm__ __volatile__ (
        "2:\trep\n\t"
        "movsl\n\t"
        "cld"
-       : /* no output */
-       :"c"(count),"D"(count-4+(long)d),"S"(count-4+(long)s)
-       :"ax","cx","di","si","memory");
+       : "=&c" (d0), "=&D" (d1), "=&S" (d2), "=&a" (d3)
+       :"0"(count),"1"(count-4+(long)d),"2"(count-4+(long)s)
+       :"memory");
     }
 }
 
index 199a08ff7e9a0d179bc78c40dd682f0ae8e49918..8478ead6b07db54d0e46eb3371e8e3ae84375036 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
  *   see a clean way to get the old behavior with the new design.
  *   The POSIX standard and SVID should be consulted to determine
  *   what behavior is mandated.
+ *
+ * Further notes on refinement (Christoph Rohland, December 1998):
+ * - The POSIX standard says, that the undo adjustments simply should
+ *   redo. So the current implementation is o.K.
+ * - The previous code had two flaws:
+ *   1) It actively gave the semaphore to the next waiting process
+ *      sleeping on the semaphore. Since this process did not have the
+ *      cpu this led to many unnecessary context switches and bad
+ *      performance. Now we only check which process should be able to
+ *      get the semaphore and if this process wants to reduce some
+ *      semaphore value we simply wake it up without doing the
+ *      operation. So it has to try to get it later. Thus e.g. the
+ *      running process may reaquire the semaphore during the current
+ *      time slice. If it only waits for zero or increases the semaphore,
+ *      we do the operation in advance and wake it up.
+ *   2) It did not wake up all zero waiting processes. We try to do
+ *      better but only get the semops right which only wait for zero or
+ *      increase. If there are decrement operations in the operations
+ *      array we do the same as before.
  */
 
 #include <linux/malloc.h>
@@ -158,12 +177,26 @@ out:
 /* Manage the doubly linked list sma->sem_pending as a FIFO:
  * insert new queue elements at the tail sma->sem_pending_last.
  */
-static inline void insert_into_queue (struct semid_ds * sma, struct sem_queue * q)
+static inline void append_to_queue (struct semid_ds * sma,
+                                    struct sem_queue * q)
 {
        *(q->prev = sma->sem_pending_last) = q;
        *(sma->sem_pending_last = &q->next) = NULL;
 }
-static inline void remove_from_queue (struct semid_ds * sma, struct sem_queue * q)
+
+static inline void prepend_to_queue (struct semid_ds * sma,
+                                     struct sem_queue * q)
+{
+        q->next = sma->sem_pending;
+        *(q->prev = &sma->sem_pending) = q;
+        if (q->next)
+                q->next->prev = &q->next;
+        else /* sma->sem_pending_last == &sma->sem_pending */
+                sma->sem_pending_last = &q->next;
+}
+
+static inline void remove_from_queue (struct semid_ds * sma,
+                                      struct sem_queue * q)
 {
        *(q->prev) = q->next;
        if (q->next)
@@ -173,112 +206,100 @@ static inline void remove_from_queue (struct semid_ds * sma, struct sem_queue *
        q->prev = NULL; /* mark as removed */
 }
 
-/* Determine whether a sequence of semaphore operations would succeed
+/*
+ * Determine whether a sequence of semaphore operations would succeed
  * all at once. Return 0 if yes, 1 if need to sleep, else return error code.
  */
-static int try_semop (struct semid_ds * sma, struct sembuf * sops, int nsops)
-{
-       int result = 0;
-       int i = 0;
-
-       while (i < nsops) {
-               struct sembuf * sop = &sops[i];
-               struct sem * curr = &sma->sem_base[sop->sem_num];
-               if (sop->sem_op + curr->semval > SEMVMX) {
-                       result = -ERANGE;
-                       break;
-               }
-               if (!sop->sem_op && curr->semval) {
-                       if (sop->sem_flg & IPC_NOWAIT)
-                               result = -EAGAIN;
-                       else
-                               result = 1;
-                       break;
-               }
-               i++;
-               curr->semval += sop->sem_op;
-               if (curr->semval < 0) {
-                       if (sop->sem_flg & IPC_NOWAIT)
-                               result = -EAGAIN;
-                       else
-                               result = 1;
-                       break;
-               }
-       }
-       while (--i >= 0) {
-               struct sembuf * sop = &sops[i];
-               struct sem * curr = &sma->sem_base[sop->sem_num];
-               curr->semval -= sop->sem_op;
-       }
-       return result;
-}
 
-/* Actually perform a sequence of semaphore operations. Atomically. */
-/* This assumes that try_semop() already returned 0. */
-static int do_semop (struct semid_ds * sma, struct sembuf * sops, int nsops,
-                    struct sem_undo * un, int pid)
+static int try_atomic_semop (struct semid_ds * sma, struct sembuf * sops,
+                             int nsops, struct sem_undo *un, int pid,
+                             int do_undo)
 {
-       int i;
+       int result, sem_op;
+       struct sembuf *sop;
+       struct sem * curr;
 
-       for (i = 0; i < nsops; i++) {
-               struct sembuf * sop = &sops[i];
-               struct sem * curr = &sma->sem_base[sop->sem_num];
-               if (sop->sem_op + curr->semval > SEMVMX) {
-                       printk("do_semop: race\n");
-                       break;
-               }
-               if (!sop->sem_op) {
-                       if (curr->semval) {
-                               printk("do_semop: race\n");
-                               break;
-                       }
-               } else {
-                       curr->semval += sop->sem_op;
-                       if (curr->semval < 0) {
-                               printk("do_semop: race\n");
-                               break;
-                       }
-                       if (sop->sem_flg & SEM_UNDO)
-                               un->semadj[sop->sem_num] -= sop->sem_op;
-               }
-               curr->sempid = pid;
+       for (sop = sops; sop < sops + nsops; sop++) {
+               curr = sma->sem_base + sop->sem_num;
+               sem_op = sop->sem_op;
+
+               if (!sem_op && curr->semval)
+                       goto would_block;
+
+               curr->sempid = (curr->sempid << 16) | pid;
+               curr->semval += sem_op;
+               if (sop->sem_flg & SEM_UNDO)
+                       un->semadj[sop->sem_num] -= sem_op;
+
+               if (curr->semval < 0)
+                       goto would_block;
+               if (curr->semval > SEMVMX)
+                       goto out_of_range;
        }
-       sma->sem_otime = CURRENT_TIME;
 
-       /* Previous implementation returned the last semaphore's semval.
-        * This is wrong because we may not have checked read permission,
-        * only write permission.
-        */
+        if (do_undo)
+        {
+                sop--;
+                result = 0;
+                goto undo;
+        }
+
+       sma->sem_otime = CURRENT_TIME;
        return 0;
+
+out_of_range:
+       result = -ERANGE;
+       goto undo;
+
+would_block:
+       if (sop->sem_flg & IPC_NOWAIT)
+               result = -EAGAIN;
+       else
+               result = 1;
+
+undo:
+        while (sop >= sops) {
+               curr = sma->sem_base + sop->sem_num;
+               curr->semval -= sop->sem_op;
+               curr->sempid >>= 16;
+
+               if (sop->sem_flg & SEM_UNDO)
+                       un->semadj[sop->sem_num] += sop->sem_op;
+               sop--;
+       }
+
+       return result;
 }
 
 /* Go through the pending queue for the indicated semaphore
- * looking for tasks that can be completed. Keep cycling through
- * the queue until a pass is made in which no process is woken up.
+ * looking for tasks that can be completed.
  */
 static void update_queue (struct semid_ds * sma)
 {
-       int wokeup, error;
+       int error;
        struct sem_queue * q;
 
-       do {
-               wokeup = 0;
-               for (q = sma->sem_pending; q; q = q->next) {
-                       error = try_semop(sma, q->sops, q->nsops);
-                       /* Does q->sleeper still need to sleep? */
-                       if (error > 0)
-                               continue;
-                       /* Perform the operations the sleeper was waiting for */
-                       if (!error)
-                               error = do_semop(sma, q->sops, q->nsops, q->undo, q->pid);
-                       q->status = error;
-                       /* Remove it from the queue */
-                       remove_from_queue(sma,q);
-                       /* Wake it up */
-                       wake_up_interruptible(&q->sleeper); /* doesn't sleep! */
-                       wokeup++;
-               }
-       } while (wokeup);
+        for (q = sma->sem_pending; q; q = q->next) {
+                        
+                if (q->status == 1)
+                        return; /* wait for other process */
+
+                error = try_atomic_semop(sma, q->sops, q->nsops,
+                                         q->undo, q->pid, q->alter);
+
+                /* Does q->sleeper still need to sleep? */
+                if (error <= 0) {
+                                /* Found one, wake it up */
+                        wake_up_interruptible(&q->sleeper);
+                        if (error == 0 && q->alter) {
+                                /* if q-> alter let it self try */
+                                q->status = 1;
+                                return;
+                        }
+                        q->status = error;
+                        remove_from_queue(sma,q);
+                }
+        }
 }
 
 /* The following counts are associated to each semaphore:
@@ -460,7 +481,7 @@ asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
                        goto out;
                switch (cmd) {
                case GETVAL : err = curr->semval; goto out;
-               case GETPID : err = curr->sempid; goto out;
+               case GETPID : err = curr->sempid & 0xffff; goto out;
                case GETNCNT: err = count_semncnt(sma,semnum); goto out;
                case GETZCNT: err = count_semzcnt(sma,semnum); goto out;
                case GETALL:
@@ -582,11 +603,12 @@ out:
 
 asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
 {
-       int i, id, size, error = -EINVAL;
+       int id, size, error = -EINVAL;
        struct semid_ds *sma;
        struct sembuf sops[SEMOPM], *sop;
        struct sem_undo *un;
-       int undos = 0, alter = 0;
+       int undos = 0, decrease = 0, alter = 0;
+       struct sem_queue queue;
 
        lock_kernel();
        if (nsops < 1 || semid < 0)
@@ -595,8 +617,6 @@ asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
        if (nsops > SEMOPM)
                goto out;
        error = -EFAULT;
-       if (!tsops)
-               goto out;
        if (copy_from_user (sops, tsops, nsops * sizeof(*tsops)))
                goto out;
        id = (unsigned int) semid % SEMMNI;
@@ -606,22 +626,23 @@ asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
        error = -EIDRM;
        if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI)
                goto out;
-       for (i = 0; i < nsops; i++) {
-               sop = &sops[i];
+
                error = -EFBIG;
+       for (sop = sops; sop < sops + nsops; sop++) {
                if (sop->sem_num >= sma->sem_nsems)
                        goto out;
                if (sop->sem_flg & SEM_UNDO)
                        undos++;
-               if (sop->sem_op)
-                       alter++;
+               if (sop->sem_op < 0)
+                       decrease = 1;
+                if (sop->sem_op > 0)
+                        alter = 1;
        }
+        alter |= decrease;
+
        error = -EACCES;
        if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO))
                goto out;
-       error = try_semop(sma, sops, nsops);
-       if (error < 0)
-               goto out;
        if (undos) {
                /* Make sure we have an undo structure
                 * for this process and this semaphore set.
@@ -646,40 +667,59 @@ asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
                }
        } else
                un = NULL;
-       if (error == 0) {
-               /* the operations go through immediately */
-               error = do_semop(sma, sops, nsops, un, current->pid);
-               /* maybe some queued-up processes were waiting for this */
-               update_queue(sma);
-               goto out;
-       } else {
-               /* We need to sleep on this operation, so we put the current
-                * task into the pending queue and go to sleep.
-                */
-               struct sem_queue queue;
-
-               queue.sma = sma;
-               queue.sops = sops;
-               queue.nsops = nsops;
-               queue.undo = un;
-               queue.pid = current->pid;
-               queue.status = 0;
-               insert_into_queue(sma,&queue);
-               queue.sleeper = NULL;
-               current->semsleeping = &queue;
-               interruptible_sleep_on(&queue.sleeper);
-               current->semsleeping = NULL;
-               /* When we wake up, either the operation is finished,
-                * or some kind of error happened.
-                */
-               if (!queue.prev) {
-                       /* operation is finished, update_queue() removed us */
-                       error = queue.status;
-               } else {
-                       remove_from_queue(sma,&queue);
-                       error = -EINTR;
-               }
-       }
+
+       error = try_atomic_semop (sma, sops, nsops, un, current->pid, 0);
+       if (error <= 0)
+                goto update;
+
+        /* We need to sleep on this operation, so we put the current
+         * task into the pending queue and go to sleep.
+         */
+                
+        queue.sma = sma;
+        queue.sops = sops;
+        queue.nsops = nsops;
+        queue.undo = un;
+        queue.pid = current->pid;
+        queue.alter = decrease;
+        current->semsleeping = &queue;
+        if (alter)
+                append_to_queue(sma ,&queue);
+        else
+                prepend_to_queue(sma ,&queue);
+
+        for (;;) {
+                queue.status = -EINTR;
+                queue.sleeper = NULL;
+                interruptible_sleep_on(&queue.sleeper);
+
+                /*
+                 * If queue.status == 1 we where woken up and
+                 * have to retry else we simply return.
+                 * If an interrupt occured we have to clean up the
+                 * queue
+                 *
+                 */
+                if (queue.status == 1)
+                {
+                        error = try_atomic_semop (sma, sops, nsops, un,
+                                                  current->pid,0);
+                        if (error <= 0) 
+                                break;
+                } else {
+                        error = queue.status;;
+                        if (queue.prev) /* got Interrupt */
+                                break;
+                        /* Everything done by update_queue */
+                        current->semsleeping = NULL;
+                        goto out;
+                }
+        }
+        current->semsleeping = NULL;
+        remove_from_queue(sma,&queue);
+update:
+        if (alter)
+                update_queue (sma);
 out:
        unlock_kernel();
        return error;
index 9e3dedb90ba705681408a132a2359526c2773b30..2c1b2312a91d81a7554322a2536958cc80f48e58 100644 (file)
@@ -109,7 +109,6 @@ EXPORT_SYMBOL(vmtruncate);
 EXPORT_SYMBOL(update_atime);
 EXPORT_SYMBOL(get_super);
 EXPORT_SYMBOL(getname);
-EXPORT_SYMBOL(putname);
 EXPORT_SYMBOL(__fput);
 EXPORT_SYMBOL(iget);
 EXPORT_SYMBOL(iput);
@@ -129,7 +128,7 @@ EXPORT_SYMBOL(d_path);
 EXPORT_SYMBOL(__mark_inode_dirty);
 EXPORT_SYMBOL(get_empty_filp);
 EXPORT_SYMBOL(init_private_file);
-EXPORT_SYMBOL(insert_file_free);
+EXPORT_SYMBOL(fput);
 EXPORT_SYMBOL(check_disk_change);
 EXPORT_SYMBOL(invalidate_buffers);
 EXPORT_SYMBOL(invalidate_inodes);
@@ -161,7 +160,6 @@ EXPORT_SYMBOL(posix_lock_file);
 EXPORT_SYMBOL(posix_test_lock);
 EXPORT_SYMBOL(posix_block_lock);
 EXPORT_SYMBOL(posix_unblock_lock);
-EXPORT_SYMBOL(locks_remove_flock);
 EXPORT_SYMBOL(dput);
 EXPORT_SYMBOL(get_cached_page);
 EXPORT_SYMBOL(put_cached_page);
index 59884d8e2a62b1d5eda4e5c0bc72382275d96a38..c5591db7f7774727ecac6eb0b8bac65556339b07 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
 #include <asm/pgtable.h>
+#include <linux/init.h>
 
 /*
  * Originally by Anonymous (as far as I know...)
@@ -30,7 +31,7 @@ static struct module kernel_module =
        NULL,                   /* next */
        "",                     /* name */
        0,                      /* size */
-       1,                      /* usecount */
+       {ATOMIC_INIT(1)},       /* usecount */
        MOD_RUNNING,            /* flags */
        0,                      /* nsyms -- to filled in in init_modules */
        0,                      /* ndeps */
@@ -56,7 +57,7 @@ static void free_module(struct module *, int tag_freed);
  * Called at boot time
  */
 
-void init_modules(void)
+__initfunc(void init_modules(void))
 {
        kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
 
@@ -328,13 +329,13 @@ sys_init_module(const char *name_user, struct module *mod_user)
        put_mod_name(name);
 
        /* Initialize the module.  */
-       mod->usecount = 1;
+       atomic_set(&mod->uc.usecount,1);
        if (mod->init && mod->init() != 0) {
-               mod->usecount = 0;
+               atomic_set(&mod->uc.usecount,0);
                error = -EBUSY;
                goto err0;
        }
-       mod->usecount--;
+       atomic_dec(&mod->uc.usecount);
 
        /* And set it running.  */
        mod->flags |= MOD_RUNNING;
@@ -614,7 +615,7 @@ qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
                info.size = mod->size;
                info.flags = mod->flags;
                info.usecount = (mod_member_present(mod, can_unload)
-                                && mod->can_unload ? -1 : mod->usecount);
+                                && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
 
                if (copy_to_user(buf, &info, sizeof(struct module_info)))
                        return -EFAULT;
@@ -853,7 +854,7 @@ int get_module_list(char *p)
                        len = sprintf(tmpstr, "%4ld",
                                      (mod_member_present(mod, can_unload)
                                       && mod->can_unload
-                                      ? -1 : mod->usecount));
+                                      ? -1L : (long)atomic_read(&mod->uc.usecount)));
                        safe_copy_str(tmpstr, len);
                }
 
index c8c297180888488cf74655e4583952ddbf7107ca..bd3746995d33e312735df69557609d367a6de26e 100644 (file)
@@ -7,6 +7,11 @@
  *  1996-12-23  Modified by Dave Grothe to fix bugs in semaphores and
  *              make semaphores SMP safe
  *  1997-01-28  Modified by Finn Arne Gangstad to make timers scale better.
+ *  1998-11-19 Implemented schedule_timeout() and related stuff
+ *             by Andrea Arcangeli
+ *  1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
+ *             serialize accesses to xtime/lost_ticks).
+ *                             Copyright (C) 1998  Andrea Arcangeli
  */
 
 /*
@@ -149,6 +154,7 @@ static inline void add_to_runqueue(struct task_struct * p)
        init_task.next_run = p;
        p->next_run = next;
        next->prev_run = p;
+       nr_running++;
 }
 
 static inline void del_from_runqueue(struct task_struct * p)
@@ -227,7 +233,6 @@ void wake_up_process(struct task_struct * p)
        if (!p->next_run) {
                add_to_runqueue(p);
                reschedule_idle(p);
-               nr_running++;
        }
        spin_unlock_irqrestore(&runqueue_lock, flags);
 }
@@ -437,23 +442,6 @@ signed long schedule_timeout(signed long timeout)
        struct timer_list timer;
        unsigned long expire;
 
-       /*
-        * PARANOID.
-        */
-       if (current->state == TASK_UNINTERRUPTIBLE)
-       {
-               printk(KERN_WARNING "schedule_timeout: task not interrutible "
-                      "from %p\n", __builtin_return_address(0));
-               /*
-                * We don' t want to interrupt a not interruptible task
-                * risking to cause corruption. Better a a deadlock ;-).
-                */
-               timeout = MAX_SCHEDULE_TIMEOUT;
-       }
-
-       /*
-        * Here we start for real.
-        */
        switch (timeout)
        {
        case MAX_SCHEDULE_TIMEOUT:
@@ -594,10 +582,12 @@ asmlinkage void schedule(void)
 
 #ifdef __SMP__
        next->has_cpu = 1;
-       next->processor = this_cpu;
 #endif
 
        if (prev != next) {
+#ifdef __SMP__
+               next->processor = this_cpu;
+#endif
                kstat.context_swtch++;
                get_mmu_context(next);
                switch_to(prev,next);
@@ -1189,13 +1179,21 @@ static void update_process_times(unsigned long ticks, unsigned long system)
 volatile unsigned long lost_ticks = 0;
 static unsigned long lost_ticks_system = 0;
 
+/*
+ * This spinlock protect us from races in SMP while playing with xtime. -arca
+ */
+rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
+
 static inline void update_times(void)
 {
        unsigned long ticks;
-       unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       /*
+        * update_times() is run from the raw timer_bh handler so we
+        * just know that the irqs are locally enabled and so we don't
+        * need to save/restore the flags of the local CPU here. -arca
+        */
+       write_lock_irq(&xtime_lock);
 
        ticks = lost_ticks;
        lost_ticks = 0;
@@ -1206,12 +1204,12 @@ static inline void update_times(void)
 
                calc_load(ticks);
                update_wall_time(ticks);
-               restore_flags(flags);
+               write_unlock_irq(&xtime_lock);
                
                update_process_times(ticks, system);
 
        } else
-               restore_flags(flags);
+               write_unlock_irq(&xtime_lock);
 }
 
 static void timer_bh(void)
index f23fd80891b9d3ea0af35d508f6ef704fc48886b..7564d2ee117408e6ec238af6418a22d38aa012e3 100644 (file)
@@ -7,6 +7,7 @@
  *  Asynchronous swapping added 30.12.95. Stephen Tweedie
  *  Removed race in async swapping. 14.4.1996. Bruno Haible
  *  Add swap of shared pages through the page cache. 20.2.1998. Stephen Tweedie
+ *  Always use brw_page, life becomes simpler. 12 May 1998 Eric Biederman
  */
 
 #include <linux/mm.h>
@@ -15,8 +16,6 @@
 #include <linux/locks.h>
 #include <linux/swapctl.h>
 
-#include <asm/dma.h>
-#include <asm/uaccess.h> /* for copy_to/from_user */
 #include <asm/pgtable.h>
 
 static struct wait_queue * lock_queue = NULL;
@@ -24,8 +23,6 @@ static struct wait_queue * lock_queue = NULL;
 /*
  * Reads or writes a swap page.
  * wait=1: start I/O and wait for completion. wait=0: start asynchronous I/O.
- * All IO to swap files (as opposed to swap partitions) is done
- * synchronously.
  *
  * Important prevention of race condition: the caller *must* atomically 
  * create a unique swap cache entry for this swap page before calling
@@ -38,21 +35,22 @@ static struct wait_queue * lock_queue = NULL;
  * that shared pages stay shared while being swapped.
  */
 
-void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
+static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, int wait)
 {
        unsigned long type, offset;
        struct swap_info_struct * p;
-       struct page *page = mem_map + MAP_NR(buf);
+       int zones[PAGE_SIZE/512];
+       int zones_used;
+       kdev_t dev;
+       int block_size;
 
 #ifdef DEBUG_SWAP
        printk ("DebugVM: %s_swap_page entry %08lx, page %p (count %d), %s\n",
                (rw == READ) ? "read" : "write", 
-               entry, buf, atomic_read(&page->count),
+               entry, (char *) page_address(page), atomic_read(&page->count),
                wait ? "wait" : "nowait");
 #endif
 
-       if (page->inode && page->inode != &swapper_inode)
-               panic ("Tried to swap a non-swapper page");
        type = SWP_TYPE(entry);
        if (type >= nr_swapfiles) {
                printk("Internal error: bad swap-device\n");
@@ -85,13 +83,27 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                printk(KERN_ERR "VM: swap page is unlocked\n");
                return;
        }
-       
-       /* Make sure we are the only process doing I/O with this swap page. */
-       while (test_and_set_bit(offset,p->swap_lockmap)) {
-               run_task_queue(&tq_disk);
-               sleep_on(&lock_queue);
+
+       if (PageSwapCache(page)) {
+               /* Make sure we are the only process doing I/O with this swap page. */
+               while (test_and_set_bit(offset,p->swap_lockmap)) {
+                       run_task_queue(&tq_disk);
+                       sleep_on(&lock_queue);
+               }
+
+               /* 
+                * Make sure that we have a swap cache association for this
+                * page.  We need this to find which swap page to unlock once
+                * the swap IO has completed to the physical page.  If the page
+                * is not already in the cache, just overload the offset entry
+                * as if it were: we are not allowed to manipulate the inode
+                * hashing for locked pages.
+                */
+               if (page->offset != entry) {
+                       printk ("swap entry mismatch");
+                       return;
+               }
        }
-       
        if (rw == READ) {
                clear_bit(PG_uptodate, &page->flags);
                kstat.pswpin++;
@@ -99,54 +111,25 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                kstat.pswpout++;
 
        atomic_inc(&page->count);
-       /* 
-        * Make sure that we have a swap cache association for this
-        * page.  We need this to find which swap page to unlock once
-        * the swap IO has completed to the physical page.  If the page
-        * is not already in the cache, just overload the offset entry
-        * as if it were: we are not allowed to manipulate the inode
-        * hashing for locked pages.
-        */
-       if (!PageSwapCache(page)) {
-               printk(KERN_ERR "VM: swap page is not in swap cache\n");
-               return;
-       }
-       if (page->offset != entry) {
-               printk (KERN_ERR "VM: swap entry mismatch\n");
-               return;
-       }
-
        if (p->swap_device) {
-               if (!wait) {
-                       set_bit(PG_free_after, &page->flags);
-                       set_bit(PG_decr_after, &page->flags);
-                       set_bit(PG_swap_unlock_after, &page->flags);
-                       atomic_inc(&nr_async_pages);
-               }
-               ll_rw_page(rw,p->swap_device,offset,buf);
-               /*
-                * NOTE! We don't decrement the page count if we
-                * don't wait - that will happen asynchronously
-                * when the IO completes.
-                */
-               if (!wait)
-                       return;
-               wait_on_page(page);
+               zones[0] = offset;
+               zones_used = 1;
+               dev = p->swap_device;
+               block_size = PAGE_SIZE;
        } else if (p->swap_file) {
                struct inode *swapf = p->swap_file->d_inode;
-               unsigned int zones[PAGE_SIZE/512];
                int i;
                if (swapf->i_op->bmap == NULL
                        && swapf->i_op->smap != NULL){
                        /*
-                               With MS-DOS, we use msdos_smap which return
+                               With MS-DOS, we use msdos_smap which returns
                                a sector number (not a cluster or block number).
                                It is a patch to enable the UMSDOS project.
                                Other people are working on better solution.
 
                                It sounds like ll_rw_swap_file defined
-                               it operation size (sector size) based on
-                               PAGE_SIZE and the number of block to read.
+                               its operation size (sector size) based on
+                               PAGE_SIZE and the number of blocks to read.
                                So using bmap or smap should work even if
                                smap will require more blocks.
                        */
@@ -159,39 +142,72 @@ void rw_swap_page(int rw, unsigned long entry, char * buf, int wait)
                                        return;
                                }
                        }
+                       block_size = 512;
                }else{
                        int j;
                        unsigned int block = offset
                                << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
 
-                       for (i=0, j=0; j< PAGE_SIZE ; i++, j +=swapf->i_sb->s_blocksize)
+                       block_size = swapf->i_sb->s_blocksize;
+                       for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size)
                                if (!(zones[i] = bmap(swapf,block++))) {
                                        printk("rw_swap_page: bad swap file\n");
                                        return;
                                }
+                       zones_used = i;
+                       dev = swapf->i_dev;
                }
-               ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
-               /* Unlike ll_rw_page, ll_rw_swap_file won't unlock the
-                  page for us. */
-               clear_bit(PG_locked, &page->flags);
-               wake_up(&page->wait);
-       } else
+       } else {
                printk(KERN_ERR "rw_swap_page: no swap file or device\n");
+               /* Do some cleaning up so if this ever happens we can hopefully
+                * trigger controlled shutdown.
+                */
+               if (PageSwapCache(page)) {
+                       if (!test_and_clear_bit(offset,p->swap_lockmap))
+                               printk("swap_after_unlock_page: lock already cleared\n");
+                       wake_up(&lock_queue);
+               }
+               atomic_dec(&page->count);
+               return;
+       }
+       if (!wait) {
+               set_bit(PG_decr_after, &page->flags);
+               atomic_inc(&nr_async_pages);
+       }
+       if (PageSwapCache(page)) {
+               /* only lock/unlock swap cache pages! */
+               set_bit(PG_swap_unlock_after, &page->flags);
+       }
+       set_bit(PG_free_after, &page->flags);
 
+       /* block_size == PAGE_SIZE/zones_used */
+       brw_page(rw, page, dev, zones, block_size, 0);
+       /* Note! For consistency we do all of the logic,
+        * decrementing the page count, and unlocking the page in the
+        * swap lock map - in the IO completion handler.
+        */
+       if (!wait) 
+               return;
+       wait_on_page(page);
        /* This shouldn't happen, but check to be sure. */
-       if (atomic_read(&page->count) == 1)
+       if (atomic_read(&page->count) == 0)
                printk(KERN_ERR "rw_swap_page: page unused while waiting!\n");
-       atomic_dec(&page->count);
-       if (offset && !test_and_clear_bit(offset,p->swap_lockmap))
-               printk(KERN_ERR "rw_swap_page: lock already cleared\n");
-       wake_up(&lock_queue);
+
 #ifdef DEBUG_SWAP
        printk ("DebugVM: %s_swap_page finished on page %p (count %d)\n",
                (rw == READ) ? "read" : "write", 
-               buf, atomic_read(&page->count));
+               (char *) page_adddress(page), 
+               atomic_read(&page->count));
 #endif
 }
 
+/* Note: We could remove this totally asynchronous function,
+ * and improve swap performance, and remove the need for the swap lock map,
+ * by not removing pages from the swap cache until after I/O has been
+ * processed and letting remove_from_page_cache decrement the swap count
+ * just before it removes the page from the page cache.
+ */
 /* This is run when asynchronous page I/O has completed. */
 void swap_after_unlock_page (unsigned long entry)
 {
@@ -214,6 +230,35 @@ void swap_after_unlock_page (unsigned long entry)
        wake_up(&lock_queue);
 }
 
+/* A simple wrapper so the base function doesn't need to enforce
+ * that all swap pages go through the swap cache!
+ */
+void rw_swap_page(int rw, unsigned long entry, char *buf, int wait)
+{
+       struct page *page = mem_map + MAP_NR(buf);
+
+       if (page->inode && page->inode != &swapper_inode)
+               panic ("Tried to swap a non-swapper page");
+
+       /*
+        * Make sure that we have a swap cache association for this
+        * page.  We need this to find which swap page to unlock once
+        * the swap IO has completed to the physical page.  If the page
+        * is not already in the cache, just overload the offset entry
+        * as if it were: we are not allowed to manipulate the inode
+        * hashing for locked pages.
+        */
+       if (!PageSwapCache(page)) {
+               printk("VM: swap page is not in swap cache\n");
+               return;
+       }
+       if (page->offset != entry) {
+               printk ("swap entry mismatch");
+               return;
+       }
+       rw_swap_page_base(rw, entry, page, wait);
+}
+
 /*
  * Setting up a new swap file needs a simple wrapper just to read the 
  * swap signature.  SysV shared memory also needs a simple wrapper.
@@ -242,33 +287,23 @@ void rw_swap_page_nocache(int rw, unsigned long entry, char *buffer)
        clear_bit(PG_swap_cache, &page->flags);
 }
 
-
-
 /*
- * Swap partitions are now read via brw_page.  ll_rw_page is an
- * asynchronous function now --- we must call wait_on_page afterwards
- * if synchronous IO is required.  
+ * shmfs needs a version that doesn't put the page in the page cache!
+ * The swap lock map insists that pages be in the page cache!
+ * Therefore we can't use it.  Later when we can remove the need for the
+ * lock map and we can reduce the number of functions exported.
  */
-void ll_rw_page(int rw, kdev_t dev, unsigned long offset, char * buffer)
+void rw_swap_page_nolock(int rw, unsigned long entry, char *buffer, int wait)
 {
-       int block = offset;
-       struct page *page;
-
-       switch (rw) {
-               case READ:
-                       break;
-               case WRITE:
-                       if (is_read_only(dev)) {
-                               printk("Can't page to read-only device %s\n",
-                                       kdevname(dev));
-                               return;
-                       }
-                       break;
-               default:
-                       panic("ll_rw_page: bad block dev cmd, must be R/W");
+       struct page *page = mem_map + MAP_NR((unsigned long) buffer);
+       
+       if (!PageLocked(page)) {
+               printk("VM: rw_swap_page_nolock: page not locked!\n");
+               return;
+       }
+       if (PageSwapCache(page)) {
+               printk ("VM: rw_swap_page_nolock: page in swap cache!\n");
+               return;
        }
-       page = mem_map + MAP_NR(buffer);
-       if (!PageLocked(page))
-               panic ("ll_rw_page: page not already locked");
-       brw_page(rw, page, dev, &block, PAGE_SIZE, 0);
+       rw_swap_page_base(rw, entry, page, wait);
 }
index 74540951f4b31744f1ee8d17d6098a2ae417a8f7..6d59b233840744b555692ccd30ca076ad6594834 100644 (file)
@@ -294,7 +294,7 @@ static void aarp_expire_timer(struct aarp_entry **n)
        while((*n)!=NULL)
        {
                /* Expired ? */
-               if((*n)->expires_at < jiffies)
+               if(time_after(jiffies, (*n)->expires_at))
                {
                        t= *n;
                        *n=(*n)->next;
index c47f83263492562d08201d9e15e3e416a9121a82..ebb381b52251d95ea4f66fa41f5b14bd5af8a7e3 100644 (file)
  *                                             AppleTalk drivers, cleaned it.
  *             Rob Newberry            :       Added proxy AARP and AARP proc fs, 
  *                                             moved probing to AARP module.
+ *              Adrian Sun/ 
+ *              Michael Zuelsdorff      :       fix for net.0 packets. don't 
+ *                                              allow illegal ether/tokentalk
+ *                                              port assignment. we lose a 
+ *                                              valid localtalk port as a 
+ *                                              result.
+ *              
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
  *             as published by the Free Software Foundation; either version
  *             2 of the License, or (at your option) any later version.
- *
+ * 
  */
 
 #include <linux/config.h>
@@ -141,7 +148,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa
                        continue;
                }
 
-               if(to->sat_addr.s_net == 0
+               if(to->sat_addr.s_net == ATADDR_ANYNET
                        && to->sat_addr.s_node == ATADDR_BCAST
                        && s->protinfo.af_at.src_net == atif->address.s_net)
                {
@@ -156,7 +163,14 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa
                        break;
                }
 
-               /* XXXX.0 */
+               /* XXXX.0 -- we got a request for this router. make sure
+                * that the node is appropriately set. */
+               if (to->sat_addr.s_node == ATADDR_ANYNODE &&
+                   to->sat_addr.s_net != ATADDR_ANYNET &&
+                   atif->address.s_node == s->protinfo.af_at.src_node) {
+                       to->sat_addr.s_node = atif->address.s_node;
+                       break; 
+               }
        }
 
        return (s);
@@ -502,6 +516,12 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
                        && iface->address.s_net==net 
                        && !(iface->status & ATIF_PROBE))
                        return (iface);
+
+               /* XXXX.0 -- net.0 returns the iface associated with net */
+               if ((node==ATADDR_ANYNODE) && (net != ATADDR_ANYNET) &&
+                   (ntohs(iface->nets.nr_firstnet) <= ntohs(net)) &&
+                   (ntohs(net) <= ntohs(iface->nets.nr_lastnet)))
+                       return (iface);
        }
 
        return (NULL);
index b648ec4a8624c9fe2f77e2ad9c748afe7c74d06d..e86b8a54dac356e34083f8539bdd6b740d6d6c21 100644 (file)
@@ -1539,7 +1539,7 @@ static inline int mcast_quench(struct fdb *f)
                f->mcast_timer = jiffies;
        else {
                if(f->mcast_count > max_mcast_per_period) {
-                       if(jiffies > (f->mcast_timer + mcast_hold_time))
+                       if(time_after(jiffies, f->mcast_timer + mcast_hold_time))
                                f->mcast_count = 0;
                        else    return 1;
                }
index b40c35d00c3dc54fd5e9e0be940ed17055ac2765..1ced6e3c04ed582023202789fb1124451a4254d1 100644 (file)
@@ -477,7 +477,7 @@ int ipv6_unload(void)
 {
        if (!unloadable) return 1;
        /* We keep internally 3 raw sockets */
-       return __this_module.usecount - 3;
+       return atomic_read(&(__this_module.uc.usecount)) - 3;
 }
 #endif
 
index 5990b69a3cc49b03d6d5a32a37d63c6e53174f5e..443daba5aaf9614dc9c09a81456fc88635105b30 100644 (file)
@@ -50,6 +50,9 @@
  *     Revision 0.39:  SPX interfaces
  *     Revision 0.40:  Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
  *      Revision 0.41:  802.2TR removed (p.norton@computer.org)
+ *                     Fixed connecting to primary net,
+ *                     Automatic binding on send & receive,
+ *                     Martijn van Oosterhout <kleptogimp@geocities.com>
  *
  *     Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
  *     pair. Also, now usage count is managed this way
@@ -450,7 +453,57 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c
        struct sock *sock1 = NULL, *sock2 = NULL;
        struct sk_buff *skb1 = NULL, *skb2 = NULL;
 
-       sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
+       if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) 
+       {
+               /* 
+                * The packet's target is a NCP connection handler. We want to
+                * hand it to the correct socket directly within the kernel,
+                * so that the mars_nwe packet distribution process
+                * does not have to do it. Here we only care about NCP and
+                * BURST packets.
+                * You might call this a hack, but believe me, you do not
+                * want a complete NCP layer in the kernel, and this is
+                * VERY fast as well.
+                */
+               int connection = 0;
+
+               if (*((char*)(ipx+1)) == 0x22 &&  *((char*)(ipx+1)+1) == 0x22) 
+               {
+                       /*
+                        * The packet is a NCP request
+                        */
+                       connection = ( ((int) *((char*)(ipx+1)+5)) << 8 )
+                              | (int) *((char*)(ipx+1)+3);
+               } 
+               else if (*((char*)(ipx+1))== 0x77 &&  *((char*)(ipx+1)+1) == 0x77) 
+               {
+                       /*
+                        * The packet is a BURST packet
+                        */
+                       connection = ( ((int) *((char*)(ipx+1)+9)) << 8 )
+                              | (int) *((char*)(ipx+1)+8);
+               }
+
+               if (connection) 
+               {
+                       /*
+                        * Now we have to look for a special NCP connection handling
+                        * socket. Only these sockets have ipx_ncp_conn != 0, set
+                        * by SIOCIPXNCPCONN.
+                        */
+                       for (sock1=intrfc->if_sklist;
+                               (sock1 != NULL) &&
+                               (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
+                                       sock1=sock1->next);
+               }
+        }
+        if (sock1 == NULL) 
+       {
+               /* No special socket found, forward the packet the
+                * normal way.
+                */
+               sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
+       }
 
        /*
         * We need to check if there is a primary net and if
@@ -1822,7 +1875,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        }
 
        /* protect IPX system stuff like routing/sap */
-       if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !suser())
+       if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN))
                return (-EACCES);
 
        sk->protinfo.af_ipx.port = addr->sipx_port;
@@ -1930,7 +1983,8 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
                        return (ret);
        }
 
-       if(ipxrtr_lookup(addr->sipx_network) == NULL)
+        /* We can either connect to primary network or somewhere we can route to */
+       if( !(addr->sipx_network == 0 && ipx_primary_net != NULL) && ipxrtr_lookup(addr->sipx_network) == NULL)
                return (-ENETUNREACH);
 
        sk->protinfo.af_ipx.dest_addr.net  = addr->sipx_network;
@@ -2061,8 +2115,9 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
        int retval;
        int flags = msg->msg_flags;
 
-       if(sk->zapped)
-               return (-EIO);  /* Socket not bound */
+       /* Socket gets bound below anyway */
+/*     if(sk->zapped)
+               return (-EIO); */       /* Socket not bound */
        if(flags & ~MSG_DONTWAIT)
                return (-EINVAL);
 
@@ -2120,6 +2175,26 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size,
        struct sk_buff *skb;
        int copied, err;
 
+       /* put the autobinding in */
+       if(sk->protinfo.af_ipx.port == 0)
+       {
+               struct sockaddr_ipx uaddr;
+               int ret;
+
+               uaddr.sipx_port         = 0;
+               uaddr.sipx_network      = 0;
+
+#ifdef CONFIG_IPX_INTERN
+               memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,
+                      IPX_NODE_LEN);
+#endif /* CONFIG_IPX_INTERN */
+
+               ret = ipx_bind(sock, (struct sockaddr *)&uaddr,
+                               sizeof(struct sockaddr_ipx));
+               if(ret != 0)
+                       return (ret);
+       }
+       
        if(sk->zapped)
                return (-ENOTCONN);
 
@@ -2191,14 +2266,14 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
 
                case SIOCADDRT:
                case SIOCDELRT:
-                       if(!suser())
+                       if(!capable(CAP_NET_ADMIN))
                                return (-EPERM);
                        return (ipxrtr_ioctl(cmd,(void *)arg));
 
                case SIOCSIFADDR:
                case SIOCAIPXITFCRT:
                case SIOCAIPXPRISLT:
-                       if(!suser())
+                       if(!capable(CAP_NET_ADMIN))
                                return (-EPERM);
 
                case SIOCGIFADDR:
@@ -2207,6 +2282,18 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
                case SIOCIPXCFGDATA:
                        return (ipxcfg_get_config_data((void *)arg));
 
+               case SIOCIPXNCPCONN:
+                {
+                       int err;
+                       /*
+                        * This socket wants to take care of the NCP connection
+                        * handed to us in arg.
+                        */
+                       if (!capable(CAP_NET_ADMIN))
+                               return(-EPERM);
+                       return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg));
+                }
+
                case SIOCGSTAMP:
                {
                        int ret = -EINVAL;
index f2fb9e36f944196dd52c90a894b60933f7eda547..0e314653ea172fe26863a6754764a183adb2dcc0 100644 (file)
@@ -898,7 +898,7 @@ __initfunc(int psched_calibrate_clock(void))
        stop = jiffies + HZ/10;
        PSCHED_GET_TIME(stamp);
        do_gettimeofday(&tv);
-       while (jiffies < stop)
+       while (time_before(jiffies, stop))
                barrier();
        PSCHED_GET_TIME(stamp1);
        do_gettimeofday(&tv1);
index 2ac1f7b7f2b88c2c8fa0e44820cbc8a489714f9d..0a907a8f199a2b7ba721d3a1291c29da06db7ee1 100644 (file)
@@ -117,7 +117,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth)
                                printk("RPC: rpcauth_gc_credcache looping!\n");
                                break;
                        }
-                       if (!cred->cr_count && cred->cr_expire < jiffies) {
+                       if (!cred->cr_count && time_after(jiffies, cred->cr_expire)) {
                                *q = cred->cr_next;
                                cred->cr_next = free;
                                free = cred;
@@ -160,7 +160,7 @@ rpcauth_lookup_credcache(struct rpc_task *task)
 
        nr = RPC_DO_ROOTOVERRIDE(task)? 0 : (current->uid % RPC_CREDCACHE_NR);
 
-       if (auth->au_nextgc < jiffies)
+       if (time_after(jiffies, auth->au_nextgc))
                rpcauth_gc_credcache(auth);
 
        q = &auth->au_credcache[nr];
index 851f4d9523a9724d6dee151f6a64470db05ab228..827a8d42ee383d566871cef986e546d4269e3c67 100644 (file)
@@ -293,7 +293,7 @@ xprt_adjust_cwnd(struct rpc_xprt *xprt, int result)
        if (xprt->nocong)
                return;
        if (result >= 0) {
-               if (xprt->cong < cwnd || jiffies < xprt->congtime)
+               if (xprt->cong < cwnd || time_before(jiffies, xprt->congtime))
                        return;
                /* The (cwnd >> 1) term makes sure
                 * the result gets rounded properly. */
@@ -543,7 +543,7 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied)
                pkt_cnt++;
                pkt_len += req->rq_slen + copied;
                pkt_rtt += jiffies - req->rq_xtime;
-               if (nextstat < jiffies) {
+               if (time_after(jiffies, nextstat)) {
                        printk("RPC: %lu %ld cwnd\n", jiffies, xprt->cwnd);
                        printk("RPC: %ld %ld %ld %ld stat\n",
                                        jiffies, pkt_cnt, pkt_len, pkt_rtt);
index d8ca35755eb05ad48418dba97298c367928d880d..47515f69c735dd5f16303a27e09505b9bb20e8b8 100644 (file)
 #
 # 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help
 # texts.
+#
+# 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net)
+# Remove a /tmp security hole in get_def (also makes it faster).
+# Give uninitialized variables canonical values rather than null value.
+# Change a lot of places to call set_x_info uniformly.
+# Take out message about preparing version (old sound driver cruft).
+#
+# 13 Dec 1998, Riley H Williams (rhw@bigfoot.com)
+# When an error occurs, actually display the error message as well as
+# our comments thereon.
 
 
 #
@@ -65,20 +75,24 @@ single_menu_mode=
 #
 set -h +o posix
 
-#
-# Converts "# xxx is not..." to xxx=n
-#
-parse_config () {
-       sed -e 's/# \(.*\) is not.*/\1=n/'
-}
 
+
+# Given a configuration variable, set the global variable $x to its value,
+# and the global variable $info to the string " (NEW)" if this is a new
+# variable.
 #
-# Parses the defconfig file to set the default for a new parameter.
-#
-function get_def () {
-       parse_config < arch/$ARCH/defconfig | grep "^$1=" > /tmp/conf.$$
-       . /tmp/conf.$$
-       rm /tmp/conf.$$
+# This function looks for: (1) the current value, or (2) the default value
+# from the arch-dependent defconfig file, or (3) a default passed by the caller.
+
+function set_x_info () {
+    eval x=\$$1
+    if [ -z "$x" ]; then
+       eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig`
+       eval x=\${$1:-"$2"}
+       eval $1=$x
+       eval INFO_$1="' (NEW)'"
+    fi
+    eval info="\$INFO_$1"
 }
 
 #
@@ -92,19 +106,6 @@ function get_def () {
 #
 load_functions () {
 
-#
-# Macro for setting the x and info varibles. get's default from defconfig
-# file if it's a new parameter.
-#
-function set_x () {
-       eval x=\$$1
-       if [ -z "$x" ]; then
-               get_def "$1"
-               eval x=\${$1:-'n'} INFO_$1="' (NEW)'"
-       fi
-       eval info="\$INFO_$1"
-}
-
 #
 # Additional comments
 #
@@ -125,7 +126,7 @@ function define_bool () {
 # which calls our local bool function.
 #
 function bool () {
-       set_x "$2"
+       set_x_info "$2" "n"
 
        case $x in
        y|m)    flag="*" ;;
@@ -148,7 +149,7 @@ function tristate () {
        then
                bool "$1" "$2"
        else
-               set_x "$2"
+               set_x_info "$2" "n"
        
                case $x in
                y) flag="*" ;;
@@ -193,9 +194,9 @@ function dep_tristate () {
 # Add a menu item which will call our local int function.
 # 
 function int () {
-       eval $2=\${$2:-"$3"} x=\$$2
+       set_x_info "$2" "$3"
 
-       echo -ne "'$2' '($x) $1' " >>MCmenu
+       echo -ne "'$2' '($x) $1$info' " >>MCmenu
 
        echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists
 }
@@ -204,9 +205,10 @@ function int () {
 # Add a menu item which will call our local hex function.
 # 
 function hex () {
-       eval $2=\${$2:-"$3"} x=\${$2##*[x,X]}
+       set_x_info "$2" "$3"
+       x=${x##*[x,X]}
 
-       echo -ne "'$2' '($x) $1' " >>MCmenu
+       echo -ne "'$2' '($x) $1$info' " >>MCmenu
 
        echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists
 }
@@ -215,9 +217,9 @@ function hex () {
 # Add a menu item which will call our local string function.
 # 
 function string () {
-       eval $2=\${$2:-"$3"} x=\$$2
+       set_x_info "$2" "$3"
 
-       echo -ne "'$2' '     $1: \"$x\"' " >>MCmenu
+       echo -ne "'$2' '     $1: \"$x\"$info' " >>MCmenu
 
        echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists
 }
@@ -370,7 +372,7 @@ function l_bool () {
 # Same as bool() except options are (Module/No)
 #
 function mod_bool () {
-       set_x "$2"
+       set_x_info "$2" "n"
 
        case $x in
        y|m) flag='M' ;;
@@ -722,14 +724,20 @@ function activate_menu () {
        do
                comment_ctr=0           #So comment lines get unique tags
 
-               $1 "$default"           #Create the lxdialog menu & functions
+               $1 "$default" 2> MCerror #Create the lxdialog menu & functions
 
                if [ "$?" != "0" ]
                then
                        clear
                        cat <<EOM
+
 Menuconfig has encountered a possible error in one of the kernel's
-configuration files and is unable to continue.
+configuration files and is unable to continue.  Here is the error
+report:
+
+EOM
+                       sed 's/^/ Q> /' MCerror
+                       cat <<EOM
 
 Please report this to the maintainer <mec@shout.net>.  You may also
 send a problem report to <linux-kernel@vger.rutgers.edu>.
@@ -741,6 +749,7 @@ EOM
                        cleanup
                        exit 1
                fi
+               rm -f MCerror
 
                . ./MCradiolists                #Source the menu's functions
 
@@ -778,6 +787,7 @@ EOM
                        stty sane
                        clear
                        cat <<EOM
+
 There seems to be a problem with the lxdialog companion utility which is
 built prior to running Menuconfig.  Usually this is an indicator that you
 have upgraded/downgraded your ncurses libraries and did not remove the 
@@ -953,18 +963,6 @@ save_configuration () {
         echo
        echo -n "Saving your kernel configuration."
 
-       #
-       # Macro for setting the newval varible. get's default from defconfig
-       # file if it's a new parameter and it has not been shown yet.
-       #
-       function set_newval () {
-               eval newval=\$$1
-               if [ -z "$newval" ]; then
-                       get_def "$1"
-                       eval newval=\${$1:-'n'}
-               fi
-       }
-
        #
        # Now, let's redefine the configuration functions for final
        # output to the config files.
@@ -972,43 +970,35 @@ save_configuration () {
        # Nested function definitions, YIPEE!
        #
        function bool () {
-               set_newval "$2"
-               eval define_bool "$2" "$newval"
+               set_x_info "$2" "n"
+               eval define_bool "$2" "$x"
        }
 
        function tristate () {
-               set_newval "$2"
-               eval define_bool "$2" "$newval"
+               set_x_info "$2" "n"
+               eval define_bool "$2" "$x"
        }
 
        function dep_tristate () {
-               set_newval "$2"
-
-               if eval [ "_$3" = "_m" ]
-               then
-                       if [ "$newval" = "y" ]
-                       then
-                               newval="m"
-                       fi
-               fi
-
-               define_bool "$2" "$newval"
+               set_x_info "$2" "n"
+               if [ "$3" = "m" -a "$x" = "y" ]; then x="m"; fi
+               define_bool "$2" "$x"
        }
 
        function int () {
-               eval x=\${$2:-"$3"}
+               set_x_info "$2" "$3"
                echo "$2=$x"            >>$CONFIG
                echo "#define $2 ($x)"  >>$CONFIG_H
        }
 
        function hex () {
-               eval x=\${$2:-"$3"}
+               set_x_info "$2" "$3"
                echo "$2=$x"                     >>$CONFIG
                echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H
        }
 
        function string () {
-               eval x=\${$2:-"$3"}
+               set_x_info "$2" "$3"
                echo "$2=\"$x\""                         >>$CONFIG
                echo "#define $2 \"$x\""        >>$CONFIG_H
        }
@@ -1250,10 +1240,8 @@ fi
 # Fresh new log.
 >.menuconfig.log
 
-echo -n "Preparing configuration scripts: version" 
-
 # Load the functions used by the config.in files.
-echo -n ", functions"
+echo -n "Preparing scripts: functions" 
 load_functions
 
 if [ ! -e $CONFIG_IN ]